@angular/cdk-experimental 14.0.0-next.5 → 14.0.0-next.8

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 (117) 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/esm2020/column-resize/column-resize-directives/column-resize-flex.mjs +3 -3
  6. package/esm2020/column-resize/column-resize-directives/column-resize.mjs +3 -3
  7. package/esm2020/column-resize/column-resize-directives/default-enabled-column-resize-flex.mjs +3 -3
  8. package/esm2020/column-resize/column-resize-directives/default-enabled-column-resize.mjs +3 -3
  9. package/esm2020/column-resize/column-resize-module.mjs +8 -8
  10. package/esm2020/column-resize/column-resize-notifier.mjs +6 -6
  11. package/esm2020/column-resize/column-resize.mjs +3 -3
  12. package/esm2020/column-resize/column-size-store.mjs +3 -3
  13. package/esm2020/column-resize/event-dispatcher.mjs +3 -3
  14. package/esm2020/column-resize/overlay-handle.mjs +3 -3
  15. package/esm2020/column-resize/resizable.mjs +3 -3
  16. package/esm2020/column-resize/resize-strategy.mjs +9 -9
  17. package/esm2020/combobox/combobox-module.mjs +6 -7
  18. package/esm2020/combobox/combobox-popup.mjs +12 -23
  19. package/esm2020/combobox/combobox.mjs +50 -34
  20. package/esm2020/combobox/public-api.mjs +1 -2
  21. package/esm2020/dialog/dialog-container.mjs +28 -11
  22. package/esm2020/dialog/dialog-module.mjs +4 -4
  23. package/esm2020/dialog/dialog.mjs +3 -3
  24. package/esm2020/listbox/listbox-module.mjs +4 -4
  25. package/esm2020/listbox/listbox.mjs +26 -44
  26. package/esm2020/menu/context-menu.mjs +46 -82
  27. package/esm2020/menu/menu-aim.mjs +6 -6
  28. package/esm2020/menu/menu-bar.mjs +16 -13
  29. package/esm2020/menu/menu-errors.mjs +1 -9
  30. package/esm2020/menu/menu-group.mjs +3 -3
  31. package/esm2020/menu/menu-item-checkbox.mjs +3 -3
  32. package/esm2020/menu/menu-item-radio.mjs +15 -8
  33. package/esm2020/menu/menu-item-selectable.mjs +3 -3
  34. package/esm2020/menu/menu-item-trigger.mjs +63 -88
  35. package/esm2020/menu/menu-item.mjs +29 -37
  36. package/esm2020/menu/menu-module.mjs +5 -9
  37. package/esm2020/menu/menu-stack.mjs +10 -6
  38. package/esm2020/menu/menu-trigger.mjs +43 -0
  39. package/esm2020/menu/menu.mjs +32 -45
  40. package/esm2020/menu/public-api.mjs +3 -3
  41. package/esm2020/popover-edit/edit-event-dispatcher.mjs +3 -3
  42. package/esm2020/popover-edit/edit-ref.mjs +3 -3
  43. package/esm2020/popover-edit/edit-services.mjs +3 -3
  44. package/esm2020/popover-edit/focus-dispatcher.mjs +3 -3
  45. package/esm2020/popover-edit/focus-escape-notifier.mjs +3 -3
  46. package/esm2020/popover-edit/lens-directives.mjs +9 -9
  47. package/esm2020/popover-edit/popover-edit-module.mjs +4 -4
  48. package/esm2020/popover-edit/popover-edit-position-strategy-factory.mjs +6 -6
  49. package/esm2020/popover-edit/table-directives.mjs +15 -15
  50. package/esm2020/scrolling/auto-size-virtual-scroll.mjs +3 -3
  51. package/esm2020/scrolling/scrolling-module.mjs +4 -4
  52. package/esm2020/selection/row-selection.mjs +3 -3
  53. package/esm2020/selection/select-all.mjs +3 -3
  54. package/esm2020/selection/selection-column.mjs +3 -3
  55. package/esm2020/selection/selection-module.mjs +4 -4
  56. package/esm2020/selection/selection-toggle.mjs +3 -3
  57. package/esm2020/selection/selection.mjs +3 -3
  58. package/esm2020/table-scroll-container/table-scroll-container-module.mjs +4 -4
  59. package/esm2020/table-scroll-container/table-scroll-container.mjs +3 -3
  60. package/esm2020/version.mjs +1 -1
  61. package/fesm2015/cdk-experimental.mjs +1 -1
  62. package/fesm2015/cdk-experimental.mjs.map +1 -1
  63. package/fesm2015/column-resize.mjs +50 -50
  64. package/fesm2015/column-resize.mjs.map +1 -1
  65. package/fesm2015/combobox.mjs +63 -106
  66. package/fesm2015/combobox.mjs.map +1 -1
  67. package/fesm2015/dialog.mjs +34 -17
  68. package/fesm2015/dialog.mjs.map +1 -1
  69. package/fesm2015/listbox.mjs +31 -47
  70. package/fesm2015/listbox.mjs.map +1 -1
  71. package/fesm2015/menu.mjs +334 -421
  72. package/fesm2015/menu.mjs.map +1 -1
  73. package/fesm2015/popover-edit.mjs +49 -49
  74. package/fesm2015/popover-edit.mjs.map +1 -1
  75. package/fesm2015/scrolling.mjs +7 -7
  76. package/fesm2015/scrolling.mjs.map +1 -1
  77. package/fesm2015/selection.mjs +19 -19
  78. package/fesm2015/selection.mjs.map +1 -1
  79. package/fesm2015/table-scroll-container.mjs +7 -7
  80. package/fesm2015/table-scroll-container.mjs.map +1 -1
  81. package/fesm2020/cdk-experimental.mjs +1 -1
  82. package/fesm2020/cdk-experimental.mjs.map +1 -1
  83. package/fesm2020/column-resize.mjs +50 -50
  84. package/fesm2020/column-resize.mjs.map +1 -1
  85. package/fesm2020/combobox.mjs +62 -103
  86. package/fesm2020/combobox.mjs.map +1 -1
  87. package/fesm2020/dialog.mjs +34 -17
  88. package/fesm2020/dialog.mjs.map +1 -1
  89. package/fesm2020/listbox.mjs +29 -46
  90. package/fesm2020/listbox.mjs.map +1 -1
  91. package/fesm2020/menu.mjs +238 -321
  92. package/fesm2020/menu.mjs.map +1 -1
  93. package/fesm2020/popover-edit.mjs +49 -49
  94. package/fesm2020/popover-edit.mjs.map +1 -1
  95. package/fesm2020/scrolling.mjs +7 -7
  96. package/fesm2020/scrolling.mjs.map +1 -1
  97. package/fesm2020/selection.mjs +19 -19
  98. package/fesm2020/selection.mjs.map +1 -1
  99. package/fesm2020/table-scroll-container.mjs +7 -7
  100. package/fesm2020/table-scroll-container.mjs.map +1 -1
  101. package/listbox/listbox.d.ts +16 -13
  102. package/menu/context-menu.d.ts +12 -30
  103. package/menu/menu-bar.d.ts +2 -2
  104. package/menu/menu-errors.d.ts +0 -5
  105. package/menu/menu-item-radio.d.ts +4 -3
  106. package/menu/menu-item-trigger.d.ts +11 -18
  107. package/menu/menu-item.d.ts +11 -6
  108. package/menu/menu-module.d.ts +9 -10
  109. package/menu/menu-stack.d.ts +7 -6
  110. package/menu/menu-trigger.d.ts +24 -0
  111. package/menu/menu.d.ts +7 -23
  112. package/menu/public-api.d.ts +2 -2
  113. package/package.json +2 -2
  114. package/combobox/combobox-panel.d.ts +0 -27
  115. package/esm2020/combobox/combobox-panel.mjs +0 -48
  116. package/esm2020/menu/menu-panel.mjs +0 -37
  117. package/menu/menu-panel.d.ts +0 -30
package/fesm2020/menu.mjs CHANGED
@@ -1,13 +1,13 @@
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, Injectable, Directive, Injector, Inject, EventEmitter, Optional, SkipSelf, Input, Output, Self, ContentChildren, NgModule } from '@angular/core';
3
3
  import * as i1 from '@angular/cdk/overlay';
4
- import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
4
+ import { OverlayConfig, STANDARD_DROPDOWN_BELOW_POSITIONS, STANDARD_DROPDOWN_ADJACENT_POSITIONS, OverlayModule } from '@angular/cdk/overlay';
5
5
  import { FocusKeyManager } from '@angular/cdk/a11y';
6
6
  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';
7
+ import * as i1$1 from '@angular/cdk/bidi';
8
8
  import { Subject, fromEvent, merge, defer, partition } from 'rxjs';
9
9
  import { filter, takeUntil, startWith, mergeMap, mapTo, mergeAll, take, switchMap, skip } from 'rxjs/operators';
10
- import * as i1$1 from '@angular/cdk/collections';
10
+ import * as i1$2 from '@angular/cdk/collections';
11
11
  import { UniqueSelectionDispatcher } from '@angular/cdk/collections';
12
12
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
13
13
  import { TemplatePortal } from '@angular/cdk/portal';
@@ -29,6 +29,8 @@ 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');
32
34
  /**
33
35
  * MenuStack allows subscribers to listen for close events (when a MenuStackItem is popped off
34
36
  * of the stack) in order to perform closing actions. Upon the MenuStack being empty it emits
@@ -121,11 +123,11 @@ class MenuStack {
121
123
  return this._elements[this._elements.length - 1];
122
124
  }
123
125
  }
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
- }
126
+ MenuStack.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: MenuStack, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
127
+ MenuStack.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: MenuStack });
128
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: MenuStack, decorators: [{
129
+ type: Injectable
130
+ }] });
129
131
 
130
132
  /**
131
133
  * @license
@@ -134,14 +136,6 @@ class NoopMenuStack extends MenuStack {
134
136
  * Use of this source code is governed by an MIT-style license that can be
135
137
  * found in the LICENSE file at https://angular.io/license
136
138
  */
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
139
  /**
146
140
  * Throws an exception when an instance of the PointerFocusTracker is not provided.
147
141
  * @docs-private
@@ -329,9 +323,9 @@ class TargetMenuAim {
329
323
  this._destroyed.complete();
330
324
  }
331
325
  }
332
- TargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", ngImport: i0, type: TargetMenuAim });
334
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: TargetMenuAim, decorators: [{
326
+ TargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: TargetMenuAim, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
327
+ TargetMenuAim.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: TargetMenuAim });
328
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: TargetMenuAim, decorators: [{
335
329
  type: Injectable
336
330
  }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
337
331
  /**
@@ -340,9 +334,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
340
334
  */
341
335
  class CdkTargetMenuAim {
342
336
  }
343
- CdkTargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkTargetMenuAim, deps: [], target: i0.ɵɵFactoryTarget.Directive });
344
- CdkTargetMenuAim.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", ngImport: i0, type: CdkTargetMenuAim, decorators: [{
337
+ CdkTargetMenuAim.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkTargetMenuAim, deps: [], target: i0.ɵɵFactoryTarget.Directive });
338
+ CdkTargetMenuAim.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", type: CdkTargetMenuAim, selector: "[cdkTargetMenuAim]", providers: [{ provide: MENU_AIM, useClass: TargetMenuAim }], exportAs: ["cdkTargetMenuAim"], ngImport: i0 });
339
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkTargetMenuAim, decorators: [{
346
340
  type: Directive,
347
341
  args: [{
348
342
  selector: '[cdkTargetMenuAim]',
@@ -351,6 +345,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
351
345
  }]
352
346
  }] });
353
347
 
348
+ /**
349
+ * @license
350
+ * Copyright Google LLC All Rights Reserved.
351
+ *
352
+ * Use of this source code is governed by an MIT-style license that can be
353
+ * found in the LICENSE file at https://angular.io/license
354
+ */
355
+ /** Injection token used for an implementation of MenuStack. */
356
+ const MENU_TRIGGER = new InjectionToken('cdk-menu-trigger');
357
+ class MenuTrigger {
358
+ constructor(injector, menuStack) {
359
+ this.injector = injector;
360
+ this.menuStack = menuStack;
361
+ }
362
+ getChildMenuInjector() {
363
+ this._childMenuInjector =
364
+ this._childMenuInjector ||
365
+ Injector.create({
366
+ providers: [
367
+ { provide: MENU_TRIGGER, useValue: this },
368
+ { provide: MENU_STACK, useValue: this.menuStack },
369
+ ],
370
+ parent: this.injector,
371
+ });
372
+ return this._childMenuInjector;
373
+ }
374
+ registerChildMenu(child) {
375
+ this.childMenu = child;
376
+ }
377
+ }
378
+ MenuTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: MenuTrigger, deps: [{ token: i0.Injector }, { token: MENU_STACK }], target: i0.ɵɵFactoryTarget.Injectable });
379
+ MenuTrigger.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: MenuTrigger });
380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: MenuTrigger, decorators: [{
381
+ type: Injectable
382
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: MenuStack, decorators: [{
383
+ type: Inject,
384
+ args: [MENU_STACK]
385
+ }] }]; } });
386
+
354
387
  /**
355
388
  * @license
356
389
  * Copyright Google LLC All Rights Reserved.
@@ -382,8 +415,9 @@ function isClickInsideMenuOverlay(target) {
382
415
  * The directive must be placed along with the `cdkMenuItem` directive in order to enable full
383
416
  * functionality.
384
417
  */
385
- class CdkMenuItemTrigger {
386
- constructor(_elementRef, _viewContainerRef, _overlay, _ngZone, _parentMenu, _menuAim, _directionality) {
418
+ class CdkMenuItemTrigger extends MenuTrigger {
419
+ constructor(injector, _elementRef, _viewContainerRef, _overlay, _ngZone, menuStack, _parentMenu, _menuAim, _directionality) {
420
+ super(injector, menuStack);
387
421
  this._elementRef = _elementRef;
388
422
  this._viewContainerRef = _viewContainerRef;
389
423
  this._overlay = _overlay;
@@ -395,8 +429,6 @@ class CdkMenuItemTrigger {
395
429
  this.opened = new EventEmitter();
396
430
  /** Emits when the attached menu is requested to close */
397
431
  this.closed = new EventEmitter();
398
- /** The menu stack for this trigger and its sub-menus. */
399
- this._menuStack = new MenuStack();
400
432
  /** A reference to the overlay which manages the triggered menu */
401
433
  this._overlayRef = null;
402
434
  /** Emits when this trigger is destroyed. */
@@ -406,22 +438,6 @@ class CdkMenuItemTrigger {
406
438
  this._registerCloseHandler();
407
439
  this._subscribeToMouseEnter();
408
440
  }
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
441
  /** Open/close the attached menu if the trigger has been configured with one */
426
442
  toggle() {
427
443
  if (this.hasMenu()) {
@@ -447,7 +463,7 @@ class CdkMenuItemTrigger {
447
463
  }
448
464
  /** Return true if the trigger has an attached menu */
449
465
  hasMenu() {
450
- return !!this.menuPanel;
466
+ return !!this._menuTemplateRef;
451
467
  }
452
468
  /** Whether the menu this button is a trigger for is open */
453
469
  isMenuOpen() {
@@ -458,7 +474,7 @@ class CdkMenuItemTrigger {
458
474
  * @return the menu if it is open, otherwise undefined.
459
475
  */
460
476
  getMenu() {
461
- return this.menuPanel?._menu;
477
+ return this.childMenu;
462
478
  }
463
479
  /**
464
480
  * Subscribe to the mouseenter events and close any sibling menu items if this element is moused
@@ -472,7 +488,7 @@ class CdkMenuItemTrigger {
472
488
  });
473
489
  this._ngZone.runOutsideAngular(() => {
474
490
  fromEvent(this._elementRef.nativeElement, 'mouseenter')
475
- .pipe(filter(() => !this._getMenuStack()?.isEmpty() && !this.isMenuOpen()), takeUntil(this._destroyed))
491
+ .pipe(filter(() => !this.menuStack.isEmpty() && !this.isMenuOpen()), takeUntil(this._destroyed))
476
492
  .subscribe(() => {
477
493
  if (this._menuAim) {
478
494
  this._menuAim.toggle(toggleMenus);
@@ -495,17 +511,17 @@ class CdkMenuItemTrigger {
495
511
  case ENTER:
496
512
  event.preventDefault();
497
513
  this.toggle();
498
- this.menuPanel?._menu?.focusFirstItem('keyboard');
514
+ this.childMenu?.focusFirstItem('keyboard');
499
515
  break;
500
516
  case RIGHT_ARROW:
501
517
  if (this._parentMenu && this._isParentVertical()) {
502
518
  event.preventDefault();
503
519
  if (this._directionality?.value === 'rtl') {
504
- this._getMenuStack().close(this._parentMenu, 2 /* currentItem */);
520
+ this.menuStack.close(this._parentMenu, 2 /* currentItem */);
505
521
  }
506
522
  else {
507
523
  this.openMenu();
508
- this.menuPanel?._menu?.focusFirstItem('keyboard');
524
+ this.childMenu?.focusFirstItem('keyboard');
509
525
  }
510
526
  }
511
527
  break;
@@ -514,10 +530,10 @@ class CdkMenuItemTrigger {
514
530
  event.preventDefault();
515
531
  if (this._directionality?.value === 'rtl') {
516
532
  this.openMenu();
517
- this.menuPanel?._menu?.focusFirstItem('keyboard');
533
+ this.childMenu?.focusFirstItem('keyboard');
518
534
  }
519
535
  else {
520
- this._getMenuStack().close(this._parentMenu, 2 /* currentItem */);
536
+ this.menuStack.close(this._parentMenu, 2 /* currentItem */);
521
537
  }
522
538
  }
523
539
  break;
@@ -527,8 +543,8 @@ class CdkMenuItemTrigger {
527
543
  event.preventDefault();
528
544
  this.openMenu();
529
545
  keyCode === DOWN_ARROW
530
- ? this.menuPanel?._menu?.focusFirstItem('keyboard')
531
- : this.menuPanel?._menu?.focusLastItem('keyboard');
546
+ ? this.childMenu?.focusFirstItem('keyboard')
547
+ : this.childMenu?.focusLastItem('keyboard');
532
548
  }
533
549
  break;
534
550
  }
@@ -536,17 +552,17 @@ class CdkMenuItemTrigger {
536
552
  /** Close out any sibling menu trigger menus. */
537
553
  _closeSiblingTriggers() {
538
554
  if (this._parentMenu) {
539
- const menuStack = this._getMenuStack();
540
555
  // If nothing was removed from the stack and the last element is not the parent item
541
556
  // that means that the parent menu is a menu bar since we don't put the menu bar on the
542
557
  // stack
543
- const isParentMenuBar = !menuStack.closeSubMenuOf(this._parentMenu) && menuStack.peek() !== this._parentMenu;
558
+ const isParentMenuBar = !this.menuStack.closeSubMenuOf(this._parentMenu) &&
559
+ this.menuStack.peek() !== this._parentMenu;
544
560
  if (isParentMenuBar) {
545
- menuStack.closeAll();
561
+ this.menuStack.closeAll();
546
562
  }
547
563
  }
548
564
  else {
549
- this._getMenuStack().closeAll();
565
+ this.menuStack.closeAll();
550
566
  }
551
567
  }
552
568
  /** Get the configuration object used to create the overlay */
@@ -566,31 +582,21 @@ class CdkMenuItemTrigger {
566
582
  }
567
583
  /** Determine and return where to position the opened menu relative to the menu item */
568
584
  _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
- ];
585
+ return (this.menuPosition ??
586
+ (!this._parentMenu || this._parentMenu.orientation === 'horizontal'
587
+ ? STANDARD_DROPDOWN_BELOW_POSITIONS
588
+ : STANDARD_DROPDOWN_ADJACENT_POSITIONS));
583
589
  }
584
590
  /**
585
591
  * Get the portal to be attached to the overlay which contains the menu. Allows for the menu
586
592
  * content to change dynamically and be reflected in the application.
587
593
  */
588
594
  _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);
595
+ const hasMenuContentChanged = this._menuTemplateRef !== this._menuPortal?.templateRef;
596
+ if (this._menuTemplateRef && (!this._menuPortal || hasMenuContentChanged)) {
597
+ this._menuPortal = new TemplatePortal(this._menuTemplateRef, this._viewContainerRef, undefined, this.getChildMenuInjector());
592
598
  }
593
- return this._panelContent;
599
+ return this._menuPortal;
594
600
  }
595
601
  /**
596
602
  * @return true if if the enclosing parent menu is configured in a vertical orientation.
@@ -604,38 +610,18 @@ class CdkMenuItemTrigger {
604
610
  */
605
611
  _registerCloseHandler() {
606
612
  if (!this._parentMenu) {
607
- this._menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
608
- if (item === this._menuPanel?._menu) {
613
+ this.menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
614
+ if (item === this.childMenu) {
609
615
  this.closeMenu();
610
616
  }
611
617
  });
612
618
  }
613
619
  }
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
620
  ngOnDestroy() {
622
621
  this._destroyOverlay();
623
- this._resetPanelMenuStack();
624
622
  this._destroyed.next();
625
623
  this._destroyed.complete();
626
624
  }
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
625
  /**
640
626
  * Subscribe to the overlays outside pointer events stream and handle closing out the stack if a
641
627
  * click occurs outside the menus.
@@ -647,7 +633,7 @@ class CdkMenuItemTrigger {
647
633
  .pipe(takeUntil(this._stopOutsideClicksListener))
648
634
  .subscribe(event => {
649
635
  if (!isClickInsideMenuOverlay(event.target)) {
650
- this._getMenuStack().closeAll();
636
+ this.menuStack.closeAll();
651
637
  }
652
638
  });
653
639
  }
@@ -660,9 +646,16 @@ class CdkMenuItemTrigger {
660
646
  }
661
647
  }
662
648
  }
663
- CdkMenuItemTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", 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.4", ngImport: i0, type: CdkMenuItemTrigger, decorators: [{
649
+ CdkMenuItemTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", 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 });
650
+ CdkMenuItemTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", 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": "isMenuOpen()" }, classAttribute: "cdk-menu-trigger" }, providers: [
651
+ { provide: MENU_TRIGGER, useExisting: CdkMenuItemTrigger },
652
+ {
653
+ provide: MENU_STACK,
654
+ deps: [[new Optional(), new SkipSelf(), new Inject(MENU_STACK)]],
655
+ useFactory: (parentMenuStack) => parentMenuStack || new MenuStack(),
656
+ },
657
+ ], exportAs: ["cdkMenuTriggerFor"], usesInheritance: true, ngImport: i0 });
658
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItemTrigger, decorators: [{
666
659
  type: Directive,
667
660
  args: [{
668
661
  selector: '[cdkMenuTriggerFor]',
@@ -674,8 +667,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
674
667
  'aria-haspopup': 'menu',
675
668
  '[attr.aria-expanded]': 'isMenuOpen()',
676
669
  },
670
+ providers: [
671
+ { provide: MENU_TRIGGER, useExisting: CdkMenuItemTrigger },
672
+ {
673
+ provide: MENU_STACK,
674
+ deps: [[new Optional(), new SkipSelf(), new Inject(MENU_STACK)]],
675
+ useFactory: (parentMenuStack) => parentMenuStack || new MenuStack(),
676
+ },
677
+ ],
677
678
  }]
678
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: i0.NgZone }, { type: undefined, decorators: [{
679
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: i0.NgZone }, { type: MenuStack, decorators: [{
680
+ type: Inject,
681
+ args: [MENU_STACK]
682
+ }] }, { type: undefined, decorators: [{
679
683
  type: Optional
680
684
  }, {
681
685
  type: Inject,
@@ -685,11 +689,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
685
689
  }, {
686
690
  type: Inject,
687
691
  args: [MENU_AIM]
688
- }] }, { type: i2.Directionality, decorators: [{
692
+ }] }, { type: i1$1.Directionality, decorators: [{
689
693
  type: Optional
690
- }] }]; }, propDecorators: { menuPanel: [{
694
+ }] }]; }, propDecorators: { _menuTemplateRef: [{
691
695
  type: Input,
692
696
  args: ['cdkMenuTriggerFor']
697
+ }], menuPosition: [{
698
+ type: Input,
699
+ args: ['cdkMenuPosition']
693
700
  }], opened: [{
694
701
  type: Output,
695
702
  args: ['cdkMenuOpened']
@@ -705,26 +712,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
705
712
  * Use of this source code is governed by an MIT-style license that can be
706
713
  * found in the LICENSE file at https://angular.io/license
707
714
  */
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
715
  /**
716
716
  * Directive which provides the ability for an element to be focused and navigated to using the
717
717
  * keyboard when residing in a CdkMenu, CdkMenuBar, or CdkMenuGroup. It performs user defined
718
718
  * behavior when clicked.
719
719
  */
720
720
  class CdkMenuItem {
721
- constructor(_elementRef, _ngZone, _parentMenu, _menuAim, _dir,
721
+ constructor(_elementRef, _ngZone, _menuStack, _parentMenu, _menuAim, _dir,
722
722
  /** Reference to the CdkMenuItemTrigger directive if one is added to the same element */
723
723
  // `CdkMenuItem` is commonly used in combination with a `CdkMenuItemTrigger`.
724
724
  // tslint:disable-next-line: lightweight-tokens
725
725
  _menuTrigger) {
726
726
  this._elementRef = _elementRef;
727
727
  this._ngZone = _ngZone;
728
+ this._menuStack = _menuStack;
728
729
  this._parentMenu = _parentMenu;
729
730
  this._menuAim = _menuAim;
730
731
  this._dir = _dir;
@@ -773,7 +774,7 @@ class CdkMenuItem {
773
774
  return;
774
775
  }
775
776
  // don't set the tabindex if there are no open sibling or parent menus
776
- if (!event || !this._getMenuStack()?.isEmpty()) {
777
+ if (!event || !this._menuStack?.isEmpty()) {
777
778
  this._tabindex = 0;
778
779
  }
779
780
  }
@@ -788,7 +789,7 @@ class CdkMenuItem {
788
789
  trigger() {
789
790
  if (!this.disabled && !this.hasMenu()) {
790
791
  this.triggered.next();
791
- this._getMenuStack()?.closeAll();
792
+ this._menuStack?.closeAll();
792
793
  }
793
794
  }
794
795
  /** Whether the menu item opens a menu. */
@@ -812,11 +813,7 @@ class CdkMenuItem {
812
813
  }
813
814
  /** Get the label for this element which is required by the FocusableOption interface. */
814
815
  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() || '';
816
+ return this.typeahead || this._elementRef.nativeElement.textContent?.trim() || '';
820
817
  }
821
818
  /**
822
819
  * Handles keyboard events for the menu item, specifically either triggering the user defined
@@ -835,16 +832,16 @@ class CdkMenuItem {
835
832
  if (this._parentMenu && this._isParentVertical() && !this.hasMenu()) {
836
833
  event.preventDefault();
837
834
  this._dir?.value === 'rtl'
838
- ? this._getMenuStack()?.close(this._parentMenu, 1 /* previousItem */)
839
- : this._getMenuStack()?.closeAll(0 /* nextItem */);
835
+ ? this._menuStack?.close(this._parentMenu, 1 /* previousItem */)
836
+ : this._menuStack?.closeAll(0 /* nextItem */);
840
837
  }
841
838
  break;
842
839
  case LEFT_ARROW:
843
840
  if (this._parentMenu && this._isParentVertical() && !this.hasMenu()) {
844
841
  event.preventDefault();
845
842
  this._dir?.value === 'rtl'
846
- ? this._getMenuStack()?.closeAll(0 /* nextItem */)
847
- : this._getMenuStack()?.close(this._parentMenu, 1 /* previousItem */);
843
+ ? this._menuStack?.closeAll(0 /* nextItem */)
844
+ : this._menuStack?.close(this._parentMenu, 1 /* previousItem */);
848
845
  }
849
846
  break;
850
847
  }
@@ -855,9 +852,9 @@ class CdkMenuItem {
855
852
  */
856
853
  _setupMouseEnter() {
857
854
  if (!this._isStandaloneItem()) {
858
- const closeOpenSiblings = () => this._ngZone.run(() => this._getMenuStack()?.closeSubMenuOf(this._parentMenu));
855
+ const closeOpenSiblings = () => this._ngZone.run(() => this._menuStack?.closeSubMenuOf(this._parentMenu));
859
856
  this._ngZone.runOutsideAngular(() => fromEvent(this._elementRef.nativeElement, 'mouseenter')
860
- .pipe(filter(() => !this._getMenuStack()?.isEmpty() && !this.hasMenu()), takeUntil(this._destroyed))
857
+ .pipe(filter(() => !this._menuStack?.isEmpty() && !this.hasMenu()), takeUntil(this._destroyed))
861
858
  .subscribe(() => {
862
859
  if (this._menuAim) {
863
860
  this._menuAim.toggle(closeOpenSiblings);
@@ -875,20 +872,13 @@ class CdkMenuItem {
875
872
  _isParentVertical() {
876
873
  return this._parentMenu?.orientation === 'vertical';
877
874
  }
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
875
  ngOnDestroy() {
886
876
  this._destroyed.next();
887
877
  }
888
878
  }
889
- CdkMenuItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", 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.4", ngImport: i0, type: CdkMenuItem, decorators: [{
879
+ CdkMenuItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItem, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: MENU_STACK, optional: true }, { 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 });
880
+ CdkMenuItem.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", 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 });
881
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItem, decorators: [{
892
882
  type: Directive,
893
883
  args: [{
894
884
  selector: '[cdkMenuItem]',
@@ -907,7 +897,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
907
897
  '(keydown)': '_onKeydown($event)',
908
898
  },
909
899
  }]
910
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
900
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: MenuStack, decorators: [{
901
+ type: Optional
902
+ }, {
903
+ type: Inject,
904
+ args: [MENU_STACK]
905
+ }] }, { type: undefined, decorators: [{
911
906
  type: Optional
912
907
  }, {
913
908
  type: Inject,
@@ -917,7 +912,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
917
912
  }, {
918
913
  type: Inject,
919
914
  args: [MENU_AIM]
920
- }] }, { type: i2.Directionality, decorators: [{
915
+ }] }, { type: i1$1.Directionality, decorators: [{
921
916
  type: Optional
922
917
  }] }, { type: CdkMenuItemTrigger, decorators: [{
923
918
  type: Self
@@ -925,6 +920,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
925
920
  type: Optional
926
921
  }] }]; }, propDecorators: { disabled: [{
927
922
  type: Input
923
+ }], typeahead: [{
924
+ type: Input
928
925
  }], triggered: [{
929
926
  type: Output,
930
927
  args: ['cdkMenuItemTriggered']
@@ -968,9 +965,9 @@ class CdkMenuItemSelectable extends CdkMenuItem {
968
965
  }
969
966
  }
970
967
  }
971
- CdkMenuItemSelectable.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuItemSelectable, deps: null, target: i0.ɵɵFactoryTarget.Directive });
972
- CdkMenuItemSelectable.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", ngImport: i0, type: CdkMenuItemSelectable, decorators: [{
968
+ CdkMenuItemSelectable.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItemSelectable, deps: null, target: i0.ɵɵFactoryTarget.Directive });
969
+ CdkMenuItemSelectable.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", type: CdkMenuItemSelectable, inputs: { checked: "checked", name: "name", id: "id" }, outputs: { toggled: "cdkMenuItemToggled" }, usesInheritance: true, ngImport: i0 });
970
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItemSelectable, decorators: [{
974
971
  type: Directive
975
972
  }], propDecorators: { toggled: [{
976
973
  type: Output,
@@ -1026,9 +1023,9 @@ class CdkMenuGroup {
1026
1023
  this._selectableChanges.complete();
1027
1024
  }
1028
1025
  }
1029
- CdkMenuGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1030
- CdkMenuGroup.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", ngImport: i0, type: CdkMenuGroup, decorators: [{
1026
+ CdkMenuGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1027
+ CdkMenuGroup.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", 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 });
1028
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuGroup, decorators: [{
1032
1029
  type: Directive,
1033
1030
  args: [{
1034
1031
  selector: '[cdkMenuGroup]',
@@ -1046,41 +1043,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1046
1043
  args: [CdkMenuItemSelectable, { descendants: true }]
1047
1044
  }] } });
1048
1045
 
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.4", 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.4", type: CdkMenuPanel, selector: "ng-template[cdkMenuPanel]", exportAs: ["cdkMenuPanel"], ngImport: i0 });
1079
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4", 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
1046
  /**
1085
1047
  * @license
1086
1048
  * Copyright Google LLC All Rights Reserved.
@@ -1143,16 +1105,14 @@ class PointerFocusTracker {
1143
1105
  * It also acts as a RadioGroup for elements marked with role `menuitemradio`.
1144
1106
  */
1145
1107
  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) {
1108
+ constructor(_ngZone, _elementRef, _menuStack, _parentTrigger, _menuAim, _dir) {
1150
1109
  super();
1151
1110
  this._ngZone = _ngZone;
1152
1111
  this._elementRef = _elementRef;
1112
+ this._menuStack = _menuStack;
1113
+ this._parentTrigger = _parentTrigger;
1153
1114
  this._menuAim = _menuAim;
1154
1115
  this._dir = _dir;
1155
- this._menuPanel = _menuPanel;
1156
1116
  /**
1157
1117
  * Sets the aria-orientation attribute and determines where menus will be opened.
1158
1118
  * Does not affect styling/layout.
@@ -1160,14 +1120,10 @@ class CdkMenu extends CdkMenuGroup {
1160
1120
  this.orientation = 'vertical';
1161
1121
  /** Event emitted when the menu is closed. */
1162
1122
  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
1123
  }
1169
1124
  ngOnInit() {
1170
- this._registerWithParentPanel();
1125
+ this._menuStack?.push(this);
1126
+ this._parentTrigger?.registerChildMenu(this);
1171
1127
  }
1172
1128
  ngAfterContentInit() {
1173
1129
  super.ngAfterContentInit();
@@ -1211,27 +1167,16 @@ class CdkMenu extends CdkMenuGroup {
1211
1167
  case ESCAPE:
1212
1168
  if (!hasModifierKey(event)) {
1213
1169
  event.preventDefault();
1214
- this._menuStack.close(this, 2 /* currentItem */);
1170
+ this._menuStack?.close(this, 2 /* currentItem */);
1215
1171
  }
1216
1172
  break;
1217
1173
  case TAB:
1218
- this._menuStack.closeAll();
1174
+ this._menuStack?.closeAll();
1219
1175
  break;
1220
1176
  default:
1221
1177
  keyManager.onKeydown(event);
1222
1178
  }
1223
1179
  }
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
1180
  /**
1236
1181
  * Complete the change emitter if there are any nested MenuGroups or register to complete the
1237
1182
  * change emitter if a MenuGroup is rendered at some point
@@ -1279,10 +1224,10 @@ class CdkMenu extends CdkMenuGroup {
1279
1224
  }
1280
1225
  /** Subscribe to the MenuStack close and empty observables. */
1281
1226
  _subscribeToMenuStack() {
1282
- this._menuStack.closed
1227
+ this._menuStack?.closed
1283
1228
  .pipe(takeUntil(this.closed))
1284
1229
  .subscribe(item => this._closeOpenMenu(item));
1285
- this._menuStack.emptied
1230
+ this._menuStack?.emptied
1286
1231
  .pipe(takeUntil(this.closed))
1287
1232
  .subscribe(event => this._toggleMenuFocus(event));
1288
1233
  }
@@ -1347,9 +1292,7 @@ class CdkMenu extends CdkMenuGroup {
1347
1292
  * always visible in the dom.
1348
1293
  */
1349
1294
  _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;
1295
+ return !this._menuStack;
1353
1296
  }
1354
1297
  ngOnDestroy() {
1355
1298
  super.ngOnDestroy();
@@ -1362,12 +1305,12 @@ class CdkMenu extends CdkMenuGroup {
1362
1305
  this.closed.complete();
1363
1306
  }
1364
1307
  }
1365
- CdkMenu.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", 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: [
1308
+ CdkMenu.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenu, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: MENU_STACK, optional: true }, { token: MENU_TRIGGER, optional: true }, { token: MENU_AIM, optional: true, self: true }, { token: i1$1.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1309
+ CdkMenu.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", type: CdkMenu, selector: "[cdkMenu]", inputs: { orientation: ["cdkMenuOrientation", "orientation"] }, 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: [
1367
1310
  { provide: CdkMenuGroup, useExisting: CdkMenu },
1368
1311
  { provide: CDK_MENU, useExisting: CdkMenu },
1369
1312
  ], 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.4", ngImport: i0, type: CdkMenu, decorators: [{
1313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenu, decorators: [{
1371
1314
  type: Directive,
1372
1315
  args: [{
1373
1316
  selector: '[cdkMenu]',
@@ -1386,16 +1329,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1386
1329
  { provide: CDK_MENU, useExisting: CdkMenu },
1387
1330
  ],
1388
1331
  }]
1389
- }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: undefined, decorators: [{
1332
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: MenuStack, decorators: [{
1333
+ type: Optional
1334
+ }, {
1335
+ type: Inject,
1336
+ args: [MENU_STACK]
1337
+ }] }, { type: MenuTrigger, decorators: [{
1338
+ type: Optional
1339
+ }, {
1340
+ type: Inject,
1341
+ args: [MENU_TRIGGER]
1342
+ }] }, { type: undefined, decorators: [{
1390
1343
  type: Self
1391
1344
  }, {
1392
1345
  type: Optional
1393
1346
  }, {
1394
1347
  type: Inject,
1395
1348
  args: [MENU_AIM]
1396
- }] }, { type: i2.Directionality, decorators: [{
1397
- type: Optional
1398
- }] }, { type: CdkMenuPanel, decorators: [{
1349
+ }] }, { type: i1$1.Directionality, decorators: [{
1399
1350
  type: Optional
1400
1351
  }] }]; }, propDecorators: { orientation: [{
1401
1352
  type: Input,
@@ -1408,9 +1359,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1408
1359
  }], _allItems: [{
1409
1360
  type: ContentChildren,
1410
1361
  args: [CdkMenuItem, { descendants: true }]
1411
- }], _explicitPanel: [{
1412
- type: Input,
1413
- args: ['cdkMenuPanel']
1414
1362
  }] } });
1415
1363
 
1416
1364
  /**
@@ -1427,11 +1375,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1427
1375
  *
1428
1376
  */
1429
1377
  class CdkMenuBar extends CdkMenuGroup {
1430
- constructor(_menuStack, _ngZone, _elementRef, _menuAim, _dir) {
1378
+ constructor(_ngZone, _elementRef, _menuStack, _menuAim, _dir) {
1431
1379
  super();
1432
- this._menuStack = _menuStack;
1433
1380
  this._ngZone = _ngZone;
1434
1381
  this._elementRef = _elementRef;
1382
+ this._menuStack = _menuStack;
1435
1383
  this._menuAim = _menuAim;
1436
1384
  this._dir = _dir;
1437
1385
  /**
@@ -1608,13 +1556,13 @@ class CdkMenuBar extends CdkMenuGroup {
1608
1556
  this._pointerTracker?.destroy();
1609
1557
  }
1610
1558
  }
1611
- CdkMenuBar.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", 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: [
1559
+ CdkMenuBar.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", 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 });
1560
+ CdkMenuBar.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", 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: [
1613
1561
  { provide: CdkMenuGroup, useExisting: CdkMenuBar },
1614
1562
  { provide: CDK_MENU, useExisting: CdkMenuBar },
1615
- { provide: MenuStack, useClass: MenuStack },
1563
+ { provide: MENU_STACK, useClass: MenuStack },
1616
1564
  ], 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.4", ngImport: i0, type: CdkMenuBar, decorators: [{
1565
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuBar, decorators: [{
1618
1566
  type: Directive,
1619
1567
  args: [{
1620
1568
  selector: '[cdkMenuBar]',
@@ -1630,17 +1578,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1630
1578
  providers: [
1631
1579
  { provide: CdkMenuGroup, useExisting: CdkMenuBar },
1632
1580
  { provide: CDK_MENU, useExisting: CdkMenuBar },
1633
- { provide: MenuStack, useClass: MenuStack },
1581
+ { provide: MENU_STACK, useClass: MenuStack },
1634
1582
  ],
1635
1583
  }]
1636
- }], ctorParameters: function () { return [{ type: MenuStack }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: undefined, decorators: [{
1584
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: MenuStack, decorators: [{
1585
+ type: Inject,
1586
+ args: [MENU_STACK]
1587
+ }] }, { type: undefined, decorators: [{
1637
1588
  type: Self
1638
1589
  }, {
1639
1590
  type: Optional
1640
1591
  }, {
1641
1592
  type: Inject,
1642
1593
  args: [MENU_AIM]
1643
- }] }, { type: i2.Directionality, decorators: [{
1594
+ }] }, { type: i1$1.Directionality, decorators: [{
1644
1595
  type: Optional
1645
1596
  }] }]; }, propDecorators: { orientation: [{
1646
1597
  type: Input,
@@ -1663,12 +1614,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1663
1614
  * or `CdkMenuGroup` comprise a radio group with unique selection enforced.
1664
1615
  */
1665
1616
  class CdkMenuItemRadio extends CdkMenuItemSelectable {
1666
- constructor(_selectionDispatcher, element, ngZone, parentMenu, menuAim, dir,
1617
+ constructor(_selectionDispatcher, element, ngZone, menuStack, parentMenu, menuAim, dir,
1667
1618
  /** Reference to the CdkMenuItemTrigger directive if one is added to the same element */
1668
1619
  // `CdkMenuItemRadio` is commonly used in combination with a `CdkMenuItemTrigger`.
1669
1620
  // tslint:disable-next-line: lightweight-tokens
1670
1621
  menuTrigger) {
1671
- super(element, ngZone, parentMenu, menuAim, dir, menuTrigger);
1622
+ super(element, ngZone, menuStack, parentMenu, menuAim, dir, menuTrigger);
1672
1623
  this._selectionDispatcher = _selectionDispatcher;
1673
1624
  this._registerDispatcherListener();
1674
1625
  }
@@ -1688,12 +1639,12 @@ class CdkMenuItemRadio extends CdkMenuItemSelectable {
1688
1639
  this._removeDispatcherListener();
1689
1640
  }
1690
1641
  }
1691
- CdkMenuItemRadio.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", type: CdkMenuItemRadio, selector: "[cdkMenuItemRadio]", host: { attributes: { "type": "button", "role": "menuitemradio" }, properties: { "tabindex": "_tabindex", "attr.aria-checked": "checked || null", "attr.aria-disabled": "disabled || null" } }, providers: [
1642
+ CdkMenuItemRadio.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItemRadio, deps: [{ token: i1$2.UniqueSelectionDispatcher }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: MENU_STACK, optional: true }, { 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 });
1643
+ CdkMenuItemRadio.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", 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
1644
  { provide: CdkMenuItemSelectable, useExisting: CdkMenuItemRadio },
1694
1645
  { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
1695
1646
  ], exportAs: ["cdkMenuItemRadio"], usesInheritance: true, ngImport: i0 });
1696
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuItemRadio, decorators: [{
1647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItemRadio, decorators: [{
1697
1648
  type: Directive,
1698
1649
  args: [{
1699
1650
  selector: '[cdkMenuItemRadio]',
@@ -1710,7 +1661,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1710
1661
  { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
1711
1662
  ],
1712
1663
  }]
1713
- }], ctorParameters: function () { return [{ type: i1$1.UniqueSelectionDispatcher }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
1664
+ }], ctorParameters: function () { return [{ type: i1$2.UniqueSelectionDispatcher }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: MenuStack, decorators: [{
1665
+ type: Optional
1666
+ }, {
1667
+ type: Inject,
1668
+ args: [MENU_STACK]
1669
+ }] }, { type: undefined, decorators: [{
1714
1670
  type: Optional
1715
1671
  }, {
1716
1672
  type: Inject,
@@ -1720,7 +1676,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1720
1676
  }, {
1721
1677
  type: Inject,
1722
1678
  args: [MENU_AIM]
1723
- }] }, { type: i2.Directionality, decorators: [{
1679
+ }] }, { type: i1$1.Directionality, decorators: [{
1724
1680
  type: Optional
1725
1681
  }] }, { type: CdkMenuItemTrigger, decorators: [{
1726
1682
  type: Self
@@ -1748,12 +1704,12 @@ class CdkMenuItemCheckbox extends CdkMenuItemSelectable {
1748
1704
  }
1749
1705
  }
1750
1706
  }
1751
- CdkMenuItemCheckbox.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuItemCheckbox, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1752
- CdkMenuItemCheckbox.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.4", type: CdkMenuItemCheckbox, selector: "[cdkMenuItemCheckbox]", host: { attributes: { "type": "button", "role": "menuitemcheckbox" }, properties: { "tabindex": "_tabindex", "attr.aria-checked": "checked || null", "attr.aria-disabled": "disabled || null" } }, providers: [
1707
+ CdkMenuItemCheckbox.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItemCheckbox, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1708
+ CdkMenuItemCheckbox.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", 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
1709
  { provide: CdkMenuItemSelectable, useExisting: CdkMenuItemCheckbox },
1754
1710
  { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
1755
1711
  ], exportAs: ["cdkMenuItemCheckbox"], usesInheritance: true, ngImport: i0 });
1756
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuItemCheckbox, decorators: [{
1712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuItemCheckbox, decorators: [{
1757
1713
  type: Directive,
1758
1714
  args: [{
1759
1715
  selector: '[cdkMenuItemCheckbox]',
@@ -1779,6 +1735,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
1779
1735
  * Use of this source code is governed by an MIT-style license that can be
1780
1736
  * found in the LICENSE file at https://angular.io/license
1781
1737
  */
1738
+ // In cases where the first menu item in the context menu is a trigger the submenu opens on a
1739
+ // hover event. We offset the context menu 2px by default to prevent this from occurring.
1740
+ const CONTEXT_MENU_POSITIONS = STANDARD_DROPDOWN_BELOW_POSITIONS.map(position => {
1741
+ const offsetX = position.overlayX === 'start' ? 2 : -2;
1742
+ const offsetY = position.overlayY === 'top' ? 2 : -2;
1743
+ return { ...position, offsetX, offsetY };
1744
+ });
1782
1745
  /** Tracks the last open context menu trigger across the entire application. */
1783
1746
  class ContextMenuTracker {
1784
1747
  /**
@@ -1792,25 +1755,23 @@ class ContextMenuTracker {
1792
1755
  }
1793
1756
  }
1794
1757
  }
1795
- ContextMenuTracker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: ContextMenuTracker, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1796
- ContextMenuTracker.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: ContextMenuTracker, providedIn: 'root' });
1797
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: ContextMenuTracker, decorators: [{
1758
+ ContextMenuTracker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: ContextMenuTracker, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1759
+ ContextMenuTracker.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: ContextMenuTracker, providedIn: 'root' });
1760
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: ContextMenuTracker, decorators: [{
1798
1761
  type: Injectable,
1799
1762
  args: [{ providedIn: 'root' }]
1800
1763
  }] });
1801
- /** Injection token for the ContextMenu options object. */
1802
- const CDK_CONTEXT_MENU_DEFAULT_OPTIONS = new InjectionToken('cdk-context-menu-default-options');
1803
1764
  /**
1804
1765
  * A directive which when placed on some element opens a the Menu it is bound to when a user
1805
1766
  * right-clicks within that element. It is aware of nested Context Menus and the lowest level
1806
1767
  * non-disabled context menu will trigger.
1807
1768
  */
1808
- class CdkContextMenuTrigger {
1809
- constructor(_viewContainerRef, _overlay, _contextMenuTracker, _options, _directionality) {
1769
+ class CdkContextMenuTrigger extends MenuTrigger {
1770
+ constructor(injector, _viewContainerRef, _overlay, _contextMenuTracker, menuStack, _directionality) {
1771
+ super(injector, menuStack);
1810
1772
  this._viewContainerRef = _viewContainerRef;
1811
1773
  this._overlay = _overlay;
1812
1774
  this._contextMenuTracker = _contextMenuTracker;
1813
- this._options = _options;
1814
1775
  this._directionality = _directionality;
1815
1776
  /** Emits when the attached menu is requested to open. */
1816
1777
  this.opened = new EventEmitter();
@@ -1821,25 +1782,10 @@ class CdkContextMenuTrigger {
1821
1782
  this._overlayRef = null;
1822
1783
  /** Emits when the element is destroyed. */
1823
1784
  this._destroyed = new Subject();
1824
- /** The menu stack for this trigger and its associated menus. */
1825
- this._menuStack = new MenuStack();
1826
1785
  /** Emits when the outside pointer events listener on the overlay should be stopped. */
1827
1786
  this._stopOutsideClicksListener = merge(this.closed, this._destroyed);
1828
1787
  this._setMenuStackListener();
1829
1788
  }
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
1789
  /** Whether the context menu should be disabled. */
1844
1790
  get disabled() {
1845
1791
  return this._disabled;
@@ -1861,7 +1807,7 @@ class CdkContextMenuTrigger {
1861
1807
  else if (this.isOpen()) {
1862
1808
  // since we're moving this menu we need to close any submenus first otherwise they end up
1863
1809
  // disconnected from this one.
1864
- this._menuStack.closeSubMenuOf(this._menuPanel._menu);
1810
+ this.menuStack.closeSubMenuOf(this.childMenu);
1865
1811
  this._overlayRef.getConfig().positionStrategy.setOrigin(coordinates);
1866
1812
  this._overlayRef.updatePosition();
1867
1813
  }
@@ -1880,7 +1826,7 @@ class CdkContextMenuTrigger {
1880
1826
  }
1881
1827
  /** Close the opened menu. */
1882
1828
  close() {
1883
- this._menuStack.closeAll();
1829
+ this.menuStack.closeAll();
1884
1830
  }
1885
1831
  /**
1886
1832
  * Open the context menu and close any previously open menus.
@@ -1898,13 +1844,13 @@ class CdkContextMenuTrigger {
1898
1844
  this._open({ x: event.clientX, y: event.clientY }, true);
1899
1845
  // A context menu can be triggered via a mouse right click or a keyboard shortcut.
1900
1846
  if (event.button === 2) {
1901
- this._menuPanel._menu?.focusFirstItem('mouse');
1847
+ this.childMenu?.focusFirstItem('mouse');
1902
1848
  }
1903
1849
  else if (event.button === 0) {
1904
- this._menuPanel._menu?.focusFirstItem('keyboard');
1850
+ this.childMenu?.focusFirstItem('keyboard');
1905
1851
  }
1906
1852
  else {
1907
- this._menuPanel._menu?.focusFirstItem('program');
1853
+ this.childMenu?.focusFirstItem('program');
1908
1854
  }
1909
1855
  }
1910
1856
  }
@@ -1931,37 +1877,23 @@ class CdkContextMenuTrigger {
1931
1877
  return this._overlay
1932
1878
  .position()
1933
1879
  .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
- ];
1880
+ .withPositions(this.menuPosition ?? CONTEXT_MENU_POSITIONS);
1949
1881
  }
1950
1882
  /**
1951
1883
  * Get the portal to be attached to the overlay which contains the menu. Allows for the menu
1952
1884
  * content to change dynamically and be reflected in the application.
1953
1885
  */
1954
1886
  _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);
1887
+ const hasMenuContentChanged = this._menuTemplateRef !== this._menuPortal?.templateRef;
1888
+ if (this._menuTemplateRef && (!this._menuPortal || hasMenuContentChanged)) {
1889
+ this._menuPortal = new TemplatePortal(this._menuTemplateRef, this._viewContainerRef, undefined, this.getChildMenuInjector());
1958
1890
  }
1959
- return this._panelContent;
1891
+ return this._menuPortal;
1960
1892
  }
1961
1893
  /** Subscribe to the menu stack close events and close this menu when requested. */
1962
1894
  _setMenuStackListener() {
1963
- this._menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
1964
- if (item === this._menuPanel._menu && this.isOpen()) {
1895
+ this.menuStack.closed.pipe(takeUntil(this._destroyed)).subscribe(item => {
1896
+ if (item === this.childMenu && this.isOpen()) {
1965
1897
  this.closed.next();
1966
1898
  this._overlayRef.detach();
1967
1899
  }
@@ -1982,14 +1914,13 @@ class CdkContextMenuTrigger {
1982
1914
  }
1983
1915
  outsideClicks.pipe(takeUntil(this._stopOutsideClicksListener)).subscribe(event => {
1984
1916
  if (!isClickInsideMenuOverlay(event.target)) {
1985
- this._menuStack.closeAll();
1917
+ this.menuStack.closeAll();
1986
1918
  }
1987
1919
  });
1988
1920
  }
1989
1921
  }
1990
1922
  ngOnDestroy() {
1991
1923
  this._destroyOverlay();
1992
- this._resetPanelMenuStack();
1993
1924
  this._destroyed.next();
1994
1925
  this._destroyed.complete();
1995
1926
  }
@@ -2000,26 +1931,13 @@ class CdkContextMenuTrigger {
2000
1931
  this._overlayRef = null;
2001
1932
  }
2002
1933
  }
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
1934
  }
2016
- CdkContextMenuTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", 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.4", 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.4", ngImport: i0, type: CdkContextMenuTrigger, decorators: [{
1935
+ CdkContextMenuTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", 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 });
1936
+ CdkContextMenuTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "14.0.0-next.6", type: CdkContextMenuTrigger, selector: "[cdkContextMenuTriggerFor]", inputs: { _menuTemplateRef: ["cdkContextMenuTriggerFor", "_menuTemplateRef"], menuPosition: ["cdkMenuPosition", "menuPosition"], disabled: ["cdkContextMenuDisabled", "disabled"] }, outputs: { opened: "cdkContextMenuOpened", closed: "cdkContextMenuClosed" }, host: { listeners: { "contextmenu": "_openOnContextMenu($event)" } }, providers: [
1937
+ { provide: MENU_TRIGGER, useExisting: CdkContextMenuTrigger },
1938
+ { provide: MENU_STACK, useClass: MenuStack },
1939
+ ], exportAs: ["cdkContextMenuTriggerFor"], usesInheritance: true, ngImport: i0 });
1940
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkContextMenuTrigger, decorators: [{
2023
1941
  type: Directive,
2024
1942
  args: [{
2025
1943
  selector: '[cdkContextMenuTriggerFor]',
@@ -2028,19 +1946,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
2028
1946
  '(contextmenu)': '_openOnContextMenu($event)',
2029
1947
  },
2030
1948
  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 } },
1949
+ { provide: MENU_TRIGGER, useExisting: CdkContextMenuTrigger },
1950
+ { provide: MENU_STACK, useClass: MenuStack },
2034
1951
  ],
2035
1952
  }]
2036
- }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: ContextMenuTracker }, { type: undefined, decorators: [{
1953
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: ContextMenuTracker }, { type: MenuStack, decorators: [{
2037
1954
  type: Inject,
2038
- args: [CDK_CONTEXT_MENU_DEFAULT_OPTIONS]
2039
- }] }, { type: i2.Directionality, decorators: [{
1955
+ args: [MENU_STACK]
1956
+ }] }, { type: i1$1.Directionality, decorators: [{
2040
1957
  type: Optional
2041
- }] }]; }, propDecorators: { menuPanel: [{
1958
+ }] }]; }, propDecorators: { _menuTemplateRef: [{
2042
1959
  type: Input,
2043
1960
  args: ['cdkContextMenuTriggerFor']
1961
+ }], menuPosition: [{
1962
+ type: Input,
1963
+ args: ['cdkMenuPosition']
2044
1964
  }], opened: [{
2045
1965
  type: Output,
2046
1966
  args: ['cdkContextMenuOpened']
@@ -2062,7 +1982,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
2062
1982
  const EXPORTED_DECLARATIONS = [
2063
1983
  CdkMenuBar,
2064
1984
  CdkMenu,
2065
- CdkMenuPanel,
2066
1985
  CdkMenuItem,
2067
1986
  CdkMenuItemRadio,
2068
1987
  CdkMenuItemCheckbox,
@@ -2073,10 +1992,9 @@ const EXPORTED_DECLARATIONS = [
2073
1992
  ];
2074
1993
  class CdkMenuModule {
2075
1994
  }
2076
- CdkMenuModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2077
- CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuModule, declarations: [CdkMenuBar,
1995
+ CdkMenuModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1996
+ CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuModule, declarations: [CdkMenuBar,
2078
1997
  CdkMenu,
2079
- CdkMenuPanel,
2080
1998
  CdkMenuItem,
2081
1999
  CdkMenuItemRadio,
2082
2000
  CdkMenuItemCheckbox,
@@ -2085,7 +2003,6 @@ CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version:
2085
2003
  CdkContextMenuTrigger,
2086
2004
  CdkTargetMenuAim], imports: [OverlayModule], exports: [CdkMenuBar,
2087
2005
  CdkMenu,
2088
- CdkMenuPanel,
2089
2006
  CdkMenuItem,
2090
2007
  CdkMenuItemRadio,
2091
2008
  CdkMenuItemCheckbox,
@@ -2093,8 +2010,8 @@ CdkMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version:
2093
2010
  CdkMenuGroup,
2094
2011
  CdkContextMenuTrigger,
2095
2012
  CdkTargetMenuAim] });
2096
- CdkMenuModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuModule, imports: [[OverlayModule]] });
2097
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4", ngImport: i0, type: CdkMenuModule, decorators: [{
2013
+ CdkMenuModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuModule, imports: [[OverlayModule]] });
2014
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.6", ngImport: i0, type: CdkMenuModule, decorators: [{
2098
2015
  type: NgModule,
2099
2016
  args: [{
2100
2017
  imports: [OverlayModule],
@@ -2123,5 +2040,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.4",
2123
2040
  * Generated bundle index. Do not edit.
2124
2041
  */
2125
2042
 
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 };
2043
+ 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
2044
  //# sourceMappingURL=menu.mjs.map