Skip to content

Commit

Permalink
fix(material/checkbox): focus not moved to input when clicking on tou…
Browse files Browse the repository at this point in the history
…ch target

Fixes that while we were toggling the checked state of a checkbox when its touch target is clicked, we weren't moving focus to the internal `input`.

Fixes #26486.
  • Loading branch information
crisbeto committed Feb 2, 2023
1 parent a1d5614 commit 8a16abf
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/material/checkbox/checkbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
(click)="_preventBubblingFromLabel($event)">
<div #checkbox class="mdc-checkbox">
<!-- Render this element first so the input is on top. -->
<div class="mat-mdc-checkbox-touch-target" (click)="_onInputClick()"></div>
<div class="mat-mdc-checkbox-touch-target" (click)="_onTouchTargetClick()"></div>
<input #input
type="checkbox"
class="mdc-checkbox__native-control"
Expand Down
14 changes: 14 additions & 0 deletions src/material/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,20 @@ describe('MDC-based MatCheckbox', () => {
expect(document.activeElement).toBe(inputElement);
}));

it('should focus underlying input element when the touch target is clicked', fakeAsync(() => {
const touchTarget = checkboxElement.querySelector(
'.mat-mdc-checkbox-touch-target',
) as HTMLElement;

expect(document.activeElement).not.toBe(inputElement);

touchTarget.click();
fixture.detectChanges();
flush();

expect(document.activeElement).toBe(inputElement);
}));

it('should forward the value to input element', fakeAsync(() => {
testComponent.checkboxValue = 'basic_checkbox';
fixture.detectChanges();
Expand Down
10 changes: 10 additions & 0 deletions src/material/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,16 @@ export class MatCheckbox
super._handleInputClick();
}

_onTouchTargetClick() {
super._handleInputClick();

if (!this.disabled) {
// Normally the input should be focused already, but if the click
// comes from the touch target, then we might have to focus it ourselves.
this._inputElement.nativeElement.focus();
}
}

/**
* Prevent click events that come from the `<label/>` element from bubbling. This prevents the
* click handler on the host from triggering twice when clicking on the `<label/>` element. After
Expand Down
2 changes: 2 additions & 0 deletions tools/public_api_guard/material/checkbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export class MatCheckbox extends _MatCheckboxBase<MatCheckboxChange> implements
protected _getAnimationTargetElement(): HTMLInputElement;
// (undocumented)
_onInputClick(): void;
// (undocumented)
_onTouchTargetClick(): void;
_preventBubblingFromLabel(event: MouseEvent): void;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<MatCheckbox, "mat-checkbox", ["matCheckbox"], { "disableRipple": "disableRipple"; "color": "color"; "tabIndex": "tabIndex"; }, {}, never, ["*"], false, never>;
Expand Down

0 comments on commit 8a16abf

Please sign in to comment.