Skip to content

Commit 81b6a78

Browse files
fix(animations): prevent animations when in a noopanimations module (#10881)
1 parent 7282707 commit 81b6a78

File tree

5 files changed

+54
-5
lines changed

5 files changed

+54
-5
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// If the mat-animation-noop class is present on the components root element,
2+
// prevent non css animations from running.
3+
// NOTE: Currently this mixin should only be used with components that do not
4+
// have any projected content.
5+
@mixin _noop-animation() {
6+
// @at-root is used to steps outside of the hierarchy of the scss rules. This is
7+
// done to allow a class to be added to be added to base of the scss nesting
8+
// context.
9+
// For example:
10+
// .my-root {
11+
// .my-subclass {
12+
// @include _noop-animation()
13+
// }
14+
// }
15+
// results in:
16+
// ._mat-animation-noopable.my-root .my-subclass { ... }
17+
@at-root ._mat-animation-noopable#{&} {
18+
transition: none;
19+
animation: none;
20+
}
21+
}

src/lib/progress-bar/progress-bar.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
@import '../core/style/variables';
22
@import '../core/style/vendor-prefixes';
3+
@import '../core/style/noop-animation';
34

45
$mat-progress-bar-height: 5px !default;
56
$mat-progress-bar-full-animation-duration: 2000ms !default;
67
$mat-progress-bar-piece-animation-duration: 250ms !default;
78

89

910
.mat-progress-bar {
11+
@include _noop-animation();
1012
display: block;
1113
// Height is provided for mat-progress-bar to act as a default.
1214
height: $mat-progress-bar-height;
@@ -33,6 +35,7 @@ $mat-progress-bar-piece-animation-duration: 250ms !default;
3335
// The progress bar buffer is the bar indicator showing the buffer value and is only visible
3436
// beyond the current value of the primary progress bar.
3537
.mat-progress-bar-buffer {
38+
@include _noop-animation();
3639
transform-origin: top left;
3740
transition: transform $mat-progress-bar-piece-animation-duration ease;
3841
}
@@ -45,13 +48,15 @@ $mat-progress-bar-piece-animation-duration: 250ms !default;
4548

4649
// The progress bar fill fills the progress bar with the indicator color.
4750
.mat-progress-bar-fill {
51+
@include _noop-animation();
4852
animation: none;
4953
transform-origin: top left;
5054
transition: transform $mat-progress-bar-piece-animation-duration ease;
5155
}
5256

5357
// A pseudo element is created for each progress bar bar that fills with the indicator color.
5458
.mat-progress-bar-fill::after {
59+
@include _noop-animation();
5560
animation: none;
5661
content: '';
5762
display: inline-block;
@@ -76,23 +81,27 @@ $mat-progress-bar-piece-animation-duration: 250ms !default;
7681
&[mode='indeterminate'],
7782
&[mode='query'] {
7883
.mat-progress-bar-fill {
84+
@include _noop-animation();
7985
transition: none;
8086
}
8187
.mat-progress-bar-primary {
8288
// Avoids stacked animation tearing in Firefox >= 57.
89+
@include _noop-animation();
8390
@include backface-visibility(hidden);
8491
animation: mat-progress-bar-primary-indeterminate-translate
8592
$mat-progress-bar-full-animation-duration infinite linear;
8693
left: -145.166611%;
8794
}
8895
.mat-progress-bar-primary.mat-progress-bar-fill::after {
8996
// Avoids stacked animation tearing in Firefox >= 57.
97+
@include _noop-animation();
9098
@include backface-visibility(hidden);
9199
animation: mat-progress-bar-primary-indeterminate-scale
92100
$mat-progress-bar-full-animation-duration infinite linear;
93101
}
94102
.mat-progress-bar-secondary {
95103
// Avoids stacked animation tearing in Firefox >= 57.
104+
@include _noop-animation();
96105
@include backface-visibility(hidden);
97106
animation: mat-progress-bar-secondary-indeterminate-translate
98107
$mat-progress-bar-full-animation-duration infinite linear;
@@ -101,6 +110,7 @@ $mat-progress-bar-piece-animation-duration: 250ms !default;
101110
}
102111
.mat-progress-bar-secondary.mat-progress-bar-fill::after {
103112
// Avoids stacked animation tearing in Firefox >= 57.
113+
@include _noop-animation();
104114
@include backface-visibility(hidden);
105115
animation: mat-progress-bar-secondary-indeterminate-scale
106116
$mat-progress-bar-full-animation-duration infinite linear;
@@ -110,6 +120,7 @@ $mat-progress-bar-piece-animation-duration: 250ms !default;
110120
&[mode='buffer'] {
111121
.mat-progress-bar-background {
112122
// Avoids stacked animation tearing in Firefox >= 57.
123+
@include _noop-animation();
113124
@include backface-visibility(hidden);
114125
animation: mat-progress-bar-background-scroll
115126
$mat-progress-bar-piece-animation-duration infinite linear;

src/lib/progress-bar/progress-bar.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ import {
99
Component,
1010
ChangeDetectionStrategy,
1111
ElementRef,
12+
Inject,
1213
Input,
14+
Optional,
1315
ViewEncapsulation
1416
} from '@angular/core';
17+
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
1518
import {CanColor, mixinColor} from '@angular/material/core';
1619

1720
// TODO(josephperrott): Benchpress tests.
@@ -42,6 +45,7 @@ let progressbarId = 0;
4245
'[attr.aria-valuenow]': 'value',
4346
'[attr.mode]': 'mode',
4447
'class': 'mat-progress-bar',
48+
'[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`,
4549
},
4650
inputs: ['color'],
4751
templateUrl: 'progress-bar.html',
@@ -51,7 +55,9 @@ let progressbarId = 0;
5155
})
5256
export class MatProgressBar extends _MatProgressBarMixinBase implements CanColor {
5357

54-
constructor(public _elementRef: ElementRef) {
58+
59+
constructor(public _elementRef: ElementRef,
60+
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) {
5561
super(_elementRef);
5662
}
5763

src/lib/progress-spinner/progress-spinner.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@import '../core/style/variables';
2+
@import '../core/style/noop-animation';
23

34

45
// Animation config
@@ -22,16 +23,19 @@ $_mat-progress-spinner-default-circumference: $pi * $_mat-progress-spinner-defau
2223
}
2324

2425
circle {
26+
@include _noop-animation();
2527
fill: transparent;
2628
transform-origin: center;
2729
transition: stroke-dashoffset 225ms linear;
2830
}
2931

3032
&.mat-progress-spinner-indeterminate-animation[mode='indeterminate'] {
33+
@include _noop-animation();
3134
animation: mat-progress-spinner-linear-rotate $swift-ease-in-out-duration * 4
3235
linear infinite;
3336

3437
circle {
38+
@include _noop-animation();
3539
transition-property: stroke;
3640
// Note: we multiply the duration by 8, because the animation is spread out in 8 stages.
3741
animation-duration: $swift-ease-in-out-duration * 8;
@@ -41,12 +45,14 @@ $_mat-progress-spinner-default-circumference: $pi * $_mat-progress-spinner-defau
4145
}
4246

4347
&.mat-progress-spinner-indeterminate-fallback-animation[mode='indeterminate'] {
48+
@include _noop-animation();
4449
animation: mat-progress-spinner-stroke-rotate-fallback
4550
$mat-progress-spinner-stroke-rotate-fallback-duration
4651
$mat-progress-spinner-stroke-rotate-fallback-ease
4752
infinite;
4853

4954
circle {
55+
@include _noop-animation();
5056
transition-property: stroke;
5157
}
5258
}

src/lib/progress-spinner/progress-spinner.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
import {
1010
Component,
1111
ChangeDetectionStrategy,
12+
Inject,
1213
Input,
1314
ElementRef,
1415
ViewEncapsulation,
1516
Optional,
16-
Inject,
1717
} from '@angular/core';
18+
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
1819
import {CanColor, mixinColor} from '@angular/material/core';
1920
import {Platform} from '@angular/cdk/platform';
2021
import {DOCUMENT} from '@angular/common';
@@ -80,6 +81,7 @@ const INDETERMINATE_ANIMATION_TEMPLATE = `
8081
host: {
8182
'role': 'progressbar',
8283
'class': 'mat-progress-spinner',
84+
'[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`,
8385
'[style.width.px]': 'diameter',
8486
'[style.height.px]': 'diameter',
8587
'[attr.aria-valuemin]': 'mode === "determinate" ? 0 : null',
@@ -144,7 +146,8 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
144146

145147
constructor(public _elementRef: ElementRef,
146148
platform: Platform,
147-
@Optional() @Inject(DOCUMENT) private _document: any) {
149+
@Optional() @Inject(DOCUMENT) private _document: any,
150+
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) {
148151

149152
super(_elementRef);
150153
this._fallbackAnimation = platform.EDGE || platform.TRIDENT;
@@ -233,6 +236,7 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
233236
'role': 'progressbar',
234237
'mode': 'indeterminate',
235238
'class': 'mat-spinner mat-progress-spinner',
239+
'[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`,
236240
'[style.width.px]': 'diameter',
237241
'[style.height.px]': 'diameter',
238242
},
@@ -244,8 +248,9 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
244248
})
245249
export class MatSpinner extends MatProgressSpinner {
246250
constructor(elementRef: ElementRef, platform: Platform,
247-
@Optional() @Inject(DOCUMENT) document: any) {
248-
super(elementRef, platform, document);
251+
@Optional() @Inject(DOCUMENT) document: any,
252+
@Optional() @Inject(ANIMATION_MODULE_TYPE) _animationMode?: string) {
253+
super(elementRef, platform, document, _animationMode);
249254
this.mode = 'indeterminate';
250255
}
251256
}

0 commit comments

Comments
 (0)