Skip to content

Commit

Permalink
fix(material-experimental/mdc-menu): ensure mat-mdc- prefix on all cl…
Browse files Browse the repository at this point in the history
…asses (#23559)

* fix(material-experimental/mdc-menu): ensure mat-mdc- prefix on all classes

The MDC menu trigger had `.mat-menu-trigger` class because it was using
the same directive as the non-MDC menu. This PR refactors the trigger
and content directives to extend a common base class.

* fixup! fix(material-experimental/mdc-menu): ensure mat-mdc- prefix on all classes

* fixup! fix(material-experimental/mdc-menu): ensure mat-mdc- prefix on all classes

* fixup! fix(material-experimental/mdc-menu): ensure mat-mdc- prefix on all classes

(cherry picked from commit 771afd9)
  • Loading branch information
mmalerba authored and andrewseguin committed Sep 14, 2021
1 parent 13b24ab commit e54229f
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 72 deletions.
27 changes: 27 additions & 0 deletions src/material-experimental/mdc-menu/directives.ts
@@ -0,0 +1,27 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Directive} from '@angular/core';
import {_MatMenuContentBase, _MatMenuTriggerBase, MAT_MENU_CONTENT} from '@angular/material/menu';

/** Directive applied to an element that should trigger a `mat-menu`. */
@Directive({
selector: `[mat-menu-trigger-for], [matMenuTriggerFor]`,
host: {
'class': 'mat-mdc-menu-trigger',
},
exportAs: 'matMenuTrigger'
})
export class MatMenuTrigger extends _MatMenuTriggerBase {}

/** Menu content that will be rendered lazily once the menu is opened. */
@Directive({
selector: 'ng-template[matMenuContent]',
providers: [{provide: MAT_MENU_CONTENT, useExisting: MatMenuContent}],
})
export class MatMenuContent extends _MatMenuContentBase {}
16 changes: 11 additions & 5 deletions src/material-experimental/mdc-menu/module.ts
Expand Up @@ -10,21 +10,27 @@ import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatCommonModule, MatRippleModule} from '@angular/material-experimental/mdc-core';
import {OverlayModule} from '@angular/cdk/overlay';
import {_MatMenuDirectivesModule} from '@angular/material/menu';
import {CdkScrollableModule} from '@angular/cdk/scrolling';
import {MatMenu, MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER} from './menu';
import {MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER, MatMenu} from './menu';
import {MatMenuItem} from './menu-item';
import {MatMenuContent, MatMenuTrigger} from './directives';

@NgModule({
imports: [
CommonModule,
MatRippleModule,
MatCommonModule,
OverlayModule,
_MatMenuDirectivesModule
],
exports: [CdkScrollableModule, MatMenu, MatCommonModule, MatMenuItem, _MatMenuDirectivesModule],
declarations: [MatMenu, MatMenuItem],
exports: [
CdkScrollableModule,
MatMenu,
MatCommonModule,
MatMenuItem,
MatMenuContent,
MatMenuTrigger
],
declarations: [MatMenu, MatMenuItem, MatMenuContent, MatMenuTrigger],
providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
})
export class MatMenuModule {}
4 changes: 1 addition & 3 deletions src/material-experimental/mdc-menu/public-api.ts
Expand Up @@ -8,19 +8,17 @@

export {MatMenu} from './menu';
export {MatMenuItem} from './menu-item';
export {MatMenuTrigger, MatMenuContent} from './directives';
export * from './module';

export {
_MatMenuDirectivesModule,
fadeInItems,
MAT_MENU_DEFAULT_OPTIONS,
MAT_MENU_PANEL,
MAT_MENU_SCROLL_STRATEGY,
matMenuAnimations,
MatMenuContent,
MatMenuDefaultOptions,
MatMenuPanel,
MatMenuTrigger,
MenuPositionX,
MenuPositionY,
transformMenu,
Expand Down
2 changes: 1 addition & 1 deletion src/material-experimental/mdc-menu/testing/menu-harness.ts
Expand Up @@ -18,7 +18,7 @@ import {
export class MatMenuHarness extends _MatMenuHarnessBase<
typeof MatMenuItemHarness, MatMenuItemHarness, MenuItemHarnessFilters> {
/** The selector for the host element of a `MatMenu` instance. */
static hostSelector = '.mat-menu-trigger';
static hostSelector = '.mat-mdc-menu-trigger';
protected _itemClass = MatMenuItemHarness;

/**
Expand Down
19 changes: 11 additions & 8 deletions src/material/menu/menu-content.ts
Expand Up @@ -29,14 +29,8 @@ import {Subject} from 'rxjs';
*/
export const MAT_MENU_CONTENT = new InjectionToken<MatMenuContent>('MatMenuContent');

/**
* Menu content that will be rendered lazily once the menu is opened.
*/
@Directive({
selector: 'ng-template[matMenuContent]',
providers: [{provide: MAT_MENU_CONTENT, useExisting: MatMenuContent}],
})
export class MatMenuContent implements OnDestroy {
@Directive()
export abstract class _MatMenuContentBase implements OnDestroy {
private _portal: TemplatePortal<any>;
private _outlet: DomPortalOutlet;

Expand Down Expand Up @@ -105,3 +99,12 @@ export class MatMenuContent implements OnDestroy {
}
}
}

/**
* Menu content that will be rendered lazily once the menu is opened.
*/
@Directive({
selector: 'ng-template[matMenuContent]',
providers: [{provide: MAT_MENU_CONTENT, useExisting: MatMenuContent}],
})
export class MatMenuContent extends _MatMenuContentBase {}
26 changes: 9 additions & 17 deletions src/material/menu/menu-module.ts
Expand Up @@ -16,30 +16,22 @@ import {MatMenuContent} from './menu-content';
import {MatMenuItem} from './menu-item';
import {MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER, MatMenuTrigger} from './menu-trigger';

/**
* Used by both the current `MatMenuModule` and the MDC `MatMenuModule`
* to declare the menu-related directives.
*/
@NgModule({
exports: [MatMenuTrigger, MatMenuContent, MatCommonModule],
declarations: [
MatMenuTrigger,
MatMenuContent,
],
providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
})
export class _MatMenuDirectivesModule {}

@NgModule({
imports: [
CommonModule,
MatCommonModule,
MatRippleModule,
OverlayModule,
_MatMenuDirectivesModule,
],
exports: [CdkScrollableModule, MatCommonModule, MatMenu, MatMenuItem, _MatMenuDirectivesModule],
declarations: [MatMenu, MatMenuItem],
exports: [
CdkScrollableModule,
MatCommonModule,
MatMenu,
MatMenuItem,
MatMenuTrigger,
MatMenuContent
],
declarations: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent],
providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
})
export class MatMenuModule {}
54 changes: 36 additions & 18 deletions src/material/menu/menu-trigger.ts
Expand Up @@ -20,15 +20,17 @@ import {
Overlay,
OverlayConfig,
OverlayRef,
VerticalConnectionPos,
ScrollStrategy,
VerticalConnectionPos,
} from '@angular/cdk/overlay';
import {TemplatePortal} from '@angular/cdk/portal';
import {
AfterContentInit,
Directive,
ElementRef,
EventEmitter,
HostBinding,
HostListener,
Inject,
InjectionToken,
Input,
Expand All @@ -41,10 +43,10 @@ import {
import {normalizePassiveListenerOptions} from '@angular/cdk/platform';
import {asapScheduler, merge, Observable, of as observableOf, Subscription} from 'rxjs';
import {delay, filter, take, takeUntil} from 'rxjs/operators';
import {MenuCloseReason, _MatMenuBase} from './menu';
import {_MatMenuBase, MenuCloseReason} from './menu';
import {throwMatMenuMissingError, throwMatMenuRecursiveError} from './menu-errors';
import {MatMenuItem} from './menu-item';
import {MatMenuPanel, MAT_MENU_PANEL} from './menu-panel';
import {MAT_MENU_PANEL, MatMenuPanel} from './menu-panel';
import {MenuPositionX, MenuPositionY} from './menu-positions';

/** Injection token that determines the scroll handling while the menu is open. */
Expand All @@ -71,21 +73,8 @@ const passiveEventListenerOptions = normalizePassiveListenerOptions({passive: tr

// TODO(andrewseguin): Remove the kebab versions in favor of camelCased attribute selectors

/** Directive applied to an element that should trigger a `mat-menu`. */
@Directive({
selector: `[mat-menu-trigger-for], [matMenuTriggerFor]`,
host: {
'class': 'mat-menu-trigger',
'aria-haspopup': 'true',
'[attr.aria-expanded]': 'menuOpen || null',
'[attr.aria-controls]': 'menuOpen ? menu.panelId : null',
'(mousedown)': '_handleMousedown($event)',
'(keydown)': '_handleKeydown($event)',
'(click)': '_handleClick($event)',
},
exportAs: 'matMenuTrigger'
})
export class MatMenuTrigger implements AfterContentInit, OnDestroy {
@Directive()
export abstract class _MatMenuTriggerBase implements AfterContentInit, OnDestroy {
private _portal: TemplatePortal;
private _overlayRef: OverlayRef | null = null;
private _menuOpen: boolean = false;
Expand Down Expand Up @@ -114,6 +103,22 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
// the first item of the list when the menu is opened via the keyboard
_openedBy: Exclude<FocusOrigin, 'program' | null> | undefined = undefined;

@HostBinding('attr.aria-expanded')
// Need tp use getter for HostBinding
// tslint:disable-next-line:no-private-getters
get _ariaExpanded() {
return this.menuOpen || null;
}

@HostBinding('attr.aria-controls')
// Need tp use getter for HostBinding
// tslint:disable-next-line:no-private-getters
get _ariaControl() {
return this.menuOpen ? this.menu.panelId : null;
}

@HostBinding('attr.aria-haspopup') _ariaHaspopup = true;

/**
* @deprecated
* @breaking-change 8.0.0
Expand Down Expand Up @@ -508,6 +513,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
}

/** Handles mouse presses on the trigger. */
@HostListener('mousedown', ['$event'])
_handleMousedown(event: MouseEvent): void {
if (!isFakeMousedownFromScreenReader(event)) {
// Since right or middle button clicks won't trigger the `click` event,
Expand All @@ -524,6 +530,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
}

/** Handles key presses on the trigger. */
@HostListener('keydown', ['$event'])
_handleKeydown(event: KeyboardEvent): void {
const keyCode = event.keyCode;

Expand All @@ -541,6 +548,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
}

/** Handles click events on the trigger. */
@HostListener('click', ['$event'])
_handleClick(event: MouseEvent): void {
if (this.triggersSubmenu()) {
// Stop event propagation to avoid closing the parent menu.
Expand Down Expand Up @@ -597,3 +605,13 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
}

}

/** Directive applied to an element that should trigger a `mat-menu`. */
@Directive({
selector: `[mat-menu-trigger-for], [matMenuTriggerFor]`,
host: {
'class': 'mat-menu-trigger',
},
exportAs: 'matMenuTrigger'
})
export class MatMenuTrigger extends _MatMenuTriggerBase {}
2 changes: 1 addition & 1 deletion src/material/menu/public-api.ts
Expand Up @@ -13,7 +13,7 @@ export {
_MatMenuBase,
} from './menu';
export {MatMenuItem} from './menu-item';
export {MatMenuTrigger, MAT_MENU_SCROLL_STRATEGY} from './menu-trigger';
export {MatMenuTrigger, MAT_MENU_SCROLL_STRATEGY, _MatMenuTriggerBase} from './menu-trigger';
export {MatMenuPanel, MAT_MENU_PANEL} from './menu-panel';
export * from './menu-module';
export * from './menu-animations';
Expand Down
50 changes: 31 additions & 19 deletions tools/public_api_guard/material/menu.md
Expand Up @@ -24,8 +24,8 @@ import { FocusableOption } from '@angular/cdk/a11y';
import { FocusMonitor } from '@angular/cdk/a11y';
import { FocusOrigin } from '@angular/cdk/a11y';
import * as i0 from '@angular/core';
import * as i3 from '@angular/material/core';
import * as i6 from '@angular/common';
import * as i5 from '@angular/common';
import * as i6 from '@angular/material/core';
import * as i7 from '@angular/cdk/overlay';
import * as i8 from '@angular/cdk/scrolling';
import { InjectionToken } from '@angular/core';
Expand Down Expand Up @@ -162,17 +162,25 @@ export class _MatMenuBase implements AfterContentInit, MatMenuPanel<MatMenuItem>
}

// @public
export class MatMenuContent implements OnDestroy {
export class MatMenuContent extends _MatMenuContentBase {
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<MatMenuContent, "ng-template[matMenuContent]", never, {}, {}, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<MatMenuContent, never>;
}

// @public (undocumented)
export abstract class _MatMenuContentBase implements OnDestroy {
constructor(_template: TemplateRef<any>, _componentFactoryResolver: ComponentFactoryResolver, _appRef: ApplicationRef, _injector: Injector, _viewContainerRef: ViewContainerRef, _document: any, _changeDetectorRef?: ChangeDetectorRef | undefined);
attach(context?: any): void;
readonly _attached: Subject<void>;
detach(): void;
// (undocumented)
ngOnDestroy(): void;
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<MatMenuContent, "ng-template[matMenuContent]", never, {}, {}, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<_MatMenuContentBase, never, never, {}, {}, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<MatMenuContent, never>;
static ɵfac: i0.ɵɵFactoryDeclaration<_MatMenuContentBase, never>;
}

// @public
Expand All @@ -185,16 +193,6 @@ export interface MatMenuDefaultOptions {
yPosition: MenuPositionY;
}

// @public
export class _MatMenuDirectivesModule {
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<_MatMenuDirectivesModule, never>;
// (undocumented)
static ɵinj: i0.ɵɵInjectorDeclaration<_MatMenuDirectivesModule>;
// (undocumented)
static ɵmod: i0.ɵɵNgModuleDeclaration<_MatMenuDirectivesModule, [typeof i1.MatMenuTrigger, typeof i2.MatMenuContent], never, [typeof i1.MatMenuTrigger, typeof i2.MatMenuContent, typeof i3.MatCommonModule]>;
}

// @public
export class MatMenuItem extends _MatMenuItemBase implements FocusableOption, CanDisable, CanDisableRipple, AfterViewInit, OnDestroy {
constructor(_elementRef: ElementRef<HTMLElement>,
Expand Down Expand Up @@ -236,7 +234,7 @@ export class MatMenuModule {
// (undocumented)
static ɵinj: i0.ɵɵInjectorDeclaration<MatMenuModule>;
// (undocumented)
static ɵmod: i0.ɵɵNgModuleDeclaration<MatMenuModule, [typeof i4.MatMenu, typeof i5.MatMenuItem], [typeof i6.CommonModule, typeof i3.MatCommonModule, typeof i3.MatRippleModule, typeof i7.OverlayModule, typeof _MatMenuDirectivesModule], [typeof i8.CdkScrollableModule, typeof i3.MatCommonModule, typeof i4.MatMenu, typeof i5.MatMenuItem, typeof _MatMenuDirectivesModule]>;
static ɵmod: i0.ɵɵNgModuleDeclaration<MatMenuModule, [typeof i1.MatMenu, typeof i2.MatMenuItem, typeof i3.MatMenuTrigger, typeof i4.MatMenuContent], [typeof i5.CommonModule, typeof i6.MatCommonModule, typeof i6.MatRippleModule, typeof i7.OverlayModule], [typeof i8.CdkScrollableModule, typeof i6.MatCommonModule, typeof i1.MatMenu, typeof i2.MatMenuItem, typeof i3.MatMenuTrigger, typeof i4.MatMenuContent]>;
}

// @public
Expand Down Expand Up @@ -280,8 +278,22 @@ export interface MatMenuPanel<T = any> {
}

// @public
export class MatMenuTrigger implements AfterContentInit, OnDestroy {
export class MatMenuTrigger extends _MatMenuTriggerBase {
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<MatMenuTrigger, "[mat-menu-trigger-for], [matMenuTriggerFor]", ["matMenuTrigger"], {}, {}, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<MatMenuTrigger, never>;
}

// @public (undocumented)
export abstract class _MatMenuTriggerBase implements AfterContentInit, OnDestroy {
constructor(_overlay: Overlay, _element: ElementRef<HTMLElement>, _viewContainerRef: ViewContainerRef, scrollStrategy: any, parentMenu: MatMenuPanel, _menuItemInstance: MatMenuItem, _dir: Directionality, _focusMonitor?: FocusMonitor | undefined);
// (undocumented)
get _ariaControl(): string | null | undefined;
// (undocumented)
get _ariaExpanded(): true | null;
// (undocumented)
_ariaHaspopup: boolean;
closeMenu(): void;
// @deprecated (undocumented)
get _deprecatedMatMenuTriggerFor(): MatMenuPanel;
Expand Down Expand Up @@ -313,9 +325,9 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
triggersSubmenu(): boolean;
updatePosition(): void;
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<MatMenuTrigger, "[mat-menu-trigger-for], [matMenuTriggerFor]", ["matMenuTrigger"], { "_deprecatedMatMenuTriggerFor": "mat-menu-trigger-for"; "menu": "matMenuTriggerFor"; "menuData": "matMenuTriggerData"; "restoreFocus": "matMenuTriggerRestoreFocus"; }, { "menuOpened": "menuOpened"; "onMenuOpen": "onMenuOpen"; "menuClosed": "menuClosed"; "onMenuClose": "onMenuClose"; }, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<_MatMenuTriggerBase, never, never, { "_deprecatedMatMenuTriggerFor": "mat-menu-trigger-for"; "menu": "matMenuTriggerFor"; "menuData": "matMenuTriggerData"; "restoreFocus": "matMenuTriggerRestoreFocus"; }, { "menuOpened": "menuOpened"; "onMenuOpen": "onMenuOpen"; "menuClosed": "menuClosed"; "onMenuClose": "onMenuClose"; }, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<MatMenuTrigger, [null, null, null, null, { optional: true; }, { optional: true; self: true; }, { optional: true; }, null]>;
static ɵfac: i0.ɵɵFactoryDeclaration<_MatMenuTriggerBase, [null, null, null, null, { optional: true; }, { optional: true; self: true; }, { optional: true; }, null]>;
}

// @public
Expand Down

0 comments on commit e54229f

Please sign in to comment.