diff --git a/src/lib/core/ripple/ripple-renderer.ts b/src/lib/core/ripple/ripple-renderer.ts index f3a1dac39875..fcbc66846043 100644 --- a/src/lib/core/ripple/ripple-renderer.ts +++ b/src/lib/core/ripple/ripple-renderer.ts @@ -110,12 +110,14 @@ export class RippleRenderer { this._containerElement = elementRef.nativeElement; // Specify events which need to be registered on the trigger. - this._triggerEvents.set('mousedown', this.onMousedown); - this._triggerEvents.set('mouseup', this.onPointerUp); - this._triggerEvents.set('mouseleave', this.onPointerUp); - - this._triggerEvents.set('touchstart', this.onTouchStart); - this._triggerEvents.set('touchend', this.onPointerUp); + this._triggerEvents + .set('mousedown', this.onMousedown) + .set('mouseup', this.onPointerUp) + .set('mouseleave', this.onPointerUp) + + .set('touchstart', this.onTouchStart) + .set('touchend', this.onPointerUp) + .set('touchcancel', this.onPointerUp); } } diff --git a/src/lib/core/ripple/ripple.spec.ts b/src/lib/core/ripple/ripple.spec.ts index 2d7f919d39dc..85bc3fb884e5 100644 --- a/src/lib/core/ripple/ripple.spec.ts +++ b/src/lib/core/ripple/ripple.spec.ts @@ -127,6 +127,17 @@ describe('MatRipple', () => { expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0); })); + it('should clear ripples if the touch sequence is cancelled', fakeAsync(() => { + dispatchTouchEvent(rippleTarget, 'touchstart'); + tick(enterDuration); + expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1); + + dispatchTouchEvent(rippleTarget, 'touchcancel'); + tick(exitDuration); + + expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0); + })); + it('should launch multiple ripples for multi-touch', fakeAsync(() => { const touchEvent = createTouchEvent('touchstart');