@angular/cdk-experimental 14.0.0-next.6 → 14.0.0-next.9

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.
Files changed (114) hide show
  1. package/combobox/combobox-module.d.ts +3 -4
  2. package/combobox/combobox-popup.d.ts +6 -8
  3. package/combobox/combobox.d.ts +15 -18
  4. package/combobox/public-api.d.ts +0 -1
  5. package/dialog/dialog-config.d.ts +6 -1
  6. package/esm2020/column-resize/column-resize-directives/column-resize-flex.mjs +3 -3
  7. package/esm2020/column-resize/column-resize-directives/column-resize.mjs +3 -3
  8. package/esm2020/column-resize/column-resize-directives/default-enabled-column-resize-flex.mjs +3 -3
  9. package/esm2020/column-resize/column-resize-directives/default-enabled-column-resize.mjs +3 -3
  10. package/esm2020/column-resize/column-resize-module.mjs +8 -8
  11. package/esm2020/column-resize/column-resize-notifier.mjs +6 -6
  12. package/esm2020/column-resize/column-resize.mjs +3 -3
  13. package/esm2020/column-resize/column-size-store.mjs +3 -3
  14. package/esm2020/column-resize/event-dispatcher.mjs +3 -3
  15. package/esm2020/column-resize/overlay-handle.mjs +3 -3
  16. package/esm2020/column-resize/resizable.mjs +3 -3
  17. package/esm2020/column-resize/resize-strategy.mjs +9 -9
  18. package/esm2020/combobox/combobox-module.mjs +6 -7
  19. package/esm2020/combobox/combobox-popup.mjs +12 -23
  20. package/esm2020/combobox/combobox.mjs +50 -34
  21. package/esm2020/combobox/public-api.mjs +1 -2
  22. package/esm2020/dialog/dialog-config.mjs +1 -1
  23. package/esm2020/dialog/dialog-container.mjs +12 -7
  24. package/esm2020/dialog/dialog-module.mjs +4 -4
  25. package/esm2020/dialog/dialog.mjs +5 -5
  26. package/esm2020/listbox/listbox-module.mjs +4 -4
  27. package/esm2020/listbox/listbox.mjs +26 -44
  28. package/esm2020/menu/context-menu.mjs +46 -118
  29. package/esm2020/menu/menu-aim.mjs +6 -6
  30. package/esm2020/menu/menu-bar.mjs +46 -134
  31. package/esm2020/menu/menu-base.mjs +129 -0
  32. package/esm2020/menu/menu-errors.mjs +1 -9
  33. package/esm2020/menu/menu-group.mjs +9 -9
  34. package/esm2020/menu/menu-interface.mjs +1 -1
  35. package/esm2020/menu/menu-item-checkbox.mjs +3 -3
  36. package/esm2020/menu/menu-item-radio.mjs +13 -8
  37. package/esm2020/menu/menu-item-selectable.mjs +3 -3
  38. package/esm2020/menu/menu-item-trigger.mjs +66 -151
  39. package/esm2020/menu/menu-item.mjs +51 -45
  40. package/esm2020/menu/menu-module.mjs +5 -9
  41. package/esm2020/menu/menu-stack.mjs +31 -6
  42. package/esm2020/menu/menu-trigger.mjs +70 -0
  43. package/esm2020/menu/menu.mjs +58 -155
  44. package/esm2020/menu/public-api.mjs +3 -3
  45. package/esm2020/popover-edit/edit-event-dispatcher.mjs +3 -3
  46. package/esm2020/popover-edit/edit-ref.mjs +3 -3
  47. package/esm2020/popover-edit/edit-services.mjs +3 -3
  48. package/esm2020/popover-edit/focus-dispatcher.mjs +3 -3
  49. package/esm2020/popover-edit/focus-escape-notifier.mjs +3 -3
  50. package/esm2020/popover-edit/lens-directives.mjs +9 -9
  51. package/esm2020/popover-edit/popover-edit-module.mjs +4 -4
  52. package/esm2020/popover-edit/popover-edit-position-strategy-factory.mjs +6 -6
  53. package/esm2020/popover-edit/table-directives.mjs +15 -15
  54. package/esm2020/scrolling/auto-size-virtual-scroll.mjs +3 -3
  55. package/esm2020/scrolling/scrolling-module.mjs +4 -4
  56. package/esm2020/selection/row-selection.mjs +3 -3
  57. package/esm2020/selection/select-all.mjs +3 -3
  58. package/esm2020/selection/selection-column.mjs +3 -3
  59. package/esm2020/selection/selection-module.mjs +4 -4
  60. package/esm2020/selection/selection-toggle.mjs +3 -3
  61. package/esm2020/selection/selection.mjs +3 -3
  62. package/esm2020/table-scroll-container/table-scroll-container-module.mjs +4 -4
  63. package/esm2020/table-scroll-container/table-scroll-container.mjs +3 -3
  64. package/esm2020/version.mjs +1 -1
  65. package/fesm2015/cdk-experimental.mjs +1 -1
  66. package/fesm2015/cdk-experimental.mjs.map +1 -1
  67. package/fesm2015/column-resize.mjs +50 -50
  68. package/fesm2015/combobox.mjs +63 -106
  69. package/fesm2015/combobox.mjs.map +1 -1
  70. package/fesm2015/dialog.mjs +20 -14
  71. package/fesm2015/dialog.mjs.map +1 -1
  72. package/fesm2015/listbox.mjs +31 -47
  73. package/fesm2015/listbox.mjs.map +1 -1
  74. package/fesm2015/menu.mjs +587 -766
  75. package/fesm2015/menu.mjs.map +1 -1
  76. package/fesm2015/popover-edit.mjs +49 -49
  77. package/fesm2015/scrolling.mjs +7 -7
  78. package/fesm2015/selection.mjs +19 -19
  79. package/fesm2015/table-scroll-container.mjs +7 -7
  80. package/fesm2020/cdk-experimental.mjs +1 -1
  81. package/fesm2020/cdk-experimental.mjs.map +1 -1
  82. package/fesm2020/column-resize.mjs +50 -50
  83. package/fesm2020/combobox.mjs +62 -103
  84. package/fesm2020/combobox.mjs.map +1 -1
  85. package/fesm2020/dialog.mjs +19 -14
  86. package/fesm2020/dialog.mjs.map +1 -1
  87. package/fesm2020/listbox.mjs +29 -46
  88. package/fesm2020/listbox.mjs.map +1 -1
  89. package/fesm2020/menu.mjs +482 -655
  90. package/fesm2020/menu.mjs.map +1 -1
  91. package/fesm2020/popover-edit.mjs +49 -49
  92. package/fesm2020/scrolling.mjs +7 -7
  93. package/fesm2020/selection.mjs +19 -19
  94. package/fesm2020/table-scroll-container.mjs +7 -7
  95. package/listbox/listbox.d.ts +16 -13
  96. package/menu/context-menu.d.ts +7 -46
  97. package/menu/menu-bar.d.ts +9 -50
  98. package/menu/menu-base.d.ts +64 -0
  99. package/menu/menu-errors.d.ts +0 -5
  100. package/menu/menu-group.d.ts +2 -2
  101. package/menu/menu-interface.d.ts +1 -1
  102. package/menu/menu-item-radio.d.ts +4 -3
  103. package/menu/menu-item-trigger.d.ts +8 -38
  104. package/menu/menu-item.d.ts +11 -6
  105. package/menu/menu-module.d.ts +9 -10
  106. package/menu/menu-stack.d.ts +22 -6
  107. package/menu/menu-trigger.d.ts +48 -0
  108. package/menu/menu.d.ts +11 -67
  109. package/menu/public-api.d.ts +2 -2
  110. package/package.json +2 -2
  111. package/combobox/combobox-panel.d.ts +0 -27
  112. package/esm2020/combobox/combobox-panel.mjs +0 -48
  113. package/esm2020/menu/menu-panel.mjs +0 -37
  114. package/menu/menu-panel.d.ts +0 -30
package/fesm2020/menu.mjs CHANGED
@@ -1,16 +1,16 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Directive, EventEmitter, Optional, Inject, Input, Output, Self, ContentChildren, NgModule } from '@angular/core';
2
+ import { InjectionToken, Optional, SkipSelf, Inject, Injectable, Directive, EventEmitter, Injector, Self, Input, Output, ContentChildren, NgModule } from '@angular/core';
3
3
  import * as i1 from '@angular/cdk/overlay';
4
- import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
5
- import { FocusKeyManager } from '@angular/cdk/a11y';
4
+ import { OverlayConfig, STANDARD_DROPDOWN_BELOW_POSITIONS, STANDARD_DROPDOWN_ADJACENT_POSITIONS, OverlayModule } from '@angular/cdk/overlay';
6
5
  import { UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE, TAB, ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
7
- import * as i2 from '@angular/cdk/bidi';
8
- import { Subject, fromEvent, merge, defer, partition } from 'rxjs';
9
- import { filter, takeUntil, startWith, mergeMap, mapTo, mergeAll, take, switchMap, skip } from 'rxjs/operators';
10
- import * as i1$1 from '@angular/cdk/collections';
6
+ import * as i1$1 from '@angular/cdk/bidi';
7
+ import { filter, takeUntil, startWith, mergeMap, mapTo, mergeAll, switchMap, take, skip } from 'rxjs/operators';
8
+ import * as i1$2 from '@angular/cdk/collections';
11
9
  import { UniqueSelectionDispatcher } from '@angular/cdk/collections';
12
10
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
11
+ import { Subject, fromEvent, merge, defer, partition } from 'rxjs';
13
12
  import { TemplatePortal } from '@angular/cdk/portal';
13
+ import { FocusKeyManager } from '@angular/cdk/a11y';
14
14
 
15
15
  /**
16
16
  * @license
@@ -29,6 +29,20 @@ const CDK_MENU = new InjectionToken('cdk-menu');
29
29
  * Use of this source code is governed by an MIT-style license that can be
30
30
  * found in the LICENSE file at https://angular.io/license
31
31
  */
32
+ /** Injection token used for an implementation of MenuStack. */
33
+ const MENU_STACK = new InjectionToken('cdk-menu-stack');
34
+ /** A provider that provides the parent menu stack, or a new menu stack if there is no parent one. */
35
+ const PARENT_OR_NEW_MENU_STACK_PROVIDER = {
36
+ provide: MENU_STACK,
37
+ deps: [[new Optional(), new SkipSelf(), new Inject(MENU_STACK)]],
38
+ useFactory: (parentMenuStack) => parentMenuStack || new MenuStack(),
39
+ };
40
+ /** A provider that provides the parent menu stack, or a new menu stack if there is no parent one. */
41
+ const PARENT_OR_NEW_INLINE_MENU_STACK_PROVIDER = {
42
+ provide: MENU_STACK,
43
+ deps: [[new Optional(), new SkipSelf(), new Inject(MENU_STACK)]],
44
+ useFactory: (parentMenuStack) => parentMenuStack || MenuStack.inline(),
45
+ };
32
46
  /**
33
47
  * MenuStack allows subscribers to listen for close events (when a MenuStackItem is popped off
34
48
  * of the stack) in order to perform closing actions. Upon the MenuStack being empty it emits
@@ -51,6 +65,12 @@ class MenuStack {
51
65
  * perform.
52
66
  */
53
67
  this.emptied = this._empty;
68
+ this._hasInlineMenu = false;
69
+ }
70
+ static inline() {
71
+ const stack = new MenuStack();
72
+ stack._hasInlineMenu = true;
73
+ return stack;
54
74
  }
55
75
  /** @param menu the MenuStackItem to put on the stack. */
56
76
  push(menu) {
@@ -120,12 +140,15 @@ class MenuStack {
120
140
  peek() {
121
141
  return this._elements[this._elements.length - 1];
122
142
  }
143
+ hasInlineMenu() {
144
+ return this._hasInlineMenu;
145
+ }
123
146
  }
124
- /** NoopMenuStack is a placeholder MenuStack used for inline menus. */
125
- class NoopMenuStack extends MenuStack {
126
- /** Noop push - does not add elements to the MenuStack. */
127
- push(_) { }
128
- }
147
+ MenuStack.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: MenuStack, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
148
+ MenuStack.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: MenuStack });
149
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: MenuStack, decorators: [{
150
+ type: Injectable
151
+ }] });
129
152
 
130
153
  /**
131
154
  * @license
@@ -134,14 +157,6 @@ class NoopMenuStack extends MenuStack {
134
157
  * Use of this source code is governed by an MIT-style license that can be
135
158
  * found in the LICENSE file at https://angular.io/license
136
159
  */
137
- /**
138
- * Throws an exception when a menu panel already has a menu stack.
139
- * @docs-private
140
- */
141
- function throwExistingMenuStackError() {
142
- throw Error('CdkMenuPanel is already referenced by different CdkMenuTrigger. Ensure that a menu is' +
143
- ' opened by a single trigger only.');
144
- }
145
160
  /**
146
161
  * Throws an exception when an instance of the PointerFocusTracker is not provided.
147
162
  * @docs-private
@@ -329,9 +344,9 @@ class TargetMenuAim {
329
344
  this._destroyed.complete();
330
345
  }
331
346
  }
332
- TargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: TargetMenuAim, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
333
- TargetMenuAim.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: TargetMenuAim });
334
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: TargetMenuAim, decorators: [{
347
+ TargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: TargetMenuAim, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
348
+ TargetMenuAim.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: TargetMenuAim });
349
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: TargetMenuAim, decorators: [{
335
350
  type: Injectable
336
351
  }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
337
352
  /**
@@ -340,9 +355,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
340
355
  */
341
356
  class CdkTargetMenuAim {
342
357
  }
343
- CdkTargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkTargetMenuAim, deps: [], target: i0.ɵɵFactoryTarget.Directive });
344
- CdkTargetMenuAim.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkTargetMenuAim, selector: "[cdkTargetMenuAim]", providers: [{ provide: MENU_AIM, useClass: TargetMenuAim }], exportAs: ["cdkTargetMenuAim"], ngImport: i0 });
345
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkTargetMenuAim, decorators: [{
358
+ CdkTargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkTargetMenuAim, deps: [], target: i0.ɵɵFactoryTarget.Directive });
359
+ CdkTargetMenuAim.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkTargetMenuAim, selector: "[cdkTargetMenuAim]", providers: [{ provide: MENU_AIM, useClass: TargetMenuAim }], exportAs: ["cdkTargetMenuAim"], ngImport: i0 });
360
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkTargetMenuAim, decorators: [{
346
361
  type: Directive,
347
362
  args: [{
348
363
  selector: '[cdkTargetMenuAim]',
@@ -351,6 +366,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
351
366
  }]
352
367
  }] });
353
368
 
369
+ /**
370
+ * @license
371
+ * Copyright Google LLC All Rights Reserved.
372
+ *
373
+ * Use of this source code is governed by an MIT-style license that can be
374
+ * found in the LICENSE file at https://angular.io/license
375
+ */
376
+ /** Injection token used for an implementation of MenuStack. */
377
+ const MENU_TRIGGER = new InjectionToken('cdk-menu-trigger');
378
+ class MenuTrigger {
379
+ constructor(injector, menuStack) {
380
+ this.injector = injector;
381
+ this.menuStack = menuStack;
382
+ /** Emits when the attached menu is requested to open */
383
+ this.opened = new EventEmitter();
384
+ /** Emits when the attached menu is requested to close */
385
+ this.closed = new EventEmitter();
386
+ /** A reference to the overlay which manages the triggered menu */
387
+ this._overlayRef = null;
388
+ /** Emits when this trigger is destroyed. */
389
+ this._destroyed = new Subject();
390
+ /** Emits when the outside pointer events listener on the overlay should be stopped. */
391
+ this._stopOutsideClicksListener = merge(this.closed, this._destroyed);
392
+ }
393
+ ngOnDestroy() {
394
+ this._destroyOverlay();
395
+ this._destroyed.next();
396
+ this._destroyed.complete();
397
+ }
398
+ /** Whether the attached menu is open. */
399
+ isOpen() {
400
+ return !!this._overlayRef?.hasAttached();
401
+ }
402
+ registerChildMenu(child) {
403
+ this.childMenu = child;
404
+ }
405
+ getChildMenuInjector() {
406
+ this._childMenuInjector =
407
+ this._childMenuInjector ||
408
+ Injector.create({
409
+ providers: [
410
+ { provide: MENU_TRIGGER, useValue: this },
411
+ { provide: MENU_STACK, useValue: this.menuStack },
412
+ ],
413
+ parent: this.injector,
414
+ });
415
+ return this._childMenuInjector;
416
+ }
417
+ /** Destroy and unset the overlay reference it if exists */
418
+ _destroyOverlay() {
419
+ if (this._overlayRef) {
420
+ this._overlayRef.dispose();
421
+ this._overlayRef = null;
422
+ }
423
+ }
424
+ }
425
+ MenuTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: MenuTrigger, deps: [{ token: i0.Injector }, { token: MENU_STACK }], target: i0.ɵɵFactoryTarget.Directive });
426
+ MenuTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: MenuTrigger, ngImport: i0 });
427
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: MenuTrigger, decorators: [{
428
+ type: Directive
429
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: MenuStack, decorators: [{
430
+ type: Inject,
431
+ args: [MENU_STACK]
432
+ }] }]; } });
433
+
354
434
  /**
355
435
  * @license
356
436
  * Copyright Google LLC All Rights Reserved.
@@ -382,8 +462,9 @@ function isClickInsideMenuOverlay(target) {
382
462
  * The directive must be placed along with the `cdkMenuItem` directive in order to enable full
383
463
  * functionality.
384
464
  */
385
- class CdkMenuItemTrigger {
386
- constructor(_elementRef, _viewContainerRef, _overlay, _ngZone, _parentMenu, _menuAim, _directionality) {
465
+ class CdkMenuItemTrigger extends MenuTrigger {
466
+ constructor(injector, _elementRef, _viewContainerRef, _overlay, _ngZone, menuStack, _parentMenu, _menuAim, _directionality) {
467
+ super(injector, menuStack);
387
468
  this._elementRef = _elementRef;
388
469
  this._viewContainerRef = _viewContainerRef;
389
470
  this._overlay = _overlay;
@@ -391,46 +472,16 @@ class CdkMenuItemTrigger {
391
472
  this._parentMenu = _parentMenu;
392
473
  this._menuAim = _menuAim;
393
474
  this._directionality = _directionality;
394
- /** Emits when the attached menu is requested to open */
395
- this.opened = new EventEmitter();
396
- /** Emits when the attached menu is requested to close */
397
- this.closed = new EventEmitter();
398
- /** The menu stack for this trigger and its sub-menus. */
399
- this._menuStack = new MenuStack();
400
- /** A reference to the overlay which manages the triggered menu */
401
- this._overlayRef = null;
402
- /** Emits when this trigger is destroyed. */
403
- this._destroyed = new Subject();
404
- /** Emits when the outside pointer events listener on the overlay should be stopped. */
405
- this._stopOutsideClicksListener = merge(this.closed, this._destroyed);
406
475
  this._registerCloseHandler();
407
476
  this._subscribeToMouseEnter();
408
477
  }
409
- /** Template reference variable to the menu this trigger opens */
410
- get menuPanel() {
411
- return this._menuPanel;
412
- }
413
- set menuPanel(panel) {
414
- // If the provided panel already has a stack, that means it already has a trigger configured.
415
- // Note however that there are some edge cases where two triggers **may** share the same menu,
416
- // e.g. two triggers in two separate menus.
417
- if ((typeof ngDevMode === 'undefined' || ngDevMode) && panel?._menuStack) {
418
- throwExistingMenuStackError();
419
- }
420
- this._menuPanel = panel;
421
- if (this._menuPanel) {
422
- this._menuPanel._menuStack = this._getMenuStack();
423
- }
424
- }
425
478
  /** Open/close the attached menu if the trigger has been configured with one */
426
479
  toggle() {
427
- if (this.hasMenu()) {
428
- this.isMenuOpen() ? this.closeMenu() : this.openMenu();
429
- }
480
+ this.isOpen() ? this.close() : this.open();
430
481
  }
431
482
  /** Open the attached menu. */
432
- openMenu() {
433
- if (!this.isMenuOpen()) {
483
+ open() {
484
+ if (!this.isOpen()) {
434
485
  this.opened.next();
435
486
  this._overlayRef = this._overlayRef || this._overlay.create(this._getOverlayConfig());
436
487
  this._overlayRef.attach(this._getPortal());
@@ -438,27 +489,19 @@ class CdkMenuItemTrigger {
438
489
  }
439
490
  }
440
491
  /** Close the opened menu. */
441
- closeMenu() {
442
- if (this.isMenuOpen()) {
492
+ close() {
493
+ if (this.isOpen()) {
443
494
  this.closed.next();
444
495
  this._overlayRef.detach();
445
496
  }
446
497
  this._closeSiblingTriggers();
447
498
  }
448
- /** Return true if the trigger has an attached menu */
449
- hasMenu() {
450
- return !!this.menuPanel;
451
- }
452
- /** Whether the menu this button is a trigger for is open */
453
- isMenuOpen() {
454
- return this._overlayRef ? this._overlayRef.hasAttached() : false;
455
- }
456
499
  /**
457
500
  * Get a reference to the rendered Menu if the Menu is open and it is visible in the DOM.
458
501
  * @return the menu if it is open, otherwise undefined.
459
502
  */
460
503
  getMenu() {
461
- return this.menuPanel?._menu;
504
+ return this.childMenu;
462
505
  }
463
506
  /**
464
507
  * Subscribe to the mouseenter events and close any sibling menu items if this element is moused
@@ -468,11 +511,11 @@ class CdkMenuItemTrigger {
468
511
  // Closes any sibling menu items and opens the menu associated with this trigger.
469
512
  const toggleMenus = () => this._ngZone.run(() => {
470
513
  this._closeSiblingTriggers();
471
- this.openMenu();
514
+ this.open();
472
515
  });
473
516
  this._ngZone.runOutsideAngular(() => {
474
517
  fromEvent(this._elementRef.nativeElement, 'mouseenter')
475
- .pipe(filter(() => !this._getMenuStack()?.isEmpty() && !this.isMenuOpen()), takeUntil(this._destroyed))
518
+ .pipe(filter(() => !this.menuStack.isEmpty() && !this.isOpen()), takeUntil(this._destroyed))
476
519
  .subscribe(() => {
477
520
  if (this._menuAim) {
478
521
  this._menuAim.toggle(toggleMenus);
@@ -495,40 +538,30 @@ class CdkMenuItemTrigger {
495
538
  case ENTER:
496
539
  event.preventDefault();
497
540
  this.toggle();
498
- this.menuPanel?._menu?.focusFirstItem('keyboard');
541
+ this.childMenu?.focusFirstItem('keyboard');
499
542
  break;
500
543
  case RIGHT_ARROW:
501
- if (this._parentMenu && this._isParentVertical()) {
544
+ if (this._parentMenu && this._isParentVertical() && this._directionality?.value !== 'rtl') {
502
545
  event.preventDefault();
503
- if (this._directionality?.value === 'rtl') {
504
- this._getMenuStack().close(this._parentMenu, 2 /* currentItem */);
505
- }
506
- else {
507
- this.openMenu();
508
- this.menuPanel?._menu?.focusFirstItem('keyboard');
509
- }
546
+ this.open();
547
+ this.childMenu?.focusFirstItem('keyboard');
510
548
  }
511
549
  break;
512
550
  case LEFT_ARROW:
513
- if (this._parentMenu && this._isParentVertical()) {
551
+ if (this._parentMenu && this._isParentVertical() && this._directionality?.value === 'rtl') {
514
552
  event.preventDefault();
515
- if (this._directionality?.value === 'rtl') {
516
- this.openMenu();
517
- this.menuPanel?._menu?.focusFirstItem('keyboard');
518
- }
519
- else {
520
- this._getMenuStack().close(this._parentMenu, 2 /* currentItem */);
521
- }
553
+ this.open();
554
+ this.childMenu?.focusFirstItem('keyboard');
522
555
  }
523
556
  break;
524
557
  case DOWN_ARROW:
525
558
  case UP_ARROW:
526
559
  if (!this._isParentVertical()) {
527
560
  event.preventDefault();
528
- this.openMenu();
561
+ this.open();
529
562
  keyCode === DOWN_ARROW
530
- ? this.menuPanel?._menu?.focusFirstItem('keyboard')
531
- : this.menuPanel?._menu?.focusLastItem('keyboard');
563
+ ? this.childMenu?.focusFirstItem('keyboard')
564
+ : this.childMenu?.focusLastItem('keyboard');
532
565
  }
533
566
  break;
534
567
  }
@@ -536,17 +569,17 @@ class CdkMenuItemTrigger {
536
569
  /** Close out any sibling menu trigger menus. */
537
570
  _closeSiblingTriggers() {
538
571
  if (this._parentMenu) {
539
- const menuStack = this._getMenuStack();
540
572
  // If nothing was removed from the stack and the last element is not the parent item
541
573
  // that means that the parent menu is a menu bar since we don't put the menu bar on the
542
574
  // stack
543
- const isParentMenuBar = !menuStack.closeSubMenuOf(this._parentMenu) && menuStack.peek() !== this._parentMenu;
575
+ const isParentMenuBar = !this.menuStack.closeSubMenuOf(this._parentMenu) &&
576
+ this.menuStack.peek() !== this._parentMenu;
544
577
  if (isParentMenuBar) {
545
- menuStack.closeAll();
578
+ this.menuStack.closeAll();
546
579
  }
547
580
  }
548
581
  else {
549
- this._getMenuStack().closeAll();
582
+ this.menuStack.closeAll();
550
583
  }
551
584
  }
552
585
  /** Get the configuration object used to create the overlay */
@@ -566,31 +599,21 @@ class CdkMenuItemTrigger {
566
599
  }
567
600
  /** Determine and return where to position the opened menu relative to the menu item */
568
601
  _getOverlayPositions() {
569
- // TODO: use a common positioning config from (possibly) cdk/overlay
570
- return !this._parentMenu || this._parentMenu.orientation === 'horizontal'
571
- ? [
572
- { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },
573
- { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },
574
- { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top' },
575
- { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom' },
576
- ]
577
- : [
578
- { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top' },
579
- { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom' },
580
- { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top' },
581
- { originX: 'start', originY: 'bottom', overlayX: 'end', overlayY: 'bottom' },
582
- ];
602
+ return (this.menuPosition ??
603
+ (!this._parentMenu || this._parentMenu.orientation === 'horizontal'
604
+ ? STANDARD_DROPDOWN_BELOW_POSITIONS
605
+ : STANDARD_DROPDOWN_ADJACENT_POSITIONS));
583
606
  }
584
607
  /**
585
608
  * Get the portal to be attached to the overlay which contains the menu. Allows for the menu
586
609
  * content to change dynamically and be reflected in the application.
587
610
  */
588
611
  _getPortal() {
589
- const hasMenuContentChanged = this.menuPanel?._templateRef !== this._panelContent?.templateRef;
590
- if (this.menuPanel && (!this._panelContent || hasMenuContentChanged)) {
591
- this._panelContent = new TemplatePortal(this.menuPanel._templateRef, this._viewContainerRef);
612
+ const hasMenuContentChanged = this._menuTemplateRef !== this._menuPortal?.templateRef;
613
+ if (this._menuTemplateRef && (!this._menuPortal || hasMenuContentChanged)) {
614
+ this._menuPortal = new TemplatePortal(this._menuTemplateRef, this._viewContainerRef, undefined, this.getChildMenuInjector());
592
615
  }
593
- return this._panelContent;
616
+ return this._menuPortal;
594
617
  }
595
618
  /**
596
619
  * @return true if if the enclosing parent menu is configured in a vertical orientation.
@@ -604,38 +627,13 @@ class CdkMenuItemTrigger {
604
627
  */
605
628
  _registerCloseHandler() {
606
629
  if (!this._parentMenu) {
607
- this._menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
608
- if (item === this._menuPanel?._menu) {
609
- this.closeMenu();
630
+ this.menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
631
+ if (item === this.childMenu) {
632
+ this.close();
610
633
  }
611
634
  });
612
635
  }
613
636
  }
614
- /** Get the menu stack for this trigger - either from the parent or this trigger. */
615
- _getMenuStack() {
616
- // We use a function since at the construction of the MenuItemTrigger the parent Menu won't have
617
- // its menu stack set. Therefore we need to reference the menu stack from the parent each time
618
- // we want to use it.
619
- return this._parentMenu?._menuStack || this._menuStack;
620
- }
621
- ngOnDestroy() {
622
- this._destroyOverlay();
623
- this._resetPanelMenuStack();
624
- this._destroyed.next();
625
- this._destroyed.complete();
626
- }
627
- /** Set the menu panels menu stack back to null. */
628
- _resetPanelMenuStack() {
629
- // If a CdkMenuTrigger is placed in a submenu, each time the trigger is rendered (its parent
630
- // menu is opened) the panel setter for CdkMenuPanel is called. From the first render onward,
631
- // the attached CdkMenuPanel has the MenuStack set. Since we throw an error if a panel already
632
- // has a stack set, we want to reset the attached stack here to prevent the error from being
633
- // thrown if the trigger re-configures its attached panel (in the case where there is a 1:1
634
- // relationship between the panel and trigger).
635
- if (this._menuPanel) {
636
- this._menuPanel._menuStack = null;
637
- }
638
- }
639
637
  /**
640
638
  * Subscribe to the overlays outside pointer events stream and handle closing out the stack if a
641
639
  * click occurs outside the menus.
@@ -647,35 +645,40 @@ class CdkMenuItemTrigger {
647
645
  .pipe(takeUntil(this._stopOutsideClicksListener))
648
646
  .subscribe(event => {
649
647
  if (!isClickInsideMenuOverlay(event.target)) {
650
- this._getMenuStack().closeAll();
648
+ this.menuStack.closeAll();
651
649
  }
652
650
  });
653
651
  }
654
652
  }
655
- /** Destroy and unset the overlay reference it if exists */
656
- _destroyOverlay() {
657
- if (this._overlayRef) {
658
- this._overlayRef.dispose();
659
- this._overlayRef = null;
660
- }
661
- }
662
653
  }
663
- CdkMenuItemTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemTrigger, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.Overlay }, { token: i0.NgZone }, { token: CDK_MENU, optional: true }, { token: MENU_AIM, optional: true }, { token: i2.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
664
- CdkMenuItemTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuItemTrigger, selector: "[cdkMenuTriggerFor]", inputs: { menuPanel: ["cdkMenuTriggerFor", "menuPanel"] }, outputs: { opened: "cdkMenuOpened", closed: "cdkMenuClosed" }, host: { attributes: { "aria-haspopup": "menu" }, listeners: { "keydown": "_toggleOnKeydown($event)", "click": "toggle()" }, properties: { "attr.aria-expanded": "isMenuOpen()" }, classAttribute: "cdk-menu-trigger" }, exportAs: ["cdkMenuTriggerFor"], ngImport: i0 });
665
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemTrigger, decorators: [{
654
+ CdkMenuItemTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemTrigger, deps: [{ token: i0.Injector }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.Overlay }, { token: i0.NgZone }, { token: MENU_STACK }, { token: CDK_MENU, optional: true }, { token: MENU_AIM, optional: true }, { token: i1$1.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
655
+ CdkMenuItemTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuItemTrigger, selector: "[cdkMenuTriggerFor]", inputs: { _menuTemplateRef: ["cdkMenuTriggerFor", "_menuTemplateRef"], menuPosition: ["cdkMenuPosition", "menuPosition"] }, outputs: { opened: "cdkMenuOpened", closed: "cdkMenuClosed" }, host: { attributes: { "aria-haspopup": "menu" }, listeners: { "keydown": "_toggleOnKeydown($event)", "click": "toggle()" }, properties: { "attr.aria-expanded": "isOpen()" }, classAttribute: "cdk-menu-trigger" }, providers: [
656
+ { provide: MENU_TRIGGER, useExisting: CdkMenuItemTrigger },
657
+ PARENT_OR_NEW_MENU_STACK_PROVIDER,
658
+ ], exportAs: ["cdkMenuTriggerFor"], usesInheritance: true, ngImport: i0 });
659
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemTrigger, decorators: [{
666
660
  type: Directive,
667
661
  args: [{
668
662
  selector: '[cdkMenuTriggerFor]',
669
663
  exportAs: 'cdkMenuTriggerFor',
670
664
  host: {
671
- '(keydown)': '_toggleOnKeydown($event)',
672
- '(click)': 'toggle()',
673
665
  'class': 'cdk-menu-trigger',
674
666
  'aria-haspopup': 'menu',
675
- '[attr.aria-expanded]': 'isMenuOpen()',
667
+ '(keydown)': '_toggleOnKeydown($event)',
668
+ '(click)': 'toggle()',
669
+ '[attr.aria-expanded]': 'isOpen()',
676
670
  },
671
+ inputs: ['_menuTemplateRef: cdkMenuTriggerFor', 'menuPosition: cdkMenuPosition'],
672
+ outputs: ['opened: cdkMenuOpened', 'closed: cdkMenuClosed'],
673
+ providers: [
674
+ { provide: MENU_TRIGGER, useExisting: CdkMenuItemTrigger },
675
+ PARENT_OR_NEW_MENU_STACK_PROVIDER,
676
+ ],
677
677
  }]
678
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: i0.NgZone }, { type: undefined, decorators: [{
678
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: i0.NgZone }, { type: MenuStack, decorators: [{
679
+ type: Inject,
680
+ args: [MENU_STACK]
681
+ }] }, { type: undefined, decorators: [{
679
682
  type: Optional
680
683
  }, {
681
684
  type: Inject,
@@ -685,18 +688,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
685
688
  }, {
686
689
  type: Inject,
687
690
  args: [MENU_AIM]
688
- }] }, { type: i2.Directionality, decorators: [{
691
+ }] }, { type: i1$1.Directionality, decorators: [{
689
692
  type: Optional
690
- }] }]; }, propDecorators: { menuPanel: [{
691
- type: Input,
692
- args: ['cdkMenuTriggerFor']
693
- }], opened: [{
694
- type: Output,
695
- args: ['cdkMenuOpened']
696
- }], closed: [{
697
- type: Output,
698
- args: ['cdkMenuClosed']
699
- }] } });
693
+ }] }]; } });
700
694
 
701
695
  /**
702
696
  * @license
@@ -705,26 +699,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
705
699
  * Use of this source code is governed by an MIT-style license that can be
706
700
  * found in the LICENSE file at https://angular.io/license
707
701
  */
708
- // TODO refactor this to be configurable allowing for custom elements to be removed
709
- /** Removes all icons from within the given element. */
710
- function removeIcons(element) {
711
- for (const icon of Array.from(element.querySelectorAll('mat-icon, .material-icons'))) {
712
- icon.remove();
713
- }
714
- }
715
702
  /**
716
703
  * Directive which provides the ability for an element to be focused and navigated to using the
717
704
  * keyboard when residing in a CdkMenu, CdkMenuBar, or CdkMenuGroup. It performs user defined
718
705
  * behavior when clicked.
719
706
  */
720
707
  class CdkMenuItem {
721
- constructor(_elementRef, _ngZone, _parentMenu, _menuAim, _dir,
708
+ constructor(_elementRef, _ngZone, _menuStack, _parentMenu, _menuAim, _dir,
722
709
  /** Reference to the CdkMenuItemTrigger directive if one is added to the same element */
723
710
  // `CdkMenuItem` is commonly used in combination with a `CdkMenuItemTrigger`.
724
711
  // tslint:disable-next-line: lightweight-tokens
725
712
  _menuTrigger) {
726
713
  this._elementRef = _elementRef;
727
714
  this._ngZone = _ngZone;
715
+ this._menuStack = _menuStack;
728
716
  this._parentMenu = _parentMenu;
729
717
  this._menuAim = _menuAim;
730
718
  this._dir = _dir;
@@ -773,7 +761,7 @@ class CdkMenuItem {
773
761
  return;
774
762
  }
775
763
  // don't set the tabindex if there are no open sibling or parent menus
776
- if (!event || !this._getMenuStack()?.isEmpty()) {
764
+ if (!event || !this._menuStack.isEmpty()) {
777
765
  this._tabindex = 0;
778
766
  }
779
767
  }
@@ -788,16 +776,16 @@ class CdkMenuItem {
788
776
  trigger() {
789
777
  if (!this.disabled && !this.hasMenu()) {
790
778
  this.triggered.next();
791
- this._getMenuStack()?.closeAll();
779
+ this._menuStack.closeAll();
792
780
  }
793
781
  }
794
782
  /** Whether the menu item opens a menu. */
795
783
  hasMenu() {
796
- return !!this._menuTrigger?.hasMenu();
784
+ return !!this._menuTrigger;
797
785
  }
798
786
  /** Return true if this MenuItem has an attached menu and it is open. */
799
787
  isMenuOpen() {
800
- return !!this._menuTrigger?.isMenuOpen();
788
+ return !!this._menuTrigger?.isOpen();
801
789
  }
802
790
  /**
803
791
  * Get a reference to the rendered Menu if the Menu is open and it is visible in the DOM.
@@ -812,11 +800,7 @@ class CdkMenuItem {
812
800
  }
813
801
  /** Get the label for this element which is required by the FocusableOption interface. */
814
802
  getLabel() {
815
- // TODO cloning the tree may be expensive; implement a better method
816
- // we know that the current node is an element type
817
- const clone = this._elementRef.nativeElement.cloneNode(true);
818
- removeIcons(clone);
819
- return clone.textContent?.trim() || '';
803
+ return this.typeahead || this._elementRef.nativeElement.textContent?.trim() || '';
820
804
  }
821
805
  /**
822
806
  * Handles keyboard events for the menu item, specifically either triggering the user defined
@@ -832,19 +816,35 @@ class CdkMenuItem {
832
816
  this.trigger();
833
817
  break;
834
818
  case RIGHT_ARROW:
835
- if (this._parentMenu && this._isParentVertical() && !this.hasMenu()) {
836
- event.preventDefault();
837
- this._dir?.value === 'rtl'
838
- ? this._getMenuStack()?.close(this._parentMenu, 1 /* previousItem */)
839
- : this._getMenuStack()?.closeAll(0 /* nextItem */);
819
+ if (this._parentMenu && this._isParentVertical()) {
820
+ if (this._dir?.value === 'rtl') {
821
+ if (this._menuStack.hasInlineMenu() || this._menuStack.length() > 1) {
822
+ event.preventDefault();
823
+ this._menuStack.close(this._parentMenu, 1 /* previousItem */);
824
+ }
825
+ }
826
+ else if (!this.hasMenu()) {
827
+ if (this._menuStack.hasInlineMenu()) {
828
+ event.preventDefault();
829
+ this._menuStack.closeAll(0 /* nextItem */);
830
+ }
831
+ }
840
832
  }
841
833
  break;
842
834
  case LEFT_ARROW:
843
- if (this._parentMenu && this._isParentVertical() && !this.hasMenu()) {
844
- event.preventDefault();
845
- this._dir?.value === 'rtl'
846
- ? this._getMenuStack()?.closeAll(0 /* nextItem */)
847
- : this._getMenuStack()?.close(this._parentMenu, 1 /* previousItem */);
835
+ if (this._parentMenu && this._isParentVertical()) {
836
+ if (this._dir?.value !== 'rtl') {
837
+ if (this._menuStack.hasInlineMenu() || this._menuStack.length() > 1) {
838
+ event.preventDefault();
839
+ this._menuStack.close(this._parentMenu, 1 /* previousItem */);
840
+ }
841
+ }
842
+ else if (!this.hasMenu()) {
843
+ if (this._menuStack.hasInlineMenu()) {
844
+ event.preventDefault();
845
+ this._menuStack.closeAll(0 /* nextItem */);
846
+ }
847
+ }
848
848
  }
849
849
  break;
850
850
  }
@@ -855,9 +855,9 @@ class CdkMenuItem {
855
855
  */
856
856
  _setupMouseEnter() {
857
857
  if (!this._isStandaloneItem()) {
858
- const closeOpenSiblings = () => this._ngZone.run(() => this._getMenuStack()?.closeSubMenuOf(this._parentMenu));
858
+ const closeOpenSiblings = () => this._ngZone.run(() => this._menuStack.closeSubMenuOf(this._parentMenu));
859
859
  this._ngZone.runOutsideAngular(() => fromEvent(this._elementRef.nativeElement, 'mouseenter')
860
- .pipe(filter(() => !this._getMenuStack()?.isEmpty() && !this.hasMenu()), takeUntil(this._destroyed))
860
+ .pipe(filter(() => !this._menuStack.isEmpty() && !this.hasMenu()), takeUntil(this._destroyed))
861
861
  .subscribe(() => {
862
862
  if (this._menuAim) {
863
863
  this._menuAim.toggle(closeOpenSiblings);
@@ -875,20 +875,13 @@ class CdkMenuItem {
875
875
  _isParentVertical() {
876
876
  return this._parentMenu?.orientation === 'vertical';
877
877
  }
878
- /** Get the MenuStack from the parent menu. */
879
- _getMenuStack() {
880
- // We use a function since at the construction of the MenuItemTrigger the parent Menu won't have
881
- // its menu stack set. Therefore we need to reference the menu stack from the parent each time
882
- // we want to use it.
883
- return this._parentMenu?._menuStack;
884
- }
885
878
  ngOnDestroy() {
886
879
  this._destroyed.next();
887
880
  }
888
881
  }
889
- CdkMenuItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItem, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: CDK_MENU, optional: true }, { token: MENU_AIM, optional: true }, { token: i2.Directionality, optional: true }, { token: CdkMenuItemTrigger, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
890
- CdkMenuItem.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuItem, selector: "[cdkMenuItem]", inputs: { disabled: "disabled" }, outputs: { triggered: "cdkMenuItemTriggered" }, host: { attributes: { "type": "button", "role": "menuitem" }, listeners: { "blur": "_resetTabIndex()", "mouseout": "_resetTabIndex()", "focus": "_setTabIndex()", "mouseenter": "_setTabIndex($event)", "click": "trigger()", "keydown": "_onKeydown($event)" }, properties: { "tabindex": "_tabindex", "attr.aria-disabled": "disabled || null" }, classAttribute: "cdk-menu-item" }, exportAs: ["cdkMenuItem"], ngImport: i0 });
891
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItem, decorators: [{
882
+ CdkMenuItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItem, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: MENU_STACK }, { token: CDK_MENU, optional: true }, { token: MENU_AIM, optional: true }, { token: i1$1.Directionality, optional: true }, { token: CdkMenuItemTrigger, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
883
+ CdkMenuItem.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuItem, selector: "[cdkMenuItem]", inputs: { disabled: "disabled", typeahead: "typeahead" }, outputs: { triggered: "cdkMenuItemTriggered" }, host: { attributes: { "type": "button", "role": "menuitem" }, listeners: { "blur": "_resetTabIndex()", "mouseout": "_resetTabIndex()", "focus": "_setTabIndex()", "mouseenter": "_setTabIndex($event)", "click": "trigger()", "keydown": "_onKeydown($event)" }, properties: { "tabindex": "_tabindex", "attr.aria-disabled": "disabled || null" }, classAttribute: "cdk-menu-item" }, exportAs: ["cdkMenuItem"], ngImport: i0 });
884
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItem, decorators: [{
892
885
  type: Directive,
893
886
  args: [{
894
887
  selector: '[cdkMenuItem]',
@@ -907,7 +900,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
907
900
  '(keydown)': '_onKeydown($event)',
908
901
  },
909
902
  }]
910
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
903
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: MenuStack, decorators: [{
904
+ type: Inject,
905
+ args: [MENU_STACK]
906
+ }] }, { type: undefined, decorators: [{
911
907
  type: Optional
912
908
  }, {
913
909
  type: Inject,
@@ -917,7 +913,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
917
913
  }, {
918
914
  type: Inject,
919
915
  args: [MENU_AIM]
920
- }] }, { type: i2.Directionality, decorators: [{
916
+ }] }, { type: i1$1.Directionality, decorators: [{
921
917
  type: Optional
922
918
  }] }, { type: CdkMenuItemTrigger, decorators: [{
923
919
  type: Self
@@ -925,6 +921,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
925
921
  type: Optional
926
922
  }] }]; }, propDecorators: { disabled: [{
927
923
  type: Input
924
+ }], typeahead: [{
925
+ type: Input
928
926
  }], triggered: [{
929
927
  type: Output,
930
928
  args: ['cdkMenuItemTriggered']
@@ -968,9 +966,9 @@ class CdkMenuItemSelectable extends CdkMenuItem {
968
966
  }
969
967
  }
970
968
  }
971
- CdkMenuItemSelectable.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemSelectable, deps: null, target: i0.ɵɵFactoryTarget.Directive });
972
- CdkMenuItemSelectable.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuItemSelectable, inputs: { checked: "checked", name: "name", id: "id" }, outputs: { toggled: "cdkMenuItemToggled" }, usesInheritance: true, ngImport: i0 });
973
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemSelectable, decorators: [{
969
+ CdkMenuItemSelectable.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemSelectable, deps: null, target: i0.ɵɵFactoryTarget.Directive });
970
+ CdkMenuItemSelectable.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuItemSelectable, inputs: { checked: "checked", name: "name", id: "id" }, outputs: { toggled: "cdkMenuItemToggled" }, usesInheritance: true, ngImport: i0 });
971
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemSelectable, decorators: [{
974
972
  type: Directive
975
973
  }], propDecorators: { toggled: [{
976
974
  type: Output,
@@ -1004,6 +1002,10 @@ class CdkMenuGroup {
1004
1002
  ngAfterContentInit() {
1005
1003
  this._registerMenuSelectionListeners();
1006
1004
  }
1005
+ ngOnDestroy() {
1006
+ this._selectableChanges.next();
1007
+ this._selectableChanges.complete();
1008
+ }
1007
1009
  /**
1008
1010
  * Register the child selectable elements with the change emitter and ensure any new child
1009
1011
  * elements do so as well.
@@ -1021,14 +1023,10 @@ class CdkMenuGroup {
1021
1023
  .pipe(takeUntil(this._selectableChanges))
1022
1024
  .subscribe(() => this.change.next(selectable));
1023
1025
  }
1024
- ngOnDestroy() {
1025
- this._selectableChanges.next();
1026
- this._selectableChanges.complete();
1027
- }
1028
1026
  }
1029
- CdkMenuGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1030
- CdkMenuGroup.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuGroup, selector: "[cdkMenuGroup]", outputs: { change: "change" }, host: { attributes: { "role": "group" }, classAttribute: "cdk-menu-group" }, providers: [{ provide: UniqueSelectionDispatcher, useClass: UniqueSelectionDispatcher }], queries: [{ propertyName: "_selectableItems", predicate: CdkMenuItemSelectable, descendants: true }], exportAs: ["cdkMenuGroup"], ngImport: i0 });
1031
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuGroup, decorators: [{
1027
+ CdkMenuGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1028
+ CdkMenuGroup.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuGroup, selector: "[cdkMenuGroup]", outputs: { change: "change" }, host: { attributes: { "role": "group" }, classAttribute: "cdk-menu-group" }, providers: [{ provide: UniqueSelectionDispatcher, useClass: UniqueSelectionDispatcher }], queries: [{ propertyName: "_selectableItems", predicate: CdkMenuItemSelectable, descendants: true }], exportAs: ["cdkMenuGroup"], ngImport: i0 });
1029
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuGroup, decorators: [{
1032
1030
  type: Directive,
1033
1031
  args: [{
1034
1032
  selector: '[cdkMenuGroup]',
@@ -1046,41 +1044,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
1046
1044
  args: [CdkMenuItemSelectable, { descendants: true }]
1047
1045
  }] } });
1048
1046
 
1049
- /**
1050
- * @license
1051
- * Copyright Google LLC All Rights Reserved.
1052
- *
1053
- * Use of this source code is governed by an MIT-style license that can be
1054
- * found in the LICENSE file at https://angular.io/license
1055
- */
1056
- /**
1057
- * Directive applied to an ng-template which wraps a CdkMenu and provides a reference to the
1058
- * child element it wraps which allows for opening of the CdkMenu in an overlay.
1059
- */
1060
- class CdkMenuPanel {
1061
- constructor(_templateRef) {
1062
- this._templateRef = _templateRef;
1063
- }
1064
- /**
1065
- * Set the Menu component on the menu panel. Since we cannot use ContentChild to fetch the
1066
- * child Menu component, the child Menu must register its self with the parent MenuPanel.
1067
- */
1068
- _registerMenu(child) {
1069
- this._menu = child;
1070
- // The ideal solution would be to affect the CdkMenuPanel injector from the CdkMenuTrigger and
1071
- // inject the menu stack reference into the child menu and menu items, however this isn't
1072
- // possible at this time.
1073
- this._menu._menuStack = this._menuStack;
1074
- this._menuStack?.push(child);
1075
- }
1076
- }
1077
- CdkMenuPanel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuPanel, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1078
- CdkMenuPanel.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuPanel, selector: "ng-template[cdkMenuPanel]", exportAs: ["cdkMenuPanel"], ngImport: i0 });
1079
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuPanel, decorators: [{
1080
- type: Directive,
1081
- args: [{ selector: 'ng-template[cdkMenuPanel]', exportAs: 'cdkMenuPanel' }]
1082
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
1083
-
1084
1047
  /**
1085
1048
  * @license
1086
1049
  * Copyright Google LLC All Rights Reserved.
@@ -1135,66 +1098,164 @@ class PointerFocusTracker {
1135
1098
  * Use of this source code is governed by an MIT-style license that can be
1136
1099
  * found in the LICENSE file at https://angular.io/license
1137
1100
  */
1138
- /**
1139
- * Directive which configures the element as a Menu which should contain child elements marked as
1140
- * CdkMenuItem or CdkMenuGroup. Sets the appropriate role and aria-attributes for a menu and
1141
- * contains accessible keyboard and mouse handling logic.
1142
- *
1143
- * It also acts as a RadioGroup for elements marked with role `menuitemradio`.
1144
- */
1145
- class CdkMenu extends CdkMenuGroup {
1146
- constructor(_ngZone, _elementRef, _menuAim, _dir,
1147
- // `CdkMenuPanel` is always used in combination with a `CdkMenu`.
1148
- // tslint:disable-next-line: lightweight-tokens
1149
- _menuPanel) {
1101
+ class CdkMenuBase extends CdkMenuGroup {
1102
+ constructor(_elementRef, menuStack, dir) {
1150
1103
  super();
1151
- this._ngZone = _ngZone;
1152
1104
  this._elementRef = _elementRef;
1153
- this._menuAim = _menuAim;
1154
- this._dir = _dir;
1155
- this._menuPanel = _menuPanel;
1105
+ this.menuStack = menuStack;
1106
+ this.dir = dir;
1156
1107
  /**
1157
1108
  * Sets the aria-orientation attribute and determines where menus will be opened.
1158
1109
  * Does not affect styling/layout.
1159
1110
  */
1160
1111
  this.orientation = 'vertical';
1161
- /** Event emitted when the menu is closed. */
1162
- this.closed = new EventEmitter();
1163
- // We provide a default MenuStack implementation in case the menu is an inline menu.
1164
- // For Menus part of a MenuBar nested within a MenuPanel this will be overwritten
1165
- // to the correct parent MenuStack.
1166
- /** Track the Menus making up the open menu stack. */
1167
- this._menuStack = new NoopMenuStack();
1168
- }
1169
- ngOnInit() {
1170
- this._registerWithParentPanel();
1112
+ /** Emits when the MenuBar is destroyed. */
1113
+ this.destroyed = new Subject();
1171
1114
  }
1172
1115
  ngAfterContentInit() {
1173
1116
  super.ngAfterContentInit();
1174
- this._completeChangeEmitter();
1175
1117
  this._setKeyManager();
1176
1118
  this._subscribeToMenuOpen();
1177
- this._subscribeToMenuStack();
1178
- this._subscribeToMouseManager();
1179
- this._menuAim?.initialize(this, this._pointerTracker);
1119
+ this._subscribeToMenuStackClosed();
1120
+ }
1121
+ ngOnDestroy() {
1122
+ super.ngOnDestroy();
1123
+ this.destroyed.next();
1124
+ this.destroyed.complete();
1180
1125
  }
1181
1126
  /** Place focus on the first MenuItem in the menu and set the focus origin. */
1182
1127
  focusFirstItem(focusOrigin = 'program') {
1183
- this._keyManager.setFocusOrigin(focusOrigin);
1184
- this._keyManager.setFirstItemActive();
1128
+ this.keyManager.setFocusOrigin(focusOrigin);
1129
+ this.keyManager.setFirstItemActive();
1185
1130
  }
1186
1131
  /** Place focus on the last MenuItem in the menu and set the focus origin. */
1187
1132
  focusLastItem(focusOrigin = 'program') {
1188
- this._keyManager.setFocusOrigin(focusOrigin);
1189
- this._keyManager.setLastItemActive();
1133
+ this.keyManager.setFocusOrigin(focusOrigin);
1134
+ this.keyManager.setLastItemActive();
1135
+ }
1136
+ /** Return true if this menu has been configured in a horizontal orientation. */
1137
+ isHorizontal() {
1138
+ return this.orientation === 'horizontal';
1139
+ }
1140
+ /** Return true if the MenuBar has an open submenu. */
1141
+ hasOpenSubmenu() {
1142
+ return !!this.openItem;
1143
+ }
1144
+ /**
1145
+ * Close the open menu if the current active item opened the requested MenuStackItem.
1146
+ * @param item the MenuStackItem requested to be closed.
1147
+ */
1148
+ closeOpenMenu(menu) {
1149
+ const keyManager = this.keyManager;
1150
+ const trigger = this.openItem;
1151
+ if (menu === trigger?.getMenuTrigger()?.getMenu()) {
1152
+ trigger?.getMenuTrigger()?.close();
1153
+ // If the user has moused over a sibling item we want to focus the element under mouse focus
1154
+ // not the trigger which previously opened the now closed menu.
1155
+ if (trigger) {
1156
+ keyManager.setActiveItem(this.pointerTracker?.activeElement || trigger);
1157
+ }
1158
+ }
1159
+ }
1160
+ /** Setup the FocusKeyManager with the correct orientation for the menu. */
1161
+ _setKeyManager() {
1162
+ this.keyManager = new FocusKeyManager(this.items).withWrap().withTypeAhead().withHomeAndEnd();
1163
+ if (this.isHorizontal()) {
1164
+ this.keyManager.withHorizontalOrientation(this.dir?.value || 'ltr');
1165
+ }
1166
+ else {
1167
+ this.keyManager.withVerticalOrientation();
1168
+ }
1169
+ }
1170
+ /**
1171
+ * Subscribe to the menu trigger's open events in order to track the trigger which opened the menu
1172
+ * and stop tracking it when the menu is closed.
1173
+ */
1174
+ _subscribeToMenuOpen() {
1175
+ const exitCondition = merge(this.items.changes, this.destroyed);
1176
+ this.items.changes
1177
+ .pipe(startWith(this.items), mergeMap((list) => list
1178
+ .filter(item => item.hasMenu())
1179
+ .map(item => item.getMenuTrigger().opened.pipe(mapTo(item), takeUntil(exitCondition)))), mergeAll(), switchMap((item) => {
1180
+ this.openItem = item;
1181
+ return item.getMenuTrigger().closed;
1182
+ }), takeUntil(this.destroyed))
1183
+ .subscribe(() => (this.openItem = undefined));
1184
+ }
1185
+ /** Subscribe to the MenuStack close and empty observables. */
1186
+ _subscribeToMenuStackClosed() {
1187
+ this.menuStack.closed
1188
+ .pipe(takeUntil(this.destroyed))
1189
+ .subscribe(item => this.closeOpenMenu(item));
1190
+ }
1191
+ }
1192
+ CdkMenuBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuBase, deps: [{ token: i0.ElementRef }, { token: MENU_STACK }, { token: i1$1.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1193
+ CdkMenuBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuBase, host: { listeners: { "focus": "focusFirstItem()" }, properties: { "attr.aria-orientation": "orientation" } }, queries: [{ propertyName: "items", predicate: CdkMenuItem, descendants: true }], usesInheritance: true, ngImport: i0 });
1194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuBase, decorators: [{
1195
+ type: Directive,
1196
+ args: [{
1197
+ host: {
1198
+ '[attr.aria-orientation]': 'orientation',
1199
+ '(focus)': 'focusFirstItem()',
1200
+ },
1201
+ }]
1202
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: MenuStack, decorators: [{
1203
+ type: Inject,
1204
+ args: [MENU_STACK]
1205
+ }] }, { type: i1$1.Directionality, decorators: [{
1206
+ type: Optional
1207
+ }] }]; }, propDecorators: { items: [{
1208
+ type: ContentChildren,
1209
+ args: [CdkMenuItem, { descendants: true }]
1210
+ }] } });
1211
+
1212
+ /**
1213
+ * @license
1214
+ * Copyright Google LLC All Rights Reserved.
1215
+ *
1216
+ * Use of this source code is governed by an MIT-style license that can be
1217
+ * found in the LICENSE file at https://angular.io/license
1218
+ */
1219
+ /**
1220
+ * Directive which configures the element as a Menu which should contain child elements marked as
1221
+ * CdkMenuItem or CdkMenuGroup. Sets the appropriate role and aria-attributes for a menu and
1222
+ * contains accessible keyboard and mouse handling logic.
1223
+ *
1224
+ * It also acts as a RadioGroup for elements marked with role `menuitemradio`.
1225
+ */
1226
+ class CdkMenu extends CdkMenuBase {
1227
+ constructor(_ngZone, elementRef, menuStack, _parentTrigger, _menuAim, dir) {
1228
+ super(elementRef, menuStack, dir);
1229
+ this._ngZone = _ngZone;
1230
+ this._parentTrigger = _parentTrigger;
1231
+ this._menuAim = _menuAim;
1232
+ /** Event emitted when the menu is closed. */
1233
+ this.closed = new EventEmitter();
1234
+ this.destroyed.subscribe(this.closed);
1235
+ if (!this._isInline()) {
1236
+ this.menuStack.push(this);
1237
+ }
1238
+ this._parentTrigger?.registerChildMenu(this);
1239
+ }
1240
+ ngAfterContentInit() {
1241
+ super.ngAfterContentInit();
1242
+ this._completeChangeEmitter();
1243
+ this._subscribeToMenuStackEmptied();
1244
+ this._subscribeToMouseManager();
1245
+ this._menuAim?.initialize(this, this.pointerTracker);
1246
+ }
1247
+ ngOnDestroy() {
1248
+ super.ngOnDestroy();
1249
+ this.closed.complete();
1250
+ this.pointerTracker?.destroy();
1190
1251
  }
1191
1252
  /** Handle keyboard events for the Menu. */
1192
1253
  _handleKeyEvent(event) {
1193
- const keyManager = this._keyManager;
1254
+ const keyManager = this.keyManager;
1194
1255
  switch (event.keyCode) {
1195
1256
  case LEFT_ARROW:
1196
1257
  case RIGHT_ARROW:
1197
- if (this._isHorizontal()) {
1258
+ if (this.isHorizontal()) {
1198
1259
  event.preventDefault();
1199
1260
  keyManager.setFocusOrigin('keyboard');
1200
1261
  keyManager.onKeydown(event);
@@ -1202,7 +1263,7 @@ class CdkMenu extends CdkMenuGroup {
1202
1263
  break;
1203
1264
  case UP_ARROW:
1204
1265
  case DOWN_ARROW:
1205
- if (!this._isHorizontal()) {
1266
+ if (!this.isHorizontal()) {
1206
1267
  event.preventDefault();
1207
1268
  keyManager.setFocusOrigin('keyboard');
1208
1269
  keyManager.onKeydown(event);
@@ -1211,31 +1272,23 @@ class CdkMenu extends CdkMenuGroup {
1211
1272
  case ESCAPE:
1212
1273
  if (!hasModifierKey(event)) {
1213
1274
  event.preventDefault();
1214
- this._menuStack.close(this, 2 /* currentItem */);
1275
+ this.menuStack.close(this, 2 /* currentItem */);
1215
1276
  }
1216
1277
  break;
1217
1278
  case TAB:
1218
- this._menuStack.closeAll();
1279
+ this.menuStack.closeAll();
1219
1280
  break;
1220
1281
  default:
1221
1282
  keyManager.onKeydown(event);
1222
1283
  }
1223
1284
  }
1224
- /** Register this menu with its enclosing parent menu panel */
1225
- _registerWithParentPanel() {
1226
- this._getMenuPanel()?._registerMenu(this);
1227
- }
1228
- /**
1229
- * Get the enclosing CdkMenuPanel defaulting to the injected reference over the developer
1230
- * provided reference.
1231
- */
1232
- _getMenuPanel() {
1233
- return this._menuPanel || this._explicitPanel;
1234
- }
1235
1285
  /**
1236
1286
  * Complete the change emitter if there are any nested MenuGroups or register to complete the
1237
1287
  * change emitter if a MenuGroup is rendered at some point
1238
1288
  */
1289
+ // TODO(mmalerba): This doesnt' quite work. It causes change events to stop
1290
+ // firing for radio items directly in the menu if a second group of options
1291
+ // is added in a menu-group.
1239
1292
  _completeChangeEmitter() {
1240
1293
  if (this._hasNestedGroups()) {
1241
1294
  this.change.complete();
@@ -1252,59 +1305,21 @@ class CdkMenu extends CdkMenuGroup {
1252
1305
  // order to ensure that we return true iff there are child CdkMenuGroup elements.
1253
1306
  return this._nestedGroups.length > 0 && !(this._nestedGroups.first instanceof CdkMenu);
1254
1307
  }
1255
- /** Setup the FocusKeyManager with the correct orientation for the menu. */
1256
- _setKeyManager() {
1257
- this._keyManager = new FocusKeyManager(this._allItems)
1258
- .withWrap()
1259
- .withTypeAhead()
1260
- .withHomeAndEnd();
1261
- if (this._isHorizontal()) {
1262
- this._keyManager.withHorizontalOrientation(this._dir?.value || 'ltr');
1263
- }
1264
- else {
1265
- this._keyManager.withVerticalOrientation();
1266
- }
1267
- }
1268
1308
  /**
1269
1309
  * Set the PointerFocusTracker and ensure that when mouse focus changes the key manager is updated
1270
1310
  * with the latest menu item under mouse focus.
1271
1311
  */
1272
1312
  _subscribeToMouseManager() {
1273
1313
  this._ngZone.runOutsideAngular(() => {
1274
- this._pointerTracker = new PointerFocusTracker(this._allItems);
1275
- this._pointerTracker.entered
1314
+ this.pointerTracker = new PointerFocusTracker(this.items);
1315
+ this.pointerTracker.entered
1276
1316
  .pipe(takeUntil(this.closed))
1277
- .subscribe(item => this._keyManager.setActiveItem(item));
1317
+ .subscribe(item => this.keyManager.setActiveItem(item));
1278
1318
  });
1279
1319
  }
1280
- /** Subscribe to the MenuStack close and empty observables. */
1281
- _subscribeToMenuStack() {
1282
- this._menuStack.closed
1283
- .pipe(takeUntil(this.closed))
1284
- .subscribe(item => this._closeOpenMenu(item));
1285
- this._menuStack.emptied
1286
- .pipe(takeUntil(this.closed))
1287
- .subscribe(event => this._toggleMenuFocus(event));
1288
- }
1289
- /**
1290
- * Close the open menu if the current active item opened the requested MenuStackItem.
1291
- * @param item the MenuStackItem requested to be closed.
1292
- */
1293
- _closeOpenMenu(menu) {
1294
- const keyManager = this._keyManager;
1295
- const trigger = this._openItem;
1296
- if (menu === trigger?.getMenuTrigger()?.getMenu()) {
1297
- trigger?.getMenuTrigger()?.closeMenu();
1298
- // If the user has moused over a sibling item we want to focus the element under mouse focus
1299
- // not the trigger which previously opened the now closed menu.
1300
- if (trigger) {
1301
- keyManager.setActiveItem(this._pointerTracker?.activeElement || trigger);
1302
- }
1303
- }
1304
- }
1305
1320
  /** Set focus the either the current, previous or next item based on the FocusNext event. */
1306
1321
  _toggleMenuFocus(event) {
1307
- const keyManager = this._keyManager;
1322
+ const keyManager = this.keyManager;
1308
1323
  switch (event) {
1309
1324
  case 0 /* nextItem */:
1310
1325
  keyManager.setFocusOrigin('keyboard');
@@ -1322,95 +1337,65 @@ class CdkMenu extends CdkMenuGroup {
1322
1337
  break;
1323
1338
  }
1324
1339
  }
1325
- // TODO(andy9775): remove duplicate logic between menu an menu bar
1326
- /**
1327
- * Subscribe to the menu trigger's open events in order to track the trigger which opened the menu
1328
- * and stop tracking it when the menu is closed.
1329
- */
1330
- _subscribeToMenuOpen() {
1331
- const exitCondition = merge(this._allItems.changes, this.closed);
1332
- this._allItems.changes
1333
- .pipe(startWith(this._allItems), mergeMap((list) => list
1334
- .filter(item => item.hasMenu())
1335
- .map(item => item.getMenuTrigger().opened.pipe(mapTo(item), takeUntil(exitCondition)))), mergeAll(), switchMap((item) => {
1336
- this._openItem = item;
1337
- return item.getMenuTrigger().closed;
1338
- }), takeUntil(this.closed))
1339
- .subscribe(() => (this._openItem = undefined));
1340
- }
1341
- /** Return true if this menu has been configured in a horizontal orientation. */
1342
- _isHorizontal() {
1343
- return this.orientation === 'horizontal';
1344
- }
1345
1340
  /**
1346
1341
  * Return true if this menu is an inline menu. That is, it does not exist in a pop-up and is
1347
1342
  * always visible in the dom.
1348
1343
  */
1349
1344
  _isInline() {
1350
- // NoopMenuStack is the default. If this menu is not inline than the NoopMenuStack is replaced
1351
- // automatically.
1352
- return this._menuStack instanceof NoopMenuStack;
1345
+ return !this._parentTrigger;
1353
1346
  }
1354
- ngOnDestroy() {
1355
- super.ngOnDestroy();
1356
- this._emitClosedEvent();
1357
- this._pointerTracker?.destroy();
1358
- }
1359
- /** Emit and complete the closed event emitter */
1360
- _emitClosedEvent() {
1361
- this.closed.next();
1362
- this.closed.complete();
1347
+ _subscribeToMenuStackEmptied() {
1348
+ this.menuStack.emptied
1349
+ .pipe(takeUntil(this.destroyed))
1350
+ .subscribe(event => this._toggleMenuFocus(event));
1363
1351
  }
1364
1352
  }
1365
- CdkMenu.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenu, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: MENU_AIM, optional: true, self: true }, { token: i2.Directionality, optional: true }, { token: CdkMenuPanel, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1366
- CdkMenu.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenu, selector: "[cdkMenu]", inputs: { orientation: ["cdkMenuOrientation", "orientation"], _explicitPanel: ["cdkMenuPanel", "_explicitPanel"] }, outputs: { closed: "closed" }, host: { attributes: { "role": "menu" }, listeners: { "focus": "focusFirstItem()", "keydown": "_handleKeyEvent($event)" }, properties: { "tabindex": "_isInline() ? 0 : null", "class.cdk-menu-inline": "_isInline()", "attr.aria-orientation": "orientation" }, classAttribute: "cdk-menu" }, providers: [
1353
+ CdkMenu.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenu, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: MENU_STACK }, { token: MENU_TRIGGER, optional: true }, { token: MENU_AIM, optional: true, self: true }, { token: i1$1.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1354
+ CdkMenu.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenu, selector: "[cdkMenu]", outputs: { closed: "closed" }, host: { attributes: { "role": "menu" }, listeners: { "keydown": "_handleKeyEvent($event)" }, properties: { "tabindex": "_isInline() ? 0 : null", "class.cdk-menu-inline": "_isInline()" }, classAttribute: "cdk-menu" }, providers: [
1367
1355
  { provide: CdkMenuGroup, useExisting: CdkMenu },
1368
1356
  { provide: CDK_MENU, useExisting: CdkMenu },
1369
- ], queries: [{ propertyName: "_nestedGroups", predicate: CdkMenuGroup, descendants: true }, { propertyName: "_allItems", predicate: CdkMenuItem, descendants: true }], exportAs: ["cdkMenu"], usesInheritance: true, ngImport: i0 });
1370
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenu, decorators: [{
1357
+ PARENT_OR_NEW_INLINE_MENU_STACK_PROVIDER,
1358
+ ], queries: [{ propertyName: "_nestedGroups", predicate: CdkMenuGroup, descendants: true }], exportAs: ["cdkMenu"], usesInheritance: true, ngImport: i0 });
1359
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenu, decorators: [{
1371
1360
  type: Directive,
1372
1361
  args: [{
1373
1362
  selector: '[cdkMenu]',
1374
1363
  exportAs: 'cdkMenu',
1375
1364
  host: {
1376
- '[tabindex]': '_isInline() ? 0 : null',
1377
1365
  'role': 'menu',
1378
1366
  'class': 'cdk-menu',
1367
+ '[tabindex]': '_isInline() ? 0 : null',
1379
1368
  '[class.cdk-menu-inline]': '_isInline()',
1380
- '[attr.aria-orientation]': 'orientation',
1381
- '(focus)': 'focusFirstItem()',
1382
1369
  '(keydown)': '_handleKeyEvent($event)',
1383
1370
  },
1384
1371
  providers: [
1385
1372
  { provide: CdkMenuGroup, useExisting: CdkMenu },
1386
1373
  { provide: CDK_MENU, useExisting: CdkMenu },
1374
+ PARENT_OR_NEW_INLINE_MENU_STACK_PROVIDER,
1387
1375
  ],
1388
1376
  }]
1389
- }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: undefined, decorators: [{
1377
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: MenuStack, decorators: [{
1378
+ type: Inject,
1379
+ args: [MENU_STACK]
1380
+ }] }, { type: MenuTrigger, decorators: [{
1381
+ type: Optional
1382
+ }, {
1383
+ type: Inject,
1384
+ args: [MENU_TRIGGER]
1385
+ }] }, { type: undefined, decorators: [{
1390
1386
  type: Self
1391
1387
  }, {
1392
1388
  type: Optional
1393
1389
  }, {
1394
1390
  type: Inject,
1395
1391
  args: [MENU_AIM]
1396
- }] }, { type: i2.Directionality, decorators: [{
1392
+ }] }, { type: i1$1.Directionality, decorators: [{
1397
1393
  type: Optional
1398
- }] }, { type: CdkMenuPanel, decorators: [{
1399
- type: Optional
1400
- }] }]; }, propDecorators: { orientation: [{
1401
- type: Input,
1402
- args: ['cdkMenuOrientation']
1403
- }], closed: [{
1394
+ }] }]; }, propDecorators: { closed: [{
1404
1395
  type: Output
1405
1396
  }], _nestedGroups: [{
1406
1397
  type: ContentChildren,
1407
1398
  args: [CdkMenuGroup, { descendants: true }]
1408
- }], _allItems: [{
1409
- type: ContentChildren,
1410
- args: [CdkMenuItem, { descendants: true }]
1411
- }], _explicitPanel: [{
1412
- type: Input,
1413
- args: ['cdkMenuPanel']
1414
1399
  }] } });
1415
1400
 
1416
1401
  /**
@@ -1426,39 +1411,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
1426
1411
  * this directive is applied to should contain components marked with CdkMenuItem.
1427
1412
  *
1428
1413
  */
1429
- class CdkMenuBar extends CdkMenuGroup {
1430
- constructor(_menuStack, _ngZone, _elementRef, _menuAim, _dir) {
1431
- super();
1432
- this._menuStack = _menuStack;
1414
+ class CdkMenuBar extends CdkMenuBase {
1415
+ constructor(_ngZone, elementRef, menuStack, _menuAim, dir) {
1416
+ super(elementRef, menuStack, dir);
1433
1417
  this._ngZone = _ngZone;
1434
- this._elementRef = _elementRef;
1435
1418
  this._menuAim = _menuAim;
1436
- this._dir = _dir;
1437
- /**
1438
- * Sets the aria-orientation attribute and determines where menus will be opened.
1439
- * Does not affect styling/layout.
1440
- */
1441
1419
  this.orientation = 'horizontal';
1442
- /** Emits when the MenuBar is destroyed. */
1443
- this._destroyed = new Subject();
1444
1420
  }
1445
1421
  ngAfterContentInit() {
1446
1422
  super.ngAfterContentInit();
1447
- this._setKeyManager();
1448
- this._subscribeToMenuOpen();
1449
- this._subscribeToMenuStack();
1423
+ this._subscribeToMenuStackEmptied();
1450
1424
  this._subscribeToMouseManager();
1451
- this._menuAim?.initialize(this, this._pointerTracker);
1452
- }
1453
- /** Place focus on the first MenuItem in the menu and set the focus origin. */
1454
- focusFirstItem(focusOrigin = 'program') {
1455
- this._keyManager.setFocusOrigin(focusOrigin);
1456
- this._keyManager.setFirstItemActive();
1425
+ this._menuAim?.initialize(this, this.pointerTracker);
1457
1426
  }
1458
- /** Place focus on the last MenuItem in the menu and set the focus origin. */
1459
- focusLastItem(focusOrigin = 'program') {
1460
- this._keyManager.setFocusOrigin(focusOrigin);
1461
- this._keyManager.setLastItemActive();
1427
+ ngOnDestroy() {
1428
+ super.ngOnDestroy();
1429
+ this.pointerTracker?.destroy();
1462
1430
  }
1463
1431
  /**
1464
1432
  * Handle keyboard events, specifically changing the focused element and/or toggling the active
@@ -1466,7 +1434,7 @@ class CdkMenuBar extends CdkMenuGroup {
1466
1434
  * @param event the KeyboardEvent to handle.
1467
1435
  */
1468
1436
  _handleKeyEvent(event) {
1469
- const keyManager = this._keyManager;
1437
+ const keyManager = this.keyManager;
1470
1438
  switch (event.keyCode) {
1471
1439
  case UP_ARROW:
1472
1440
  case DOWN_ARROW:
@@ -1476,97 +1444,59 @@ class CdkMenuBar extends CdkMenuGroup {
1476
1444
  // For a horizontal menu if the left/right keys were clicked, or a vertical menu if the
1477
1445
  // up/down keys were clicked: if the current menu is open, close it then focus and open the
1478
1446
  // next menu.
1479
- if ((this._isHorizontal() && horizontalArrows) ||
1480
- (!this._isHorizontal() && !horizontalArrows)) {
1447
+ if ((this.isHorizontal() && horizontalArrows) ||
1448
+ (!this.isHorizontal() && !horizontalArrows)) {
1481
1449
  event.preventDefault();
1482
1450
  const prevIsOpen = keyManager.activeItem?.isMenuOpen();
1483
- keyManager.activeItem?.getMenuTrigger()?.closeMenu();
1451
+ keyManager.activeItem?.getMenuTrigger()?.close();
1484
1452
  keyManager.setFocusOrigin('keyboard');
1485
1453
  keyManager.onKeydown(event);
1486
1454
  if (prevIsOpen) {
1487
- keyManager.activeItem?.getMenuTrigger()?.openMenu();
1455
+ keyManager.activeItem?.getMenuTrigger()?.open();
1488
1456
  }
1489
1457
  }
1490
1458
  break;
1491
1459
  case ESCAPE:
1492
1460
  event.preventDefault();
1493
- keyManager.activeItem?.getMenuTrigger()?.closeMenu();
1461
+ keyManager.activeItem?.getMenuTrigger()?.close();
1494
1462
  break;
1495
1463
  case TAB:
1496
- keyManager.activeItem?.getMenuTrigger()?.closeMenu();
1464
+ keyManager.activeItem?.getMenuTrigger()?.close();
1497
1465
  break;
1498
1466
  default:
1499
1467
  keyManager.onKeydown(event);
1500
1468
  }
1501
1469
  }
1502
- /** Setup the FocusKeyManager with the correct orientation for the menu bar. */
1503
- _setKeyManager() {
1504
- this._keyManager = new FocusKeyManager(this._allItems)
1505
- .withWrap()
1506
- .withTypeAhead()
1507
- .withHomeAndEnd();
1508
- if (this._isHorizontal()) {
1509
- this._keyManager.withHorizontalOrientation(this._dir?.value || 'ltr');
1510
- }
1511
- else {
1512
- this._keyManager.withVerticalOrientation();
1513
- }
1514
- }
1515
1470
  /**
1516
1471
  * Set the PointerFocusTracker and ensure that when mouse focus changes the key manager is updated
1517
1472
  * with the latest menu item under mouse focus.
1518
1473
  */
1519
1474
  _subscribeToMouseManager() {
1520
1475
  this._ngZone.runOutsideAngular(() => {
1521
- this._pointerTracker = new PointerFocusTracker(this._allItems);
1522
- this._pointerTracker.entered.pipe(takeUntil(this._destroyed)).subscribe(item => {
1523
- if (this._hasOpenSubmenu()) {
1524
- this._keyManager.setActiveItem(item);
1476
+ this.pointerTracker = new PointerFocusTracker(this.items);
1477
+ this.pointerTracker.entered.pipe(takeUntil(this.destroyed)).subscribe(item => {
1478
+ if (this.hasOpenSubmenu()) {
1479
+ this.keyManager.setActiveItem(item);
1525
1480
  }
1526
1481
  });
1527
1482
  });
1528
1483
  }
1529
- /** Subscribe to the MenuStack close and empty observables. */
1530
- _subscribeToMenuStack() {
1531
- this._menuStack.closed
1532
- .pipe(takeUntil(this._destroyed))
1533
- .subscribe(item => this._closeOpenMenu(item));
1534
- this._menuStack.emptied
1535
- .pipe(takeUntil(this._destroyed))
1536
- .subscribe(event => this._toggleOpenMenu(event));
1537
- }
1538
- /**
1539
- * Close the open menu if the current active item opened the requested MenuStackItem.
1540
- * @param item the MenuStackItem requested to be closed.
1541
- */
1542
- _closeOpenMenu(menu) {
1543
- const trigger = this._openItem;
1544
- const keyManager = this._keyManager;
1545
- if (menu === trigger?.getMenuTrigger()?.getMenu()) {
1546
- trigger?.getMenuTrigger()?.closeMenu();
1547
- // If the user has moused over a sibling item we want to focus the element under mouse focus
1548
- // not the trigger which previously opened the now closed menu.
1549
- if (trigger) {
1550
- keyManager.setActiveItem(this._pointerTracker?.activeElement || trigger);
1551
- }
1552
- }
1553
- }
1554
1484
  /**
1555
1485
  * Set focus to either the current, previous or next item based on the FocusNext event, then
1556
1486
  * open the previous or next item.
1557
1487
  */
1558
1488
  _toggleOpenMenu(event) {
1559
- const keyManager = this._keyManager;
1489
+ const keyManager = this.keyManager;
1560
1490
  switch (event) {
1561
1491
  case 0 /* nextItem */:
1562
1492
  keyManager.setFocusOrigin('keyboard');
1563
1493
  keyManager.setNextItemActive();
1564
- keyManager.activeItem?.getMenuTrigger()?.openMenu();
1494
+ keyManager.activeItem?.getMenuTrigger()?.open();
1565
1495
  break;
1566
1496
  case 1 /* previousItem */:
1567
1497
  keyManager.setFocusOrigin('keyboard');
1568
1498
  keyManager.setPreviousItemActive();
1569
- keyManager.activeItem?.getMenuTrigger()?.openMenu();
1499
+ keyManager.activeItem?.getMenuTrigger()?.open();
1570
1500
  break;
1571
1501
  case 2 /* currentItem */:
1572
1502
  if (keyManager.activeItem) {
@@ -1576,45 +1506,19 @@ class CdkMenuBar extends CdkMenuGroup {
1576
1506
  break;
1577
1507
  }
1578
1508
  }
1579
- /**
1580
- * @return true if the menu bar is configured to be horizontal.
1581
- */
1582
- _isHorizontal() {
1583
- return this.orientation === 'horizontal';
1584
- }
1585
- /**
1586
- * Subscribe to the menu trigger's open events in order to track the trigger which opened the menu
1587
- * and stop tracking it when the menu is closed.
1588
- */
1589
- _subscribeToMenuOpen() {
1590
- const exitCondition = merge(this._allItems.changes, this._destroyed);
1591
- this._allItems.changes
1592
- .pipe(startWith(this._allItems), mergeMap((list) => list
1593
- .filter(item => item.hasMenu())
1594
- .map(item => item.getMenuTrigger().opened.pipe(mapTo(item), takeUntil(exitCondition)))), mergeAll(), switchMap((item) => {
1595
- this._openItem = item;
1596
- return item.getMenuTrigger().closed;
1597
- }), takeUntil(this._destroyed))
1598
- .subscribe(() => (this._openItem = undefined));
1599
- }
1600
- /** Return true if the MenuBar has an open submenu. */
1601
- _hasOpenSubmenu() {
1602
- return !!this._openItem;
1603
- }
1604
- ngOnDestroy() {
1605
- super.ngOnDestroy();
1606
- this._destroyed.next();
1607
- this._destroyed.complete();
1608
- this._pointerTracker?.destroy();
1509
+ _subscribeToMenuStackEmptied() {
1510
+ this.menuStack?.emptied
1511
+ .pipe(takeUntil(this.destroyed))
1512
+ .subscribe(event => this._toggleOpenMenu(event));
1609
1513
  }
1610
1514
  }
1611
- CdkMenuBar.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuBar, deps: [{ token: MenuStack }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: MENU_AIM, optional: true, self: true }, { token: i2.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1612
- CdkMenuBar.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuBar, selector: "[cdkMenuBar]", inputs: { orientation: ["cdkMenuBarOrientation", "orientation"] }, host: { attributes: { "role": "menubar", "tabindex": "0" }, listeners: { "focus": "focusFirstItem()", "keydown": "_handleKeyEvent($event)" }, properties: { "attr.aria-orientation": "orientation" }, classAttribute: "cdk-menu-bar" }, providers: [
1515
+ CdkMenuBar.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuBar, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: MENU_STACK }, { token: MENU_AIM, optional: true, self: true }, { token: i1$1.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1516
+ CdkMenuBar.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuBar, selector: "[cdkMenuBar]", host: { attributes: { "role": "menubar", "tabindex": "0" }, listeners: { "keydown": "_handleKeyEvent($event)" }, classAttribute: "cdk-menu-bar" }, providers: [
1613
1517
  { provide: CdkMenuGroup, useExisting: CdkMenuBar },
1614
1518
  { provide: CDK_MENU, useExisting: CdkMenuBar },
1615
- { provide: MenuStack, useClass: MenuStack },
1616
- ], queries: [{ propertyName: "_allItems", predicate: CdkMenuItem, descendants: true }], exportAs: ["cdkMenuBar"], usesInheritance: true, ngImport: i0 });
1617
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuBar, decorators: [{
1519
+ { provide: MENU_STACK, useFactory: () => MenuStack.inline() },
1520
+ ], exportAs: ["cdkMenuBar"], usesInheritance: true, ngImport: i0 });
1521
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuBar, decorators: [{
1618
1522
  type: Directive,
1619
1523
  args: [{
1620
1524
  selector: '[cdkMenuBar]',
@@ -1623,32 +1527,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
1623
1527
  'role': 'menubar',
1624
1528
  'class': 'cdk-menu-bar',
1625
1529
  'tabindex': '0',
1626
- '[attr.aria-orientation]': 'orientation',
1627
- '(focus)': 'focusFirstItem()',
1628
1530
  '(keydown)': '_handleKeyEvent($event)',
1629
1531
  },
1630
1532
  providers: [
1631
1533
  { provide: CdkMenuGroup, useExisting: CdkMenuBar },
1632
1534
  { provide: CDK_MENU, useExisting: CdkMenuBar },
1633
- { provide: MenuStack, useClass: MenuStack },
1535
+ { provide: MENU_STACK, useFactory: () => MenuStack.inline() },
1634
1536
  ],
1635
1537
  }]
1636
- }], ctorParameters: function () { return [{ type: MenuStack }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: undefined, decorators: [{
1538
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: MenuStack, decorators: [{
1539
+ type: Inject,
1540
+ args: [MENU_STACK]
1541
+ }] }, { type: undefined, decorators: [{
1637
1542
  type: Self
1638
1543
  }, {
1639
1544
  type: Optional
1640
1545
  }, {
1641
1546
  type: Inject,
1642
1547
  args: [MENU_AIM]
1643
- }] }, { type: i2.Directionality, decorators: [{
1548
+ }] }, { type: i1$1.Directionality, decorators: [{
1644
1549
  type: Optional
1645
- }] }]; }, propDecorators: { orientation: [{
1646
- type: Input,
1647
- args: ['cdkMenuBarOrientation']
1648
- }], _allItems: [{
1649
- type: ContentChildren,
1650
- args: [CdkMenuItem, { descendants: true }]
1651
- }] } });
1550
+ }] }]; } });
1652
1551
 
1653
1552
  /**
1654
1553
  * @license
@@ -1663,12 +1562,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
1663
1562
  * or `CdkMenuGroup` comprise a radio group with unique selection enforced.
1664
1563
  */
1665
1564
  class CdkMenuItemRadio extends CdkMenuItemSelectable {
1666
- constructor(_selectionDispatcher, element, ngZone, parentMenu, menuAim, dir,
1565
+ constructor(_selectionDispatcher, element, ngZone, menuStack, parentMenu, menuAim, dir,
1667
1566
  /** Reference to the CdkMenuItemTrigger directive if one is added to the same element */
1668
1567
  // `CdkMenuItemRadio` is commonly used in combination with a `CdkMenuItemTrigger`.
1669
1568
  // tslint:disable-next-line: lightweight-tokens
1670
1569
  menuTrigger) {
1671
- super(element, ngZone, parentMenu, menuAim, dir, menuTrigger);
1570
+ super(element, ngZone, menuStack, parentMenu, menuAim, dir, menuTrigger);
1672
1571
  this._selectionDispatcher = _selectionDispatcher;
1673
1572
  this._registerDispatcherListener();
1674
1573
  }
@@ -1688,12 +1587,12 @@ class CdkMenuItemRadio extends CdkMenuItemSelectable {
1688
1587
  this._removeDispatcherListener();
1689
1588
  }
1690
1589
  }
1691
- CdkMenuItemRadio.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemRadio, deps: [{ token: i1$1.UniqueSelectionDispatcher }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: CDK_MENU, optional: true }, { token: MENU_AIM, optional: true }, { token: i2.Directionality, optional: true }, { token: CdkMenuItemTrigger, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
1692
- CdkMenuItemRadio.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuItemRadio, selector: "[cdkMenuItemRadio]", host: { attributes: { "type": "button", "role": "menuitemradio" }, properties: { "tabindex": "_tabindex", "attr.aria-checked": "checked || null", "attr.aria-disabled": "disabled || null" } }, providers: [
1590
+ CdkMenuItemRadio.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemRadio, deps: [{ token: i1$2.UniqueSelectionDispatcher }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: MENU_STACK }, { token: CDK_MENU, optional: true }, { token: MENU_AIM, optional: true }, { token: i1$1.Directionality, optional: true }, { token: CdkMenuItemTrigger, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
1591
+ CdkMenuItemRadio.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuItemRadio, selector: "[cdkMenuItemRadio]", host: { attributes: { "type": "button", "role": "menuitemradio" }, properties: { "tabindex": "_tabindex", "attr.aria-checked": "checked || null", "attr.aria-disabled": "disabled || null" } }, providers: [
1693
1592
  { provide: CdkMenuItemSelectable, useExisting: CdkMenuItemRadio },
1694
1593
  { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
1695
1594
  ], exportAs: ["cdkMenuItemRadio"], usesInheritance: true, ngImport: i0 });
1696
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemRadio, decorators: [{
1595
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemRadio, decorators: [{
1697
1596
  type: Directive,
1698
1597
  args: [{
1699
1598
  selector: '[cdkMenuItemRadio]',
@@ -1710,7 +1609,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
1710
1609
  { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
1711
1610
  ],
1712
1611
  }]
1713
- }], ctorParameters: function () { return [{ type: i1$1.UniqueSelectionDispatcher }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
1612
+ }], ctorParameters: function () { return [{ type: i1$2.UniqueSelectionDispatcher }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: MenuStack, decorators: [{
1613
+ type: Inject,
1614
+ args: [MENU_STACK]
1615
+ }] }, { type: undefined, decorators: [{
1714
1616
  type: Optional
1715
1617
  }, {
1716
1618
  type: Inject,
@@ -1720,7 +1622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
1720
1622
  }, {
1721
1623
  type: Inject,
1722
1624
  args: [MENU_AIM]
1723
- }] }, { type: i2.Directionality, decorators: [{
1625
+ }] }, { type: i1$1.Directionality, decorators: [{
1724
1626
  type: Optional
1725
1627
  }] }, { type: CdkMenuItemTrigger, decorators: [{
1726
1628
  type: Self
@@ -1748,12 +1650,12 @@ class CdkMenuItemCheckbox extends CdkMenuItemSelectable {
1748
1650
  }
1749
1651
  }
1750
1652
  }
1751
- CdkMenuItemCheckbox.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemCheckbox, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1752
- CdkMenuItemCheckbox.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkMenuItemCheckbox, selector: "[cdkMenuItemCheckbox]", host: { attributes: { "type": "button", "role": "menuitemcheckbox" }, properties: { "tabindex": "_tabindex", "attr.aria-checked": "checked || null", "attr.aria-disabled": "disabled || null" } }, providers: [
1653
+ CdkMenuItemCheckbox.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemCheckbox, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1654
+ CdkMenuItemCheckbox.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkMenuItemCheckbox, selector: "[cdkMenuItemCheckbox]", host: { attributes: { "type": "button", "role": "menuitemcheckbox" }, properties: { "tabindex": "_tabindex", "attr.aria-checked": "checked || null", "attr.aria-disabled": "disabled || null" } }, providers: [
1753
1655
  { provide: CdkMenuItemSelectable, useExisting: CdkMenuItemCheckbox },
1754
1656
  { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
1755
1657
  ], exportAs: ["cdkMenuItemCheckbox"], usesInheritance: true, ngImport: i0 });
1756
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuItemCheckbox, decorators: [{
1658
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuItemCheckbox, decorators: [{
1757
1659
  type: Directive,
1758
1660
  args: [{
1759
1661
  selector: '[cdkMenuItemCheckbox]',
@@ -1779,6 +1681,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
1779
1681
  * Use of this source code is governed by an MIT-style license that can be
1780
1682
  * found in the LICENSE file at https://angular.io/license
1781
1683
  */
1684
+ // In cases where the first menu item in the context menu is a trigger the submenu opens on a
1685
+ // hover event. We offset the context menu 2px by default to prevent this from occurring.
1686
+ const CONTEXT_MENU_POSITIONS = STANDARD_DROPDOWN_BELOW_POSITIONS.map(position => {
1687
+ const offsetX = position.overlayX === 'start' ? 2 : -2;
1688
+ const offsetY = position.overlayY === 'top' ? 2 : -2;
1689
+ return { ...position, offsetX, offsetY };
1690
+ });
1782
1691
  /** Tracks the last open context menu trigger across the entire application. */
1783
1692
  class ContextMenuTracker {
1784
1693
  /**
@@ -1792,54 +1701,27 @@ class ContextMenuTracker {
1792
1701
  }
1793
1702
  }
1794
1703
  }
1795
- ContextMenuTracker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: ContextMenuTracker, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1796
- ContextMenuTracker.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: ContextMenuTracker, providedIn: 'root' });
1797
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: ContextMenuTracker, decorators: [{
1704
+ ContextMenuTracker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: ContextMenuTracker, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1705
+ ContextMenuTracker.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: ContextMenuTracker, providedIn: 'root' });
1706
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: ContextMenuTracker, decorators: [{
1798
1707
  type: Injectable,
1799
1708
  args: [{ providedIn: 'root' }]
1800
1709
  }] });
1801
- /** Injection token for the ContextMenu options object. */
1802
- const CDK_CONTEXT_MENU_DEFAULT_OPTIONS = new InjectionToken('cdk-context-menu-default-options');
1803
1710
  /**
1804
1711
  * A directive which when placed on some element opens a the Menu it is bound to when a user
1805
1712
  * right-clicks within that element. It is aware of nested Context Menus and the lowest level
1806
1713
  * non-disabled context menu will trigger.
1807
1714
  */
1808
- class CdkContextMenuTrigger {
1809
- constructor(_viewContainerRef, _overlay, _contextMenuTracker, _options, _directionality) {
1715
+ class CdkContextMenuTrigger extends MenuTrigger {
1716
+ constructor(injector, _viewContainerRef, _overlay, _contextMenuTracker, menuStack, _directionality) {
1717
+ super(injector, menuStack);
1810
1718
  this._viewContainerRef = _viewContainerRef;
1811
1719
  this._overlay = _overlay;
1812
1720
  this._contextMenuTracker = _contextMenuTracker;
1813
- this._options = _options;
1814
1721
  this._directionality = _directionality;
1815
- /** Emits when the attached menu is requested to open. */
1816
- this.opened = new EventEmitter();
1817
- /** Emits when the attached menu is requested to close. */
1818
- this.closed = new EventEmitter();
1819
1722
  this._disabled = false;
1820
- /** A reference to the overlay which manages the triggered menu. */
1821
- this._overlayRef = null;
1822
- /** Emits when the element is destroyed. */
1823
- this._destroyed = new Subject();
1824
- /** The menu stack for this trigger and its associated menus. */
1825
- this._menuStack = new MenuStack();
1826
- /** Emits when the outside pointer events listener on the overlay should be stopped. */
1827
- this._stopOutsideClicksListener = merge(this.closed, this._destroyed);
1828
1723
  this._setMenuStackListener();
1829
1724
  }
1830
- /** Template reference variable to the menu to open on right click. */
1831
- get menuPanel() {
1832
- return this._menuPanel;
1833
- }
1834
- set menuPanel(panel) {
1835
- if ((typeof ngDevMode === 'undefined' || ngDevMode) && panel._menuStack) {
1836
- throwExistingMenuStackError();
1837
- }
1838
- this._menuPanel = panel;
1839
- if (this._menuPanel) {
1840
- this._menuPanel._menuStack = this._menuStack;
1841
- }
1842
- }
1843
1725
  /** Whether the context menu should be disabled. */
1844
1726
  get disabled() {
1845
1727
  return this._disabled;
@@ -1861,7 +1743,7 @@ class CdkContextMenuTrigger {
1861
1743
  else if (this.isOpen()) {
1862
1744
  // since we're moving this menu we need to close any submenus first otherwise they end up
1863
1745
  // disconnected from this one.
1864
- this._menuStack.closeSubMenuOf(this._menuPanel._menu);
1746
+ this.menuStack.closeSubMenuOf(this.childMenu);
1865
1747
  this._overlayRef.getConfig().positionStrategy.setOrigin(coordinates);
1866
1748
  this._overlayRef.updatePosition();
1867
1749
  }
@@ -1880,7 +1762,7 @@ class CdkContextMenuTrigger {
1880
1762
  }
1881
1763
  /** Close the opened menu. */
1882
1764
  close() {
1883
- this._menuStack.closeAll();
1765
+ this.menuStack.closeAll();
1884
1766
  }
1885
1767
  /**
1886
1768
  * Open the context menu and close any previously open menus.
@@ -1898,20 +1780,16 @@ class CdkContextMenuTrigger {
1898
1780
  this._open({ x: event.clientX, y: event.clientY }, true);
1899
1781
  // A context menu can be triggered via a mouse right click or a keyboard shortcut.
1900
1782
  if (event.button === 2) {
1901
- this._menuPanel._menu?.focusFirstItem('mouse');
1783
+ this.childMenu?.focusFirstItem('mouse');
1902
1784
  }
1903
1785
  else if (event.button === 0) {
1904
- this._menuPanel._menu?.focusFirstItem('keyboard');
1786
+ this.childMenu?.focusFirstItem('keyboard');
1905
1787
  }
1906
1788
  else {
1907
- this._menuPanel._menu?.focusFirstItem('program');
1789
+ this.childMenu?.focusFirstItem('program');
1908
1790
  }
1909
1791
  }
1910
1792
  }
1911
- /** Whether the attached menu is open. */
1912
- isOpen() {
1913
- return !!this._overlayRef?.hasAttached();
1914
- }
1915
1793
  /**
1916
1794
  * Get the configuration object used to create the overlay.
1917
1795
  * @param coordinates the location to place the opened menu
@@ -1931,37 +1809,23 @@ class CdkContextMenuTrigger {
1931
1809
  return this._overlay
1932
1810
  .position()
1933
1811
  .flexibleConnectedTo(coordinates)
1934
- .withDefaultOffsetX(this._options.offsetX)
1935
- .withDefaultOffsetY(this._options.offsetY)
1936
- .withPositions(this._getOverlayPositions());
1937
- }
1938
- /**
1939
- * Determine and return where to position the opened menu relative to the mouse location.
1940
- */
1941
- _getOverlayPositions() {
1942
- // TODO: this should be configurable through the injected context menu options
1943
- return [
1944
- { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top' },
1945
- { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top' },
1946
- { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom' },
1947
- { originX: 'start', originY: 'bottom', overlayX: 'end', overlayY: 'bottom' },
1948
- ];
1812
+ .withPositions(this.menuPosition ?? CONTEXT_MENU_POSITIONS);
1949
1813
  }
1950
1814
  /**
1951
1815
  * Get the portal to be attached to the overlay which contains the menu. Allows for the menu
1952
1816
  * content to change dynamically and be reflected in the application.
1953
1817
  */
1954
1818
  _getMenuContent() {
1955
- const hasMenuContentChanged = this.menuPanel._templateRef !== this._panelContent?.templateRef;
1956
- if (this.menuPanel && (!this._panelContent || hasMenuContentChanged)) {
1957
- this._panelContent = new TemplatePortal(this.menuPanel._templateRef, this._viewContainerRef);
1819
+ const hasMenuContentChanged = this._menuTemplateRef !== this._menuPortal?.templateRef;
1820
+ if (this._menuTemplateRef && (!this._menuPortal || hasMenuContentChanged)) {
1821
+ this._menuPortal = new TemplatePortal(this._menuTemplateRef, this._viewContainerRef, undefined, this.getChildMenuInjector());
1958
1822
  }
1959
- return this._panelContent;
1823
+ return this._menuPortal;
1960
1824
  }
1961
1825
  /** Subscribe to the menu stack close events and close this menu when requested. */
1962
1826
  _setMenuStackListener() {
1963
- this._menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
1964
- if (item === this._menuPanel._menu && this.isOpen()) {
1827
+ this.menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
1828
+ if (item === this.childMenu && this.isOpen()) {
1965
1829
  this.closed.next();
1966
1830
  this._overlayRef.detach();
1967
1831
  }
@@ -1982,44 +1846,18 @@ class CdkContextMenuTrigger {
1982
1846
  }
1983
1847
  outsideClicks.pipe(takeUntil(this._stopOutsideClicksListener)).subscribe(event => {
1984
1848
  if (!isClickInsideMenuOverlay(event.target)) {
1985
- this._menuStack.closeAll();
1849
+ this.menuStack.closeAll();
1986
1850
  }
1987
1851
  });
1988
1852
  }
1989
1853
  }
1990
- ngOnDestroy() {
1991
- this._destroyOverlay();
1992
- this._resetPanelMenuStack();
1993
- this._destroyed.next();
1994
- this._destroyed.complete();
1995
- }
1996
- /** Destroy and unset the overlay reference it if exists. */
1997
- _destroyOverlay() {
1998
- if (this._overlayRef) {
1999
- this._overlayRef.dispose();
2000
- this._overlayRef = null;
2001
- }
2002
- }
2003
- /** Set the menu panels menu stack back to null. */
2004
- _resetPanelMenuStack() {
2005
- // If a ContextMenuTrigger is placed in a conditionally rendered view, each time the trigger is
2006
- // rendered the panel setter for ContextMenuTrigger is called. From the first render onward,
2007
- // the attached CdkMenuPanel has the MenuStack set. Since we throw an error if a panel already
2008
- // has a stack set, we want to reset the attached stack here to prevent the error from being
2009
- // thrown if the trigger re-configures its attached panel (in the case where there is a 1:1
2010
- // relationship between the panel and trigger).
2011
- if (this._menuPanel) {
2012
- this._menuPanel._menuStack = null;
2013
- }
2014
- }
2015
1854
  }
2016
- CdkContextMenuTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkContextMenuTrigger, deps: [{ token: i0.ViewContainerRef }, { token: i1.Overlay }, { token: ContextMenuTracker }, { token: CDK_CONTEXT_MENU_DEFAULT_OPTIONS }, { token: i2.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2017
- CdkContextMenuTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.5", type: CdkContextMenuTrigger, selector: "[cdkContextMenuTriggerFor]", inputs: { menuPanel: ["cdkContextMenuTriggerFor", "menuPanel"], disabled: ["cdkContextMenuDisabled", "disabled"] }, outputs: { opened: "cdkContextMenuOpened", closed: "cdkContextMenuClosed" }, host: { listeners: { "contextmenu": "_openOnContextMenu($event)" } }, providers: [
2018
- // In cases where the first menu item in the context menu is a trigger the submenu opens on a
2019
- // hover event. Offsetting the opened context menu by 2px prevents this from occurring.
2020
- { provide: CDK_CONTEXT_MENU_DEFAULT_OPTIONS, useValue: { offsetX: 2, offsetY: 2 } },
2021
- ], exportAs: ["cdkContextMenuTriggerFor"], ngImport: i0 });
2022
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkContextMenuTrigger, decorators: [{
1855
+ CdkContextMenuTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkContextMenuTrigger, deps: [{ token: i0.Injector }, { token: i0.ViewContainerRef }, { token: i1.Overlay }, { token: ContextMenuTracker }, { token: MENU_STACK }, { token: i1$1.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1856
+ CdkContextMenuTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.9", type: CdkContextMenuTrigger, selector: "[cdkContextMenuTriggerFor]", inputs: { _menuTemplateRef: ["cdkContextMenuTriggerFor", "_menuTemplateRef"], menuPosition: ["cdkContextMenuPosition", "menuPosition"], disabled: ["cdkContextMenuDisabled", "disabled"] }, outputs: { opened: "cdkContextMenuOpened", closed: "cdkContextMenuClosed" }, host: { listeners: { "contextmenu": "_openOnContextMenu($event)" } }, providers: [
1857
+ { provide: MENU_TRIGGER, useExisting: CdkContextMenuTrigger },
1858
+ { provide: MENU_STACK, useClass: MenuStack },
1859
+ ], exportAs: ["cdkContextMenuTriggerFor"], usesInheritance: true, ngImport: i0 });
1860
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkContextMenuTrigger, decorators: [{
2023
1861
  type: Directive,
2024
1862
  args: [{
2025
1863
  selector: '[cdkContextMenuTriggerFor]',
@@ -2027,27 +1865,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
2027
1865
  host: {
2028
1866
  '(contextmenu)': '_openOnContextMenu($event)',
2029
1867
  },
1868
+ inputs: ['_menuTemplateRef: cdkContextMenuTriggerFor', 'menuPosition: cdkContextMenuPosition'],
1869
+ outputs: ['opened: cdkContextMenuOpened', 'closed: cdkContextMenuClosed'],
2030
1870
  providers: [
2031
- // In cases where the first menu item in the context menu is a trigger the submenu opens on a
2032
- // hover event. Offsetting the opened context menu by 2px prevents this from occurring.
2033
- { provide: CDK_CONTEXT_MENU_DEFAULT_OPTIONS, useValue: { offsetX: 2, offsetY: 2 } },
1871
+ { provide: MENU_TRIGGER, useExisting: CdkContextMenuTrigger },
1872
+ { provide: MENU_STACK, useClass: MenuStack },
2034
1873
  ],
2035
1874
  }]
2036
- }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: ContextMenuTracker }, { type: undefined, decorators: [{
1875
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: ContextMenuTracker }, { type: MenuStack, decorators: [{
2037
1876
  type: Inject,
2038
- args: [CDK_CONTEXT_MENU_DEFAULT_OPTIONS]
2039
- }] }, { type: i2.Directionality, decorators: [{
1877
+ args: [MENU_STACK]
1878
+ }] }, { type: i1$1.Directionality, decorators: [{
2040
1879
  type: Optional
2041
- }] }]; }, propDecorators: { menuPanel: [{
2042
- type: Input,
2043
- args: ['cdkContextMenuTriggerFor']
2044
- }], opened: [{
2045
- type: Output,
2046
- args: ['cdkContextMenuOpened']
2047
- }], closed: [{
2048
- type: Output,
2049
- args: ['cdkContextMenuClosed']
2050
- }], disabled: [{
1880
+ }] }]; }, propDecorators: { disabled: [{
2051
1881
  type: Input,
2052
1882
  args: ['cdkContextMenuDisabled']
2053
1883
  }] } });
@@ -2062,7 +1892,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
2062
1892
  const EXPORTED_DECLARATIONS = [
2063
1893
  CdkMenuBar,
2064
1894
  CdkMenu,
2065
- CdkMenuPanel,
2066
1895
  CdkMenuItem,
2067
1896
  CdkMenuItemRadio,
2068
1897
  CdkMenuItemCheckbox,
@@ -2073,10 +1902,9 @@ const EXPORTED_DECLARATIONS = [
2073
1902
  ];
2074
1903
  class CdkMenuModule {
2075
1904
  }
2076
- CdkMenuModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2077
- CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuModule, declarations: [CdkMenuBar,
1905
+ CdkMenuModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1906
+ CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuModule, declarations: [CdkMenuBar,
2078
1907
  CdkMenu,
2079
- CdkMenuPanel,
2080
1908
  CdkMenuItem,
2081
1909
  CdkMenuItemRadio,
2082
1910
  CdkMenuItemCheckbox,
@@ -2085,7 +1913,6 @@ CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version:
2085
1913
  CdkContextMenuTrigger,
2086
1914
  CdkTargetMenuAim], imports: [OverlayModule], exports: [CdkMenuBar,
2087
1915
  CdkMenu,
2088
- CdkMenuPanel,
2089
1916
  CdkMenuItem,
2090
1917
  CdkMenuItemRadio,
2091
1918
  CdkMenuItemCheckbox,
@@ -2093,8 +1920,8 @@ CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version:
2093
1920
  CdkMenuGroup,
2094
1921
  CdkContextMenuTrigger,
2095
1922
  CdkTargetMenuAim] });
2096
- CdkMenuModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuModule, imports: [[OverlayModule]] });
2097
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5", ngImport: i0, type: CdkMenuModule, decorators: [{
1923
+ CdkMenuModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuModule, imports: [[OverlayModule]] });
1924
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: CdkMenuModule, decorators: [{
2098
1925
  type: NgModule,
2099
1926
  args: [{
2100
1927
  imports: [OverlayModule],
@@ -2123,5 +1950,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.5",
2123
1950
  * Generated bundle index. Do not edit.
2124
1951
  */
2125
1952
 
2126
- export { CDK_CONTEXT_MENU_DEFAULT_OPTIONS, CDK_MENU, CdkContextMenuTrigger, CdkMenu, CdkMenuBar, CdkMenuGroup, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuItemTrigger, CdkMenuModule, CdkMenuPanel, CdkTargetMenuAim, ContextMenuTracker, MENU_AIM, MenuStack, TargetMenuAim, isClickInsideMenuOverlay };
1953
+ export { CDK_MENU, CdkContextMenuTrigger, CdkMenu, CdkMenuBar, CdkMenuGroup, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuItemTrigger, CdkMenuModule, CdkTargetMenuAim, ContextMenuTracker, MENU_AIM, MENU_STACK, MENU_TRIGGER, MenuStack, MenuTrigger, TargetMenuAim, isClickInsideMenuOverlay };
2127
1954
  //# sourceMappingURL=menu.mjs.map