Skip to content

Commit 9f0071d

Browse files
author
Kevin Lee / 이지환
authored
fix(material/button): cdk-focus classes not being applied (#25619)
Fixes a bug in the Angular Material `button` component where cdk-focused, cdk-keyboard-focused, cdk-mouse-focused were not being applied upon respective focus. This is because there was no FocusManager set up with the MDC buttons like the legacy button did. Fixes #25618
1 parent 8ae0b2c commit 9f0071d

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

src/material/button/_button-theme-private.scss

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
opacity: map.get($opacities, hover);
1919
}
2020

21-
&:focus .mat-mdc-button-persistent-ripple::before {
22-
opacity: map.get($opacities, focus);
21+
&.cdk-program-focused,
22+
&.cdk-keyboard-focused {
23+
.mat-mdc-button-persistent-ripple::before {
24+
opacity: map.get($opacities, focus);
25+
}
2326
}
2427

2528
&:active .mat-mdc-button-persistent-ripple::before {

src/material/button/button-base.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,18 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y';
910
import {Platform} from '@angular/cdk/platform';
10-
import {Directive, ElementRef, NgZone, OnDestroy, OnInit, ViewChild} from '@angular/core';
11+
import {
12+
AfterViewInit,
13+
Directive,
14+
ElementRef,
15+
inject,
16+
NgZone,
17+
OnDestroy,
18+
OnInit,
19+
ViewChild,
20+
} from '@angular/core';
1121
import {
1222
CanColor,
1323
CanDisable,
@@ -17,7 +27,6 @@ import {
1727
mixinDisabled,
1828
mixinDisableRipple,
1929
} from '@angular/material/core';
20-
import {FocusOrigin} from '@angular/cdk/a11y';
2130

2231
/** Inputs common to all buttons. */
2332
export const MAT_BUTTON_INPUTS = ['disabled', 'disableRipple', 'color'];
@@ -83,8 +92,10 @@ export const _MatButtonMixin = mixinColor(
8392
@Directive()
8493
export class MatButtonBase
8594
extends _MatButtonMixin
86-
implements CanDisable, CanColor, CanDisableRipple
95+
implements CanDisable, CanColor, CanDisableRipple, AfterViewInit, OnDestroy
8796
{
97+
private readonly _focusMonitor = inject(FocusMonitor);
98+
8899
/** Whether this button is a FAB. Used to apply the correct class on the ripple. */
89100
_isFab = false;
90101

@@ -112,9 +123,21 @@ export class MatButtonBase
112123
}
113124
}
114125

126+
ngAfterViewInit() {
127+
this._focusMonitor.monitor(this._elementRef, true);
128+
}
129+
130+
ngOnDestroy() {
131+
this._focusMonitor.stopMonitoring(this._elementRef);
132+
}
133+
115134
/** Focuses the button. */
116135
focus(_origin: FocusOrigin = 'program', options?: FocusOptions): void {
117-
this._elementRef.nativeElement.focus(options);
136+
if (_origin) {
137+
this._focusMonitor.focusVia(this._elementRef.nativeElement, _origin, options);
138+
} else {
139+
this._elementRef.nativeElement.focus(options);
140+
}
118141
}
119142

120143
/** Gets whether the button has one of the given attributes. */
@@ -166,7 +189,8 @@ export class MatAnchorBase extends MatButtonBase implements OnInit, OnDestroy {
166189
});
167190
}
168191

169-
ngOnDestroy(): void {
192+
override ngOnDestroy(): void {
193+
super.ngOnDestroy();
170194
this._elementRef.nativeElement.removeEventListener('click', this._haltDisabledEvents);
171195
}
172196

tools/public_api_guard/material/button.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
```ts
66

77
import { _AbstractConstructor } from '@angular/material/core';
8+
import { AfterViewInit } from '@angular/core';
89
import { BooleanInput } from '@angular/cdk/coercion';
910
import { CanColor } from '@angular/material/core';
1011
import { CanDisable } from '@angular/material/core';

0 commit comments

Comments
 (0)