Skip to content

fix(button): focus method does not respect specified origin #17183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/material/button/button.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,19 @@ describe('MatButton', () => {
expect(buttonDebugElement.nativeElement.classList.contains('custom-class')).toBe(true);
});

it('should be able to focus button with a specific focus origin', () => {
const fixture = TestBed.createComponent(TestApp);
const buttonDebugEl = fixture.debugElement.query(By.css('button'));
const buttonInstance = buttonDebugEl.componentInstance as MatButton;

expect(buttonDebugEl.nativeElement.classList).not.toContain('cdk-focused');

buttonInstance.focus('touch');

expect(buttonDebugEl.nativeElement.classList).toContain('cdk-focused');
expect(buttonDebugEl.nativeElement.classList).toContain('cdk-touch-focused');
});

describe('button[mat-fab]', () => {
it('should have accent palette by default', () => {
const fixture = TestBed.createComponent(TestApp);
Expand Down
6 changes: 2 additions & 4 deletions src/material/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,8 @@ export class MatButton extends _MatButtonMixinBase
}

/** Focuses the button. */
focus(_origin?: FocusOrigin, options?: FocusOptions): void {
// Note that we aren't using `_origin`, but we need to keep it because some internal consumers
// use `MatButton` in a `FocusKeyManager` and we need it to match `FocusableOption`.
this._getHostElement().focus(options);
focus(origin: FocusOrigin = 'program', options?: FocusOptions): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FocusOrigin has the definition 'touch' | 'mouse' | 'keyboard' | 'program' | null; (Notice the null)

I think the correct(-er) fix would be to do:

focus(origin: FocusOrigin = null, options?: FocusOptions)

And let the FocusMonitor handle it however it wants to handle an unset FocusOrigin (which happens to be to treat it as 'program').

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. But I feel like explicitly having program as default is reasonable since this method intends to focus the button programmatically (unless a specific origin had been specified)

this._focusMonitor.focusVia(this._getHostElement(), origin, options);
}

_getHostElement() {
Expand Down
2 changes: 1 addition & 1 deletion tools/public_api_guard/material/button.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export declare class MatButton extends _MatButtonMixinBase implements OnDestroy,
_getHostElement(): any;
_hasHostAttributes(...attributes: string[]): boolean;
_isRippleDisabled(): boolean;
focus(_origin?: FocusOrigin, options?: FocusOptions): void;
focus(origin?: FocusOrigin, options?: FocusOptions): void;
ngOnDestroy(): void;
}

Expand Down