Skip to content

Commit ece4ddc

Browse files
committed
refactor(material/menu): remove mixin class usages
Replaces mixin class usages in the menu with input transforms.
1 parent 8def84e commit ece4ddc

File tree

3 files changed

+28
-46
lines changed

3 files changed

+28
-46
lines changed

src/material/menu/menu-item.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,19 @@ import {
1717
Input,
1818
AfterViewInit,
1919
ChangeDetectorRef,
20+
booleanAttribute,
2021
} from '@angular/core';
21-
import {
22-
CanDisable,
23-
CanDisableRipple,
24-
mixinDisabled,
25-
mixinDisableRipple,
26-
} from '@angular/material/core';
2722
import {FocusableOption, FocusMonitor, FocusOrigin} from '@angular/cdk/a11y';
2823
import {Subject} from 'rxjs';
2924
import {DOCUMENT} from '@angular/common';
3025
import {MatMenuPanel, MAT_MENU_PANEL} from './menu-panel';
3126

32-
// Boilerplate for applying mixins to MatMenuItem.
33-
/** @docs-private */
34-
const _MatMenuItemBase = mixinDisableRipple(mixinDisabled(class {}));
35-
3627
/**
3728
* Single item inside a `mat-menu`. Provides the menu item styling and accessibility treatment.
3829
*/
3930
@Component({
4031
selector: '[mat-menu-item]',
4132
exportAs: 'matMenuItem',
42-
inputs: ['disabled', 'disableRipple'],
4333
host: {
4434
'[attr.role]': 'role',
4535
'class': 'mat-mdc-menu-item mat-mdc-focus-indicator',
@@ -55,13 +45,16 @@ const _MatMenuItemBase = mixinDisableRipple(mixinDisabled(class {}));
5545
encapsulation: ViewEncapsulation.None,
5646
templateUrl: 'menu-item.html',
5747
})
58-
export class MatMenuItem
59-
extends _MatMenuItemBase
60-
implements FocusableOption, CanDisable, CanDisableRipple, AfterViewInit, OnDestroy
61-
{
48+
export class MatMenuItem implements FocusableOption, AfterViewInit, OnDestroy {
6249
/** ARIA role for the menu item. */
6350
@Input() role: 'menuitem' | 'menuitemradio' | 'menuitemcheckbox' = 'menuitem';
6451

52+
/** Whether the menu item is disabled. */
53+
@Input({transform: booleanAttribute}) disabled: boolean = false;
54+
55+
/** Whether ripples are disabled on the menu item. */
56+
@Input({transform: booleanAttribute}) disableRipple: boolean = false;
57+
6558
/** Stream that emits when the menu item is hovered. */
6659
readonly _hovered: Subject<MatMenuItem> = new Subject<MatMenuItem>();
6760

@@ -101,7 +94,6 @@ export class MatMenuItem
10194
@Inject(MAT_MENU_PANEL) @Optional() public _parentMenu?: MatMenuPanel<MatMenuItem>,
10295
private _changeDetectorRef?: ChangeDetectorRef,
10396
) {
104-
super();
10597
_parentMenu?.addItem?.(this);
10698
}
10799

src/material/menu/menu.ts

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ import {
2626
ViewEncapsulation,
2727
OnInit,
2828
ChangeDetectorRef,
29+
booleanAttribute,
2930
} from '@angular/core';
3031
import {AnimationEvent} from '@angular/animations';
3132
import {FocusKeyManager, FocusOrigin} from '@angular/cdk/a11y';
3233
import {Direction} from '@angular/cdk/bidi';
33-
import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
3434
import {
3535
ESCAPE,
3636
LEFT_ARROW,
@@ -204,24 +204,11 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
204204
@ContentChild(MAT_MENU_CONTENT) lazyContent: MatMenuContent;
205205

206206
/** Whether the menu should overlap its trigger. */
207-
@Input()
208-
get overlapTrigger(): boolean {
209-
return this._overlapTrigger;
210-
}
211-
set overlapTrigger(value: BooleanInput) {
212-
this._overlapTrigger = coerceBooleanProperty(value);
213-
}
214-
private _overlapTrigger: boolean;
207+
@Input({transform: booleanAttribute}) overlapTrigger: boolean;
215208

216209
/** Whether the menu has a backdrop. */
217-
@Input()
218-
get hasBackdrop(): boolean | undefined {
219-
return this._hasBackdrop;
220-
}
221-
set hasBackdrop(value: BooleanInput) {
222-
this._hasBackdrop = coerceBooleanProperty(value);
223-
}
224-
private _hasBackdrop: boolean | undefined;
210+
@Input({transform: (value: any) => (value == null ? null : booleanAttribute(value))})
211+
hasBackdrop?: boolean;
225212

226213
/**
227214
* This method takes classes set on the host mat-menu element and applies them on the
@@ -307,8 +294,8 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
307294
this._xPosition = defaultOptions.xPosition;
308295
this._yPosition = defaultOptions.yPosition;
309296
this.backdropClass = defaultOptions.backdropClass;
310-
this._overlapTrigger = defaultOptions.overlapTrigger;
311-
this._hasBackdrop = defaultOptions.hasBackdrop;
297+
this.overlapTrigger = defaultOptions.overlapTrigger;
298+
this.hasBackdrop = defaultOptions.hasBackdrop;
312299
}
313300

314301
ngOnInit() {

tools/public_api_guard/material/menu.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,13 @@
44
55
```ts
66

7-
import { _AbstractConstructor } from '@angular/material/core';
87
import { AfterContentInit } from '@angular/core';
98
import { AfterViewInit } from '@angular/core';
109
import { AnimationEvent as AnimationEvent_2 } from '@angular/animations';
1110
import { AnimationTriggerMetadata } from '@angular/animations';
1211
import { ApplicationRef } from '@angular/core';
13-
import { BooleanInput } from '@angular/cdk/coercion';
14-
import { CanDisable } from '@angular/material/core';
15-
import { CanDisableRipple } from '@angular/material/core';
1612
import { ChangeDetectorRef } from '@angular/core';
1713
import { ComponentFactoryResolver } from '@angular/core';
18-
import { _Constructor } from '@angular/material/core';
1914
import { Direction } from '@angular/cdk/bidi';
2015
import { Directionality } from '@angular/cdk/bidi';
2116
import { ElementRef } from '@angular/core';
@@ -89,14 +84,17 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
8984
direction: Direction;
9085
focusFirstItem(origin?: FocusOrigin): void;
9186
_handleKeydown(event: KeyboardEvent): void;
92-
get hasBackdrop(): boolean | undefined;
93-
set hasBackdrop(value: BooleanInput);
87+
hasBackdrop?: boolean;
9488
_hovered(): Observable<MatMenuItem>;
9589
_isAnimating: boolean;
9690
// @deprecated
9791
items: QueryList<MatMenuItem>;
9892
lazyContent: MatMenuContent;
9993
// (undocumented)
94+
static ngAcceptInputType_hasBackdrop: any;
95+
// (undocumented)
96+
static ngAcceptInputType_overlapTrigger: unknown;
97+
// (undocumented)
10098
ngAfterContentInit(): void;
10199
// (undocumented)
102100
ngOnDestroy(): void;
@@ -105,8 +103,7 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
105103
_onAnimationDone(event: AnimationEvent_2): void;
106104
// (undocumented)
107105
_onAnimationStart(event: AnimationEvent_2): void;
108-
get overlapTrigger(): boolean;
109-
set overlapTrigger(value: BooleanInput);
106+
overlapTrigger: boolean;
110107
overlayPanelClass: string | string[];
111108
_panelAnimationState: 'void' | 'enter';
112109
set panelClass(classes: string);
@@ -164,11 +161,13 @@ export interface MatMenuDefaultOptions {
164161
}
165162

166163
// @public
167-
export class MatMenuItem extends _MatMenuItemBase implements FocusableOption, CanDisable, CanDisableRipple, AfterViewInit, OnDestroy {
164+
export class MatMenuItem implements FocusableOption, AfterViewInit, OnDestroy {
168165
constructor(elementRef: ElementRef<HTMLElement>, document: any, focusMonitor: FocusMonitor, parentMenu: MatMenuPanel<MatMenuItem> | undefined, changeDetectorRef: ChangeDetectorRef);
169166
// @deprecated
170167
constructor(elementRef: ElementRef<HTMLElement>, document?: any, focusMonitor?: FocusMonitor, parentMenu?: MatMenuPanel<MatMenuItem>, changeDetectorRef?: ChangeDetectorRef);
171168
_checkDisabled(event: Event): void;
169+
disabled: boolean;
170+
disableRipple: boolean;
172171
focus(origin?: FocusOrigin, options?: FocusOptions): void;
173172
readonly _focused: Subject<MatMenuItem>;
174173
_getHostElement(): HTMLElement;
@@ -180,6 +179,10 @@ export class MatMenuItem extends _MatMenuItemBase implements FocusableOption, Ca
180179
_highlighted: boolean;
181180
readonly _hovered: Subject<MatMenuItem>;
182181
// (undocumented)
182+
static ngAcceptInputType_disabled: unknown;
183+
// (undocumented)
184+
static ngAcceptInputType_disableRipple: unknown;
185+
// (undocumented)
183186
ngAfterViewInit(): void;
184187
// (undocumented)
185188
ngOnDestroy(): void;
@@ -192,7 +195,7 @@ export class MatMenuItem extends _MatMenuItemBase implements FocusableOption, Ca
192195
_setTriggersSubmenu(triggersSubmenu: boolean): void;
193196
_triggersSubmenu: boolean;
194197
// (undocumented)
195-
static ɵcmp: i0.ɵɵComponentDeclaration<MatMenuItem, "[mat-menu-item]", ["matMenuItem"], { "disabled": { "alias": "disabled"; "required": false; }; "disableRipple": { "alias": "disableRipple"; "required": false; }; "role": { "alias": "role"; "required": false; }; }, {}, never, ["mat-icon, [matMenuItemIcon]", "*"], false, never>;
198+
static ɵcmp: i0.ɵɵComponentDeclaration<MatMenuItem, "[mat-menu-item]", ["matMenuItem"], { "role": { "alias": "role"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "disableRipple": { "alias": "disableRipple"; "required": false; }; }, {}, never, ["mat-icon, [matMenuItemIcon]", "*"], false, never>;
196199
// (undocumented)
197200
static ɵfac: i0.ɵɵFactoryDeclaration<MatMenuItem, [null, null, null, { optional: true; }, null]>;
198201
}

0 commit comments

Comments
 (0)