@angular/material 20.1.0-next.0 → 20.1.0-next.2
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/_index.scss +1 -2
- package/autocomplete/_autocomplete-theme.scss +28 -37
- package/autocomplete/_m2-autocomplete.scss +5 -2
- package/badge/_badge-theme.scss +35 -44
- package/badge/_m2-badge.scss +3 -2
- package/bottom-sheet/_bottom-sheet-theme.scss +28 -40
- package/bottom-sheet/_m2-bottom-sheet.scss +12 -11
- package/button/_button-theme.scss +37 -55
- package/button/_fab-theme.scss +42 -56
- package/button/_icon-button-theme.scss +30 -48
- package/button/_m2-button.scss +60 -59
- package/button/_m2-fab.scss +19 -15
- package/button/_m2-icon-button.scss +7 -5
- package/button/testing/index.d.ts +1 -0
- package/button-toggle/_button-toggle-theme.scss +29 -44
- package/button-toggle/_m2-button-toggle.scss +11 -17
- package/card/_card-theme.scss +28 -36
- package/card/_m2-card.scss +12 -14
- package/checkbox/_checkbox-theme.scss +35 -50
- package/checkbox/_m2-checkbox.scss +8 -8
- package/chips/_chips-theme.scss +24 -30
- package/chips/_m2-chip.scss +12 -28
- package/core/_core-theme.scss +48 -67
- package/core/focus-indicators/_private.scss +2 -5
- package/core/m2/_theming.scss +68 -113
- package/core/option/_m2-optgroup.scss +10 -7
- package/core/option/_m2-option.scss +13 -11
- package/core/option/_optgroup-theme.scss +28 -30
- package/core/option/_option-theme.scss +35 -34
- package/core/ripple/_m2-ripple.scss +6 -10
- package/core/ripple/_ripple-theme.scss +28 -33
- package/core/selection/pseudo-checkbox/_m2-pseudo-checkbox.scss +2 -3
- package/core/selection/pseudo-checkbox/_pseudo-checkbox-theme.scss +55 -45
- package/core/theming/_all-theme.scss +38 -42
- package/core/theming/_definition.scss +20 -13
- package/core/theming/_inspection.scss +0 -12
- package/core/theming/_m2-inspection.scss +0 -33
- package/core/theming/_theming.scss +4 -172
- package/core/tokens/_m2-utils.scss +5 -75
- package/core/tokens/_m3-system.scss +11 -9
- package/core/tokens/_m3-utils.scss +2 -14
- package/core/tokens/_token-utils.scss +7 -27
- package/core/tokens/m2/_index.scss +6 -0
- package/core/tokens/m2/_md-sys-color.scss +123 -0
- package/core/tokens/m2/_md-sys-elevation.scss +16 -0
- package/core/tokens/m2/_md-sys-motion.scss +36 -0
- package/core/tokens/m2/_md-sys-shape.scss +22 -0
- package/core/tokens/m2/_md-sys-state.scss +15 -0
- package/core/tokens/m2/_md-sys-typescale.scss +68 -0
- package/core/tokens/m3/_md-sys-color.scss +2 -2
- package/core/tokens/m3/_md-sys-typescale.scss +1 -1
- package/core/tokens/m3/_theme.scss +14 -26
- package/datepicker/_datepicker-theme.scss +47 -87
- package/datepicker/_m2-datepicker.scss +33 -123
- package/datepicker/index.d.ts +1 -1
- package/dialog/_dialog-theme.scss +28 -34
- package/dialog/_m2-dialog.scss +17 -17
- package/divider/_divider-theme.scss +28 -30
- package/divider/_m2-divider.scss +4 -2
- package/expansion/_expansion-theme.scss +28 -39
- package/expansion/_m2-expansion.scss +11 -10
- package/expansion/_m3-expansion.scss +2 -0
- package/fesm2022/animation-DfMFjxHu.mjs.map +1 -1
- package/fesm2022/autocomplete/testing.mjs.map +1 -1
- package/fesm2022/autocomplete.mjs +1 -1
- package/fesm2022/autocomplete.mjs.map +1 -1
- package/fesm2022/badge/testing.mjs.map +1 -1
- package/fesm2022/badge.mjs.map +1 -1
- package/fesm2022/bottom-sheet/testing.mjs.map +1 -1
- package/fesm2022/bottom-sheet.mjs.map +1 -1
- package/fesm2022/button/testing.mjs +7 -4
- package/fesm2022/button/testing.mjs.map +1 -1
- package/fesm2022/button-toggle/testing.mjs.map +1 -1
- package/fesm2022/button-toggle.mjs.map +1 -1
- package/fesm2022/button.mjs +2 -2
- package/fesm2022/button.mjs.map +1 -1
- package/fesm2022/card/testing.mjs.map +1 -1
- package/fesm2022/card.mjs.map +1 -1
- package/fesm2022/checkbox/testing.mjs.map +1 -1
- package/fesm2022/checkbox.mjs.map +1 -1
- package/fesm2022/chips/testing.mjs.map +1 -1
- package/fesm2022/chips.mjs +1 -1
- package/fesm2022/chips.mjs.map +1 -1
- package/fesm2022/common-module-cKSwHniA.mjs.map +1 -1
- package/fesm2022/core/testing.mjs.map +1 -1
- package/fesm2022/core.mjs +1 -1
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/date-formats-K6TQue-Y.mjs.map +1 -1
- package/fesm2022/date-range-input-harness-DEyfkeOs.mjs.map +1 -1
- package/fesm2022/datepicker/testing.mjs.map +1 -1
- package/fesm2022/datepicker.mjs +1 -1
- package/fesm2022/datepicker.mjs.map +1 -1
- package/fesm2022/dialog/testing.mjs.map +1 -1
- package/fesm2022/dialog.mjs.map +1 -1
- package/fesm2022/divider/testing.mjs.map +1 -1
- package/fesm2022/divider.mjs.map +1 -1
- package/fesm2022/error-options-DCNQlTOA.mjs.map +1 -1
- package/fesm2022/error-state-Dtb1IHM-.mjs.map +1 -1
- package/fesm2022/expansion/testing.mjs.map +1 -1
- package/fesm2022/expansion.mjs +2 -2
- package/fesm2022/expansion.mjs.map +1 -1
- package/fesm2022/form-field/testing/control.mjs.map +1 -1
- package/fesm2022/form-field/testing.mjs.map +1 -1
- package/fesm2022/{form-field-C9DZXojn.mjs → form-field-CFbrnFED.mjs} +3 -3
- package/fesm2022/form-field-CFbrnFED.mjs.map +1 -0
- package/fesm2022/form-field.mjs +2 -2
- package/fesm2022/form-field.mjs.map +1 -1
- package/fesm2022/grid-list/testing.mjs.map +1 -1
- package/fesm2022/grid-list.mjs.map +1 -1
- package/fesm2022/icon/testing.mjs.map +1 -1
- package/fesm2022/icon-button-DxiIc1ex.mjs.map +1 -1
- package/fesm2022/icon-registry-CwOTJ7YM.mjs.map +1 -1
- package/fesm2022/icon.mjs.map +1 -1
- package/fesm2022/index-BFRo2fUq.mjs.map +1 -1
- package/fesm2022/index-DwiL-HGk.mjs.map +1 -1
- package/fesm2022/input/testing.mjs.map +1 -1
- package/fesm2022/input-harness-C5Msdc4-.mjs.map +1 -1
- package/fesm2022/input-value-accessor-D1GvPuqO.mjs.map +1 -1
- package/fesm2022/input.mjs +3 -27
- package/fesm2022/input.mjs.map +1 -1
- package/fesm2022/internal-form-field-D5iFxU6d.mjs.map +1 -1
- package/fesm2022/line-Bz5f9Cyx.mjs.map +1 -1
- package/fesm2022/list/testing.mjs.map +1 -1
- package/fesm2022/list.mjs.map +1 -1
- package/fesm2022/material.mjs.map +1 -1
- package/fesm2022/menu/testing.mjs +97 -13
- package/fesm2022/menu/testing.mjs.map +1 -1
- package/fesm2022/menu.mjs +343 -122
- package/fesm2022/menu.mjs.map +1 -1
- package/fesm2022/{module-BDiw_nWS.mjs → module-B0CLRw5e.mjs} +3 -3
- package/fesm2022/module-B0CLRw5e.mjs.map +1 -0
- package/fesm2022/{module-DzZHEh7B.mjs → module-B62K-792.mjs} +2 -2
- package/fesm2022/module-B62K-792.mjs.map +1 -0
- package/fesm2022/module-CWxMD37a.mjs.map +1 -1
- package/fesm2022/module-Ce6F7TNm.mjs.map +1 -1
- package/fesm2022/option-BzhYL_xC.mjs.map +1 -1
- package/fesm2022/option-harness-BFcc-M_4.mjs.map +1 -1
- package/fesm2022/paginator/testing.mjs.map +1 -1
- package/fesm2022/paginator.mjs +3 -3
- package/fesm2022/paginator.mjs.map +1 -1
- package/fesm2022/progress-bar/testing.mjs.map +1 -1
- package/fesm2022/progress-bar.mjs.map +1 -1
- package/fesm2022/progress-spinner/testing.mjs.map +1 -1
- package/fesm2022/progress-spinner.mjs.map +1 -1
- package/fesm2022/pseudo-checkbox-DDmgx3P4.mjs.map +1 -1
- package/fesm2022/pseudo-checkbox-module-4F8Up4PL.mjs.map +1 -1
- package/fesm2022/public-api-BoO5eSq-.mjs.map +1 -1
- package/fesm2022/radio/testing.mjs.map +1 -1
- package/fesm2022/radio.mjs.map +1 -1
- package/fesm2022/ripple-BYgV4oZC.mjs.map +1 -1
- package/fesm2022/ripple-loader-BnMiRtmT.mjs.map +1 -1
- package/fesm2022/select/testing.mjs.map +1 -1
- package/fesm2022/select.mjs +3 -3
- package/fesm2022/select.mjs.map +1 -1
- package/fesm2022/sidenav/testing.mjs.map +1 -1
- package/fesm2022/sidenav.mjs.map +1 -1
- package/fesm2022/slide-toggle/testing.mjs.map +1 -1
- package/fesm2022/slide-toggle.mjs +2 -2
- package/fesm2022/slide-toggle.mjs.map +1 -1
- package/fesm2022/slider/testing.mjs.map +1 -1
- package/fesm2022/slider.mjs +2 -2
- package/fesm2022/slider.mjs.map +1 -1
- package/fesm2022/snack-bar/testing.mjs.map +1 -1
- package/fesm2022/snack-bar.mjs +2 -2
- package/fesm2022/snack-bar.mjs.map +1 -1
- package/fesm2022/sort/testing.mjs.map +1 -1
- package/fesm2022/sort.mjs.map +1 -1
- package/fesm2022/stepper/testing.mjs.map +1 -1
- package/fesm2022/stepper.mjs.map +1 -1
- package/fesm2022/structural-styles-CObeNzjn.mjs.map +1 -1
- package/fesm2022/table/testing.mjs.map +1 -1
- package/fesm2022/table.mjs.map +1 -1
- package/fesm2022/tabs/testing.mjs.map +1 -1
- package/fesm2022/tabs.mjs.map +1 -1
- package/fesm2022/timepicker/testing.mjs.map +1 -1
- package/fesm2022/timepicker.mjs +1 -1
- package/fesm2022/timepicker.mjs.map +1 -1
- package/fesm2022/toolbar/testing.mjs.map +1 -1
- package/fesm2022/toolbar.mjs.map +1 -1
- package/fesm2022/tooltip/testing.mjs.map +1 -1
- package/fesm2022/tooltip.mjs.map +1 -1
- package/fesm2022/tree/testing.mjs.map +1 -1
- package/fesm2022/tree.mjs.map +1 -1
- package/form-field/_form-field-theme.scss +35 -51
- package/form-field/_m2-form-field.scss +23 -31
- package/grid-list/_grid-list-theme.scss +28 -28
- package/grid-list/_m2-grid-list.scss +7 -9
- package/icon/_icon-theme.scss +40 -41
- package/input/_input-theme.scss +1 -4
- package/input/index.d.ts +0 -11
- package/list/_list-theme.scss +55 -53
- package/list/_m2-list.scss +21 -35
- package/menu/_m2-menu.scss +18 -15
- package/menu/_menu-theme.scss +28 -33
- package/menu/index.d.ts +145 -61
- package/menu/testing/index.d.ts +50 -2
- package/package.json +2 -2
- package/paginator/_m2-paginator.scss +9 -9
- package/paginator/_paginator-theme.scss +28 -33
- package/prebuilt-themes/azure-blue.css +1 -1
- package/prebuilt-themes/cyan-orange.css +1 -1
- package/prebuilt-themes/deeppurple-amber.css +1 -1
- package/prebuilt-themes/indigo-pink.css +1 -1
- package/prebuilt-themes/magenta-violet.css +1 -1
- package/prebuilt-themes/pink-bluegrey.css +1 -1
- package/prebuilt-themes/purple-green.css +1 -1
- package/prebuilt-themes/rose-red.css +1 -1
- package/progress-bar/_progress-bar-theme.scss +35 -43
- package/progress-spinner/_progress-spinner-theme.scss +42 -43
- package/radio/_m2-radio.scss +6 -5
- package/radio/_m3-radio.scss +1 -1
- package/radio/_radio-theme.scss +33 -46
- package/schematics/ng-add/index.js +1 -1
- package/select/_m2-select.scss +10 -8
- package/select/_select-theme.scss +38 -48
- package/sidenav/_sidenav-theme.scss +28 -30
- package/slide-toggle/_m2-slide-toggle.scss +45 -58
- package/slide-toggle/_m3-slide-toggle.scss +1 -0
- package/slide-toggle/_slide-toggle-theme.scss +41 -79
- package/slider/_m2-slider.scss +33 -35
- package/slider/_slider-theme.scss +38 -45
- package/snack-bar/_m2-snack-bar.scss +5 -6
- package/snack-bar/_snack-bar-theme.scss +28 -31
- package/sort/_m2-sort.scss +5 -2
- package/sort/_sort-theme.scss +28 -33
- package/stepper/_m2-stepper.scss +10 -13
- package/stepper/_stepper-theme.scss +41 -49
- package/table/_m2-table.scss +23 -28
- package/table/_table-theme.scss +28 -36
- package/tabs/_m2-tabs.scss +11 -16
- package/tabs/_tabs-theme.scss +35 -43
- package/timepicker/_m2-timepicker.scss +5 -2
- package/timepicker/_timepicker-theme.scss +28 -46
- package/toolbar/_m2-toolbar.scss +10 -9
- package/toolbar/_toolbar-theme.scss +55 -46
- package/tooltip/_m2-tooltip.scss +5 -6
- package/tooltip/_tooltip-theme.scss +28 -37
- package/tree/_m2-tree.scss +9 -5
- package/tree/_tree-theme.scss +28 -38
- package/core/tokens/_format-tokens.scss +0 -5
- package/fesm2022/form-field-C9DZXojn.mjs.map +0 -1
- package/fesm2022/module-BDiw_nWS.mjs.map +0 -1
- package/fesm2022/module-DzZHEh7B.mjs.map +0 -1
package/fesm2022/menu.mjs
CHANGED
|
@@ -3,18 +3,18 @@ import { InjectionToken, inject, ElementRef, DOCUMENT, ChangeDetectorRef, boolea
|
|
|
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, take, filter } from 'rxjs/operators';
|
|
6
|
+
import { startWith, switchMap, takeUntil, take, filter, skipWhile } from 'rxjs/operators';
|
|
7
7
|
import { _CdkPrivateStyleLoader } from '@angular/cdk/private';
|
|
8
8
|
import { _ as _StructuralStylesLoader } from './structural-styles-CObeNzjn.mjs';
|
|
9
9
|
import { M as MatRipple } from './ripple-BYgV4oZC.mjs';
|
|
10
10
|
import { TemplatePortal, DomPortalOutlet } from '@angular/cdk/portal';
|
|
11
11
|
import { _ as _animationsDisabled } from './animation-DfMFjxHu.mjs';
|
|
12
12
|
import { Directionality } from '@angular/cdk/bidi';
|
|
13
|
-
import { createRepositionScrollStrategy, createOverlayRef, OverlayConfig, createFlexibleConnectedPositionStrategy, OverlayModule } from '@angular/cdk/overlay';
|
|
13
|
+
import { createRepositionScrollStrategy, createOverlayRef, OverlayConfig, createFlexibleConnectedPositionStrategy, ViewportRuler, ScrollDispatcher, OverlayModule } from '@angular/cdk/overlay';
|
|
14
|
+
import { _getEventTarget, _getShadowRoot } from '@angular/cdk/platform';
|
|
14
15
|
import { CdkScrollableModule } from '@angular/cdk/scrolling';
|
|
15
16
|
import { M as MatRippleModule } from './index-BFRo2fUq.mjs';
|
|
16
17
|
import { M as MatCommonModule } from './common-module-cKSwHniA.mjs';
|
|
17
|
-
import '@angular/cdk/platform';
|
|
18
18
|
import '@angular/cdk/coercion';
|
|
19
19
|
import '@angular/cdk/layout';
|
|
20
20
|
|
|
@@ -703,7 +703,8 @@ const MENU_PANEL_TOP_PADDING = 8;
|
|
|
703
703
|
/** Mapping between menu panels and the last trigger that opened them. */
|
|
704
704
|
const PANELS_TO_TRIGGERS = new WeakMap();
|
|
705
705
|
/** Directive applied to an element that should trigger a `mat-menu`. */
|
|
706
|
-
class
|
|
706
|
+
class MatMenuTriggerBase {
|
|
707
|
+
_canHaveBackdrop;
|
|
707
708
|
_element = inject(ElementRef);
|
|
708
709
|
_viewContainerRef = inject(ViewContainerRef);
|
|
709
710
|
_menuItemInstance = inject(MatMenuItem, { optional: true, self: true });
|
|
@@ -714,12 +715,10 @@ class MatMenuTrigger {
|
|
|
714
715
|
_scrollStrategy = inject(MAT_MENU_SCROLL_STRATEGY);
|
|
715
716
|
_changeDetectorRef = inject(ChangeDetectorRef);
|
|
716
717
|
_animationsDisabled = _animationsDisabled();
|
|
717
|
-
_cleanupTouchstart;
|
|
718
718
|
_portal;
|
|
719
719
|
_overlayRef = null;
|
|
720
720
|
_menuOpen = false;
|
|
721
721
|
_closingActionsSubscription = Subscription.EMPTY;
|
|
722
|
-
_hoverSubscription = Subscription.EMPTY;
|
|
723
722
|
_menuCloseSubscription = Subscription.EMPTY;
|
|
724
723
|
_pendingRemoval;
|
|
725
724
|
/**
|
|
@@ -735,25 +734,15 @@ class MatMenuTrigger {
|
|
|
735
734
|
// Tracking input type is necessary so it's possible to only auto-focus
|
|
736
735
|
// the first item of the list when the menu is opened via the keyboard
|
|
737
736
|
_openedBy = undefined;
|
|
738
|
-
/**
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
*/
|
|
742
|
-
get _deprecatedMatMenuTriggerFor() {
|
|
743
|
-
return this.menu;
|
|
737
|
+
/** Menu currently assigned to the trigger. */
|
|
738
|
+
get _menu() {
|
|
739
|
+
return this._menuInternal;
|
|
744
740
|
}
|
|
745
|
-
set
|
|
746
|
-
this.
|
|
747
|
-
}
|
|
748
|
-
/** References the menu instance that the trigger is associated with. */
|
|
749
|
-
get menu() {
|
|
750
|
-
return this._menu;
|
|
751
|
-
}
|
|
752
|
-
set menu(menu) {
|
|
753
|
-
if (menu === this._menu) {
|
|
741
|
+
set _menu(menu) {
|
|
742
|
+
if (menu === this._menuInternal) {
|
|
754
743
|
return;
|
|
755
744
|
}
|
|
756
|
-
this.
|
|
745
|
+
this._menuInternal = menu;
|
|
757
746
|
this._menuCloseSubscription.unsubscribe();
|
|
758
747
|
if (menu) {
|
|
759
748
|
if (menu === this._parentMaterialMenu && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
@@ -767,57 +756,21 @@ class MatMenuTrigger {
|
|
|
767
756
|
}
|
|
768
757
|
});
|
|
769
758
|
}
|
|
770
|
-
this._menuItemInstance?._setTriggersSubmenu(this.
|
|
759
|
+
this._menuItemInstance?._setTriggersSubmenu(this._triggersSubmenu());
|
|
771
760
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
/**
|
|
776
|
-
* Whether focus should be restored when the menu is closed.
|
|
777
|
-
* Note that disabling this option can have accessibility implications
|
|
778
|
-
* and it's up to you to manage focus, if you decide to turn it off.
|
|
779
|
-
*/
|
|
780
|
-
restoreFocus = true;
|
|
781
|
-
/** Event emitted when the associated menu is opened. */
|
|
782
|
-
menuOpened = new EventEmitter();
|
|
783
|
-
/**
|
|
784
|
-
* Event emitted when the associated menu is opened.
|
|
785
|
-
* @deprecated Switch to `menuOpened` instead
|
|
786
|
-
* @breaking-change 8.0.0
|
|
787
|
-
*/
|
|
788
|
-
// tslint:disable-next-line:no-output-on-prefix
|
|
789
|
-
onMenuOpen = this.menuOpened;
|
|
790
|
-
/** Event emitted when the associated menu is closed. */
|
|
791
|
-
menuClosed = new EventEmitter();
|
|
792
|
-
/**
|
|
793
|
-
* Event emitted when the associated menu is closed.
|
|
794
|
-
* @deprecated Switch to `menuClosed` instead
|
|
795
|
-
* @breaking-change 8.0.0
|
|
796
|
-
*/
|
|
797
|
-
// tslint:disable-next-line:no-output-on-prefix
|
|
798
|
-
onMenuClose = this.menuClosed;
|
|
799
|
-
constructor() {
|
|
761
|
+
_menuInternal;
|
|
762
|
+
constructor(_canHaveBackdrop) {
|
|
763
|
+
this._canHaveBackdrop = _canHaveBackdrop;
|
|
800
764
|
const parentMenu = inject(MAT_MENU_PANEL, { optional: true });
|
|
801
|
-
const renderer = inject(Renderer2);
|
|
802
765
|
this._parentMaterialMenu = parentMenu instanceof MatMenu ? parentMenu : undefined;
|
|
803
|
-
this._cleanupTouchstart = renderer.listen(this._element.nativeElement, 'touchstart', (event) => {
|
|
804
|
-
if (!isFakeTouchstartFromScreenReader(event)) {
|
|
805
|
-
this._openedBy = 'touch';
|
|
806
|
-
}
|
|
807
|
-
}, { passive: true });
|
|
808
|
-
}
|
|
809
|
-
ngAfterContentInit() {
|
|
810
|
-
this._handleHover();
|
|
811
766
|
}
|
|
812
767
|
ngOnDestroy() {
|
|
813
|
-
if (this.
|
|
814
|
-
PANELS_TO_TRIGGERS.delete(this.
|
|
768
|
+
if (this._menu && this._ownsMenu(this._menu)) {
|
|
769
|
+
PANELS_TO_TRIGGERS.delete(this._menu);
|
|
815
770
|
}
|
|
816
|
-
this._cleanupTouchstart();
|
|
817
771
|
this._pendingRemoval?.unsubscribe();
|
|
818
772
|
this._menuCloseSubscription.unsubscribe();
|
|
819
773
|
this._closingActionsSubscription.unsubscribe();
|
|
820
|
-
this._hoverSubscription.unsubscribe();
|
|
821
774
|
if (this._overlayRef) {
|
|
822
775
|
this._overlayRef.dispose();
|
|
823
776
|
this._overlayRef = null;
|
|
@@ -832,21 +785,15 @@ class MatMenuTrigger {
|
|
|
832
785
|
return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
|
|
833
786
|
}
|
|
834
787
|
/** Whether the menu triggers a sub-menu or a top-level one. */
|
|
835
|
-
|
|
836
|
-
return !!(this._menuItemInstance && this._parentMaterialMenu && this.
|
|
837
|
-
}
|
|
838
|
-
/** Toggles the menu between the open and closed states. */
|
|
839
|
-
toggleMenu() {
|
|
840
|
-
return this._menuOpen ? this.closeMenu() : this.openMenu();
|
|
788
|
+
_triggersSubmenu() {
|
|
789
|
+
return !!(this._menuItemInstance && this._parentMaterialMenu && this._menu);
|
|
841
790
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
// Auto focus by default
|
|
845
|
-
this._openMenu(true);
|
|
791
|
+
_closeMenu() {
|
|
792
|
+
this._menu?.close.emit();
|
|
846
793
|
}
|
|
847
794
|
/** Internal method to open menu providing option to auto focus on first item. */
|
|
848
795
|
_openMenu(autoFocus) {
|
|
849
|
-
const menu = this.
|
|
796
|
+
const menu = this._menu;
|
|
850
797
|
if (this._menuOpen || !menu) {
|
|
851
798
|
return;
|
|
852
799
|
}
|
|
@@ -856,25 +803,31 @@ class MatMenuTrigger {
|
|
|
856
803
|
// If the same menu is currently attached to another trigger,
|
|
857
804
|
// we need to close it so it doesn't end up in a broken state.
|
|
858
805
|
if (previousTrigger && previousTrigger !== this) {
|
|
859
|
-
previousTrigger.
|
|
806
|
+
previousTrigger._closeMenu();
|
|
860
807
|
}
|
|
861
808
|
const overlayRef = this._createOverlay(menu);
|
|
862
809
|
const overlayConfig = overlayRef.getConfig();
|
|
863
810
|
const positionStrategy = overlayConfig.positionStrategy;
|
|
864
811
|
this._setPosition(menu, positionStrategy);
|
|
865
|
-
|
|
866
|
-
|
|
812
|
+
if (this._canHaveBackdrop) {
|
|
813
|
+
overlayConfig.hasBackdrop =
|
|
814
|
+
menu.hasBackdrop == null ? !this._triggersSubmenu() : menu.hasBackdrop;
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
overlayConfig.hasBackdrop = false;
|
|
818
|
+
}
|
|
867
819
|
// We need the `hasAttached` check for the case where the user kicked off a removal animation,
|
|
868
820
|
// but re-entered the menu. Re-attaching the same portal will trigger an error otherwise.
|
|
869
821
|
if (!overlayRef.hasAttached()) {
|
|
870
822
|
overlayRef.attach(this._getPortal(menu));
|
|
871
823
|
menu.lazyContent?.attach(this.menuData);
|
|
872
824
|
}
|
|
873
|
-
this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this.
|
|
874
|
-
menu.parentMenu = this.
|
|
825
|
+
this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this._closeMenu());
|
|
826
|
+
menu.parentMenu = this._triggersSubmenu() ? this._parentMaterialMenu : undefined;
|
|
875
827
|
menu.direction = this.dir;
|
|
876
|
-
if (autoFocus)
|
|
828
|
+
if (autoFocus) {
|
|
877
829
|
menu.focusFirstItem(this._openedBy || 'program');
|
|
830
|
+
}
|
|
878
831
|
this._setIsMenuOpen(true);
|
|
879
832
|
if (menu instanceof MatMenu) {
|
|
880
833
|
menu._setIsOpen(true);
|
|
@@ -886,10 +839,6 @@ class MatMenuTrigger {
|
|
|
886
839
|
});
|
|
887
840
|
}
|
|
888
841
|
}
|
|
889
|
-
/** Closes the menu. */
|
|
890
|
-
closeMenu() {
|
|
891
|
-
this.menu?.close.emit();
|
|
892
|
-
}
|
|
893
842
|
/**
|
|
894
843
|
* Focuses the menu trigger.
|
|
895
844
|
* @param origin Source of the menu trigger's focus.
|
|
@@ -902,12 +851,6 @@ class MatMenuTrigger {
|
|
|
902
851
|
this._element.nativeElement.focus(options);
|
|
903
852
|
}
|
|
904
853
|
}
|
|
905
|
-
/**
|
|
906
|
-
* Updates the position of the menu to ensure that it fits all options within the viewport.
|
|
907
|
-
*/
|
|
908
|
-
updatePosition() {
|
|
909
|
-
this._overlayRef?.updatePosition();
|
|
910
|
-
}
|
|
911
854
|
/** Closes the menu and does the necessary cleanup. */
|
|
912
855
|
_destroyMenu(reason) {
|
|
913
856
|
const overlayRef = this._overlayRef;
|
|
@@ -937,7 +880,8 @@ class MatMenuTrigger {
|
|
|
937
880
|
// programmatically. We don't restore for non-root triggers, because it can prevent focus
|
|
938
881
|
// from making it back to the root trigger when closing a long chain of menus by clicking
|
|
939
882
|
// on the backdrop.
|
|
940
|
-
if (this.restoreFocus &&
|
|
883
|
+
if (this.restoreFocus &&
|
|
884
|
+
(reason === 'keydown' || !this._openedBy || !this._triggersSubmenu())) {
|
|
941
885
|
this.focus(this._openedBy);
|
|
942
886
|
}
|
|
943
887
|
this._openedBy = undefined;
|
|
@@ -948,7 +892,7 @@ class MatMenuTrigger {
|
|
|
948
892
|
if (isOpen !== this._menuOpen) {
|
|
949
893
|
this._menuOpen = isOpen;
|
|
950
894
|
this._menuOpen ? this.menuOpened.emit() : this.menuClosed.emit();
|
|
951
|
-
if (this.
|
|
895
|
+
if (this._triggersSubmenu()) {
|
|
952
896
|
this._menuItemInstance._setHighlighted(isOpen);
|
|
953
897
|
}
|
|
954
898
|
this._changeDetectorRef.markForCheck();
|
|
@@ -964,8 +908,8 @@ class MatMenuTrigger {
|
|
|
964
908
|
this._subscribeToPositions(menu, config.positionStrategy);
|
|
965
909
|
this._overlayRef = createOverlayRef(this._injector, config);
|
|
966
910
|
this._overlayRef.keydownEvents().subscribe(event => {
|
|
967
|
-
if (this.
|
|
968
|
-
this.
|
|
911
|
+
if (this._menu instanceof MatMenu) {
|
|
912
|
+
this._menu._handleKeydown(event);
|
|
969
913
|
}
|
|
970
914
|
});
|
|
971
915
|
}
|
|
@@ -977,7 +921,7 @@ class MatMenuTrigger {
|
|
|
977
921
|
*/
|
|
978
922
|
_getOverlayConfig(menu) {
|
|
979
923
|
return new OverlayConfig({
|
|
980
|
-
positionStrategy: createFlexibleConnectedPositionStrategy(this._injector, this.
|
|
924
|
+
positionStrategy: createFlexibleConnectedPositionStrategy(this._injector, this._getOverlayOrigin())
|
|
981
925
|
.withLockedPosition()
|
|
982
926
|
.withGrowAfterOpen()
|
|
983
927
|
.withTransformOriginOn('.mat-menu-panel, .mat-mdc-menu-panel'),
|
|
@@ -1015,7 +959,7 @@ class MatMenuTrigger {
|
|
|
1015
959
|
let [originY, originFallbackY] = [overlayY, overlayFallbackY];
|
|
1016
960
|
let [overlayX, overlayFallbackX] = [originX, originFallbackX];
|
|
1017
961
|
let offsetY = 0;
|
|
1018
|
-
if (this.
|
|
962
|
+
if (this._triggersSubmenu()) {
|
|
1019
963
|
// When the menu is a sub-menu, it should always align itself
|
|
1020
964
|
// to the edges of the trigger, instead of overlapping it.
|
|
1021
965
|
overlayFallbackX = originX = menu.xPosition === 'before' ? 'start' : 'end';
|
|
@@ -1053,7 +997,7 @@ class MatMenuTrigger {
|
|
|
1053
997
|
}
|
|
1054
998
|
/** Returns a stream that emits whenever an action that should close the menu occurs. */
|
|
1055
999
|
_menuClosingActions() {
|
|
1056
|
-
const
|
|
1000
|
+
const outsideClicks = this._getOutsideClickStream(this._overlayRef);
|
|
1057
1001
|
const detachments = this._overlayRef.detachments();
|
|
1058
1002
|
const parentClose = this._parentMaterialMenu ? this._parentMaterialMenu.closed : of();
|
|
1059
1003
|
const hover = this._parentMaterialMenu
|
|
@@ -1061,7 +1005,124 @@ class MatMenuTrigger {
|
|
|
1061
1005
|
._hovered()
|
|
1062
1006
|
.pipe(filter(active => this._menuOpen && active !== this._menuItemInstance))
|
|
1063
1007
|
: of();
|
|
1064
|
-
return merge(
|
|
1008
|
+
return merge(outsideClicks, parentClose, hover, detachments);
|
|
1009
|
+
}
|
|
1010
|
+
/** Gets the portal that should be attached to the overlay. */
|
|
1011
|
+
_getPortal(menu) {
|
|
1012
|
+
// Note that we can avoid this check by keeping the portal on the menu panel.
|
|
1013
|
+
// While it would be cleaner, we'd have to introduce another required method on
|
|
1014
|
+
// `MatMenuPanel`, making it harder to consume.
|
|
1015
|
+
if (!this._portal || this._portal.templateRef !== menu.templateRef) {
|
|
1016
|
+
this._portal = new TemplatePortal(menu.templateRef, this._viewContainerRef);
|
|
1017
|
+
}
|
|
1018
|
+
return this._portal;
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Determines whether the trigger owns a specific menu panel, at the current point in time.
|
|
1022
|
+
* This allows us to distinguish the case where the same panel is passed into multiple triggers
|
|
1023
|
+
* and multiple are open at a time.
|
|
1024
|
+
*/
|
|
1025
|
+
_ownsMenu(menu) {
|
|
1026
|
+
return PANELS_TO_TRIGGERS.get(menu) === this;
|
|
1027
|
+
}
|
|
1028
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatMenuTriggerBase, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
|
|
1029
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.0", type: MatMenuTriggerBase, isStandalone: true, ngImport: i0 });
|
|
1030
|
+
}
|
|
1031
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatMenuTriggerBase, decorators: [{
|
|
1032
|
+
type: Directive
|
|
1033
|
+
}], ctorParameters: () => [{ type: undefined }] });
|
|
1034
|
+
|
|
1035
|
+
/** Directive applied to an element that should trigger a `mat-menu`. */
|
|
1036
|
+
class MatMenuTrigger extends MatMenuTriggerBase {
|
|
1037
|
+
_cleanupTouchstart;
|
|
1038
|
+
_hoverSubscription = Subscription.EMPTY;
|
|
1039
|
+
/**
|
|
1040
|
+
* @deprecated
|
|
1041
|
+
* @breaking-change 8.0.0
|
|
1042
|
+
*/
|
|
1043
|
+
get _deprecatedMatMenuTriggerFor() {
|
|
1044
|
+
return this.menu;
|
|
1045
|
+
}
|
|
1046
|
+
set _deprecatedMatMenuTriggerFor(v) {
|
|
1047
|
+
this.menu = v;
|
|
1048
|
+
}
|
|
1049
|
+
/** References the menu instance that the trigger is associated with. */
|
|
1050
|
+
get menu() {
|
|
1051
|
+
return this._menu;
|
|
1052
|
+
}
|
|
1053
|
+
set menu(menu) {
|
|
1054
|
+
this._menu = menu;
|
|
1055
|
+
}
|
|
1056
|
+
/** Data to be passed along to any lazily-rendered content. */
|
|
1057
|
+
menuData;
|
|
1058
|
+
/**
|
|
1059
|
+
* Whether focus should be restored when the menu is closed.
|
|
1060
|
+
* Note that disabling this option can have accessibility implications
|
|
1061
|
+
* and it's up to you to manage focus, if you decide to turn it off.
|
|
1062
|
+
*/
|
|
1063
|
+
restoreFocus = true;
|
|
1064
|
+
/** Event emitted when the associated menu is opened. */
|
|
1065
|
+
menuOpened = new EventEmitter();
|
|
1066
|
+
/**
|
|
1067
|
+
* Event emitted when the associated menu is opened.
|
|
1068
|
+
* @deprecated Switch to `menuOpened` instead
|
|
1069
|
+
* @breaking-change 8.0.0
|
|
1070
|
+
*/
|
|
1071
|
+
// tslint:disable-next-line:no-output-on-prefix
|
|
1072
|
+
onMenuOpen = this.menuOpened;
|
|
1073
|
+
/** Event emitted when the associated menu is closed. */
|
|
1074
|
+
menuClosed = new EventEmitter();
|
|
1075
|
+
/**
|
|
1076
|
+
* Event emitted when the associated menu is closed.
|
|
1077
|
+
* @deprecated Switch to `menuClosed` instead
|
|
1078
|
+
* @breaking-change 8.0.0
|
|
1079
|
+
*/
|
|
1080
|
+
// tslint:disable-next-line:no-output-on-prefix
|
|
1081
|
+
onMenuClose = this.menuClosed;
|
|
1082
|
+
constructor() {
|
|
1083
|
+
super(true);
|
|
1084
|
+
const renderer = inject(Renderer2);
|
|
1085
|
+
this._cleanupTouchstart = renderer.listen(this._element.nativeElement, 'touchstart', (event) => {
|
|
1086
|
+
if (!isFakeTouchstartFromScreenReader(event)) {
|
|
1087
|
+
this._openedBy = 'touch';
|
|
1088
|
+
}
|
|
1089
|
+
}, { passive: true });
|
|
1090
|
+
}
|
|
1091
|
+
/** Whether the menu triggers a sub-menu or a top-level one. */
|
|
1092
|
+
triggersSubmenu() {
|
|
1093
|
+
return super._triggersSubmenu();
|
|
1094
|
+
}
|
|
1095
|
+
/** Toggles the menu between the open and closed states. */
|
|
1096
|
+
toggleMenu() {
|
|
1097
|
+
return this.menuOpen ? this.closeMenu() : this.openMenu();
|
|
1098
|
+
}
|
|
1099
|
+
/** Opens the menu. */
|
|
1100
|
+
openMenu() {
|
|
1101
|
+
this._openMenu(true);
|
|
1102
|
+
}
|
|
1103
|
+
/** Closes the menu. */
|
|
1104
|
+
closeMenu() {
|
|
1105
|
+
this._closeMenu();
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Updates the position of the menu to ensure that it fits all options within the viewport.
|
|
1109
|
+
*/
|
|
1110
|
+
updatePosition() {
|
|
1111
|
+
this._overlayRef?.updatePosition();
|
|
1112
|
+
}
|
|
1113
|
+
ngAfterContentInit() {
|
|
1114
|
+
this._handleHover();
|
|
1115
|
+
}
|
|
1116
|
+
ngOnDestroy() {
|
|
1117
|
+
super.ngOnDestroy();
|
|
1118
|
+
this._cleanupTouchstart();
|
|
1119
|
+
this._hoverSubscription.unsubscribe();
|
|
1120
|
+
}
|
|
1121
|
+
_getOverlayOrigin() {
|
|
1122
|
+
return this._element;
|
|
1123
|
+
}
|
|
1124
|
+
_getOutsideClickStream(overlayRef) {
|
|
1125
|
+
return overlayRef.backdropClick();
|
|
1065
1126
|
}
|
|
1066
1127
|
/** Handles mouse presses on the trigger. */
|
|
1067
1128
|
_handleMousedown(event) {
|
|
@@ -1117,31 +1178,13 @@ class MatMenuTrigger {
|
|
|
1117
1178
|
});
|
|
1118
1179
|
}
|
|
1119
1180
|
}
|
|
1120
|
-
/** Gets the portal that should be attached to the overlay. */
|
|
1121
|
-
_getPortal(menu) {
|
|
1122
|
-
// Note that we can avoid this check by keeping the portal on the menu panel.
|
|
1123
|
-
// While it would be cleaner, we'd have to introduce another required method on
|
|
1124
|
-
// `MatMenuPanel`, making it harder to consume.
|
|
1125
|
-
if (!this._portal || this._portal.templateRef !== menu.templateRef) {
|
|
1126
|
-
this._portal = new TemplatePortal(menu.templateRef, this._viewContainerRef);
|
|
1127
|
-
}
|
|
1128
|
-
return this._portal;
|
|
1129
|
-
}
|
|
1130
|
-
/**
|
|
1131
|
-
* Determines whether the trigger owns a specific menu panel, at the current point in time.
|
|
1132
|
-
* This allows us to distinguish the case where the same panel is passed into multiple triggers
|
|
1133
|
-
* and multiple are open at a time.
|
|
1134
|
-
*/
|
|
1135
|
-
_ownsMenu(menu) {
|
|
1136
|
-
return PANELS_TO_TRIGGERS.get(menu) === this;
|
|
1137
|
-
}
|
|
1138
1181
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1139
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.0", 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 });
|
|
1182
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.0", 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"], usesInheritance: true, ngImport: i0 });
|
|
1140
1183
|
}
|
|
1141
1184
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatMenuTrigger, decorators: [{
|
|
1142
1185
|
type: Directive,
|
|
1143
1186
|
args: [{
|
|
1144
|
-
selector:
|
|
1187
|
+
selector: '[mat-menu-trigger-for], [matMenuTriggerFor]',
|
|
1145
1188
|
host: {
|
|
1146
1189
|
'class': 'mat-mdc-menu-trigger',
|
|
1147
1190
|
'[attr.aria-haspopup]': 'menu ? "menu" : null',
|
|
@@ -1175,6 +1218,180 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
|
|
|
1175
1218
|
type: Output
|
|
1176
1219
|
}] } });
|
|
1177
1220
|
|
|
1221
|
+
/**
|
|
1222
|
+
* Trigger that opens a menu whenever the user right-clicks within its host element.
|
|
1223
|
+
*/
|
|
1224
|
+
class MatContextMenuTrigger extends MatMenuTriggerBase {
|
|
1225
|
+
_point = { x: 0, y: 0, initialX: 0, initialY: 0, initialScrollX: 0, initialScrollY: 0 };
|
|
1226
|
+
_triggerPressedControl = false;
|
|
1227
|
+
_rootNode;
|
|
1228
|
+
_document = inject(DOCUMENT);
|
|
1229
|
+
_viewportRuler = inject(ViewportRuler);
|
|
1230
|
+
_scrollDispatcher = inject(ScrollDispatcher);
|
|
1231
|
+
_scrollSubscription;
|
|
1232
|
+
/** References the menu instance that the trigger is associated with. */
|
|
1233
|
+
get menu() {
|
|
1234
|
+
return this._menu;
|
|
1235
|
+
}
|
|
1236
|
+
set menu(menu) {
|
|
1237
|
+
this._menu = menu;
|
|
1238
|
+
}
|
|
1239
|
+
/** Data to be passed along to any lazily-rendered content. */
|
|
1240
|
+
menuData;
|
|
1241
|
+
/**
|
|
1242
|
+
* Whether focus should be restored when the menu is closed.
|
|
1243
|
+
* Note that disabling this option can have accessibility implications
|
|
1244
|
+
* and it's up to you to manage focus, if you decide to turn it off.
|
|
1245
|
+
*/
|
|
1246
|
+
restoreFocus = true;
|
|
1247
|
+
/** Whether the context menu is disabled. */
|
|
1248
|
+
disabled = false;
|
|
1249
|
+
/** Event emitted when the associated menu is opened. */
|
|
1250
|
+
menuOpened = new EventEmitter();
|
|
1251
|
+
/** Event emitted when the associated menu is closed. */
|
|
1252
|
+
menuClosed = new EventEmitter();
|
|
1253
|
+
constructor() {
|
|
1254
|
+
super(false);
|
|
1255
|
+
}
|
|
1256
|
+
ngOnDestroy() {
|
|
1257
|
+
super.ngOnDestroy();
|
|
1258
|
+
this._scrollSubscription?.unsubscribe();
|
|
1259
|
+
}
|
|
1260
|
+
/** Handler for `contextmenu` events. */
|
|
1261
|
+
_handleContextMenuEvent(event) {
|
|
1262
|
+
if (!this.disabled) {
|
|
1263
|
+
event.preventDefault();
|
|
1264
|
+
// If the menu is already open, only update its position.
|
|
1265
|
+
if (this.menuOpen) {
|
|
1266
|
+
this._initializePoint(event.clientX, event.clientY);
|
|
1267
|
+
this._updatePosition();
|
|
1268
|
+
}
|
|
1269
|
+
else {
|
|
1270
|
+
this._openContextMenu(event);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
_destroyMenu(reason) {
|
|
1275
|
+
super._destroyMenu(reason);
|
|
1276
|
+
this._scrollSubscription?.unsubscribe();
|
|
1277
|
+
}
|
|
1278
|
+
_getOverlayOrigin() {
|
|
1279
|
+
return this._point;
|
|
1280
|
+
}
|
|
1281
|
+
_getOutsideClickStream(overlayRef) {
|
|
1282
|
+
return overlayRef.outsidePointerEvents().pipe(skipWhile((event, index) => {
|
|
1283
|
+
if (event.type === 'contextmenu') {
|
|
1284
|
+
// Do not close when attempting to open a context menu within the trigger.
|
|
1285
|
+
return this._isWithinMenuOrTrigger(_getEventTarget(event));
|
|
1286
|
+
}
|
|
1287
|
+
else if (event.type === 'auxclick') {
|
|
1288
|
+
// Skip the first `auxclick` since it happens at
|
|
1289
|
+
// the same time as the event that opens the menu.
|
|
1290
|
+
if (index === 0) {
|
|
1291
|
+
return true;
|
|
1292
|
+
}
|
|
1293
|
+
// Do not close on `auxclick` within the menu since we want to reposition the menu
|
|
1294
|
+
// instead. Note that we have to resolve the clicked element using its position,
|
|
1295
|
+
// rather than `event.target`, because the `target` is set to the `body`.
|
|
1296
|
+
this._rootNode ??= _getShadowRoot(this._element.nativeElement) || this._document;
|
|
1297
|
+
return this._isWithinMenuOrTrigger(this._rootNode.elementFromPoint(event.clientX, event.clientY));
|
|
1298
|
+
}
|
|
1299
|
+
// Using a mouse, the `contextmenu` event can fire either when pressing the right button
|
|
1300
|
+
// or left button + control. Most browsers won't dispatch a `click` event right after
|
|
1301
|
+
// a `contextmenu` event triggered by left button + control, but Safari will (see #27832).
|
|
1302
|
+
// This closes the menu immediately. To work around it, we check that both the triggering
|
|
1303
|
+
// event and the current outside click event both had the control key pressed, and that
|
|
1304
|
+
// that this is the first outside click event.
|
|
1305
|
+
return this._triggerPressedControl && index === 0 && event.ctrlKey;
|
|
1306
|
+
}));
|
|
1307
|
+
}
|
|
1308
|
+
/** Checks whether an element is within the trigger or the opened overlay. */
|
|
1309
|
+
_isWithinMenuOrTrigger(target) {
|
|
1310
|
+
if (!target) {
|
|
1311
|
+
return false;
|
|
1312
|
+
}
|
|
1313
|
+
const element = this._element.nativeElement;
|
|
1314
|
+
if (target === element || element.contains(target)) {
|
|
1315
|
+
return true;
|
|
1316
|
+
}
|
|
1317
|
+
const overlay = this._overlayRef?.hostElement;
|
|
1318
|
+
return overlay === target || !!overlay?.contains(target);
|
|
1319
|
+
}
|
|
1320
|
+
/** Opens the context menu. */
|
|
1321
|
+
_openContextMenu(event) {
|
|
1322
|
+
// A context menu can be triggered via a mouse right click or a keyboard shortcut.
|
|
1323
|
+
if (event.button === 2) {
|
|
1324
|
+
this._openedBy = 'mouse';
|
|
1325
|
+
}
|
|
1326
|
+
else {
|
|
1327
|
+
this._openedBy = event.button === 0 ? 'keyboard' : undefined;
|
|
1328
|
+
}
|
|
1329
|
+
this._initializePoint(event.clientX, event.clientY);
|
|
1330
|
+
this._triggerPressedControl = event.ctrlKey;
|
|
1331
|
+
super._openMenu(true);
|
|
1332
|
+
this._scrollSubscription?.unsubscribe();
|
|
1333
|
+
this._scrollSubscription = this._scrollDispatcher.scrolled(0).subscribe(() => {
|
|
1334
|
+
// When passing a point to the connected position strategy, the position
|
|
1335
|
+
// won't update as the user is scrolling so we have to do it manually.
|
|
1336
|
+
const position = this._viewportRuler.getViewportScrollPosition();
|
|
1337
|
+
const point = this._point;
|
|
1338
|
+
point.y = point.initialY + (point.initialScrollY - position.top);
|
|
1339
|
+
point.x = point.initialX + (point.initialScrollX - position.left);
|
|
1340
|
+
this._updatePosition();
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
/** Initializes the point representing the origin relative to which the menu will be rendered. */
|
|
1344
|
+
_initializePoint(x, y) {
|
|
1345
|
+
const scrollPosition = this._viewportRuler.getViewportScrollPosition();
|
|
1346
|
+
const point = this._point;
|
|
1347
|
+
point.x = point.initialX = x;
|
|
1348
|
+
point.y = point.initialY = y;
|
|
1349
|
+
point.initialScrollX = scrollPosition.left;
|
|
1350
|
+
point.initialScrollY = scrollPosition.top;
|
|
1351
|
+
}
|
|
1352
|
+
/** Refreshes the position of the overlay. */
|
|
1353
|
+
_updatePosition() {
|
|
1354
|
+
const overlayRef = this._overlayRef;
|
|
1355
|
+
if (overlayRef) {
|
|
1356
|
+
const positionStrategy = overlayRef.getConfig()
|
|
1357
|
+
.positionStrategy;
|
|
1358
|
+
positionStrategy.setOrigin(this._point);
|
|
1359
|
+
overlayRef.updatePosition();
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatContextMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1363
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.0.0", type: MatContextMenuTrigger, isStandalone: true, selector: "[matContextMenuTriggerFor]", inputs: { menu: ["matContextMenuTriggerFor", "menu"], menuData: ["matContextMenuTriggerData", "menuData"], restoreFocus: ["matContextMenuTriggerRestoreFocus", "restoreFocus"], disabled: ["matContextMenuTriggerDisabled", "disabled", booleanAttribute] }, outputs: { menuOpened: "menuOpened", menuClosed: "menuClosed" }, host: { listeners: { "contextmenu": "_handleContextMenuEvent($event)" }, properties: { "class.mat-context-menu-trigger-disabled": "disabled", "attr.aria-controls": "menuOpen ? menu?.panelId : null" }, classAttribute: "mat-context-menu-trigger" }, exportAs: ["matContextMenuTrigger"], usesInheritance: true, ngImport: i0 });
|
|
1364
|
+
}
|
|
1365
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatContextMenuTrigger, decorators: [{
|
|
1366
|
+
type: Directive,
|
|
1367
|
+
args: [{
|
|
1368
|
+
selector: '[matContextMenuTriggerFor]',
|
|
1369
|
+
host: {
|
|
1370
|
+
'class': 'mat-context-menu-trigger',
|
|
1371
|
+
'[class.mat-context-menu-trigger-disabled]': 'disabled',
|
|
1372
|
+
'[attr.aria-controls]': 'menuOpen ? menu?.panelId : null',
|
|
1373
|
+
'(contextmenu)': '_handleContextMenuEvent($event)',
|
|
1374
|
+
},
|
|
1375
|
+
exportAs: 'matContextMenuTrigger',
|
|
1376
|
+
}]
|
|
1377
|
+
}], ctorParameters: () => [], propDecorators: { menu: [{
|
|
1378
|
+
type: Input,
|
|
1379
|
+
args: [{ alias: 'matContextMenuTriggerFor', required: true }]
|
|
1380
|
+
}], menuData: [{
|
|
1381
|
+
type: Input,
|
|
1382
|
+
args: ['matContextMenuTriggerData']
|
|
1383
|
+
}], restoreFocus: [{
|
|
1384
|
+
type: Input,
|
|
1385
|
+
args: ['matContextMenuTriggerRestoreFocus']
|
|
1386
|
+
}], disabled: [{
|
|
1387
|
+
type: Input,
|
|
1388
|
+
args: [{ alias: 'matContextMenuTriggerDisabled', transform: booleanAttribute }]
|
|
1389
|
+
}], menuOpened: [{
|
|
1390
|
+
type: Output
|
|
1391
|
+
}], menuClosed: [{
|
|
1392
|
+
type: Output
|
|
1393
|
+
}] } });
|
|
1394
|
+
|
|
1178
1395
|
class MatMenuModule {
|
|
1179
1396
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1180
1397
|
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.0", ngImport: i0, type: MatMenuModule, imports: [MatRippleModule,
|
|
@@ -1183,12 +1400,14 @@ class MatMenuModule {
|
|
|
1183
1400
|
MatMenu,
|
|
1184
1401
|
MatMenuItem,
|
|
1185
1402
|
MatMenuContent,
|
|
1186
|
-
MatMenuTrigger
|
|
1403
|
+
MatMenuTrigger,
|
|
1404
|
+
MatContextMenuTrigger], exports: [CdkScrollableModule,
|
|
1187
1405
|
MatMenu,
|
|
1188
1406
|
MatCommonModule,
|
|
1189
1407
|
MatMenuItem,
|
|
1190
1408
|
MatMenuContent,
|
|
1191
|
-
MatMenuTrigger
|
|
1409
|
+
MatMenuTrigger,
|
|
1410
|
+
MatContextMenuTrigger] });
|
|
1192
1411
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MatMenuModule, providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER], imports: [MatRippleModule,
|
|
1193
1412
|
MatCommonModule,
|
|
1194
1413
|
OverlayModule, CdkScrollableModule,
|
|
@@ -1205,6 +1424,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
|
|
|
1205
1424
|
MatMenuItem,
|
|
1206
1425
|
MatMenuContent,
|
|
1207
1426
|
MatMenuTrigger,
|
|
1427
|
+
MatContextMenuTrigger,
|
|
1208
1428
|
],
|
|
1209
1429
|
exports: [
|
|
1210
1430
|
CdkScrollableModule,
|
|
@@ -1213,6 +1433,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
|
|
|
1213
1433
|
MatMenuItem,
|
|
1214
1434
|
MatMenuContent,
|
|
1215
1435
|
MatMenuTrigger,
|
|
1436
|
+
MatContextMenuTrigger,
|
|
1216
1437
|
],
|
|
1217
1438
|
providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER],
|
|
1218
1439
|
}]
|
|
@@ -1337,5 +1558,5 @@ const fadeInItems = matMenuAnimations.fadeInItems;
|
|
|
1337
1558
|
*/
|
|
1338
1559
|
const transformMenu = matMenuAnimations.transformMenu;
|
|
1339
1560
|
|
|
1340
|
-
export { MAT_MENU_CONTENT, MAT_MENU_DEFAULT_OPTIONS, MAT_MENU_PANEL, MAT_MENU_SCROLL_STRATEGY, MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER, MENU_PANEL_TOP_PADDING, MatMenu, MatMenuContent, MatMenuItem, MatMenuModule, MatMenuTrigger, fadeInItems, matMenuAnimations, transformMenu };
|
|
1561
|
+
export { MAT_MENU_CONTENT, MAT_MENU_DEFAULT_OPTIONS, MAT_MENU_PANEL, MAT_MENU_SCROLL_STRATEGY, MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER, MENU_PANEL_TOP_PADDING, MatContextMenuTrigger, MatMenu, MatMenuContent, MatMenuItem, MatMenuModule, MatMenuTrigger, fadeInItems, matMenuAnimations, transformMenu };
|
|
1341
1562
|
//# sourceMappingURL=menu.mjs.map
|