+
diff --git a/src/material-experimental/mdc-checkbox/checkbox.spec.ts b/src/material-experimental/mdc-checkbox/checkbox.spec.ts
index 0e4861a25df6..d3c09398eeb7 100644
--- a/src/material-experimental/mdc-checkbox/checkbox.spec.ts
+++ b/src/material-experimental/mdc-checkbox/checkbox.spec.ts
@@ -309,7 +309,20 @@ describe('MDC-based MatCheckbox', () => {
);
}));
- it('should not trigger the click event multiple times', fakeAsync(() => {
+ it('should trigger the click once when clicking on the ', fakeAsync(() => {
+ spyOn(testComponent, 'onCheckboxClick');
+
+ expect(inputElement.checked).toBe(false);
+
+ inputElement.click();
+ fixture.detectChanges();
+ flush();
+
+ expect(inputElement.checked).toBe(true);
+ expect(testComponent.onCheckboxClick).toHaveBeenCalledTimes(1);
+ }));
+
+ it('should trigger the click event once when clicking on the label', fakeAsync(() => {
// By default, when clicking on a label element, a generated click will be dispatched
// on the associated input element.
// Since we're using a label element and a visual hidden input, this behavior can led
@@ -1037,7 +1050,7 @@ describe('MatCheckboxDefaultOptions', () => {
/** Simple component for testing a single checkbox. */
@Component({
template: `
-
+
{
[color]="checkboxColor"
[disableRipple]="disableRipple"
[value]="checkboxValue"
- (click)="onCheckboxClick($event)"
(change)="onCheckboxChange($event)">
Simple checkbox
diff --git a/src/material-experimental/mdc-checkbox/checkbox.ts b/src/material-experimental/mdc-checkbox/checkbox.ts
index 7005098f9528..8454b5893a92 100644
--- a/src/material-experimental/mdc-checkbox/checkbox.ts
+++ b/src/material-experimental/mdc-checkbox/checkbox.ts
@@ -116,4 +116,17 @@ export class MatCheckbox
_onInputClick() {
super._handleInputClick();
}
+
+ /**
+ * Prevent click events that come from the `` element from bubbling. This prevents the
+ * click handler on the host from triggering twice when clicking on the `` element. After
+ * the click event on the `` propagates, the browsers dispatches click on the associated
+ * ``. By preventing clicks on the label by bubbling, we ensure only one click event
+ * bubbles when the label is clicked.
+ */
+ _preventBubblingFromLabel(event: MouseEvent) {
+ if (!!event.target && this._labelElement.nativeElement.contains(event.target as HTMLElement)) {
+ event.stopPropagation();
+ }
+ }
}
diff --git a/src/material/checkbox/checkbox.spec.ts b/src/material/checkbox/checkbox.spec.ts
index 6108131b2a2f..3933ffb0da3a 100644
--- a/src/material/checkbox/checkbox.spec.ts
+++ b/src/material/checkbox/checkbox.spec.ts
@@ -296,12 +296,7 @@ describe('MatCheckbox', () => {
expect(checkboxNativeElement.classList).toContain('mat-checkbox-label-before');
});
- it('should not trigger the click event multiple times', () => {
- // By default, when clicking on a label element, a generated click will be dispatched
- // on the associated input element.
- // Since we're using a label element and a visual hidden input, this behavior can led
- // to an issue, where the click events on the checkbox are getting executed twice.
-
+ it('should trigger the click event once when clicking on the label', () => {
spyOn(testComponent, 'onCheckboxClick');
expect(inputElement.checked).toBe(false);
diff --git a/src/material/checkbox/checkbox.ts b/src/material/checkbox/checkbox.ts
index 928458d1f969..f0640c3a2748 100644
--- a/src/material/checkbox/checkbox.ts
+++ b/src/material/checkbox/checkbox.ts
@@ -183,6 +183,9 @@ export abstract class _MatCheckboxBase
/** The native `` element */
@ViewChild('input') _inputElement: ElementRef;
+ /** The native `