@ng-matero/extensions 14.2.1 → 14.3.0

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 (134) hide show
  1. package/esm2020/alert/alert.component.mjs +3 -3
  2. package/esm2020/alert/alert.module.mjs +4 -4
  3. package/esm2020/button/button-loading.directive.mjs +3 -3
  4. package/esm2020/button/button.module.mjs +4 -4
  5. package/esm2020/checkbox-group/checkbox-group.component.mjs +3 -3
  6. package/esm2020/checkbox-group/checkbox-group.module.mjs +4 -4
  7. package/esm2020/colorpicker/colorpicker-input.mjs +3 -3
  8. package/esm2020/colorpicker/colorpicker-module.mjs +4 -4
  9. package/esm2020/colorpicker/colorpicker-toggle.mjs +6 -6
  10. package/esm2020/colorpicker/colorpicker.mjs +6 -6
  11. package/esm2020/column-resize/column-resize-directives/column-resize-flex.mjs +3 -3
  12. package/esm2020/column-resize/column-resize-directives/column-resize.mjs +3 -3
  13. package/esm2020/column-resize/column-resize-module.mjs +4 -4
  14. package/esm2020/column-resize/column-resize-notifier.mjs +6 -6
  15. package/esm2020/column-resize/column-resize.mjs +3 -3
  16. package/esm2020/column-resize/column-size-store.mjs +3 -3
  17. package/esm2020/column-resize/event-dispatcher.mjs +3 -3
  18. package/esm2020/column-resize/overlay-handle.mjs +3 -3
  19. package/esm2020/column-resize/resizable.mjs +3 -3
  20. package/esm2020/column-resize/resize-strategy.mjs +9 -9
  21. package/esm2020/core/datetime/datetime.module.mjs +8 -8
  22. package/esm2020/core/datetime/native-datetime-adapter.mjs +3 -3
  23. package/esm2020/core/pipes/pipes.module.mjs +4 -4
  24. package/esm2020/core/pipes/to-observable.pipe.mjs +3 -3
  25. package/esm2020/datetimepicker/calendar-body.mjs +3 -3
  26. package/esm2020/datetimepicker/calendar.mjs +3 -3
  27. package/esm2020/datetimepicker/clock.mjs +3 -3
  28. package/esm2020/datetimepicker/datetimepicker-input.mjs +3 -3
  29. package/esm2020/datetimepicker/datetimepicker-module.mjs +4 -4
  30. package/esm2020/datetimepicker/datetimepicker-toggle.mjs +6 -6
  31. package/esm2020/datetimepicker/datetimepicker.mjs +6 -6
  32. package/esm2020/datetimepicker/month-view.mjs +3 -3
  33. package/esm2020/datetimepicker/multi-year-view.mjs +3 -3
  34. package/esm2020/datetimepicker/year-view.mjs +3 -3
  35. package/esm2020/dialog/dialog.component.mjs +3 -3
  36. package/esm2020/dialog/dialog.mjs +3 -3
  37. package/esm2020/dialog/dialog.module.mjs +4 -4
  38. package/esm2020/drawer/drawer-container.mjs +3 -3
  39. package/esm2020/drawer/drawer-module.mjs +4 -4
  40. package/esm2020/drawer/drawer.mjs +3 -3
  41. package/esm2020/form-group/form-group.component.mjs +3 -3
  42. package/esm2020/form-group/form-group.module.mjs +4 -4
  43. package/esm2020/grid/cell.component.mjs +3 -3
  44. package/esm2020/grid/column-menu.component.mjs +13 -19
  45. package/esm2020/grid/column-resize/column-resize-directives/column-resize-flex.mjs +3 -3
  46. package/esm2020/grid/column-resize/column-resize-directives/column-resize.mjs +3 -3
  47. package/esm2020/grid/column-resize/column-resize-module.mjs +8 -8
  48. package/esm2020/grid/column-resize/overlay-handle.mjs +3 -3
  49. package/esm2020/grid/column-resize/resizable-directives/resizable.mjs +3 -3
  50. package/esm2020/grid/column-resize/resize-strategy.mjs +3 -3
  51. package/esm2020/grid/expansion-toggle.directive.mjs +3 -3
  52. package/esm2020/grid/grid.component.mjs +8 -8
  53. package/esm2020/grid/grid.module.mjs +4 -4
  54. package/esm2020/grid/grid.service.mjs +3 -3
  55. package/esm2020/loader/loader.component.mjs +3 -3
  56. package/esm2020/loader/loader.module.mjs +4 -4
  57. package/esm2020/popover/popover-animations.mjs +10 -13
  58. package/esm2020/popover/popover-content.mjs +90 -0
  59. package/esm2020/popover/popover-interfaces.mjs +1 -1
  60. package/esm2020/popover/popover-module.mjs +11 -9
  61. package/esm2020/popover/popover-target.mjs +6 -6
  62. package/esm2020/popover/popover-trigger.mjs +215 -185
  63. package/esm2020/popover/popover-types.mjs +1 -1
  64. package/esm2020/popover/popover.mjs +187 -134
  65. package/esm2020/popover/public-api.mjs +2 -1
  66. package/esm2020/progress/progress.component.mjs +3 -3
  67. package/esm2020/progress/progress.module.mjs +4 -4
  68. package/esm2020/select/option.component.mjs +3 -3
  69. package/esm2020/select/select.component.mjs +3 -3
  70. package/esm2020/select/select.module.mjs +4 -4
  71. package/esm2020/select/templates.directive.mjs +33 -33
  72. package/esm2020/slider/slider-module.mjs +4 -4
  73. package/esm2020/slider/slider.mjs +3 -3
  74. package/esm2020/split/split-pane.directive.mjs +3 -3
  75. package/esm2020/split/split.component.mjs +3 -3
  76. package/esm2020/split/split.module.mjs +4 -4
  77. package/esm2020/text3d/text3d.component.mjs +3 -3
  78. package/esm2020/text3d/text3d.module.mjs +4 -4
  79. package/esm2020/tooltip/tooltip-module.mjs +4 -4
  80. package/esm2020/tooltip/tooltip.mjs +6 -6
  81. package/fesm2015/mtxAlert.mjs +7 -7
  82. package/fesm2015/mtxButton.mjs +7 -7
  83. package/fesm2015/mtxCheckboxGroup.mjs +7 -7
  84. package/fesm2015/mtxColorpicker.mjs +19 -19
  85. package/fesm2015/mtxColumnResize.mjs +40 -40
  86. package/fesm2015/mtxCore.mjs +18 -18
  87. package/fesm2015/mtxDatetimepicker.mjs +37 -37
  88. package/fesm2015/mtxDialog.mjs +10 -10
  89. package/fesm2015/mtxDrawer.mjs +10 -10
  90. package/fesm2015/mtxFormGroup.mjs +7 -7
  91. package/fesm2015/mtxGrid.mjs +55 -61
  92. package/fesm2015/mtxGrid.mjs.map +1 -1
  93. package/fesm2015/mtxLoader.mjs +7 -7
  94. package/fesm2015/mtxPopover.mjs +525 -359
  95. package/fesm2015/mtxPopover.mjs.map +1 -1
  96. package/fesm2015/mtxProgress.mjs +7 -7
  97. package/fesm2015/mtxSelect.mjs +43 -43
  98. package/fesm2015/mtxSlider.mjs +7 -7
  99. package/fesm2015/mtxSplit.mjs +10 -10
  100. package/fesm2015/mtxText3d.mjs +7 -7
  101. package/fesm2015/mtxTooltip.mjs +10 -10
  102. package/fesm2020/mtxAlert.mjs +7 -7
  103. package/fesm2020/mtxButton.mjs +7 -7
  104. package/fesm2020/mtxCheckboxGroup.mjs +7 -7
  105. package/fesm2020/mtxColorpicker.mjs +19 -19
  106. package/fesm2020/mtxColumnResize.mjs +40 -40
  107. package/fesm2020/mtxCore.mjs +18 -18
  108. package/fesm2020/mtxDatetimepicker.mjs +37 -37
  109. package/fesm2020/mtxDialog.mjs +10 -10
  110. package/fesm2020/mtxDrawer.mjs +10 -10
  111. package/fesm2020/mtxFormGroup.mjs +7 -7
  112. package/fesm2020/mtxGrid.mjs +55 -61
  113. package/fesm2020/mtxGrid.mjs.map +1 -1
  114. package/fesm2020/mtxLoader.mjs +7 -7
  115. package/fesm2020/mtxPopover.mjs +519 -357
  116. package/fesm2020/mtxPopover.mjs.map +1 -1
  117. package/fesm2020/mtxProgress.mjs +7 -7
  118. package/fesm2020/mtxSelect.mjs +43 -43
  119. package/fesm2020/mtxSlider.mjs +7 -7
  120. package/fesm2020/mtxSplit.mjs +10 -10
  121. package/fesm2020/mtxText3d.mjs +7 -7
  122. package/fesm2020/mtxTooltip.mjs +10 -10
  123. package/grid/column-menu.component.d.ts +4 -6
  124. package/package.json +1 -1
  125. package/popover/popover-animations.d.ts +1 -1
  126. package/popover/popover-content.d.ts +43 -0
  127. package/popover/popover-interfaces.d.ts +37 -31
  128. package/popover/popover-module.d.ts +4 -3
  129. package/popover/popover-target.d.ts +2 -2
  130. package/popover/popover-trigger.d.ts +67 -62
  131. package/popover/popover-types.d.ts +6 -1
  132. package/popover/popover.d.ts +99 -71
  133. package/popover/popover.scss +2 -0
  134. package/popover/public-api.d.ts +1 -0
@@ -1,18 +1,127 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, TemplateRef, Component, ChangeDetectionStrategy, ViewEncapsulation, Optional, HostBinding, Input, Output, ViewChild, Directive, HostListener, NgModule } from '@angular/core';
3
- import * as i2 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
2
+ import { InjectionToken, Directive, Inject, EventEmitter, TemplateRef, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Output, ViewChild, ContentChild, Optional, NgModule } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { DOCUMENT, CommonModule } from '@angular/common';
5
5
  import * as i1$1 from '@angular/cdk/overlay';
6
- import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
6
+ import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
7
7
  import * as i3 from '@angular/cdk/a11y';
8
8
  import { isFakeMousedownFromScreenReader, A11yModule } from '@angular/cdk/a11y';
9
9
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
10
- import { ESCAPE } from '@angular/cdk/keycodes';
10
+ import { ESCAPE, hasModifierKey, ENTER, SPACE } from '@angular/cdk/keycodes';
11
+ import { Subject, Subscription, of, merge } from 'rxjs';
11
12
  import { trigger, state, style, transition, animate } from '@angular/animations';
12
- import * as i1 from '@angular/cdk/bidi';
13
- import { TemplatePortal } from '@angular/cdk/portal';
14
- import { Subject } from 'rxjs';
15
- import { takeUntil } from 'rxjs/operators';
13
+ import { TemplatePortal, DomPortalOutlet } from '@angular/cdk/portal';
14
+ import { filter, take, takeUntil } from 'rxjs/operators';
15
+ import * as i2 from '@angular/cdk/bidi';
16
+
17
+ /**
18
+ * Below are all the animations for the mtx-popover component.
19
+ * Animation duration and timing values are based on AngularJS Material.
20
+ */
21
+ /**
22
+ * This animation controls the popover panel's entry and exit from the page.
23
+ *
24
+ * When the popover panel is added to the DOM, it scales in and fades in its border.
25
+ *
26
+ * When the popover panel is removed from the DOM, it simply fades out after a brief
27
+ * delay to display the ripple.
28
+ */
29
+ const transformPopover = trigger('transformPopover', [
30
+ state('void', style({
31
+ opacity: 0,
32
+ transform: 'scale(0.8)',
33
+ })),
34
+ transition('void => enter', animate('120ms cubic-bezier(0, 0, 0.2, 1)', style({
35
+ opacity: 1,
36
+ transform: 'scale(1)',
37
+ }))),
38
+ transition('* => void', animate('100ms 25ms linear', style({ opacity: 0 }))),
39
+ ]);
40
+
41
+ /**
42
+ * Injection token that can be used to reference instances of `MtxPopoverContent`. It serves
43
+ * as alternative token to the actual `MtxPopoverContent` class which could cause unnecessary
44
+ * retention of the class and its directive metadata.
45
+ */
46
+ const MTX_POPOVER_CONTENT = new InjectionToken('MtxPopoverContent');
47
+ class _MtxPopoverContentBase {
48
+ constructor(_template, _componentFactoryResolver, _appRef, _injector, _viewContainerRef, _document, _changeDetectorRef) {
49
+ this._template = _template;
50
+ this._componentFactoryResolver = _componentFactoryResolver;
51
+ this._appRef = _appRef;
52
+ this._injector = _injector;
53
+ this._viewContainerRef = _viewContainerRef;
54
+ this._document = _document;
55
+ this._changeDetectorRef = _changeDetectorRef;
56
+ /** Emits when the popover content has been attached. */
57
+ this._attached = new Subject();
58
+ }
59
+ /**
60
+ * Attaches the content with a particular context.
61
+ * @docs-private
62
+ */
63
+ attach(context = {}) {
64
+ if (!this._portal) {
65
+ this._portal = new TemplatePortal(this._template, this._viewContainerRef);
66
+ }
67
+ this.detach();
68
+ if (!this._outlet) {
69
+ this._outlet = new DomPortalOutlet(this._document.createElement('div'), this._componentFactoryResolver, this._appRef, this._injector);
70
+ }
71
+ const element = this._template.elementRef.nativeElement;
72
+ // Because we support opening the same popover from different triggers (which in turn have their
73
+ // own `OverlayRef` panel), we have to re-insert the host element every time, otherwise we
74
+ // risk it staying attached to a pane that's no longer in the DOM.
75
+ element.parentNode.insertBefore(this._outlet.outletElement, element);
76
+ // When `MtxPopoverContent` is used in an `OnPush` component, the insertion of the popover
77
+ // content via `createEmbeddedView` does not cause the content to be seen as "dirty"
78
+ // by Angular. This causes the `@ContentChildren` for popover items within the popover to
79
+ // not be updated by Angular. By explicitly marking for check here, we tell Angular that
80
+ // it needs to check for new popover items and update the `@ContentChild` in `MtxPopover`.
81
+ // @breaking-change 9.0.0 Make change detector ref required
82
+ if (this._changeDetectorRef) {
83
+ this._changeDetectorRef.markForCheck();
84
+ }
85
+ this._portal.attach(this._outlet, context);
86
+ this._attached.next();
87
+ }
88
+ /**
89
+ * Detaches the content.
90
+ * @docs-private
91
+ */
92
+ detach() {
93
+ if (this._portal.isAttached) {
94
+ this._portal.detach();
95
+ }
96
+ }
97
+ ngOnDestroy() {
98
+ if (this._outlet) {
99
+ this._outlet.dispose();
100
+ }
101
+ }
102
+ }
103
+ /** @nocollapse */ _MtxPopoverContentBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: _MtxPopoverContentBase, deps: [{ token: i0.TemplateRef }, { token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }, { token: i0.ViewContainerRef }, { token: DOCUMENT }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
104
+ /** @nocollapse */ _MtxPopoverContentBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.0", type: _MtxPopoverContentBase, ngImport: i0 });
105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: _MtxPopoverContentBase, decorators: [{
106
+ type: Directive
107
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
108
+ type: Inject,
109
+ args: [DOCUMENT]
110
+ }] }, { type: i0.ChangeDetectorRef }]; } });
111
+ /**
112
+ * Popover content that will be rendered lazily once the popover is opened.
113
+ */
114
+ class MtxPopoverContent extends _MtxPopoverContentBase {
115
+ }
116
+ /** @nocollapse */ MtxPopoverContent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverContent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
117
+ /** @nocollapse */ MtxPopoverContent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.0", type: MtxPopoverContent, selector: "ng-template[mtxPopoverContent]", providers: [{ provide: MTX_POPOVER_CONTENT, useExisting: MtxPopoverContent }], usesInheritance: true, ngImport: i0 });
118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverContent, decorators: [{
119
+ type: Directive,
120
+ args: [{
121
+ selector: 'ng-template[mtxPopoverContent]',
122
+ providers: [{ provide: MTX_POPOVER_CONTENT, useExisting: MtxPopoverContent }],
123
+ }]
124
+ }] });
16
125
 
17
126
  /**
18
127
  * Throws an exception for the case when popover trigger doesn't have a valid mtx-popover instance
@@ -41,190 +150,180 @@ function throwMtxPopoverInvalidPositionEnd() {
41
150
  Example: <mtx-popover [position]="['below', 'after']" #popover="mtxPopover"></mtx-popover>`);
42
151
  }
43
152
 
44
- /**
45
- * Below are all the animations for the md-popover component.
46
- * Animation duration and timing values are based on AngularJS Material.
47
- */
48
- /**
49
- * This animation controls the popover panel's entry and exit from the page.
50
- *
51
- * When the popover panel is added to the DOM, it scales in and fades in its border.
52
- *
53
- * When the popover panel is removed from the DOM, it simply fades out after a brief
54
- * delay to display the ripple.
55
- */
56
- const transformPopover = trigger('transformPopover', [
57
- state('enter', style({
58
- opacity: 1,
59
- transform: `scale(1)`,
60
- })),
61
- transition('void => *', [
62
- style({
63
- opacity: 0,
64
- transform: `scale(0)`,
65
- }),
66
- animate(`200ms cubic-bezier(0.25, 0.8, 0.25, 1)`),
67
- ]),
68
- transition('* => void', [animate('50ms 100ms linear', style({ opacity: 0 }))]),
69
- ]);
70
-
153
+ /** Injection token to be used to override the default options for `mtx-popover`. */
154
+ const MTX_POPOVER_DEFAULT_OPTIONS = new InjectionToken('mtx-popover-default-options', {
155
+ providedIn: 'root',
156
+ factory: MTX_POPOVER_DEFAULT_OPTIONS_FACTORY,
157
+ });
158
+ /** @docs-private */
159
+ function MTX_POPOVER_DEFAULT_OPTIONS_FACTORY() {
160
+ return {
161
+ backdropClass: 'cdk-overlay-transparent-backdrop',
162
+ };
163
+ }
164
+ let popoverPanelUid = 0;
71
165
  class MtxPopover {
72
- constructor(_dir, _elementRef, zone) {
73
- this._dir = _dir;
166
+ constructor(_elementRef, _ngZone, _defaultOptions) {
74
167
  this._elementRef = _elementRef;
75
- this.zone = zone;
76
- this.role = 'dialog';
77
- /** Settings for popover, view setters and getters for more detail */
78
- this._position = ['below', 'after'];
79
- this._triggerEvent = 'hover';
80
- this._scrollStrategy = 'reposition';
81
- this._enterDelay = 100;
82
- this._leaveDelay = 100;
83
- this._panelOffsetX = 0;
84
- this._panelOffsetY = 0;
85
- this._closeOnPanelClick = false;
86
- this._closeOnBackdropClick = true;
87
- this._disableAnimation = false;
88
- this._focusTrapEnabled = true;
89
- this._focusTrapAutoCaptureEnabled = true;
90
- this._arrowOffsetX = 20;
91
- this._arrowOffsetY = 20;
92
- this._arrowWidth = 16;
93
- this._arrowHeight = 16;
94
- /** Config object to be passed into the popover's ngClass */
168
+ this._ngZone = _ngZone;
169
+ this._defaultOptions = _defaultOptions;
170
+ this._triggerEvent = this._defaultOptions.triggerEvent ?? 'hover';
171
+ this._enterDelay = this._defaultOptions.enterDelay ?? 100;
172
+ this._leaveDelay = this._defaultOptions.leaveDelay ?? 100;
173
+ this._position = this._defaultOptions.position ?? ['below', 'after'];
174
+ this._panelOffsetX = this._defaultOptions.xOffset ?? 0;
175
+ this._panelOffsetY = this._defaultOptions.yOffset ?? 0;
176
+ this._arrowWidth = this._defaultOptions.arrowWidth ?? 16;
177
+ this._arrowHeight = this._defaultOptions.arrowHeight ?? 16;
178
+ this._arrowOffsetX = this._defaultOptions.arrowOffsetX ?? 20;
179
+ this._arrowOffsetY = this._defaultOptions.arrowOffsetY ?? 20;
180
+ this._closeOnPanelClick = this._defaultOptions.closeOnPanelClick ?? false;
181
+ this._closeOnBackdropClick = this._defaultOptions.closeOnBackdropClick ?? true;
182
+ this._focusTrapEnabled = this._defaultOptions.focusTrapEnabled ?? false;
183
+ this._focusTrapAutoCaptureEnabled = this._defaultOptions.focusTrapAutoCaptureEnabled ?? false;
184
+ this._hasBackdrop = this._defaultOptions.hasBackdrop;
185
+ this._elevation = this._defaultOptions.elevation ?? 8;
186
+ this._elevationPrefix = 'mat-elevation-z';
187
+ /** Config object to be passed into the popover's ngClass. */
95
188
  this._classList = {};
96
- /** Whether popover's `targetElement` is defined */
97
- this.containerPositioning = false;
189
+ /** Current state of the panel animation. */
190
+ this._panelAnimationState = 'void';
191
+ /** Emits whenever an animation on the popover completes. */
192
+ this._animationDone = new Subject();
193
+ /** Whether the popover is animating. */
194
+ this._isAnimating = false;
98
195
  /** Closing disabled on popover */
99
196
  this.closeDisabled = false;
100
- /** Emits the current animation state whenever it changes. */
101
- this._onAnimationStateChange = new EventEmitter();
197
+ /** Class or list of classes to be added to the overlay panel. */
198
+ this.overlayPanelClass = this._defaultOptions.overlayPanelClass || '';
199
+ /** Class to be added to the backdrop element. */
200
+ this.backdropClass = this._defaultOptions.backdropClass;
102
201
  /** Event emitted when the popover is closed. */
103
202
  this.closed = new EventEmitter();
104
- this.setPositionClasses();
105
- }
106
- /** Position of the popover. */
107
- get position() {
108
- return this._position;
109
- }
110
- set position(value) {
111
- if (!['before', 'after', 'above', 'below'].includes(value[0])) {
112
- throwMtxPopoverInvalidPositionStart();
113
- }
114
- if (!['before', 'after', 'above', 'below', 'center'].includes(value[1])) {
115
- throwMtxPopoverInvalidPositionEnd();
116
- }
117
- this._position = value;
118
- this.setPositionClasses();
203
+ this.panelId = `mtx-popover-panel-${popoverPanelUid++}`;
119
204
  }
120
- /** Popover trigger event */
205
+ /** Popover's trigger event. */
121
206
  get triggerEvent() {
122
207
  return this._triggerEvent;
123
208
  }
124
209
  set triggerEvent(value) {
125
210
  this._triggerEvent = value;
126
211
  }
127
- /** Popover scroll strategy */
128
- get scrollStrategy() {
129
- return this._scrollStrategy;
130
- }
131
- set scrollStrategy(value) {
132
- this._scrollStrategy = value;
133
- }
134
- /** Popover enter delay */
212
+ /** Popover's enter delay. */
135
213
  get enterDelay() {
136
214
  return this._enterDelay;
137
215
  }
138
216
  set enterDelay(value) {
139
217
  this._enterDelay = value;
140
218
  }
141
- /** Popover leave delay */
219
+ /** Popover's leave delay. */
142
220
  get leaveDelay() {
143
221
  return this._leaveDelay;
144
222
  }
145
223
  set leaveDelay(value) {
146
224
  this._leaveDelay = value;
147
225
  }
148
- /** Popover target offset x */
226
+ /** Popover's position. */
227
+ get position() {
228
+ return this._position;
229
+ }
230
+ set position(value) {
231
+ if (!['before', 'after', 'above', 'below'].includes(value[0])) {
232
+ throwMtxPopoverInvalidPositionStart();
233
+ }
234
+ if (!['before', 'after', 'above', 'below', 'center'].includes(value[1])) {
235
+ throwMtxPopoverInvalidPositionEnd();
236
+ }
237
+ this._position = value;
238
+ this.setPositionClasses();
239
+ }
240
+ /** Popover-panel's X offset. */
149
241
  get xOffset() {
150
242
  return this._panelOffsetX;
151
243
  }
152
244
  set xOffset(value) {
153
245
  this._panelOffsetX = value;
154
246
  }
155
- /** Popover target offset y */
247
+ /** Popover-panel's Y offset. */
156
248
  get yOffset() {
157
249
  return this._panelOffsetY;
158
250
  }
159
251
  set yOffset(value) {
160
252
  this._panelOffsetY = value;
161
253
  }
162
- /** Popover arrow offset x */
163
- get arrowOffsetX() {
164
- return this._arrowOffsetX;
165
- }
166
- set arrowOffsetX(value) {
167
- this._arrowOffsetX = value;
168
- }
169
- /** Popover arrow offset y */
170
- get arrowOffsetY() {
171
- return this._arrowOffsetY;
172
- }
173
- set arrowOffsetY(value) {
174
- this._arrowOffsetY = value;
175
- }
176
- /** Popover arrow width */
254
+ /** Popover-arrow's width. */
177
255
  get arrowWidth() {
178
256
  return this._arrowWidth;
179
257
  }
180
258
  set arrowWidth(value) {
181
259
  this._arrowWidth = value;
182
260
  }
183
- /** Popover arrow height */
261
+ /** Popover-arrow's height. */
184
262
  get arrowHeight() {
185
263
  return this._arrowHeight;
186
264
  }
187
265
  set arrowHeight(value) {
188
266
  this._arrowHeight = value;
189
267
  }
190
- /** Popover close on container click */
268
+ /** Popover-arrow's X offset. */
269
+ get arrowOffsetX() {
270
+ return this._arrowOffsetX;
271
+ }
272
+ set arrowOffsetX(value) {
273
+ this._arrowOffsetX = value;
274
+ }
275
+ /** Popover-arrow's Y offset. */
276
+ get arrowOffsetY() {
277
+ return this._arrowOffsetY;
278
+ }
279
+ set arrowOffsetY(value) {
280
+ this._arrowOffsetY = value;
281
+ }
282
+ /** Whether popover can be closed when click the popover-panel. */
191
283
  get closeOnPanelClick() {
192
284
  return this._closeOnPanelClick;
193
285
  }
194
286
  set closeOnPanelClick(value) {
195
287
  this._closeOnPanelClick = coerceBooleanProperty(value);
196
288
  }
197
- /** Popover close on backdrop click */
289
+ /** Whether popover can be closed when click the backdrop. */
198
290
  get closeOnBackdropClick() {
199
291
  return this._closeOnBackdropClick;
200
292
  }
201
293
  set closeOnBackdropClick(value) {
202
294
  this._closeOnBackdropClick = coerceBooleanProperty(value);
203
295
  }
204
- /** Disable animations of popover and all child elements */
205
- get disableAnimation() {
206
- return this._disableAnimation;
207
- }
208
- set disableAnimation(value) {
209
- this._disableAnimation = coerceBooleanProperty(value);
210
- }
211
- /** Popover focus trap using cdkTrapFocus */
296
+ /** Whether enable focus trap using `cdkTrapFocus`. */
212
297
  get focusTrapEnabled() {
213
298
  return this._focusTrapEnabled;
214
299
  }
215
300
  set focusTrapEnabled(value) {
216
301
  this._focusTrapEnabled = coerceBooleanProperty(value);
217
302
  }
218
- /** Popover focus trap auto capture using cdkTrapFocusAutoCapture */
303
+ /** Whether enable focus trap auto capture using `cdkTrapFocusAutoCapture`. */
219
304
  get focusTrapAutoCaptureEnabled() {
220
305
  return this._focusTrapAutoCaptureEnabled;
221
306
  }
222
307
  set focusTrapAutoCaptureEnabled(value) {
223
308
  this._focusTrapAutoCaptureEnabled = coerceBooleanProperty(value);
224
309
  }
310
+ /** Whether the popover has a backdrop. It will always be false if the trigger event is hover. */
311
+ get hasBackdrop() {
312
+ return this._hasBackdrop;
313
+ }
314
+ set hasBackdrop(value) {
315
+ this._hasBackdrop = coerceBooleanProperty(value);
316
+ }
317
+ /** Popover-panel's elevation (0~24). */
318
+ get elevation() {
319
+ return Math.max(0, Math.min(Math.round(this._elevation), 24));
320
+ }
321
+ set elevation(value) {
322
+ this._elevation = value;
323
+ }
225
324
  /**
226
325
  * This method takes classes set on the host md-popover element and applies them on the
227
- * popover template that displays in the overlay container. Otherwise, it's difficult
326
+ * popover template that displays in the overlay container. Otherwise, it's difficult
228
327
  * to style the containing popover from outside the component.
229
328
  * @param classes list of class names
230
329
  */
@@ -240,7 +339,7 @@ class MtxPopover {
240
339
  }
241
340
  /**
242
341
  * This method takes classes set on the host md-popover element and applies them on the
243
- * popover template that displays in the overlay container. Otherwise, it's difficult
342
+ * popover template that displays in the overlay container. Otherwise, it's difficult
244
343
  * to style the containing popover from outside the component.
245
344
  * @deprecated Use `panelClass` instead.
246
345
  * @breaking-change 8.0.0
@@ -251,47 +350,46 @@ class MtxPopover {
251
350
  set classList(classes) {
252
351
  this.panelClass = classes;
253
352
  }
353
+ ngOnInit() {
354
+ this.setPositionClasses();
355
+ }
254
356
  ngOnDestroy() {
255
- this._emitCloseEvent();
256
357
  this.closed.complete();
257
358
  }
258
359
  /** Handle a keyboard event from the popover, delegating to the appropriate action. */
259
360
  _handleKeydown(event) {
260
- switch (event.keyCode) {
361
+ const keyCode = event.keyCode;
362
+ switch (keyCode) {
261
363
  case ESCAPE:
262
- this._emitCloseEvent();
263
- return;
364
+ if (!hasModifierKey(event)) {
365
+ event.preventDefault();
366
+ this.closed.emit('keydown');
367
+ }
368
+ break;
264
369
  }
265
370
  }
266
- /**
267
- * This emits a close event to which the trigger is subscribed. When emitted, the
268
- * trigger will close the popover.
269
- */
270
- _emitCloseEvent() {
271
- this.closed.emit();
272
- }
273
- /** Close popover on click if closeOnPanelClick is true */
274
- onClick() {
371
+ /** Close popover on click if `closeOnPanelClick` is true. */
372
+ _handleClick() {
275
373
  if (this.closeOnPanelClick) {
276
- this._emitCloseEvent();
374
+ this.closed.emit('click');
277
375
  }
278
376
  }
279
- /** Disables close of popover when leaving trigger element and mouse over the popover */
280
- onMouseOver() {
377
+ /** Disables close of popover when leaving trigger element and mouse over the popover. */
378
+ _handleMouseOver() {
281
379
  if (this.triggerEvent === 'hover') {
282
380
  this.closeDisabled = true;
283
381
  }
284
382
  }
285
- /** Enables close of popover when mouse leaving popover element */
286
- onMouseLeave() {
383
+ /** Enables close of popover when mouse leaving popover element. */
384
+ _handleMouseLeave() {
287
385
  if (this.triggerEvent === 'hover') {
288
386
  setTimeout(() => {
289
387
  this.closeDisabled = false;
290
- this._emitCloseEvent();
388
+ this.closed.emit();
291
389
  }, this.leaveDelay);
292
390
  }
293
391
  }
294
- /** Sets the current styles for the popover to allow for dynamically changing settings */
392
+ /** Sets the current styles for the popover to allow for dynamically changing settings. */
295
393
  setCurrentStyles(pos = this.position) {
296
394
  const left = pos[1] === 'after'
297
395
  ? `${this.arrowOffsetX - this.arrowWidth / 2}px`
@@ -305,16 +403,13 @@ class MtxPopover {
305
403
  ? `calc(50% - ${this.arrowHeight / 2}px)`
306
404
  : '';
307
405
  const top = pos[1] === 'below' ? `${this.arrowOffsetY - this.arrowHeight / 2}px` : '';
308
- this.popoverArrowStyles =
406
+ this.arrowStyles =
309
407
  pos[0] === 'above' || pos[0] === 'below'
310
408
  ? {
311
- left: this._dir.value === 'ltr' ? left : right,
312
- right: this._dir.value === 'ltr' ? right : left,
409
+ left: this.direction === 'ltr' ? left : right,
410
+ right: this.direction === 'ltr' ? right : left,
313
411
  }
314
- : {
315
- top,
316
- bottom,
317
- };
412
+ : { top, bottom };
318
413
  }
319
414
  /**
320
415
  * It's necessary to set position-based classes to ensure the popover panel animation
@@ -334,49 +429,85 @@ class MtxPopover {
334
429
  this._classList['mtx-popover-below-center'] = pos[0] === 'below' && pos[1] === 'center';
335
430
  this._classList['mtx-popover-below-after'] = pos[0] === 'below' && pos[1] === 'after';
336
431
  }
432
+ /** Sets the popover-panel's elevation. */
433
+ setElevation() {
434
+ const newElevation = `${this._elevationPrefix}${this.elevation}`;
435
+ if (this._previousElevation) {
436
+ this._classList[this._previousElevation] = false;
437
+ }
438
+ this._classList[newElevation] = true;
439
+ this._previousElevation = newElevation;
440
+ }
441
+ /** Starts the enter animation. */
442
+ _startAnimation() {
443
+ // @breaking-change 8.0.0 Combine with _resetAnimation.
444
+ this._panelAnimationState = 'enter';
445
+ }
446
+ /** Resets the panel animation to its initial state. */
447
+ _resetAnimation() {
448
+ // @breaking-change 8.0.0 Combine with _startAnimation.
449
+ this._panelAnimationState = 'void';
450
+ }
451
+ /** Callback that is invoked when the panel animation completes. */
452
+ _onAnimationDone(event) {
453
+ this._animationDone.next(event);
454
+ this._isAnimating = false;
455
+ }
456
+ _onAnimationStart(event) {
457
+ this._isAnimating = true;
458
+ }
337
459
  }
338
- /** @nocollapse */ MtxPopover.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopover, deps: [{ token: i1.Directionality, optional: true }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
339
- /** @nocollapse */ MtxPopover.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.2", type: MtxPopover, selector: "mtx-popover", inputs: { position: "position", triggerEvent: "triggerEvent", scrollStrategy: "scrollStrategy", enterDelay: "enterDelay", leaveDelay: "leaveDelay", xOffset: "xOffset", yOffset: "yOffset", arrowOffsetX: "arrowOffsetX", arrowOffsetY: "arrowOffsetY", arrowWidth: "arrowWidth", arrowHeight: "arrowHeight", closeOnPanelClick: "closeOnPanelClick", closeOnBackdropClick: "closeOnBackdropClick", disableAnimation: "disableAnimation", focusTrapEnabled: "focusTrapEnabled", focusTrapAutoCaptureEnabled: "focusTrapAutoCaptureEnabled", panelClass: ["class", "panelClass"], classList: "classList" }, outputs: { closed: "closed" }, host: { properties: { "attr.role": "this.role" } }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], exportAs: ["mtxPopover"], ngImport: i0, template: "<ng-template>\r\n <div class=\"mtx-popover-panel mat-elevation-z8\" role=\"dialog\"\r\n [ngClass]=\"_classList\"\r\n [ngStyle]=\"popoverPanelStyles\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (click)=\"onClick()\"\r\n (mouseover)=\"onMouseOver()\"\r\n (mouseleave)=\"onMouseLeave()\"\r\n [@.disabled]=\"disableAnimation\"\r\n [@transformPopover]=\"'enter'\">\r\n <div class=\"mtx-popover-direction-arrow\" [ngStyle]=\"popoverArrowStyles\"></div>\r\n <div class=\"mtx-popover-content\"\r\n [ngStyle]=\"popoverContentStyles\"\r\n [cdkTrapFocus]=\"focusTrapEnabled\"\r\n [cdkTrapFocusAutoCapture]=\"focusTrapAutoCaptureEnabled\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [".mtx-popover-panel{max-height:calc(100vh - 48px);padding:8px;border-radius:4px;font-size:16px}.mtx-popover-panel[class*=mtx-popover-below]{margin-top:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-above]{margin-bottom:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-before]{margin-right:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-before]{margin-right:auto;margin-left:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-after]{margin-left:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-after]{margin-left:auto;margin-right:calc(.5em + 2px)}.mtx-popover-direction-arrow{position:absolute}.mtx-popover-direction-arrow:before,.mtx-popover-direction-arrow:after{position:absolute;display:inline-block;content:\"\";border-width:.5em;border-style:solid}.mtx-popover-direction-arrow:after{border-width:calc(.5em - 1px)}[class*=mtx-popover-below] .mtx-popover-direction-arrow,[class*=mtx-popover-above] .mtx-popover-direction-arrow{width:1em}[class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{left:1px}[dir=rtl] [class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[dir=rtl] [class*=mtx-popover-above] .mtx-popover-direction-arrow:after{right:1px;left:auto}[class*=mtx-popover-below] .mtx-popover-direction-arrow{top:0}[class*=mtx-popover-below] .mtx-popover-direction-arrow:before,[class*=mtx-popover-below] .mtx-popover-direction-arrow:after{bottom:0;border-top-width:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow{bottom:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow:before,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{top:0;border-bottom-width:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow,[class*=mtx-popover-after] .mtx-popover-direction-arrow{height:1em}[class*=mtx-popover-before] .mtx-popover-direction-arrow:after,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{top:1px}[class*=mtx-popover-before] .mtx-popover-direction-arrow{right:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow{right:auto;left:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:auto;right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before{border-right-width:.5em}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{border-right-width:calc(.5em - 1px)}[class*=mtx-popover-after] .mtx-popover-direction-arrow{left:0}[class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow{left:auto;right:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:auto;left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before{border-left-width:.5em}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{border-left-width:calc(.5em - 1px)}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], animations: [transformPopover], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
340
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopover, decorators: [{
460
+ /** @nocollapse */ MtxPopover.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopover, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: MTX_POPOVER_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
461
+ /** @nocollapse */ MtxPopover.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.0", type: MtxPopover, selector: "mtx-popover", inputs: { backdropClass: "backdropClass", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"], ariaDescribedby: ["aria-describedby", "ariaDescribedby"], triggerEvent: "triggerEvent", enterDelay: "enterDelay", leaveDelay: "leaveDelay", position: "position", xOffset: "xOffset", yOffset: "yOffset", arrowWidth: "arrowWidth", arrowHeight: "arrowHeight", arrowOffsetX: "arrowOffsetX", arrowOffsetY: "arrowOffsetY", closeOnPanelClick: "closeOnPanelClick", closeOnBackdropClick: "closeOnBackdropClick", focusTrapEnabled: "focusTrapEnabled", focusTrapAutoCaptureEnabled: "focusTrapAutoCaptureEnabled", hasBackdrop: "hasBackdrop", elevation: "elevation", panelClass: ["class", "panelClass"], classList: "classList" }, outputs: { closed: "closed" }, queries: [{ propertyName: "lazyContent", first: true, predicate: MTX_POPOVER_CONTENT, descendants: true }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], exportAs: ["mtxPopover"], ngImport: i0, template: "<ng-template>\r\n <div class=\"mtx-popover-panel\"\r\n [id]=\"panelId\"\r\n [ngClass]=\"_classList\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (click)=\"_handleClick()\"\r\n (mouseover)=\"_handleMouseOver()\"\r\n (mouseleave)=\"_handleMouseLeave()\"\r\n [@transformPopover]=\"_panelAnimationState\"\r\n (@transformPopover.start)=\"_onAnimationStart($event)\"\r\n (@transformPopover.done)=\"_onAnimationDone($event)\"\r\n tabindex=\"-1\"\r\n role=\"dialog\"\r\n [attr.aria-label]=\"ariaLabel || null\"\r\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\r\n [attr.aria-describedby]=\"ariaDescribedby || null\"\r\n [cdkTrapFocus]=\"focusTrapEnabled\"\r\n [cdkTrapFocusAutoCapture]=\"focusTrapAutoCaptureEnabled\">\r\n <div class=\"mtx-popover-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"mtx-popover-direction-arrow\" [ngStyle]=\"arrowStyles\"></div>\r\n </div>\r\n</ng-template>\r\n", styles: [".mtx-popover-panel{position:relative;max-height:calc(100vh - 48px);padding:8px;border-radius:4px;font-size:16px;outline:0}.mtx-popover-panel[class*=mtx-popover-below]{margin-top:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-above]{margin-bottom:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-before]{margin-right:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-before]{margin-right:auto;margin-left:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-after]{margin-left:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-after]{margin-left:auto;margin-right:calc(.5em + 2px)}.mtx-popover-direction-arrow{position:absolute}.mtx-popover-direction-arrow:before,.mtx-popover-direction-arrow:after{position:absolute;display:inline-block;content:\"\";border-width:.5em;border-style:solid}.mtx-popover-direction-arrow:after{border-width:calc(.5em - 1px)}[class*=mtx-popover-below] .mtx-popover-direction-arrow,[class*=mtx-popover-above] .mtx-popover-direction-arrow{width:1em}[class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{left:1px}[dir=rtl] [class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[dir=rtl] [class*=mtx-popover-above] .mtx-popover-direction-arrow:after{right:1px;left:auto}[class*=mtx-popover-below] .mtx-popover-direction-arrow{top:0}[class*=mtx-popover-below] .mtx-popover-direction-arrow:before,[class*=mtx-popover-below] .mtx-popover-direction-arrow:after{bottom:0;border-top-width:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow{bottom:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow:before,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{top:0;border-bottom-width:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow,[class*=mtx-popover-after] .mtx-popover-direction-arrow{height:1em}[class*=mtx-popover-before] .mtx-popover-direction-arrow:after,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{top:1px}[class*=mtx-popover-before] .mtx-popover-direction-arrow{right:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow{right:auto;left:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:auto;right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before{border-right-width:.5em}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{border-right-width:calc(.5em - 1px)}[class*=mtx-popover-after] .mtx-popover-direction-arrow{left:0}[class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow{left:auto;right:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:auto;left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before{border-left-width:.5em}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{border-left-width:calc(.5em - 1px)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], animations: [transformPopover], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
462
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopover, decorators: [{
341
463
  type: Component,
342
- args: [{ selector: 'mtx-popover', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, animations: [transformPopover], exportAs: 'mtxPopover', template: "<ng-template>\r\n <div class=\"mtx-popover-panel mat-elevation-z8\" role=\"dialog\"\r\n [ngClass]=\"_classList\"\r\n [ngStyle]=\"popoverPanelStyles\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (click)=\"onClick()\"\r\n (mouseover)=\"onMouseOver()\"\r\n (mouseleave)=\"onMouseLeave()\"\r\n [@.disabled]=\"disableAnimation\"\r\n [@transformPopover]=\"'enter'\">\r\n <div class=\"mtx-popover-direction-arrow\" [ngStyle]=\"popoverArrowStyles\"></div>\r\n <div class=\"mtx-popover-content\"\r\n [ngStyle]=\"popoverContentStyles\"\r\n [cdkTrapFocus]=\"focusTrapEnabled\"\r\n [cdkTrapFocusAutoCapture]=\"focusTrapAutoCaptureEnabled\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [".mtx-popover-panel{max-height:calc(100vh - 48px);padding:8px;border-radius:4px;font-size:16px}.mtx-popover-panel[class*=mtx-popover-below]{margin-top:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-above]{margin-bottom:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-before]{margin-right:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-before]{margin-right:auto;margin-left:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-after]{margin-left:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-after]{margin-left:auto;margin-right:calc(.5em + 2px)}.mtx-popover-direction-arrow{position:absolute}.mtx-popover-direction-arrow:before,.mtx-popover-direction-arrow:after{position:absolute;display:inline-block;content:\"\";border-width:.5em;border-style:solid}.mtx-popover-direction-arrow:after{border-width:calc(.5em - 1px)}[class*=mtx-popover-below] .mtx-popover-direction-arrow,[class*=mtx-popover-above] .mtx-popover-direction-arrow{width:1em}[class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{left:1px}[dir=rtl] [class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[dir=rtl] [class*=mtx-popover-above] .mtx-popover-direction-arrow:after{right:1px;left:auto}[class*=mtx-popover-below] .mtx-popover-direction-arrow{top:0}[class*=mtx-popover-below] .mtx-popover-direction-arrow:before,[class*=mtx-popover-below] .mtx-popover-direction-arrow:after{bottom:0;border-top-width:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow{bottom:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow:before,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{top:0;border-bottom-width:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow,[class*=mtx-popover-after] .mtx-popover-direction-arrow{height:1em}[class*=mtx-popover-before] .mtx-popover-direction-arrow:after,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{top:1px}[class*=mtx-popover-before] .mtx-popover-direction-arrow{right:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow{right:auto;left:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:auto;right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before{border-right-width:.5em}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{border-right-width:calc(.5em - 1px)}[class*=mtx-popover-after] .mtx-popover-direction-arrow{left:0}[class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow{left:auto;right:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:auto;left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before{border-left-width:.5em}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{border-left-width:calc(.5em - 1px)}\n"] }]
343
- }], ctorParameters: function () { return [{ type: i1.Directionality, decorators: [{
344
- type: Optional
345
- }] }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { role: [{
346
- type: HostBinding,
347
- args: ['attr.role']
348
- }], position: [{
464
+ args: [{ selector: 'mtx-popover', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, animations: [transformPopover], exportAs: 'mtxPopover', template: "<ng-template>\r\n <div class=\"mtx-popover-panel\"\r\n [id]=\"panelId\"\r\n [ngClass]=\"_classList\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (click)=\"_handleClick()\"\r\n (mouseover)=\"_handleMouseOver()\"\r\n (mouseleave)=\"_handleMouseLeave()\"\r\n [@transformPopover]=\"_panelAnimationState\"\r\n (@transformPopover.start)=\"_onAnimationStart($event)\"\r\n (@transformPopover.done)=\"_onAnimationDone($event)\"\r\n tabindex=\"-1\"\r\n role=\"dialog\"\r\n [attr.aria-label]=\"ariaLabel || null\"\r\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\r\n [attr.aria-describedby]=\"ariaDescribedby || null\"\r\n [cdkTrapFocus]=\"focusTrapEnabled\"\r\n [cdkTrapFocusAutoCapture]=\"focusTrapAutoCaptureEnabled\">\r\n <div class=\"mtx-popover-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"mtx-popover-direction-arrow\" [ngStyle]=\"arrowStyles\"></div>\r\n </div>\r\n</ng-template>\r\n", styles: [".mtx-popover-panel{position:relative;max-height:calc(100vh - 48px);padding:8px;border-radius:4px;font-size:16px;outline:0}.mtx-popover-panel[class*=mtx-popover-below]{margin-top:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-above]{margin-bottom:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-before]{margin-right:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-before]{margin-right:auto;margin-left:calc(.5em + 2px)}.mtx-popover-panel[class*=mtx-popover-after]{margin-left:calc(.5em + 2px)}[dir=rtl] .mtx-popover-panel[class*=mtx-popover-after]{margin-left:auto;margin-right:calc(.5em + 2px)}.mtx-popover-direction-arrow{position:absolute}.mtx-popover-direction-arrow:before,.mtx-popover-direction-arrow:after{position:absolute;display:inline-block;content:\"\";border-width:.5em;border-style:solid}.mtx-popover-direction-arrow:after{border-width:calc(.5em - 1px)}[class*=mtx-popover-below] .mtx-popover-direction-arrow,[class*=mtx-popover-above] .mtx-popover-direction-arrow{width:1em}[class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{left:1px}[dir=rtl] [class*=mtx-popover-below] .mtx-popover-direction-arrow:after,[dir=rtl] [class*=mtx-popover-above] .mtx-popover-direction-arrow:after{right:1px;left:auto}[class*=mtx-popover-below] .mtx-popover-direction-arrow{top:0}[class*=mtx-popover-below] .mtx-popover-direction-arrow:before,[class*=mtx-popover-below] .mtx-popover-direction-arrow:after{bottom:0;border-top-width:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow{bottom:0}[class*=mtx-popover-above] .mtx-popover-direction-arrow:before,[class*=mtx-popover-above] .mtx-popover-direction-arrow:after{top:0;border-bottom-width:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow,[class*=mtx-popover-after] .mtx-popover-direction-arrow{height:1em}[class*=mtx-popover-before] .mtx-popover-direction-arrow:after,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{top:1px}[class*=mtx-popover-before] .mtx-popover-direction-arrow{right:0}[class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow{right:auto;left:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{left:auto;right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:before{border-right-width:.5em}[dir=rtl] [class*=mtx-popover-before] .mtx-popover-direction-arrow:after{border-right-width:calc(.5em - 1px)}[class*=mtx-popover-after] .mtx-popover-direction-arrow{left:0}[class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:0;border-left-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow{left:auto;right:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before,[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{right:auto;left:0;border-right-width:0}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:before{border-left-width:.5em}[dir=rtl] [class*=mtx-popover-after] .mtx-popover-direction-arrow:after{border-left-width:calc(.5em - 1px)}\n"] }]
465
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
466
+ type: Inject,
467
+ args: [MTX_POPOVER_DEFAULT_OPTIONS]
468
+ }] }]; }, propDecorators: { backdropClass: [{
349
469
  type: Input
470
+ }], ariaLabel: [{
471
+ type: Input,
472
+ args: ['aria-label']
473
+ }], ariaLabelledby: [{
474
+ type: Input,
475
+ args: ['aria-labelledby']
476
+ }], ariaDescribedby: [{
477
+ type: Input,
478
+ args: ['aria-describedby']
350
479
  }], triggerEvent: [{
351
480
  type: Input
352
- }], scrollStrategy: [{
353
- type: Input
354
481
  }], enterDelay: [{
355
482
  type: Input
356
483
  }], leaveDelay: [{
357
484
  type: Input
485
+ }], position: [{
486
+ type: Input
358
487
  }], xOffset: [{
359
488
  type: Input
360
489
  }], yOffset: [{
361
490
  type: Input
362
- }], arrowOffsetX: [{
363
- type: Input
364
- }], arrowOffsetY: [{
365
- type: Input
366
491
  }], arrowWidth: [{
367
492
  type: Input
368
493
  }], arrowHeight: [{
369
494
  type: Input
495
+ }], arrowOffsetX: [{
496
+ type: Input
497
+ }], arrowOffsetY: [{
498
+ type: Input
370
499
  }], closeOnPanelClick: [{
371
500
  type: Input
372
501
  }], closeOnBackdropClick: [{
373
502
  type: Input
374
- }], disableAnimation: [{
375
- type: Input
376
503
  }], focusTrapEnabled: [{
377
504
  type: Input
378
505
  }], focusTrapAutoCaptureEnabled: [{
379
506
  type: Input
507
+ }], hasBackdrop: [{
508
+ type: Input
509
+ }], elevation: [{
510
+ type: Input
380
511
  }], panelClass: [{
381
512
  type: Input,
382
513
  args: ['class']
@@ -387,41 +518,78 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
387
518
  }], templateRef: [{
388
519
  type: ViewChild,
389
520
  args: [TemplateRef]
521
+ }], lazyContent: [{
522
+ type: ContentChild,
523
+ args: [MTX_POPOVER_CONTENT]
390
524
  }] } });
391
525
 
526
+ /** Injection token that determines the scroll handling while the popover is open. */
527
+ const MTX_POPOVER_SCROLL_STRATEGY = new InjectionToken('mtx-popover-scroll-strategy');
528
+ /** @docs-private */
529
+ function MTX_POPOVER_SCROLL_STRATEGY_FACTORY(overlay) {
530
+ return () => overlay.scrollStrategies.reposition();
531
+ }
532
+ /** @docs-private */
533
+ const MTX_POPOVER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
534
+ provide: MTX_POPOVER_SCROLL_STRATEGY,
535
+ deps: [Overlay],
536
+ useFactory: MTX_POPOVER_SCROLL_STRATEGY_FACTORY,
537
+ };
392
538
  /**
393
- * This directive is intended to be used in conjunction with an mtx-popover tag. It is
539
+ * This directive is intended to be used in conjunction with an `mtx-popover` tag. It is
394
540
  * responsible for toggling the display of the provided popover instance.
395
541
  */
396
542
  class MtxPopoverTrigger {
397
- constructor(_overlay, _elementRef, _viewContainerRef, _dir, _changeDetectorRef) {
543
+ constructor(_overlay, _elementRef, _viewContainerRef, scrollStrategy, _dir, _changeDetectorRef, _focusMonitor) {
398
544
  this._overlay = _overlay;
399
545
  this._elementRef = _elementRef;
400
546
  this._viewContainerRef = _viewContainerRef;
401
547
  this._dir = _dir;
402
548
  this._changeDetectorRef = _changeDetectorRef;
403
- this.ariaHaspopup = true;
404
- this.popoverOpened$ = new Subject();
405
- this.popoverClosed$ = new Subject();
549
+ this._focusMonitor = _focusMonitor;
406
550
  this._overlayRef = null;
407
551
  this._popoverOpen = false;
408
552
  this._halt = false;
409
- // tracking input type is necessary so it's possible to only auto-focus
553
+ this._positionSubscription = Subscription.EMPTY;
554
+ this._popoverCloseSubscription = Subscription.EMPTY;
555
+ this._closingActionsSubscription = Subscription.EMPTY;
556
+ // Tracking input type is necessary so it's possible to only auto-focus
410
557
  // the first item of the list when the popover is opened via the keyboard
411
- this._openedByMouse = false;
412
- this._onDestroy = new Subject();
558
+ this._openedBy = undefined;
413
559
  /** Event emitted when the associated popover is opened. */
414
560
  this.popoverOpened = new EventEmitter();
415
561
  /** Event emitted when the associated popover is closed. */
416
562
  this.popoverClosed = new EventEmitter();
563
+ this._scrollStrategy = scrollStrategy;
564
+ }
565
+ /** References the popover instance that the trigger is associated with. */
566
+ get popover() {
567
+ return this._popover;
568
+ }
569
+ set popover(popover) {
570
+ if (popover === this._popover) {
571
+ return;
572
+ }
573
+ this._popover = popover;
574
+ this._popoverCloseSubscription.unsubscribe();
575
+ if (popover) {
576
+ this._popoverCloseSubscription = popover.closed.subscribe((reason) => {
577
+ this._destroyPopover();
578
+ });
579
+ }
417
580
  }
418
- ngAfterViewInit() {
581
+ ngAfterContentInit() {
419
582
  this._checkPopover();
420
583
  this._setCurrentConfig();
421
- this.popover.closed.subscribe(() => this.closePopover());
422
584
  }
423
585
  ngOnDestroy() {
424
- this.destroyPopover();
586
+ if (this._overlayRef) {
587
+ this._overlayRef.dispose();
588
+ this._overlayRef = null;
589
+ }
590
+ this._positionSubscription.unsubscribe();
591
+ this._popoverCloseSubscription.unsubscribe();
592
+ this._closingActionsSubscription.unsubscribe();
425
593
  }
426
594
  _setCurrentConfig() {
427
595
  if (this.triggerEvent) {
@@ -433,12 +601,18 @@ class MtxPopoverTrigger {
433
601
  get popoverOpen() {
434
602
  return this._popoverOpen;
435
603
  }
436
- onClick(event) {
604
+ /** The text direction of the containing app. */
605
+ get dir() {
606
+ return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
607
+ }
608
+ /** Handles mouse click on the trigger. */
609
+ _handleClick(event) {
437
610
  if (this.popover.triggerEvent === 'click') {
438
611
  this.togglePopover();
439
612
  }
440
613
  }
441
- onMouseEnter(event) {
614
+ /** Handles mouse enter on the trigger. */
615
+ _handleMouseEnter(event) {
442
616
  this._halt = false;
443
617
  if (this.popover.triggerEvent === 'hover') {
444
618
  this._mouseoverTimer = setTimeout(() => {
@@ -446,7 +620,8 @@ class MtxPopoverTrigger {
446
620
  }, this.popover.enterDelay);
447
621
  }
448
622
  }
449
- onMouseLeave(event) {
623
+ /** Handles mouse leave on the trigger. */
624
+ _handleMouseLeave(event) {
450
625
  if (this.popover.triggerEvent === 'hover') {
451
626
  if (this._mouseoverTimer) {
452
627
  clearTimeout(this._mouseoverTimer);
@@ -464,117 +639,119 @@ class MtxPopoverTrigger {
464
639
  }
465
640
  }
466
641
  }
642
+ /** Handles mouse presses on the trigger. */
643
+ _handleMousedown(event) {
644
+ if (!isFakeMousedownFromScreenReader(event)) {
645
+ // Since right or middle button clicks won't trigger the `click` event,
646
+ // we shouldn't consider the popover as opened by mouse in those cases.
647
+ this._openedBy = event.button === 0 ? 'mouse' : undefined;
648
+ }
649
+ }
650
+ /** Handles key presses on the trigger. */
651
+ _handleKeydown(event) {
652
+ const keyCode = event.keyCode;
653
+ // Pressing enter on the trigger will trigger the click handler later.
654
+ if (keyCode === ENTER || keyCode === SPACE) {
655
+ this._openedBy = 'keyboard';
656
+ }
657
+ }
467
658
  /** Toggles the popover between the open and closed states. */
468
659
  togglePopover() {
469
660
  return this._popoverOpen ? this.closePopover() : this.openPopover();
470
661
  }
471
662
  /** Opens the popover. */
472
663
  openPopover() {
473
- if (!this._popoverOpen && !this._halt) {
474
- this._createOverlay().attach(this._portal);
475
- this._subscribeToBackdrop();
476
- this._subscribeToDetachments();
477
- this._initPopover();
664
+ if (this._popoverOpen || this._halt) {
665
+ return;
666
+ }
667
+ this._checkPopover();
668
+ const overlayRef = this._createOverlay();
669
+ const overlayConfig = overlayRef.getConfig();
670
+ this._setPosition(overlayConfig.positionStrategy);
671
+ if (this.popover.triggerEvent === 'click') {
672
+ overlayConfig.hasBackdrop = this.popover.hasBackdrop ?? true;
673
+ }
674
+ overlayRef.attach(this._getPortal());
675
+ if (this.popover.lazyContent) {
676
+ this.popover.lazyContent.attach(this.popoverData);
677
+ }
678
+ this._closingActionsSubscription = this._popoverClosingActions().subscribe(() => this.closePopover());
679
+ this._initPopover();
680
+ if (this.popover instanceof MtxPopover) {
681
+ this.popover._startAnimation();
478
682
  }
479
683
  }
480
684
  /** Closes the popover. */
481
685
  closePopover() {
482
- if (this._overlayRef) {
483
- this._overlayRef.detach();
484
- this._resetPopover();
686
+ this.popover.closed.emit();
687
+ }
688
+ /**
689
+ * Focuses the popover trigger.
690
+ * @param origin Source of the popover trigger's focus.
691
+ */
692
+ focus(origin, options) {
693
+ if (this._focusMonitor && origin) {
694
+ this._focusMonitor.focusVia(this._elementRef, origin, options);
695
+ }
696
+ else {
697
+ this._elementRef.nativeElement.focus(options);
485
698
  }
486
- this.destroyPopover();
487
699
  }
488
700
  /** Removes the popover from the DOM. */
489
- destroyPopover() {
701
+ _destroyPopover(reason) {
702
+ if (!this._overlayRef || !this.popoverOpen) {
703
+ return;
704
+ }
705
+ // Clear the timeout for hover event.
490
706
  if (this._mouseoverTimer) {
491
707
  clearTimeout(this._mouseoverTimer);
492
708
  this._mouseoverTimer = null;
493
709
  }
494
- if (this._overlayRef) {
495
- this._overlayRef.dispose();
496
- this._overlayRef = null;
497
- this._cleanUpSubscriptions();
498
- }
499
- this._onDestroy.next();
500
- this._onDestroy.complete();
501
- }
502
- /** Focuses the popover trigger. */
503
- focus() {
504
- this._elementRef.nativeElement.focus();
505
- }
506
- /** The text direction of the containing app. */
507
- get dir() {
508
- return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
509
- }
510
- /**
511
- * This method ensures that the popover closes when the overlay backdrop is clicked.
512
- * We do not use first() here because doing so would not catch clicks from within
513
- * the popover, and it would fail to unsubscribe properly. Instead, we unsubscribe
514
- * explicitly when the popover is closed or destroyed.
515
- */
516
- _subscribeToBackdrop() {
517
- if (this._overlayRef) {
518
- /** Only subscribe to backdrop if trigger event is click */
519
- if (this.triggerEvent === 'click' && this.popover.closeOnBackdropClick === true) {
520
- this._overlayRef
521
- .backdropClick()
522
- .pipe(takeUntil(this.popoverClosed$), takeUntil(this._onDestroy))
523
- .subscribe(() => {
524
- this.popover._emitCloseEvent();
710
+ const popover = this.popover;
711
+ this._closingActionsSubscription.unsubscribe();
712
+ this._overlayRef.detach();
713
+ this._openedBy = undefined;
714
+ if (popover instanceof MtxPopover) {
715
+ popover._resetAnimation();
716
+ if (popover.lazyContent) {
717
+ // Wait for the exit animation to finish before detaching the content.
718
+ popover._animationDone
719
+ .pipe(filter(event => event.toState === 'void'), take(1),
720
+ // Interrupt if the content got re-attached.
721
+ takeUntil(popover.lazyContent._attached))
722
+ .subscribe({
723
+ next: () => popover.lazyContent.detach(),
724
+ // No matter whether the content got re-attached, reset the popover.
725
+ complete: () => this._setIsPopoverOpen(false),
525
726
  });
526
727
  }
728
+ else {
729
+ this._setIsPopoverOpen(false);
730
+ }
527
731
  }
528
- }
529
- _subscribeToDetachments() {
530
- if (this._overlayRef) {
531
- this._overlayRef
532
- .detachments()
533
- .pipe(takeUntil(this.popoverClosed$), takeUntil(this._onDestroy))
534
- .subscribe(() => {
535
- this._setPopoverClosed();
536
- });
732
+ else {
733
+ this._setIsPopoverOpen(false);
734
+ if (popover.lazyContent) {
735
+ popover.lazyContent.detach();
736
+ }
537
737
  }
538
738
  }
539
739
  /**
540
- * This method sets the popover state to open and focuses the first item if
541
- * the popover was opened via the keyboard.
740
+ * This method sets the popover state to open.
542
741
  */
543
742
  _initPopover() {
544
- this._setPopoverOpened();
545
- }
546
- /**
547
- * This method resets the popover when it's closed, most importantly restoring
548
- * focus to the popover trigger if the popover was opened via the keyboard.
549
- */
550
- _resetPopover() {
551
- this._setPopoverClosed();
552
- // Focus only needs to be reset to the host element if the popover was opened
553
- // by the keyboard and manually shifted to the first popover item.
554
- if (!this._openedByMouse) {
555
- this.focus();
556
- }
557
- this._openedByMouse = false;
743
+ this.popover.direction = this.dir;
744
+ this.popover.setElevation();
745
+ this._setIsPopoverOpen(true);
558
746
  }
559
- /** set state rather than toggle to support triggers sharing a popover */
560
- _setPopoverOpened() {
561
- if (!this._popoverOpen) {
562
- this._popoverOpen = true;
563
- this.popoverOpened$.next();
564
- this.popoverOpened.emit();
565
- }
566
- }
567
- /** set state rather than toggle to support triggers sharing a popover */
568
- _setPopoverClosed() {
569
- if (this._popoverOpen) {
570
- this._popoverOpen = false;
571
- this.popoverClosed$.next();
572
- this.popoverClosed.emit();
573
- }
747
+ // set state rather than toggle to support triggers sharing a popover
748
+ _setIsPopoverOpen(isOpen) {
749
+ this._popoverOpen = isOpen;
750
+ this._popoverOpen ? this.popoverOpened.emit() : this.popoverClosed.emit();
574
751
  }
575
752
  /**
576
- * This method checks that a valid instance of MdPopover has been passed into
577
- * mdPopoverTriggerFor. If not, an exception is thrown.
753
+ * This method checks that a valid instance of MdPopover has been passed into
754
+ * `mtxPopoverTriggerFor`. If not, an exception is thrown.
578
755
  */
579
756
  _checkPopover() {
580
757
  if (!this.popover) {
@@ -582,16 +759,20 @@ class MtxPopoverTrigger {
582
759
  }
583
760
  }
584
761
  /**
585
- * This method creates the overlay from the provided popover's template and saves its
586
- * OverlayRef so that it can be attached to the DOM when openPopover is called.
762
+ * This method creates the overlay from the provided popover's template and saves its
763
+ * OverlayRef so that it can be attached to the DOM when openPopover is called.
587
764
  */
588
765
  _createOverlay() {
589
766
  if (!this._overlayRef) {
590
- this._portal = new TemplatePortal(this.popover.templateRef, this._viewContainerRef);
591
767
  const config = this._getOverlayConfig();
592
768
  this._subscribeToPositions(config.positionStrategy);
593
769
  this._overlayRef = this._overlay.create(config);
594
770
  }
771
+ else {
772
+ const overlayConfig = this._overlayRef.getConfig();
773
+ const positionStrategy = overlayConfig.positionStrategy;
774
+ positionStrategy.setOrigin(this._getTargetElement());
775
+ }
595
776
  return this._overlayRef;
596
777
  }
597
778
  /**
@@ -599,32 +780,24 @@ class MtxPopoverTrigger {
599
780
  * @returns OverlayConfig
600
781
  */
601
782
  _getOverlayConfig() {
602
- const overlayState = new OverlayConfig();
603
- overlayState.positionStrategy = this._getPosition();
604
- /** Display overlay backdrop if trigger event is click */
605
- if (this.triggerEvent === 'click') {
606
- overlayState.hasBackdrop = true;
607
- overlayState.backdropClass = 'cdk-overlay-transparent-backdrop';
608
- }
609
- overlayState.direction = this._dir;
610
- overlayState.scrollStrategy = this._getOverlayScrollStrategy(this.popover.scrollStrategy);
611
- return overlayState;
783
+ return new OverlayConfig({
784
+ positionStrategy: this._overlay
785
+ .position()
786
+ .flexibleConnectedTo(this._getTargetElement())
787
+ .withLockedPosition()
788
+ .withGrowAfterOpen()
789
+ .withTransformOriginOn('.mtx-popover-panel'),
790
+ backdropClass: this.popover.backdropClass || 'cdk-overlay-transparent-backdrop',
791
+ panelClass: this.popover.overlayPanelClass,
792
+ scrollStrategy: this._scrollStrategy(),
793
+ direction: this._dir,
794
+ });
612
795
  }
613
- /**
614
- * This method returns the scroll strategy used by the cdk/overlay.
615
- */
616
- _getOverlayScrollStrategy(strategy) {
617
- switch (strategy) {
618
- case 'noop':
619
- return this._overlay.scrollStrategies.noop();
620
- case 'close':
621
- return this._overlay.scrollStrategies.close();
622
- case 'block':
623
- return this._overlay.scrollStrategies.block();
624
- case 'reposition':
625
- default:
626
- return this._overlay.scrollStrategies.reposition();
796
+ _getTargetElement() {
797
+ if (this.targetElement) {
798
+ return this.targetElement.elementRef;
627
799
  }
800
+ return this._elementRef;
628
801
  }
629
802
  /**
630
803
  * Listens to changes in the position of the overlay and sets the correct classes
@@ -648,18 +821,16 @@ class MtxPopoverTrigger {
648
821
  : [posX, posY];
649
822
  // required for ChangeDetectionStrategy.OnPush
650
823
  this._changeDetectorRef.markForCheck();
651
- this.popover.zone.run(() => {
652
- this.popover.setCurrentStyles(pos);
653
- this.popover.setPositionClasses(pos);
654
- });
824
+ this.popover.setCurrentStyles(pos);
825
+ this.popover.setPositionClasses(pos);
655
826
  });
656
827
  }
657
828
  /**
658
- * This method builds the position strategy for the overlay, so the popover is properly connected
659
- * to the trigger.
660
- * @returns ConnectedPositionStrategy
829
+ * Sets the appropriate positions on a position strategy
830
+ * so the overlay connects with the trigger correctly.
831
+ * @param positionStrategy Strategy whose position to update.
661
832
  */
662
- _getPosition() {
833
+ _setPosition(positionStrategy) {
663
834
  const [originX, origin2ndX, origin3rdX] = this.popover.position[0] === 'before' || this.popover.position[1] === 'after'
664
835
  ? ['start', 'center', 'end']
665
836
  : this.popover.position[0] === 'after' || this.popover.position[1] === 'before'
@@ -688,16 +859,6 @@ class MtxPopoverTrigger {
688
859
  const offsetY = this.popover.yOffset && !isNaN(Number(this.popover.yOffset))
689
860
  ? Number(this.popover.yOffset)
690
861
  : 0;
691
- /**
692
- * For overriding position element, when `mtxPopoverTargetAt` has a valid element reference.
693
- * Useful for sticking popover to parent element and offsetting arrow to trigger element.
694
- * If undefined defaults to the trigger element reference.
695
- */
696
- let element = this._elementRef;
697
- if (typeof this.targetElement !== 'undefined') {
698
- this.popover.containerPositioning = true;
699
- element = this.targetElement._elementRef;
700
- }
701
862
  let positions = [{ originX, originY, overlayX, overlayY }];
702
863
  if (this.popover.position[0] === 'above' || this.popover.position[0] === 'below') {
703
864
  positions = [
@@ -755,47 +916,59 @@ class MtxPopoverTrigger {
755
916
  },
756
917
  ];
757
918
  }
758
- return this._overlay
759
- .position()
760
- .flexibleConnectedTo(element)
761
- .withLockedPosition()
919
+ positionStrategy
762
920
  .withPositions(positions)
763
921
  .withDefaultOffsetX(offsetX)
764
922
  .withDefaultOffsetY(offsetY);
765
923
  }
766
- _cleanUpSubscriptions() {
767
- if (this._backdropSubscription) {
768
- this._backdropSubscription.unsubscribe();
769
- }
770
- if (this._positionSubscription) {
771
- this._positionSubscription.unsubscribe();
772
- }
773
- if (this._detachmentsSubscription) {
774
- this._detachmentsSubscription.unsubscribe();
775
- }
776
- }
777
- _handleMousedown(event) {
778
- if (event && !isFakeMousedownFromScreenReader(event)) {
779
- this._openedByMouse = true;
924
+ /** Returns a stream that emits whenever an action that should close the popover occurs. */
925
+ _popoverClosingActions() {
926
+ const backdrop = this.popover.triggerEvent === 'click' && this.popover.closeOnBackdropClick === true
927
+ ? this._overlayRef.backdropClick()
928
+ : of();
929
+ const detachments = this._overlayRef.detachments();
930
+ return merge(backdrop, detachments);
931
+ }
932
+ /** Gets the portal that should be attached to the overlay. */
933
+ _getPortal() {
934
+ // Note that we can avoid this check by keeping the portal on the popover panel.
935
+ // While it would be cleaner, we'd have to introduce another required method on
936
+ // `MtxPopoverPanel`, making it harder to consume.
937
+ if (!this._portal || this._portal.templateRef !== this.popover.templateRef) {
938
+ this._portal = new TemplatePortal(this.popover.templateRef, this._viewContainerRef);
780
939
  }
940
+ return this._portal;
781
941
  }
782
942
  }
783
- /** @nocollapse */ MtxPopoverTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverTrigger, deps: [{ token: i1$1.Overlay }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.Directionality, optional: true }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
784
- /** @nocollapse */ MtxPopoverTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.2", type: MtxPopoverTrigger, selector: "[mtxPopoverTriggerFor]", inputs: { popover: ["mtxPopoverTriggerFor", "popover"], targetElement: ["mtxPopoverTargetAt", "targetElement"], triggerEvent: ["mtxPopoverTriggerOn", "triggerEvent"] }, outputs: { popoverOpened: "popoverOpened", popoverClosed: "popoverClosed" }, host: { listeners: { "click": "onClick($event)", "mouseenter": "onMouseEnter($event)", "mouseleave": "onMouseLeave($event)", "mousedown": "_handleMousedown($event)" }, properties: { "attr.aria-haspopup": "this.ariaHaspopup" } }, exportAs: ["mtxPopoverTrigger"], ngImport: i0 });
785
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverTrigger, decorators: [{
943
+ /** @nocollapse */ MtxPopoverTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverTrigger, deps: [{ token: i1$1.Overlay }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: MTX_POPOVER_SCROLL_STRATEGY }, { token: i2.Directionality, optional: true }, { token: i0.ChangeDetectorRef }, { token: i3.FocusMonitor }], target: i0.ɵɵFactoryTarget.Directive });
944
+ /** @nocollapse */ MtxPopoverTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.0", type: MtxPopoverTrigger, selector: "[mtx-popover-trigger-for], [mtxPopoverTriggerFor]", inputs: { popover: ["mtxPopoverTriggerFor", "popover"], popoverData: ["mtxPopoverTriggerData", "popoverData"], targetElement: ["mtxPopoverTargetAt", "targetElement"], triggerEvent: ["mtxPopoverTriggerOn", "triggerEvent"] }, outputs: { popoverOpened: "popoverOpened", popoverClosed: "popoverClosed" }, host: { attributes: { "aria-haspopup": "true" }, listeners: { "click": "_handleClick($event)", "mouseenter": "_handleMouseEnter($event)", "mouseleave": "_handleMouseLeave($event)", "mousedown": "_handleMousedown($event)", "keydown": "_handleKeydown($event)" }, properties: { "attr.aria-expanded": "popoverOpen || null", "attr.aria-controls": "popoverOpen ? popover.panelId : null" } }, exportAs: ["mtxPopoverTrigger"], ngImport: i0 });
945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverTrigger, decorators: [{
786
946
  type: Directive,
787
947
  args: [{
788
- selector: '[mtxPopoverTriggerFor]',
948
+ selector: '[mtx-popover-trigger-for], [mtxPopoverTriggerFor]',
789
949
  exportAs: 'mtxPopoverTrigger',
950
+ host: {
951
+ 'aria-haspopup': 'true',
952
+ '[attr.aria-expanded]': 'popoverOpen || null',
953
+ '[attr.aria-controls]': 'popoverOpen ? popover.panelId : null',
954
+ '(click)': '_handleClick($event)',
955
+ '(mouseenter)': '_handleMouseEnter($event)',
956
+ '(mouseleave)': '_handleMouseLeave($event)',
957
+ '(mousedown)': '_handleMousedown($event)',
958
+ '(keydown)': '_handleKeydown($event)',
959
+ },
790
960
  }]
791
- }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Directionality, decorators: [{
961
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
962
+ type: Inject,
963
+ args: [MTX_POPOVER_SCROLL_STRATEGY]
964
+ }] }, { type: i2.Directionality, decorators: [{
792
965
  type: Optional
793
- }] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { ariaHaspopup: [{
794
- type: HostBinding,
795
- args: ['attr.aria-haspopup']
796
- }], popover: [{
966
+ }] }, { type: i0.ChangeDetectorRef }, { type: i3.FocusMonitor }]; }, propDecorators: { popover: [{
797
967
  type: Input,
798
968
  args: ['mtxPopoverTriggerFor']
969
+ }], popoverData: [{
970
+ type: Input,
971
+ args: ['mtxPopoverTriggerData']
799
972
  }], targetElement: [{
800
973
  type: Input,
801
974
  args: ['mtxPopoverTargetAt']
@@ -806,28 +979,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
806
979
  type: Output
807
980
  }], popoverClosed: [{
808
981
  type: Output
809
- }], onClick: [{
810
- type: HostListener,
811
- args: ['click', ['$event']]
812
- }], onMouseEnter: [{
813
- type: HostListener,
814
- args: ['mouseenter', ['$event']]
815
- }], onMouseLeave: [{
816
- type: HostListener,
817
- args: ['mouseleave', ['$event']]
818
- }], _handleMousedown: [{
819
- type: HostListener,
820
- args: ['mousedown', ['$event']]
821
982
  }] } });
822
983
 
823
984
  class MtxPopoverTarget {
824
- constructor(_elementRef) {
825
- this._elementRef = _elementRef;
985
+ constructor(elementRef) {
986
+ this.elementRef = elementRef;
826
987
  }
827
988
  }
828
- /** @nocollapse */ MtxPopoverTarget.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverTarget, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
829
- /** @nocollapse */ MtxPopoverTarget.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.2", type: MtxPopoverTarget, selector: "mtx-popover-target, [mtxPopoverTarget]", exportAs: ["mtxPopoverTarget"], ngImport: i0 });
830
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverTarget, decorators: [{
989
+ /** @nocollapse */ MtxPopoverTarget.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverTarget, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
990
+ /** @nocollapse */ MtxPopoverTarget.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.0", type: MtxPopoverTarget, selector: "mtx-popover-target, [mtxPopoverTarget]", exportAs: ["mtxPopoverTarget"], ngImport: i0 });
991
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverTarget, decorators: [{
831
992
  type: Directive,
832
993
  args: [{
833
994
  selector: 'mtx-popover-target, [mtxPopoverTarget]',
@@ -837,15 +998,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
837
998
 
838
999
  class MtxPopoverModule {
839
1000
  }
840
- /** @nocollapse */ MtxPopoverModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
841
- /** @nocollapse */ MtxPopoverModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverModule, declarations: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget], imports: [OverlayModule, CommonModule, A11yModule], exports: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget] });
842
- /** @nocollapse */ MtxPopoverModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverModule, imports: [OverlayModule, CommonModule, A11yModule] });
843
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: MtxPopoverModule, decorators: [{
1001
+ /** @nocollapse */ MtxPopoverModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1002
+ /** @nocollapse */ MtxPopoverModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverModule, declarations: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget, MtxPopoverContent], imports: [CommonModule, OverlayModule, A11yModule], exports: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget, MtxPopoverContent] });
1003
+ /** @nocollapse */ MtxPopoverModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverModule, providers: [MTX_POPOVER_SCROLL_STRATEGY_FACTORY_PROVIDER], imports: [CommonModule, OverlayModule, A11yModule] });
1004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: MtxPopoverModule, decorators: [{
844
1005
  type: NgModule,
845
1006
  args: [{
846
- imports: [OverlayModule, CommonModule, A11yModule],
847
- exports: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget],
848
- declarations: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget],
1007
+ imports: [CommonModule, OverlayModule, A11yModule],
1008
+ exports: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget, MtxPopoverContent],
1009
+ declarations: [MtxPopover, MtxPopoverTrigger, MtxPopoverTarget, MtxPopoverContent],
1010
+ providers: [MTX_POPOVER_SCROLL_STRATEGY_FACTORY_PROVIDER],
849
1011
  }]
850
1012
  }] });
851
1013
 
@@ -853,5 +1015,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
853
1015
  * Generated bundle index. Do not edit.
854
1016
  */
855
1017
 
856
- export { MtxPopover, MtxPopoverModule, MtxPopoverTarget, MtxPopoverTrigger, transformPopover };
1018
+ export { MTX_POPOVER_CONTENT, MTX_POPOVER_DEFAULT_OPTIONS, MTX_POPOVER_DEFAULT_OPTIONS_FACTORY, MTX_POPOVER_SCROLL_STRATEGY, MTX_POPOVER_SCROLL_STRATEGY_FACTORY, MTX_POPOVER_SCROLL_STRATEGY_FACTORY_PROVIDER, MtxPopover, MtxPopoverContent, MtxPopoverModule, MtxPopoverTarget, MtxPopoverTrigger, _MtxPopoverContentBase, transformPopover };
857
1019
  //# sourceMappingURL=mtxPopover.mjs.map