@angular/material 19.1.0-next.2 → 19.1.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/autocomplete/index.d.ts +5 -5
- package/button/index.d.ts +2 -0
- package/core/index.d.ts +1 -0
- package/core/theming/_theming.scss +1 -1
- package/datepicker/index.d.ts +1 -0
- package/expansion/index.d.ts +2 -0
- package/fesm2022/autocomplete.mjs +54 -50
- package/fesm2022/autocomplete.mjs.map +1 -1
- package/fesm2022/badge.mjs +10 -10
- package/fesm2022/bottom-sheet.mjs +10 -10
- package/fesm2022/button-toggle.mjs +10 -10
- package/fesm2022/button.mjs +39 -37
- package/fesm2022/button.mjs.map +1 -1
- package/fesm2022/card.mjs +46 -46
- package/fesm2022/checkbox.mjs +14 -14
- package/fesm2022/chips.mjs +40 -40
- package/fesm2022/core.mjs +73 -75
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/datepicker.mjs +104 -111
- package/fesm2022/datepicker.mjs.map +1 -1
- package/fesm2022/dialog.mjs +25 -25
- package/fesm2022/divider.mjs +7 -7
- package/fesm2022/expansion.mjs +30 -28
- package/fesm2022/expansion.mjs.map +1 -1
- package/fesm2022/form-field.mjs +39 -37
- package/fesm2022/form-field.mjs.map +1 -1
- package/fesm2022/grid-list.mjs +22 -22
- package/fesm2022/icon/testing.mjs +7 -7
- package/fesm2022/icon.mjs +10 -10
- package/fesm2022/input.mjs +26 -32
- package/fesm2022/input.mjs.map +1 -1
- package/fesm2022/list.mjs +58 -55
- package/fesm2022/list.mjs.map +1 -1
- package/fesm2022/menu.mjs +188 -146
- package/fesm2022/menu.mjs.map +1 -1
- package/fesm2022/paginator.mjs +10 -10
- package/fesm2022/progress-bar.mjs +12 -10
- package/fesm2022/progress-bar.mjs.map +1 -1
- package/fesm2022/progress-spinner.mjs +7 -7
- package/fesm2022/radio.mjs +15 -14
- package/fesm2022/radio.mjs.map +1 -1
- package/fesm2022/select.mjs +10 -10
- package/fesm2022/sidenav.mjs +28 -27
- package/fesm2022/sidenav.mjs.map +1 -1
- package/fesm2022/slide-toggle.mjs +14 -14
- package/fesm2022/slider.mjs +38 -39
- package/fesm2022/slider.mjs.map +1 -1
- package/fesm2022/snack-bar.mjs +22 -22
- package/fesm2022/sort.mjs +13 -13
- package/fesm2022/stepper.mjs +31 -31
- package/fesm2022/table.mjs +59 -70
- package/fesm2022/table.mjs.map +1 -1
- package/fesm2022/tabs.mjs +58 -66
- package/fesm2022/tabs.mjs.map +1 -1
- package/fesm2022/timepicker.mjs +18 -16
- package/fesm2022/timepicker.mjs.map +1 -1
- package/fesm2022/toolbar.mjs +10 -10
- package/fesm2022/tooltip.mjs +54 -76
- package/fesm2022/tooltip.mjs.map +1 -1
- package/fesm2022/tree.mjs +25 -25
- package/form-field/index.d.ts +1 -0
- package/input/index.d.ts +8 -5
- package/list/index.d.ts +2 -0
- package/menu/index.d.ts +14 -19
- package/package.json +2 -2
- package/progress-bar/index.d.ts +2 -0
- package/radio/index.d.ts +2 -0
- package/schematics/ng-add/index.js +1 -1
- package/schematics/ng-add/index.mjs +1 -1
- package/sidenav/index.d.ts +1 -0
- package/slider/index.d.ts +4 -1
- package/tabs/index.d.ts +4 -2
- package/timepicker/index.d.ts +1 -0
- package/tooltip/index.d.ts +4 -5
package/fesm2022/menu.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, ElementRef, ChangeDetectorRef, booleanAttribute, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, TemplateRef, ApplicationRef, Injector, ViewContainerRef, Directive, QueryList, EventEmitter, afterNextRender, ContentChildren, ViewChild, ContentChild, Output, NgZone, NgModule } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, ElementRef, ChangeDetectorRef, booleanAttribute, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, TemplateRef, ApplicationRef, Injector, ViewContainerRef, Directive, QueryList, EventEmitter, ANIMATION_MODULE_TYPE, afterNextRender, ContentChildren, ViewChild, ContentChild, Output, NgZone, Renderer2, NgModule } from '@angular/core';
|
|
3
3
|
import { FocusMonitor, _IdGenerator, FocusKeyManager, isFakeTouchstartFromScreenReader, isFakeMousedownFromScreenReader } from '@angular/cdk/a11y';
|
|
4
4
|
import { UP_ARROW, DOWN_ARROW, RIGHT_ARROW, LEFT_ARROW, ESCAPE, hasModifierKey, ENTER, SPACE } from '@angular/cdk/keycodes';
|
|
5
5
|
import { Subject, merge, Subscription, of } from 'rxjs';
|
|
6
|
-
import { startWith, switchMap, takeUntil, filter } from 'rxjs/operators';
|
|
6
|
+
import { startWith, switchMap, takeUntil, take, filter } from 'rxjs/operators';
|
|
7
7
|
import { DOCUMENT } from '@angular/common';
|
|
8
8
|
import { _StructuralStylesLoader, MatRipple, MatRippleModule, MatCommonModule } from '@angular/material/core';
|
|
9
9
|
import { _CdkPrivateStyleLoader } from '@angular/cdk/private';
|
|
10
10
|
import { TemplatePortal, DomPortalOutlet } from '@angular/cdk/portal';
|
|
11
|
-
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
12
11
|
import { Directionality } from '@angular/cdk/bidi';
|
|
13
12
|
import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
|
|
14
|
-
import {
|
|
13
|
+
import { _bindEventWithOptions } from '@angular/cdk/platform';
|
|
15
14
|
import { CdkScrollableModule } from '@angular/cdk/scrolling';
|
|
15
|
+
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Injection token used to provide the parent menu to menu-specific components.
|
|
@@ -118,10 +118,10 @@ class MatMenuItem {
|
|
|
118
118
|
_hasFocus() {
|
|
119
119
|
return this._document && this._document.activeElement === this._getHostElement();
|
|
120
120
|
}
|
|
121
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
122
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.0-next.
|
|
121
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
122
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.0-next.3", type: MatMenuItem, isStandalone: true, selector: "[mat-menu-item]", inputs: { role: "role", disabled: ["disabled", "disabled", booleanAttribute], disableRipple: ["disableRipple", "disableRipple", booleanAttribute] }, host: { listeners: { "click": "_checkDisabled($event)", "mouseenter": "_handleMouseEnter()" }, properties: { "attr.role": "role", "class.mat-mdc-menu-item-highlighted": "_highlighted", "class.mat-mdc-menu-item-submenu-trigger": "_triggersSubmenu", "attr.tabindex": "_getTabIndex()", "attr.aria-disabled": "disabled", "attr.disabled": "disabled || null" }, classAttribute: "mat-mdc-menu-item mat-focus-indicator" }, exportAs: ["matMenuItem"], ngImport: i0, template: "<ng-content select=\"mat-icon, [matMenuItemIcon]\"></ng-content>\n<span class=\"mat-mdc-menu-item-text\"><ng-content></ng-content></span>\n<div class=\"mat-mdc-menu-ripple\" matRipple\n [matRippleDisabled]=\"disableRipple || disabled\"\n [matRippleTrigger]=\"_getHostElement()\">\n</div>\n\n@if (_triggersSubmenu) {\n <svg\n class=\"mat-mdc-menu-submenu-icon\"\n viewBox=\"0 0 5 10\"\n focusable=\"false\"\n aria-hidden=\"true\"><polygon points=\"0,0 5,5 0,10\"/></svg>\n}\n", dependencies: [{ kind: "directive", type: MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
123
123
|
}
|
|
124
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
124
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuItem, decorators: [{
|
|
125
125
|
type: Component,
|
|
126
126
|
args: [{ selector: '[mat-menu-item]', exportAs: 'matMenuItem', host: {
|
|
127
127
|
'[attr.role]': 'role',
|
|
@@ -230,10 +230,10 @@ class MatMenuContent {
|
|
|
230
230
|
this.detach();
|
|
231
231
|
this._outlet?.dispose();
|
|
232
232
|
}
|
|
233
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
234
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.0-next.
|
|
233
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
234
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.0-next.3", type: MatMenuContent, isStandalone: true, selector: "ng-template[matMenuContent]", providers: [{ provide: MAT_MENU_CONTENT, useExisting: MatMenuContent }], ngImport: i0 });
|
|
235
235
|
}
|
|
236
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
236
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuContent, decorators: [{
|
|
237
237
|
type: Directive,
|
|
238
238
|
args: [{
|
|
239
239
|
selector: 'ng-template[matMenuContent]',
|
|
@@ -241,59 +241,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.2",
|
|
|
241
241
|
}]
|
|
242
242
|
}], ctorParameters: () => [] });
|
|
243
243
|
|
|
244
|
-
/**
|
|
245
|
-
* Animations used by the mat-menu component.
|
|
246
|
-
* Animation duration and timing values are based on:
|
|
247
|
-
* https://material.io/guidelines/components/menus.html#menus-usage
|
|
248
|
-
* @docs-private
|
|
249
|
-
*/
|
|
250
|
-
const matMenuAnimations = {
|
|
251
|
-
/**
|
|
252
|
-
* This animation controls the menu panel's entry and exit from the page.
|
|
253
|
-
*
|
|
254
|
-
* When the menu panel is added to the DOM, it scales in and fades in its border.
|
|
255
|
-
*
|
|
256
|
-
* When the menu panel is removed from the DOM, it simply fades out after a brief
|
|
257
|
-
* delay to display the ripple.
|
|
258
|
-
*/
|
|
259
|
-
transformMenu: trigger('transformMenu', [
|
|
260
|
-
state('void', style({
|
|
261
|
-
opacity: 0,
|
|
262
|
-
transform: 'scale(0.8)',
|
|
263
|
-
})),
|
|
264
|
-
transition('void => enter', animate('120ms cubic-bezier(0, 0, 0.2, 1)', style({
|
|
265
|
-
opacity: 1,
|
|
266
|
-
transform: 'scale(1)',
|
|
267
|
-
}))),
|
|
268
|
-
transition('* => void', animate('100ms 25ms linear', style({ opacity: 0 }))),
|
|
269
|
-
]),
|
|
270
|
-
/**
|
|
271
|
-
* This animation fades in the background color and content of the menu panel
|
|
272
|
-
* after its containing element is scaled in.
|
|
273
|
-
*/
|
|
274
|
-
fadeInItems: trigger('fadeInItems', [
|
|
275
|
-
// TODO(crisbeto): this is inside the `transformMenu`
|
|
276
|
-
// now. Remove next time we do breaking changes.
|
|
277
|
-
state('showing', style({ opacity: 1 })),
|
|
278
|
-
transition('void => *', [
|
|
279
|
-
style({ opacity: 0 }),
|
|
280
|
-
animate('400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)'),
|
|
281
|
-
]),
|
|
282
|
-
]),
|
|
283
|
-
};
|
|
284
|
-
/**
|
|
285
|
-
* @deprecated
|
|
286
|
-
* @breaking-change 8.0.0
|
|
287
|
-
* @docs-private
|
|
288
|
-
*/
|
|
289
|
-
const fadeInItems = matMenuAnimations.fadeInItems;
|
|
290
|
-
/**
|
|
291
|
-
* @deprecated
|
|
292
|
-
* @breaking-change 8.0.0
|
|
293
|
-
* @docs-private
|
|
294
|
-
*/
|
|
295
|
-
const transformMenu = matMenuAnimations.transformMenu;
|
|
296
|
-
|
|
297
244
|
/** Injection token to be used to override the default options for `mat-menu`. */
|
|
298
245
|
const MAT_MENU_DEFAULT_OPTIONS = new InjectionToken('mat-menu-default-options', {
|
|
299
246
|
providedIn: 'root',
|
|
@@ -308,13 +255,21 @@ function MAT_MENU_DEFAULT_OPTIONS_FACTORY() {
|
|
|
308
255
|
backdropClass: 'cdk-overlay-transparent-backdrop',
|
|
309
256
|
};
|
|
310
257
|
}
|
|
258
|
+
/** Name of the enter animation `@keyframes`. */
|
|
259
|
+
const ENTER_ANIMATION = '_mat-menu-enter';
|
|
260
|
+
/** Name of the exit animation `@keyframes`. */
|
|
261
|
+
const EXIT_ANIMATION = '_mat-menu-exit';
|
|
311
262
|
class MatMenu {
|
|
312
263
|
_elementRef = inject(ElementRef);
|
|
313
264
|
_changeDetectorRef = inject(ChangeDetectorRef);
|
|
265
|
+
_injector = inject(Injector);
|
|
314
266
|
_keyManager;
|
|
315
267
|
_xPosition;
|
|
316
268
|
_yPosition;
|
|
317
269
|
_firstItemFocusRef;
|
|
270
|
+
_exitFallbackTimeout;
|
|
271
|
+
/** Whether animations are currently disabled. */
|
|
272
|
+
_animationsDisabled;
|
|
318
273
|
/** All items inside the menu. Includes items nested inside another menu. */
|
|
319
274
|
_allItems;
|
|
320
275
|
/** Only the direct descendant menu items. */
|
|
@@ -326,7 +281,7 @@ class MatMenu {
|
|
|
326
281
|
/** Emits whenever an animation on the menu completes. */
|
|
327
282
|
_animationDone = new Subject();
|
|
328
283
|
/** Whether the menu is animating. */
|
|
329
|
-
_isAnimating;
|
|
284
|
+
_isAnimating = false;
|
|
330
285
|
/** Parent menu of the current menu panel. */
|
|
331
286
|
parentMenu;
|
|
332
287
|
/** Layout direction of the menu. */
|
|
@@ -428,7 +383,6 @@ class MatMenu {
|
|
|
428
383
|
*/
|
|
429
384
|
close = this.closed;
|
|
430
385
|
panelId = inject(_IdGenerator).getId('mat-menu-panel-');
|
|
431
|
-
_injector = inject(Injector);
|
|
432
386
|
constructor() {
|
|
433
387
|
const defaultOptions = inject(MAT_MENU_DEFAULT_OPTIONS);
|
|
434
388
|
this.overlayPanelClass = defaultOptions.overlayPanelClass || '';
|
|
@@ -437,6 +391,7 @@ class MatMenu {
|
|
|
437
391
|
this.backdropClass = defaultOptions.backdropClass;
|
|
438
392
|
this.overlapTrigger = defaultOptions.overlapTrigger;
|
|
439
393
|
this.hasBackdrop = defaultOptions.hasBackdrop;
|
|
394
|
+
this._animationsDisabled = inject(ANIMATION_MODULE_TYPE, { optional: true }) === 'NoopAnimations';
|
|
440
395
|
}
|
|
441
396
|
ngOnInit() {
|
|
442
397
|
this.setPositionClasses();
|
|
@@ -476,6 +431,7 @@ class MatMenu {
|
|
|
476
431
|
this._directDescendantItems.destroy();
|
|
477
432
|
this.closed.complete();
|
|
478
433
|
this._firstItemFocusRef?.destroy();
|
|
434
|
+
clearTimeout(this._exitFallbackTimeout);
|
|
479
435
|
}
|
|
480
436
|
/** Stream that emits whenever the hovered menu item changes. */
|
|
481
437
|
_hovered() {
|
|
@@ -534,14 +490,7 @@ class MatMenu {
|
|
|
534
490
|
// Wait for `afterNextRender` to ensure iOS VoiceOver screen reader focuses the first item (#24735).
|
|
535
491
|
this._firstItemFocusRef?.destroy();
|
|
536
492
|
this._firstItemFocusRef = afterNextRender(() => {
|
|
537
|
-
|
|
538
|
-
if (this._directDescendantItems.length) {
|
|
539
|
-
// Because the `mat-menuPanel` is at the DOM insertion point, not inside the overlay, we don't
|
|
540
|
-
// have a nice way of getting a hold of the menuPanel panel. We can't use a `ViewChild` either
|
|
541
|
-
// because the panel is inside an `ng-template`. We work around it by starting from one of
|
|
542
|
-
// the items and walking up the DOM.
|
|
543
|
-
menuPanel = this._directDescendantItems.first._getHostElement().closest('[role="menu"]');
|
|
544
|
-
}
|
|
493
|
+
const menuPanel = this._resolvePanel();
|
|
545
494
|
// If an item in the menuPanel is already focused, avoid overriding the focus.
|
|
546
495
|
if (!menuPanel || !menuPanel.contains(document.activeElement)) {
|
|
547
496
|
const manager = this._keyManager;
|
|
@@ -584,32 +533,52 @@ class MatMenu {
|
|
|
584
533
|
};
|
|
585
534
|
this._changeDetectorRef.markForCheck();
|
|
586
535
|
}
|
|
587
|
-
/**
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
536
|
+
/** Callback that is invoked when the panel animation completes. */
|
|
537
|
+
_onAnimationDone(state) {
|
|
538
|
+
const isExit = state === EXIT_ANIMATION;
|
|
539
|
+
if (isExit || state === ENTER_ANIMATION) {
|
|
540
|
+
if (isExit) {
|
|
541
|
+
clearTimeout(this._exitFallbackTimeout);
|
|
542
|
+
this._exitFallbackTimeout = undefined;
|
|
543
|
+
}
|
|
544
|
+
this._animationDone.next(isExit ? 'void' : 'enter');
|
|
545
|
+
this._isAnimating = false;
|
|
546
|
+
}
|
|
591
547
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
548
|
+
_onAnimationStart(state) {
|
|
549
|
+
if (state === ENTER_ANIMATION || state === EXIT_ANIMATION) {
|
|
550
|
+
this._isAnimating = true;
|
|
551
|
+
}
|
|
596
552
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
553
|
+
_setIsOpen(isOpen) {
|
|
554
|
+
this._panelAnimationState = isOpen ? 'enter' : 'void';
|
|
555
|
+
if (isOpen) {
|
|
556
|
+
if (this._keyManager.activeItemIndex === 0) {
|
|
557
|
+
// Scroll the content element to the top as soon as the animation starts. This is necessary,
|
|
558
|
+
// because we move focus to the first item while it's still being animated, which can throw
|
|
559
|
+
// the browser off when it determines the scroll position. Alternatively we can move focus
|
|
560
|
+
// when the animation is done, however moving focus asynchronously will interrupt screen
|
|
561
|
+
// readers which are in the process of reading out the menu already. We take the `element`
|
|
562
|
+
// from the `event` since we can't use a `ViewChild` to access the pane.
|
|
563
|
+
const menuPanel = this._resolvePanel();
|
|
564
|
+
if (menuPanel) {
|
|
565
|
+
menuPanel.scrollTop = 0;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
else if (!this._animationsDisabled) {
|
|
570
|
+
// Some apps do `* { animation: none !important; }` in tests which will prevent the
|
|
571
|
+
// `animationend` event from firing. Since the exit animation is loading-bearing for
|
|
572
|
+
// removing the content from the DOM, add a fallback timer.
|
|
573
|
+
this._exitFallbackTimeout = setTimeout(() => this._onAnimationDone(EXIT_ANIMATION), 200);
|
|
612
574
|
}
|
|
575
|
+
// Animation events won't fire when animations are disabled so we simulate them.
|
|
576
|
+
if (this._animationsDisabled) {
|
|
577
|
+
setTimeout(() => {
|
|
578
|
+
this._onAnimationDone(isOpen ? ENTER_ANIMATION : EXIT_ANIMATION);
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
this._changeDetectorRef.markForCheck();
|
|
613
582
|
}
|
|
614
583
|
/**
|
|
615
584
|
* Sets up a stream that will keep track of any newly-added menu items and will update the list
|
|
@@ -625,16 +594,28 @@ class MatMenu {
|
|
|
625
594
|
this._directDescendantItems.notifyOnChanges();
|
|
626
595
|
});
|
|
627
596
|
}
|
|
628
|
-
|
|
629
|
-
|
|
597
|
+
/** Gets the menu panel DOM node. */
|
|
598
|
+
_resolvePanel() {
|
|
599
|
+
let menuPanel = null;
|
|
600
|
+
if (this._directDescendantItems.length) {
|
|
601
|
+
// Because the `mat-menuPanel` is at the DOM insertion point, not inside the overlay, we don't
|
|
602
|
+
// have a nice way of getting a hold of the menuPanel panel. We can't use a `ViewChild` either
|
|
603
|
+
// because the panel is inside an `ng-template`. We work around it by starting from one of
|
|
604
|
+
// the items and walking up the DOM.
|
|
605
|
+
menuPanel = this._directDescendantItems.first._getHostElement().closest('[role="menu"]');
|
|
606
|
+
}
|
|
607
|
+
return menuPanel;
|
|
608
|
+
}
|
|
609
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
610
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "19.1.0-next.3", type: MatMenu, isStandalone: true, selector: "mat-menu", inputs: { backdropClass: "backdropClass", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"], ariaDescribedby: ["aria-describedby", "ariaDescribedby"], xPosition: "xPosition", yPosition: "yPosition", overlapTrigger: ["overlapTrigger", "overlapTrigger", booleanAttribute], hasBackdrop: ["hasBackdrop", "hasBackdrop", (value) => (value == null ? null : booleanAttribute(value))], panelClass: ["class", "panelClass"], classList: "classList" }, outputs: { closed: "closed", close: "close" }, host: { properties: { "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null" } }, providers: [{ provide: MAT_MENU_PANEL, useExisting: MatMenu }], queries: [{ propertyName: "lazyContent", first: true, predicate: MAT_MENU_CONTENT, descendants: true }, { propertyName: "_allItems", predicate: MatMenuItem, descendants: true }, { propertyName: "items", predicate: MatMenuItem }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], exportAs: ["matMenu"], ngImport: i0, template: "<ng-template>\n <div\n class=\"mat-mdc-menu-panel\"\n [id]=\"panelId\"\n [class]=\"_classList\"\n [class.mat-menu-panel-animations-disabled]=\"_animationsDisabled\"\n [class.mat-menu-panel-exit-animation]=\"_panelAnimationState === 'void'\"\n [class.mat-menu-panel-animating]=\"_isAnimating\"\n (click)=\"closed.emit('click')\"\n tabindex=\"-1\"\n role=\"menu\"\n (animationstart)=\"_onAnimationStart($event.animationName)\"\n (animationend)=\"_onAnimationDone($event.animationName)\"\n (animationcancel)=\"_onAnimationDone($event.animationName)\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\n [attr.aria-describedby]=\"ariaDescribedby || null\">\n <div class=\"mat-mdc-menu-content\">\n <ng-content></ng-content>\n </div>\n </div>\n</ng-template>\n", styles: ["mat-menu{display:none}.mat-mdc-menu-content{margin:0;padding:8px 0;outline:0}.mat-mdc-menu-content,.mat-mdc-menu-content .mat-mdc-menu-item .mat-mdc-menu-item-text{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;flex:1;white-space:normal;font-family:var(--mat-menu-item-label-text-font, var(--mat-sys-label-large-font));line-height:var(--mat-menu-item-label-text-line-height, var(--mat-sys-label-large-line-height));font-size:var(--mat-menu-item-label-text-size, var(--mat-sys-label-large-size));letter-spacing:var(--mat-menu-item-label-text-tracking, var(--mat-sys-label-large-tracking));font-weight:var(--mat-menu-item-label-text-weight, var(--mat-sys-label-large-weight))}@keyframes _mat-menu-enter{from{opacity:0;transform:scale(0.8)}to{opacity:1;transform:none}}@keyframes _mat-menu-exit{from{opacity:1}to{opacity:0}}.mat-mdc-menu-panel{min-width:112px;max-width:280px;overflow:auto;box-sizing:border-box;outline:0;animation:_mat-menu-enter 120ms cubic-bezier(0, 0, 0.2, 1);border-radius:var(--mat-menu-container-shape, var(--mat-sys-corner-extra-small));background-color:var(--mat-menu-container-color, var(--mat-sys-surface-container));box-shadow:var(--mat-menu-container-elevation-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12));will-change:transform,opacity}.mat-mdc-menu-panel.mat-menu-panel-exit-animation{animation:_mat-menu-exit 100ms 25ms linear forwards}.mat-mdc-menu-panel.mat-menu-panel-animations-disabled{animation:none}.mat-mdc-menu-panel.mat-menu-panel-animating{pointer-events:none}.mat-mdc-menu-panel.mat-menu-panel-animating:has(.mat-mdc-menu-content:empty){display:none}@media(forced-colors: active){.mat-mdc-menu-panel{outline:solid 1px}}.mat-mdc-menu-panel .mat-divider{color:var(--mat-menu-divider-color, var(--mat-sys-surface-variant));margin-bottom:var(--mat-menu-divider-bottom-spacing, 8px);margin-top:var(--mat-menu-divider-top-spacing, 8px)}.mat-mdc-menu-item{display:flex;position:relative;align-items:center;justify-content:flex-start;overflow:hidden;padding:0;cursor:pointer;width:100%;text-align:left;box-sizing:border-box;color:inherit;font-size:inherit;background:none;text-decoration:none;margin:0;min-height:48px;padding-left:var(--mat-menu-item-leading-spacing, 12px);padding-right:var(--mat-menu-item-trailing-spacing, 12px);-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.mat-mdc-menu-item::-moz-focus-inner{border:0}[dir=rtl] .mat-mdc-menu-item{padding-left:var(--mat-menu-item-trailing-spacing, 12px);padding-right:var(--mat-menu-item-leading-spacing, 12px)}.mat-mdc-menu-item:has(.material-icons,mat-icon,[matButtonIcon]){padding-left:var(--mat-menu-item-with-icon-leading-spacing, 12px);padding-right:var(--mat-menu-item-with-icon-trailing-spacing, 12px)}[dir=rtl] .mat-mdc-menu-item:has(.material-icons,mat-icon,[matButtonIcon]){padding-left:var(--mat-menu-item-with-icon-trailing-spacing, 12px);padding-right:var(--mat-menu-item-with-icon-leading-spacing, 12px)}.mat-mdc-menu-item,.mat-mdc-menu-item:visited,.mat-mdc-menu-item:link{color:var(--mat-menu-item-label-text-color, var(--mat-sys-on-surface))}.mat-mdc-menu-item .mat-icon-no-color,.mat-mdc-menu-item .mat-mdc-menu-submenu-icon{color:var(--mat-menu-item-icon-color, var(--mat-sys-on-surface-variant))}.mat-mdc-menu-item[disabled]{cursor:default;opacity:.38}.mat-mdc-menu-item[disabled]::after{display:block;position:absolute;content:\"\";top:0;left:0;bottom:0;right:0}.mat-mdc-menu-item:focus{outline:0}.mat-mdc-menu-item .mat-icon{flex-shrink:0;margin-right:var(--mat-menu-item-spacing, 12px);height:var(--mat-menu-item-icon-size, 24px);width:var(--mat-menu-item-icon-size, 24px)}[dir=rtl] .mat-mdc-menu-item{text-align:right}[dir=rtl] .mat-mdc-menu-item .mat-icon{margin-right:0;margin-left:var(--mat-menu-item-spacing, 12px)}.mat-mdc-menu-item:not([disabled]):hover{background-color:var(--mat-menu-item-hover-state-layer-color, color-mix(in srgb, var(--mat-sys-on-surface) calc(var(--mat-sys-hover-state-layer-opacity) * 100%), transparent))}.mat-mdc-menu-item:not([disabled]).cdk-program-focused,.mat-mdc-menu-item:not([disabled]).cdk-keyboard-focused,.mat-mdc-menu-item:not([disabled]).mat-mdc-menu-item-highlighted{background-color:var(--mat-menu-item-focus-state-layer-color, color-mix(in srgb, var(--mat-sys-on-surface) calc(var(--mat-sys-focus-state-layer-opacity) * 100%), transparent))}@media(forced-colors: active){.mat-mdc-menu-item{margin-top:1px}}.mat-mdc-menu-submenu-icon{width:var(--mat-menu-item-icon-size, 24px);height:10px;fill:currentColor;padding-left:var(--mat-menu-item-spacing, 12px)}[dir=rtl] .mat-mdc-menu-submenu-icon{padding-right:var(--mat-menu-item-spacing, 12px);padding-left:0}[dir=rtl] .mat-mdc-menu-submenu-icon polygon{transform:scaleX(-1);transform-origin:center}@media(forced-colors: active){.mat-mdc-menu-submenu-icon{fill:CanvasText}}.mat-mdc-menu-item .mat-mdc-menu-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
630
611
|
}
|
|
631
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
612
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenu, decorators: [{
|
|
632
613
|
type: Component,
|
|
633
614
|
args: [{ selector: 'mat-menu', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'matMenu', host: {
|
|
634
615
|
'[attr.aria-label]': 'null',
|
|
635
616
|
'[attr.aria-labelledby]': 'null',
|
|
636
617
|
'[attr.aria-describedby]': 'null',
|
|
637
|
-
},
|
|
618
|
+
}, providers: [{ provide: MAT_MENU_PANEL, useExisting: MatMenu }], template: "<ng-template>\n <div\n class=\"mat-mdc-menu-panel\"\n [id]=\"panelId\"\n [class]=\"_classList\"\n [class.mat-menu-panel-animations-disabled]=\"_animationsDisabled\"\n [class.mat-menu-panel-exit-animation]=\"_panelAnimationState === 'void'\"\n [class.mat-menu-panel-animating]=\"_isAnimating\"\n (click)=\"closed.emit('click')\"\n tabindex=\"-1\"\n role=\"menu\"\n (animationstart)=\"_onAnimationStart($event.animationName)\"\n (animationend)=\"_onAnimationDone($event.animationName)\"\n (animationcancel)=\"_onAnimationDone($event.animationName)\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\n [attr.aria-describedby]=\"ariaDescribedby || null\">\n <div class=\"mat-mdc-menu-content\">\n <ng-content></ng-content>\n </div>\n </div>\n</ng-template>\n", styles: ["mat-menu{display:none}.mat-mdc-menu-content{margin:0;padding:8px 0;outline:0}.mat-mdc-menu-content,.mat-mdc-menu-content .mat-mdc-menu-item .mat-mdc-menu-item-text{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;flex:1;white-space:normal;font-family:var(--mat-menu-item-label-text-font, var(--mat-sys-label-large-font));line-height:var(--mat-menu-item-label-text-line-height, var(--mat-sys-label-large-line-height));font-size:var(--mat-menu-item-label-text-size, var(--mat-sys-label-large-size));letter-spacing:var(--mat-menu-item-label-text-tracking, var(--mat-sys-label-large-tracking));font-weight:var(--mat-menu-item-label-text-weight, var(--mat-sys-label-large-weight))}@keyframes _mat-menu-enter{from{opacity:0;transform:scale(0.8)}to{opacity:1;transform:none}}@keyframes _mat-menu-exit{from{opacity:1}to{opacity:0}}.mat-mdc-menu-panel{min-width:112px;max-width:280px;overflow:auto;box-sizing:border-box;outline:0;animation:_mat-menu-enter 120ms cubic-bezier(0, 0, 0.2, 1);border-radius:var(--mat-menu-container-shape, var(--mat-sys-corner-extra-small));background-color:var(--mat-menu-container-color, var(--mat-sys-surface-container));box-shadow:var(--mat-menu-container-elevation-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12));will-change:transform,opacity}.mat-mdc-menu-panel.mat-menu-panel-exit-animation{animation:_mat-menu-exit 100ms 25ms linear forwards}.mat-mdc-menu-panel.mat-menu-panel-animations-disabled{animation:none}.mat-mdc-menu-panel.mat-menu-panel-animating{pointer-events:none}.mat-mdc-menu-panel.mat-menu-panel-animating:has(.mat-mdc-menu-content:empty){display:none}@media(forced-colors: active){.mat-mdc-menu-panel{outline:solid 1px}}.mat-mdc-menu-panel .mat-divider{color:var(--mat-menu-divider-color, var(--mat-sys-surface-variant));margin-bottom:var(--mat-menu-divider-bottom-spacing, 8px);margin-top:var(--mat-menu-divider-top-spacing, 8px)}.mat-mdc-menu-item{display:flex;position:relative;align-items:center;justify-content:flex-start;overflow:hidden;padding:0;cursor:pointer;width:100%;text-align:left;box-sizing:border-box;color:inherit;font-size:inherit;background:none;text-decoration:none;margin:0;min-height:48px;padding-left:var(--mat-menu-item-leading-spacing, 12px);padding-right:var(--mat-menu-item-trailing-spacing, 12px);-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.mat-mdc-menu-item::-moz-focus-inner{border:0}[dir=rtl] .mat-mdc-menu-item{padding-left:var(--mat-menu-item-trailing-spacing, 12px);padding-right:var(--mat-menu-item-leading-spacing, 12px)}.mat-mdc-menu-item:has(.material-icons,mat-icon,[matButtonIcon]){padding-left:var(--mat-menu-item-with-icon-leading-spacing, 12px);padding-right:var(--mat-menu-item-with-icon-trailing-spacing, 12px)}[dir=rtl] .mat-mdc-menu-item:has(.material-icons,mat-icon,[matButtonIcon]){padding-left:var(--mat-menu-item-with-icon-trailing-spacing, 12px);padding-right:var(--mat-menu-item-with-icon-leading-spacing, 12px)}.mat-mdc-menu-item,.mat-mdc-menu-item:visited,.mat-mdc-menu-item:link{color:var(--mat-menu-item-label-text-color, var(--mat-sys-on-surface))}.mat-mdc-menu-item .mat-icon-no-color,.mat-mdc-menu-item .mat-mdc-menu-submenu-icon{color:var(--mat-menu-item-icon-color, var(--mat-sys-on-surface-variant))}.mat-mdc-menu-item[disabled]{cursor:default;opacity:.38}.mat-mdc-menu-item[disabled]::after{display:block;position:absolute;content:\"\";top:0;left:0;bottom:0;right:0}.mat-mdc-menu-item:focus{outline:0}.mat-mdc-menu-item .mat-icon{flex-shrink:0;margin-right:var(--mat-menu-item-spacing, 12px);height:var(--mat-menu-item-icon-size, 24px);width:var(--mat-menu-item-icon-size, 24px)}[dir=rtl] .mat-mdc-menu-item{text-align:right}[dir=rtl] .mat-mdc-menu-item .mat-icon{margin-right:0;margin-left:var(--mat-menu-item-spacing, 12px)}.mat-mdc-menu-item:not([disabled]):hover{background-color:var(--mat-menu-item-hover-state-layer-color, color-mix(in srgb, var(--mat-sys-on-surface) calc(var(--mat-sys-hover-state-layer-opacity) * 100%), transparent))}.mat-mdc-menu-item:not([disabled]).cdk-program-focused,.mat-mdc-menu-item:not([disabled]).cdk-keyboard-focused,.mat-mdc-menu-item:not([disabled]).mat-mdc-menu-item-highlighted{background-color:var(--mat-menu-item-focus-state-layer-color, color-mix(in srgb, var(--mat-sys-on-surface) calc(var(--mat-sys-focus-state-layer-opacity) * 100%), transparent))}@media(forced-colors: active){.mat-mdc-menu-item{margin-top:1px}}.mat-mdc-menu-submenu-icon{width:var(--mat-menu-item-icon-size, 24px);height:10px;fill:currentColor;padding-left:var(--mat-menu-item-spacing, 12px)}[dir=rtl] .mat-mdc-menu-submenu-icon{padding-right:var(--mat-menu-item-spacing, 12px);padding-left:0}[dir=rtl] .mat-mdc-menu-submenu-icon polygon{transform:scaleX(-1);transform-origin:center}@media(forced-colors: active){.mat-mdc-menu-submenu-icon{fill:CanvasText}}.mat-mdc-menu-item .mat-mdc-menu-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}"] }]
|
|
638
619
|
}], ctorParameters: () => [], propDecorators: { _allItems: [{
|
|
639
620
|
type: ContentChildren,
|
|
640
621
|
args: [MatMenuItem, { descendants: true }]
|
|
@@ -698,7 +679,7 @@ const MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
|
|
|
698
679
|
useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
|
|
699
680
|
};
|
|
700
681
|
/** Options for binding a passive event listener. */
|
|
701
|
-
const passiveEventListenerOptions =
|
|
682
|
+
const passiveEventListenerOptions = { passive: true };
|
|
702
683
|
/**
|
|
703
684
|
* Default top padding of the menu panel.
|
|
704
685
|
* @deprecated No longer being used. Will be removed.
|
|
@@ -718,12 +699,14 @@ class MatMenuTrigger {
|
|
|
718
699
|
_ngZone = inject(NgZone);
|
|
719
700
|
_scrollStrategy = inject(MAT_MENU_SCROLL_STRATEGY);
|
|
720
701
|
_changeDetectorRef = inject(ChangeDetectorRef);
|
|
702
|
+
_cleanupTouchstart;
|
|
721
703
|
_portal;
|
|
722
704
|
_overlayRef = null;
|
|
723
705
|
_menuOpen = false;
|
|
724
706
|
_closingActionsSubscription = Subscription.EMPTY;
|
|
725
707
|
_hoverSubscription = Subscription.EMPTY;
|
|
726
708
|
_menuCloseSubscription = Subscription.EMPTY;
|
|
709
|
+
_pendingRemoval;
|
|
727
710
|
/**
|
|
728
711
|
* We're specifically looking for a `MatMenu` here since the generic `MatMenuPanel`
|
|
729
712
|
* interface lacks some functionality around nested menus and animations.
|
|
@@ -734,15 +717,6 @@ class MatMenuTrigger {
|
|
|
734
717
|
* Used to offset sub-menus to compensate for the padding.
|
|
735
718
|
*/
|
|
736
719
|
_parentInnerPadding;
|
|
737
|
-
/**
|
|
738
|
-
* Handles touch start events on the trigger.
|
|
739
|
-
* Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
|
|
740
|
-
*/
|
|
741
|
-
_handleTouchStart = (event) => {
|
|
742
|
-
if (!isFakeTouchstartFromScreenReader(event)) {
|
|
743
|
-
this._openedBy = 'touch';
|
|
744
|
-
}
|
|
745
|
-
};
|
|
746
720
|
// Tracking input type is necessary so it's possible to only auto-focus
|
|
747
721
|
// the first item of the list when the menu is opened via the keyboard
|
|
748
722
|
_openedBy = undefined;
|
|
@@ -809,8 +783,13 @@ class MatMenuTrigger {
|
|
|
809
783
|
onMenuClose = this.menuClosed;
|
|
810
784
|
constructor() {
|
|
811
785
|
const parentMenu = inject(MAT_MENU_PANEL, { optional: true });
|
|
786
|
+
const renderer = inject(Renderer2);
|
|
812
787
|
this._parentMaterialMenu = parentMenu instanceof MatMenu ? parentMenu : undefined;
|
|
813
|
-
this._element.nativeElement
|
|
788
|
+
this._cleanupTouchstart = _bindEventWithOptions(renderer, this._element.nativeElement, 'touchstart', (event) => {
|
|
789
|
+
if (!isFakeTouchstartFromScreenReader(event)) {
|
|
790
|
+
this._openedBy = 'touch';
|
|
791
|
+
}
|
|
792
|
+
}, passiveEventListenerOptions);
|
|
814
793
|
}
|
|
815
794
|
ngAfterContentInit() {
|
|
816
795
|
this._handleHover();
|
|
@@ -819,7 +798,8 @@ class MatMenuTrigger {
|
|
|
819
798
|
if (this.menu && this._ownsMenu(this.menu)) {
|
|
820
799
|
PANELS_TO_TRIGGERS.delete(this.menu);
|
|
821
800
|
}
|
|
822
|
-
this.
|
|
801
|
+
this._cleanupTouchstart();
|
|
802
|
+
this._pendingRemoval?.unsubscribe();
|
|
823
803
|
this._menuCloseSubscription.unsubscribe();
|
|
824
804
|
this._closingActionsSubscription.unsubscribe();
|
|
825
805
|
this._hoverSubscription.unsubscribe();
|
|
@@ -850,20 +830,33 @@ class MatMenuTrigger {
|
|
|
850
830
|
if (this._menuOpen || !menu) {
|
|
851
831
|
return;
|
|
852
832
|
}
|
|
833
|
+
this._pendingRemoval?.unsubscribe();
|
|
834
|
+
const previousTrigger = PANELS_TO_TRIGGERS.get(menu);
|
|
835
|
+
PANELS_TO_TRIGGERS.set(menu, this);
|
|
836
|
+
// If the same menu is currently attached to another trigger,
|
|
837
|
+
// we need to close it so it doesn't end up in a broken state.
|
|
838
|
+
if (previousTrigger && previousTrigger !== this) {
|
|
839
|
+
previousTrigger.closeMenu();
|
|
840
|
+
}
|
|
853
841
|
const overlayRef = this._createOverlay(menu);
|
|
854
842
|
const overlayConfig = overlayRef.getConfig();
|
|
855
843
|
const positionStrategy = overlayConfig.positionStrategy;
|
|
856
844
|
this._setPosition(menu, positionStrategy);
|
|
857
845
|
overlayConfig.hasBackdrop =
|
|
858
846
|
menu.hasBackdrop == null ? !this.triggersSubmenu() : menu.hasBackdrop;
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
847
|
+
// We need the `hasAttached` check for the case where the user kicked off a removal animation,
|
|
848
|
+
// but re-entered the menu. Re-attaching the same portal will trigger an error otherwise.
|
|
849
|
+
if (!overlayRef.hasAttached()) {
|
|
850
|
+
overlayRef.attach(this._getPortal(menu));
|
|
851
|
+
menu.lazyContent?.attach(this.menuData);
|
|
862
852
|
}
|
|
863
853
|
this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this.closeMenu());
|
|
864
|
-
this.
|
|
854
|
+
menu.parentMenu = this.triggersSubmenu() ? this._parentMaterialMenu : undefined;
|
|
855
|
+
menu.direction = this.dir;
|
|
856
|
+
menu.focusFirstItem(this._openedBy || 'program');
|
|
857
|
+
this._setIsMenuOpen(true);
|
|
865
858
|
if (menu instanceof MatMenu) {
|
|
866
|
-
menu.
|
|
859
|
+
menu._setIsOpen(true);
|
|
867
860
|
menu._directDescendantItems.changes.pipe(takeUntil(menu.close)).subscribe(() => {
|
|
868
861
|
// Re-adjust the position without locking when the amount of items
|
|
869
862
|
// changes so that the overlay is allowed to pick a new optimal position.
|
|
@@ -896,11 +889,25 @@ class MatMenuTrigger {
|
|
|
896
889
|
}
|
|
897
890
|
/** Closes the menu and does the necessary cleanup. */
|
|
898
891
|
_destroyMenu(reason) {
|
|
899
|
-
|
|
892
|
+
const overlayRef = this._overlayRef;
|
|
893
|
+
const menu = this._menu;
|
|
894
|
+
if (!overlayRef || !this.menuOpen) {
|
|
900
895
|
return;
|
|
901
896
|
}
|
|
902
897
|
this._closingActionsSubscription.unsubscribe();
|
|
903
|
-
this.
|
|
898
|
+
this._pendingRemoval?.unsubscribe();
|
|
899
|
+
// Note that we don't wait for the animation to finish if another trigger took
|
|
900
|
+
// over the menu, because the panel will end up empty which looks glitchy.
|
|
901
|
+
if (menu instanceof MatMenu && this._ownsMenu(menu)) {
|
|
902
|
+
this._pendingRemoval = menu._animationDone.pipe(take(1)).subscribe(() => overlayRef.detach());
|
|
903
|
+
menu._setIsOpen(false);
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
overlayRef.detach();
|
|
907
|
+
}
|
|
908
|
+
if (menu && this._ownsMenu(menu)) {
|
|
909
|
+
PANELS_TO_TRIGGERS.delete(menu);
|
|
910
|
+
}
|
|
904
911
|
// Always restore focus if the user is navigating using the keyboard or the menu was opened
|
|
905
912
|
// programmatically. We don't restore for non-root triggers, because it can prevent focus
|
|
906
913
|
// from making it back to the root trigger when closing a long chain of menus by clicking
|
|
@@ -910,26 +917,6 @@ class MatMenuTrigger {
|
|
|
910
917
|
}
|
|
911
918
|
this._openedBy = undefined;
|
|
912
919
|
this._setIsMenuOpen(false);
|
|
913
|
-
if (this.menu && this._ownsMenu(this.menu)) {
|
|
914
|
-
PANELS_TO_TRIGGERS.delete(this.menu);
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
/**
|
|
918
|
-
* This method sets the menu state to open and focuses the first item if
|
|
919
|
-
* the menu was opened via the keyboard.
|
|
920
|
-
*/
|
|
921
|
-
_initMenu(menu) {
|
|
922
|
-
const previousTrigger = PANELS_TO_TRIGGERS.get(menu);
|
|
923
|
-
// If the same menu is currently attached to another trigger,
|
|
924
|
-
// we need to close it so it doesn't end up in a broken state.
|
|
925
|
-
if (previousTrigger && previousTrigger !== this) {
|
|
926
|
-
previousTrigger.closeMenu();
|
|
927
|
-
}
|
|
928
|
-
PANELS_TO_TRIGGERS.set(menu, this);
|
|
929
|
-
menu.parentMenu = this.triggersSubmenu() ? this._parentMaterialMenu : undefined;
|
|
930
|
-
menu.direction = this.dir;
|
|
931
|
-
menu.focusFirstItem(this._openedBy || 'program');
|
|
932
|
-
this._setIsMenuOpen(true);
|
|
933
920
|
}
|
|
934
921
|
// set state rather than toggle to support triggers sharing a menu
|
|
935
922
|
_setIsMenuOpen(isOpen) {
|
|
@@ -1121,10 +1108,10 @@ class MatMenuTrigger {
|
|
|
1121
1108
|
_ownsMenu(menu) {
|
|
1122
1109
|
return PANELS_TO_TRIGGERS.get(menu) === this;
|
|
1123
1110
|
}
|
|
1124
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
1125
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.0-next.
|
|
1111
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1112
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.0-next.3", type: MatMenuTrigger, isStandalone: true, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: { _deprecatedMatMenuTriggerFor: ["mat-menu-trigger-for", "_deprecatedMatMenuTriggerFor"], menu: ["matMenuTriggerFor", "menu"], menuData: ["matMenuTriggerData", "menuData"], restoreFocus: ["matMenuTriggerRestoreFocus", "restoreFocus"] }, outputs: { menuOpened: "menuOpened", onMenuOpen: "onMenuOpen", menuClosed: "menuClosed", onMenuClose: "onMenuClose" }, host: { listeners: { "click": "_handleClick($event)", "mousedown": "_handleMousedown($event)", "keydown": "_handleKeydown($event)" }, properties: { "attr.aria-haspopup": "menu ? \"menu\" : null", "attr.aria-expanded": "menuOpen", "attr.aria-controls": "menuOpen ? menu.panelId : null" }, classAttribute: "mat-mdc-menu-trigger" }, exportAs: ["matMenuTrigger"], ngImport: i0 });
|
|
1126
1113
|
}
|
|
1127
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
1114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuTrigger, decorators: [{
|
|
1128
1115
|
type: Directive,
|
|
1129
1116
|
args: [{
|
|
1130
1117
|
selector: `[mat-menu-trigger-for], [matMenuTriggerFor]`,
|
|
@@ -1162,8 +1149,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.2",
|
|
|
1162
1149
|
}] } });
|
|
1163
1150
|
|
|
1164
1151
|
class MatMenuModule {
|
|
1165
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
1166
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.0-next.
|
|
1152
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1153
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuModule, imports: [MatRippleModule,
|
|
1167
1154
|
MatCommonModule,
|
|
1168
1155
|
OverlayModule,
|
|
1169
1156
|
MatMenu,
|
|
@@ -1175,12 +1162,12 @@ class MatMenuModule {
|
|
|
1175
1162
|
MatMenuItem,
|
|
1176
1163
|
MatMenuContent,
|
|
1177
1164
|
MatMenuTrigger] });
|
|
1178
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
1165
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuModule, providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER], imports: [MatRippleModule,
|
|
1179
1166
|
MatCommonModule,
|
|
1180
1167
|
OverlayModule, CdkScrollableModule,
|
|
1181
1168
|
MatCommonModule] });
|
|
1182
1169
|
}
|
|
1183
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.
|
|
1170
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.3", ngImport: i0, type: MatMenuModule, decorators: [{
|
|
1184
1171
|
type: NgModule,
|
|
1185
1172
|
args: [{
|
|
1186
1173
|
imports: [
|
|
@@ -1204,6 +1191,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0-next.2",
|
|
|
1204
1191
|
}]
|
|
1205
1192
|
}] });
|
|
1206
1193
|
|
|
1194
|
+
/**
|
|
1195
|
+
* Animations used by the mat-menu component.
|
|
1196
|
+
* Animation duration and timing values are based on:
|
|
1197
|
+
* https://material.io/guidelines/components/menus.html#menus-usage
|
|
1198
|
+
* @docs-private
|
|
1199
|
+
* @deprecated No longer used, will be removed.
|
|
1200
|
+
* @breaking-change 21.0.0
|
|
1201
|
+
*/
|
|
1202
|
+
const matMenuAnimations = {
|
|
1203
|
+
/**
|
|
1204
|
+
* This animation controls the menu panel's entry and exit from the page.
|
|
1205
|
+
*
|
|
1206
|
+
* When the menu panel is added to the DOM, it scales in and fades in its border.
|
|
1207
|
+
*
|
|
1208
|
+
* When the menu panel is removed from the DOM, it simply fades out after a brief
|
|
1209
|
+
* delay to display the ripple.
|
|
1210
|
+
*/
|
|
1211
|
+
transformMenu: trigger('transformMenu', [
|
|
1212
|
+
state('void', style({
|
|
1213
|
+
opacity: 0,
|
|
1214
|
+
transform: 'scale(0.8)',
|
|
1215
|
+
})),
|
|
1216
|
+
transition('void => enter', animate('120ms cubic-bezier(0, 0, 0.2, 1)', style({
|
|
1217
|
+
opacity: 1,
|
|
1218
|
+
transform: 'scale(1)',
|
|
1219
|
+
}))),
|
|
1220
|
+
transition('* => void', animate('100ms 25ms linear', style({ opacity: 0 }))),
|
|
1221
|
+
]),
|
|
1222
|
+
/**
|
|
1223
|
+
* This animation fades in the background color and content of the menu panel
|
|
1224
|
+
* after its containing element is scaled in.
|
|
1225
|
+
*/
|
|
1226
|
+
fadeInItems: trigger('fadeInItems', [
|
|
1227
|
+
// TODO(crisbeto): this is inside the `transformMenu`
|
|
1228
|
+
// now. Remove next time we do breaking changes.
|
|
1229
|
+
state('showing', style({ opacity: 1 })),
|
|
1230
|
+
transition('void => *', [
|
|
1231
|
+
style({ opacity: 0 }),
|
|
1232
|
+
animate('400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)'),
|
|
1233
|
+
]),
|
|
1234
|
+
]),
|
|
1235
|
+
};
|
|
1236
|
+
/**
|
|
1237
|
+
* @deprecated
|
|
1238
|
+
* @breaking-change 8.0.0
|
|
1239
|
+
* @docs-private
|
|
1240
|
+
*/
|
|
1241
|
+
const fadeInItems = matMenuAnimations.fadeInItems;
|
|
1242
|
+
/**
|
|
1243
|
+
* @deprecated
|
|
1244
|
+
* @breaking-change 8.0.0
|
|
1245
|
+
* @docs-private
|
|
1246
|
+
*/
|
|
1247
|
+
const transformMenu = matMenuAnimations.transformMenu;
|
|
1248
|
+
|
|
1207
1249
|
/**
|
|
1208
1250
|
* Generated bundle index. Do not edit.
|
|
1209
1251
|
*/
|