Skip to content

Commit e022ec0

Browse files
authored
refactor(material/progress-spinner): simplify structural styles (angular#29408)
Reworks the structural styles of the progress spinner to be smaller and easier to maintain.
1 parent 8a16aa1 commit e022ec0

File tree

3 files changed

+199
-38
lines changed

3 files changed

+199
-38
lines changed

src/material/core/tokens/m2/mdc/_circular-progress.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ $prefix: (mdc, circular-progress);
3232
}
3333

3434
// Tokens that can be configured through Angular Material's color theming API.
35-
@function get-color-tokens($theme) {
35+
@function get-color-tokens($theme, $palette-name: primary) {
3636
@return (
3737
// The color of the progress spinner's active indicator.
38-
active-indicator-color: inspection.get-theme-color($theme, primary)
38+
active-indicator-color: inspection.get-theme-color($theme, $palette-name)
3939
);
4040
}
4141

src/material/progress-spinner/_progress-spinner-theme.scss

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
@use '../core/theming/validation';
55
@use '../core/tokens/token-utils';
66
@use '../core/tokens/m2/mdc/circular-progress' as tokens-mdc-circular-progress;
7-
@use '@material/circular-progress/circular-progress-theme' as mdc-circular-progress-theme;
87

98
/// Outputs base theme styles (styles not dependent on the color, typography, or density settings)
109
/// for the mat-progress-spinner.
@@ -14,11 +13,9 @@
1413
@include _theme-from-tokens(inspection.get-theme-tokens($theme, base));
1514
}
1615
@else {
17-
// Add default values for tokens not related to color, typography, or density.
1816
@include sass-utils.current-selector-or-root() {
19-
@include mdc-circular-progress-theme.theme(
20-
tokens-mdc-circular-progress.get-unthemable-tokens()
21-
);
17+
@include token-utils.create-token-values(tokens-mdc-circular-progress.$prefix,
18+
tokens-mdc-circular-progress.get-unthemable-tokens());
2219
}
2320
}
2421
}
@@ -33,19 +30,18 @@
3330
@include _theme-from-tokens(inspection.get-theme-tokens($theme, color), $options...);
3431
}
3532
@else {
36-
$mdc-circular-progress-color-tokens: tokens-mdc-circular-progress.get-color-tokens($theme);
37-
3833
@include sass-utils.current-selector-or-root() {
39-
@include mdc-circular-progress-theme.theme($mdc-circular-progress-color-tokens);
34+
@include token-utils.create-token-values(tokens-mdc-circular-progress.$prefix,
35+
tokens-mdc-circular-progress.get-color-tokens($theme, primary));
4036

4137
.mat-accent {
42-
$color: inspection.get-theme-color($theme, accent);
43-
@include mdc-circular-progress-theme.theme((active-indicator-color: $color));
38+
@include token-utils.create-token-values(tokens-mdc-circular-progress.$prefix,
39+
tokens-mdc-circular-progress.get-color-tokens($theme, accent));
4440
}
4541

4642
.mat-warn {
47-
$color: inspection.get-theme-color($theme, warn);
48-
@include mdc-circular-progress-theme.theme((active-indicator-color: $color));
43+
@include token-utils.create-token-values(tokens-mdc-circular-progress.$prefix,
44+
tokens-mdc-circular-progress.get-color-tokens($theme, warn));
4945
}
5046
}
5147
}
@@ -101,6 +97,7 @@
10197
@include validation.selector-defined(
10298
'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector');
10399
$mdc-circular-progress-tokens:
104-
token-utils.get-tokens-for($tokens, tokens-mdc-circular-progress.$prefix, $options...);
105-
@include mdc-circular-progress-theme.theme($mdc-circular-progress-tokens);
100+
token-utils.get-tokens-for($tokens, tokens-mdc-circular-progress.$prefix, $options...);
101+
@include token-utils.create-token-values(tokens-mdc-circular-progress.$prefix,
102+
$mdc-circular-progress-tokens);
106103
}
Lines changed: 186 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,6 @@
11
@use '@angular/cdk';
2-
@use '@material/circular-progress/circular-progress' as mdc-circular-progress;
3-
@use '@material/circular-progress/circular-progress-theme' as mdc-circular-progress-theme;
4-
@use '@material/theme/custom-properties' as mdc-custom-properties;
5-
@use '../core/tokens/m2/mdc/circular-progress' as m2-mdc-circular-progress;
6-
7-
// The slots for tokens that will be configured in the theme can be emitted with no fallback.
8-
@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
9-
$mdc-circular-progress-token-slots: m2-mdc-circular-progress.get-token-slots();
10-
11-
// Add the MDC progress spinner static styles.
12-
@include mdc-circular-progress.static-styles();
13-
14-
.mat-mdc-progress-spinner {
15-
// Add the official slots for the MDC circular progress.
16-
@include mdc-circular-progress-theme.theme-styles($mdc-circular-progress-token-slots);
17-
}
18-
}
2+
@use '../core/tokens/token-utils';
3+
@use '../core/tokens/m2/mdc/circular-progress' as tokens-mdc-circular-progress;
194

205
.mat-mdc-progress-spinner {
216
// Explicitly set to `block` since the browser defaults custom elements to `inline`.
@@ -26,21 +11,31 @@
2611

2712
// Spinners with a diameter less than half the existing line-height will become distorted.
2813
// Explicitly set the line-height to 0px to avoid this issue.
29-
// https://github.com/material-components/material-components-web/issues/7118
3014
line-height: 0;
15+
position: relative;
16+
direction: ltr;
17+
transition: opacity 250ms cubic-bezier(0.4, 0, 0.6, 1);
18+
19+
circle {
20+
@include token-utils.use-tokens(
21+
tokens-mdc-circular-progress.$prefix,
22+
tokens-mdc-circular-progress.get-token-slots()
23+
) {
24+
@include token-utils.create-token-slot(stroke-width, active-indicator-width);
25+
}
26+
}
3127

3228
&._mat-animation-noopable {
33-
&,
34-
.mdc-circular-progress__determinate-circle {
29+
&, .mdc-circular-progress__determinate-circle {
3530
// The spinner itself has a transition on `opacity`.
36-
transition: none;
31+
transition: none !important;
3732
}
3833

3934
.mdc-circular-progress__indeterminate-circle-graphic,
4035
.mdc-circular-progress__spinner-layer,
4136
.mdc-circular-progress__indeterminate-container {
4237
// Disables the rotation animations.
43-
animation: none;
38+
animation: none !important;
4439
}
4540

4641
.mdc-circular-progress__indeterminate-container circle {
@@ -61,3 +56,172 @@
6156
}
6257
}
6358
}
59+
60+
.mdc-circular-progress__determinate-container,
61+
.mdc-circular-progress__indeterminate-circle-graphic,
62+
.mdc-circular-progress__indeterminate-container,
63+
.mdc-circular-progress__spinner-layer {
64+
position: absolute;
65+
width: 100%;
66+
height: 100%;
67+
}
68+
69+
.mdc-circular-progress__determinate-container {
70+
transform: rotate(-90deg);
71+
72+
.mdc-circular-progress--indeterminate & {
73+
opacity: 0;
74+
}
75+
}
76+
77+
.mdc-circular-progress__indeterminate-container {
78+
font-size: 0;
79+
letter-spacing: 0;
80+
white-space: nowrap;
81+
opacity: 0;
82+
83+
.mdc-circular-progress--indeterminate & {
84+
opacity: 1;
85+
animation: mdc-circular-progress-container-rotate 1568.2352941176ms linear infinite;
86+
}
87+
}
88+
89+
.mdc-circular-progress__determinate-circle-graphic,
90+
.mdc-circular-progress__indeterminate-circle-graphic {
91+
fill: transparent;
92+
}
93+
94+
.mat-mdc-progress-spinner .mdc-circular-progress__determinate-circle,
95+
.mat-mdc-progress-spinner .mdc-circular-progress__indeterminate-circle-graphic {
96+
@include token-utils.use-tokens(
97+
tokens-mdc-circular-progress.$prefix,
98+
tokens-mdc-circular-progress.get-token-slots()
99+
) {
100+
@include token-utils.create-token-slot(stroke, active-indicator-color);
101+
}
102+
103+
@include cdk.high-contrast(active, off) {
104+
stroke: CanvasText;
105+
}
106+
}
107+
108+
.mdc-circular-progress__determinate-circle {
109+
transition: stroke-dashoffset 500ms cubic-bezier(0, 0, 0.2, 1);
110+
}
111+
112+
.mdc-circular-progress__gap-patch {
113+
position: absolute;
114+
top: 0;
115+
left: 47.5%;
116+
box-sizing: border-box;
117+
width: 5%;
118+
height: 100%;
119+
overflow: hidden;
120+
}
121+
122+
.mdc-circular-progress__indeterminate-circle-graphic {
123+
.mdc-circular-progress__gap-patch & {
124+
left: -900%;
125+
width: 2000%;
126+
transform: rotate(180deg);
127+
}
128+
129+
.mdc-circular-progress__circle-clipper & {
130+
width: 200%;
131+
}
132+
133+
.mdc-circular-progress__circle-right & {
134+
left: -100%;
135+
}
136+
137+
.mdc-circular-progress--indeterminate .mdc-circular-progress__circle-left & {
138+
animation: mdc-circular-progress-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
139+
}
140+
141+
.mdc-circular-progress--indeterminate .mdc-circular-progress__circle-right & {
142+
animation: mdc-circular-progress-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
143+
}
144+
}
145+
146+
.mdc-circular-progress__circle-clipper {
147+
display: inline-flex;
148+
position: relative;
149+
width: 50%;
150+
height: 100%;
151+
overflow: hidden;
152+
}
153+
154+
.mdc-circular-progress__spinner-layer {
155+
.mdc-circular-progress--indeterminate & {
156+
animation: mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1)
157+
infinite both;
158+
}
159+
}
160+
161+
@keyframes mdc-circular-progress-container-rotate {
162+
to {
163+
transform: rotate(360deg);
164+
}
165+
}
166+
167+
@keyframes mdc-circular-progress-spinner-layer-rotate {
168+
12.5% {
169+
transform: rotate(135deg);
170+
}
171+
172+
25% {
173+
transform: rotate(270deg);
174+
}
175+
176+
37.5% {
177+
transform: rotate(405deg);
178+
}
179+
180+
50% {
181+
transform: rotate(540deg);
182+
}
183+
184+
62.5% {
185+
transform: rotate(675deg);
186+
}
187+
188+
75% {
189+
transform: rotate(810deg);
190+
}
191+
192+
87.5% {
193+
transform: rotate(945deg);
194+
}
195+
196+
100% {
197+
transform: rotate(1080deg);
198+
}
199+
}
200+
201+
@keyframes mdc-circular-progress-left-spin {
202+
from {
203+
transform: rotate(265deg);
204+
}
205+
206+
50% {
207+
transform: rotate(130deg);
208+
}
209+
210+
to {
211+
transform: rotate(265deg);
212+
}
213+
}
214+
215+
@keyframes mdc-circular-progress-right-spin {
216+
from {
217+
transform: rotate(-265deg);
218+
}
219+
220+
50% {
221+
transform: rotate(-130deg);
222+
}
223+
224+
to {
225+
transform: rotate(-265deg);
226+
}
227+
}

0 commit comments

Comments
 (0)