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 (#26545)

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.

(cherry picked from commit 48b4445)
  • Loading branch information
crisbeto committed Feb 2, 2023
1 parent 719cff0 commit 621d175
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
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
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
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
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 621d175

Please sign in to comment.