Skip to content

Commit

Permalink
fix(material/chips): prevent default behavior on remove button (#24722)
Browse files Browse the repository at this point in the history
Adds a `preventDefault` call to the `click` handlers of the chip remove icon in order to avoid things like form submissions and link navigations.

Fixes #24436.

(cherry picked from commit 3660530)
  • Loading branch information
crisbeto authored and amysorto committed Apr 12, 2022
1 parent 0d1755d commit 6c65b1d
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/material-experimental/mdc-chips/chip-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,12 @@ export class MatChipAction
/** Whether the action is interactive. */
@Input() isInteractive = true;

_handleClick(_event: MouseEvent) {
_handleClick(event: MouseEvent) {
// Usually these events can't happen while the chip is disabled since the browser won't
// allow them which is what MDC seems to rely on, however the event can be faked in tests.
if (!this.disabled && this.isInteractive) {
this._foundation.handleClick();
event.preventDefault();
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/material-experimental/mdc-chips/chip-remove.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Component} from '@angular/core';
import {waitForAsync, ComponentFixture, TestBed, fakeAsync, flush} from '@angular/core/testing';
import {dispatchKeyboardEvent} from '@angular/cdk/testing/private';
import {dispatchKeyboardEvent, dispatchMouseEvent} from '@angular/cdk/testing/private';
import {By} from '@angular/platform-browser';
import {SPACE, ENTER} from '@angular/cdk/keycodes';
import {MDCChipAnimation, MDCChipCssClasses} from '@material/chips/chip';
Expand Down Expand Up @@ -121,6 +121,14 @@ describe('MDC-based Chip Remove', () => {
const buttonElement = chipNativeElement.querySelector('.mdc-evolution-chip__icon--trailing')!;
expect(buttonElement.classList.contains('mat-mdc-focus-indicator')).toBe(true);
}));

it('should prevent the default click action', fakeAsync(() => {
const buttonElement = chipNativeElement.querySelector('button')!;
const event = dispatchMouseEvent(buttonElement, 'click');
triggerRemoveSequence();

expect(event.defaultPrevented).toBe(true);
}));
});
});

Expand Down
9 changes: 9 additions & 0 deletions src/material/chips/chip-remove.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Component, DebugElement} from '@angular/core';
import {By} from '@angular/platform-browser';
import {waitForAsync, ComponentFixture, TestBed} from '@angular/core/testing';
import {MatChip, MatChipsModule} from './index';
import {dispatchMouseEvent} from '@angular/cdk/testing/private';

describe('Chip Remove', () => {
let fixture: ComponentFixture<TestChip>;
Expand Down Expand Up @@ -74,6 +75,14 @@ describe('Chip Remove', () => {

expect(testChip.didRemove).not.toHaveBeenCalled();
});

it('should prevent the default click action', () => {
const buttonElement = chipNativeElement.querySelector('button')!;
const event = dispatchMouseEvent(buttonElement, 'click');
fixture.detectChanges();

expect(event.defaultPrevented).toBe(true);
});
});
});

Expand Down
1 change: 1 addition & 0 deletions src/material/chips/chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,5 +497,6 @@ export class MatChipRemove {
// the parent click listener of the `MatChip` would prevent propagation, but it can happen
// that the chip is being removed before the event bubbles up.
event.stopPropagation();
event.preventDefault();
}
}

0 comments on commit 6c65b1d

Please sign in to comment.