Skip to content

Commit aaad105

Browse files
committed
fix(core): ripple mutating global options when animations are disabled
When animations are disabled, the ripple elements sets the animation duration of its global options to zero. The problem is that it's mutating the object that's used by all other ripples. The issue can be observed by going to the MDC checkbox demo and then trying to interact with something that should have a ripple.
1 parent 8a71288 commit aaad105

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

src/material/core/ripple/ripple.spec.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,14 +479,15 @@ describe('MatRipple', () => {
479479
let rippleDirective: MatRipple;
480480

481481
function createTestComponent(rippleConfig: RippleGlobalOptions,
482-
testComponent: any = BasicRippleContainer) {
482+
testComponent: any = BasicRippleContainer,
483+
extraImports: any[] = []) {
483484
// Reset the previously configured testing module to be able set new providers.
484485
// The testing module has been initialized in the root describe group for the ripples.
485486
TestBed.resetTestingModule();
486487
TestBed.configureTestingModule({
487-
imports: [MatRippleModule],
488+
imports: [MatRippleModule, ...extraImports],
488489
declarations: [testComponent],
489-
providers: [{ provide: MAT_RIPPLE_GLOBAL_OPTIONS, useValue: rippleConfig }]
490+
providers: [{provide: MAT_RIPPLE_GLOBAL_OPTIONS, useValue: rippleConfig}]
490491
});
491492

492493
fixture = TestBed.createComponent(testComponent);
@@ -569,6 +570,14 @@ describe('MatRipple', () => {
569570
// will still exist. To properly finish all timers, we just wait the remaining time.
570571
tick(enterDuration - exitDuration);
571572
}));
573+
574+
it('should not mutate the global options when NoopAnimationsModule is present', () => {
575+
const options: RippleGlobalOptions = {};
576+
577+
createTestComponent(options, RippleContainerWithoutBindings, [NoopAnimationsModule]);
578+
579+
expect(options.animation).toBeFalsy();
580+
});
572581
});
573582

574583
describe('with disabled animations', () => {

src/material/core/ripple/ripple.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
123123
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalOptions?: RippleGlobalOptions,
124124
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) {
125125

126-
this._globalOptions = globalOptions || {};
126+
// Clone the global options so we don't mutate them by accident.
127+
this._globalOptions = globalOptions ? {...globalOptions} : {};
127128
this._rippleRenderer = new RippleRenderer(this, ngZone, _elementRef, platform);
128129

129130
if (animationMode === 'NoopAnimations') {

0 commit comments

Comments
 (0)