mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(chips): event propagation not stopped by remove button (#8772)
Fixes clicking on the chip remove button propagating up and potentially triggering its parent control. This is usually handled by the chip itself, however clicking on the button could remove the chip before it has the chance to stop propagation. Fixes #8771.
This commit is contained in:
committed by
Andrew Seguin
parent
fba3728821
commit
c7e2d4ec73
@@ -1,7 +1,8 @@
|
||||
import {Component, DebugElement} from '@angular/core';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import {fakeAsync, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import {MatChip, MatChipsModule} from './index';
|
||||
import {dispatchFakeEvent} from '@angular/cdk/testing';
|
||||
|
||||
describe('Chip Remove', () => {
|
||||
let fixture: ComponentFixture<any>;
|
||||
@@ -9,7 +10,7 @@ describe('Chip Remove', () => {
|
||||
let chipDebugElement: DebugElement;
|
||||
let chipNativeElement: HTMLElement;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(fakeAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [MatChipsModule],
|
||||
declarations: [
|
||||
@@ -18,9 +19,6 @@ describe('Chip Remove', () => {
|
||||
});
|
||||
|
||||
TestBed.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(TestChip);
|
||||
testChip = fixture.debugElement.componentInstance;
|
||||
fixture.detectChanges();
|
||||
@@ -30,14 +28,14 @@ describe('Chip Remove', () => {
|
||||
}));
|
||||
|
||||
describe('basic behavior', () => {
|
||||
it('should applies the `mat-chip-remove` CSS class', () => {
|
||||
let hrefElement = chipNativeElement.querySelector('a')!;
|
||||
it('should apply the `mat-chip-remove` CSS class', () => {
|
||||
const hrefElement = chipNativeElement.querySelector('a')!;
|
||||
|
||||
expect(hrefElement.classList).toContain('mat-chip-remove');
|
||||
});
|
||||
|
||||
it('should emits (remove) on click', () => {
|
||||
let hrefElement = chipNativeElement.querySelector('a')!;
|
||||
it('should emit (remove) on click', () => {
|
||||
const hrefElement = chipNativeElement.querySelector('a')!;
|
||||
|
||||
testChip.removable = true;
|
||||
fixture.detectChanges();
|
||||
@@ -48,6 +46,19 @@ describe('Chip Remove', () => {
|
||||
|
||||
expect(testChip.didRemove).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should prevent the default click action', () => {
|
||||
const hrefElement = chipNativeElement.querySelector('a')!;
|
||||
|
||||
testChip.removable = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const event = dispatchFakeEvent(hrefElement, 'click');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(event.defaultPrevented).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -308,7 +308,7 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
|
||||
selector: '[matChipRemove]',
|
||||
host: {
|
||||
'class': 'mat-chip-remove',
|
||||
'(click)': '_handleClick()',
|
||||
'(click)': '_handleClick($event)',
|
||||
}
|
||||
})
|
||||
export class MatChipRemove {
|
||||
@@ -316,9 +316,14 @@ export class MatChipRemove {
|
||||
}
|
||||
|
||||
/** Calls the parent chip's public `remove()` method if applicable. */
|
||||
_handleClick(): void {
|
||||
_handleClick(event: MouseEvent): void {
|
||||
if (this._parentChip.removable) {
|
||||
this._parentChip.remove();
|
||||
|
||||
// Note: the parent chip does something similar, however since we're removing it,
|
||||
// its event handler will be unbound before it has had the chance to fire.
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user