@nanahoshi/mona-ui 0.1.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.
- package/README.md +25 -0
- package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +590 -0
- package/fesm2022/nanahoshi-mona-ui-avatar.mjs +168 -0
- package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +220 -0
- package/fesm2022/nanahoshi-mona-ui-button-group.mjs +225 -0
- package/fesm2022/nanahoshi-mona-ui-button.mjs +497 -0
- package/fesm2022/nanahoshi-mona-ui-calendar.mjs +1569 -0
- package/fesm2022/nanahoshi-mona-ui-check-box.mjs +339 -0
- package/fesm2022/nanahoshi-mona-ui-chip.mjs +453 -0
- package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +200 -0
- package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +853 -0
- package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +923 -0
- package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +495 -0
- package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +686 -0
- package/fesm2022/nanahoshi-mona-ui-common.mjs +642 -0
- package/fesm2022/nanahoshi-mona-ui-contextmenu.mjs +485 -0
- package/fesm2022/nanahoshi-mona-ui-date-input.mjs +132 -0
- package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +460 -0
- package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +659 -0
- package/fesm2022/nanahoshi-mona-ui-dialog.mjs +828 -0
- package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +523 -0
- package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +615 -0
- package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +701 -0
- package/fesm2022/nanahoshi-mona-ui-editor.mjs +1400 -0
- package/fesm2022/nanahoshi-mona-ui-expansion-panel.mjs +245 -0
- package/fesm2022/nanahoshi-mona-ui-fieldset.mjs +170 -0
- package/fesm2022/nanahoshi-mona-ui-filter.mjs +680 -0
- package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-cell.component-B9SQH5N-.mjs +105 -0
- package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-DlLwcCFT.mjs +42 -0
- package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-Dgea-O0X.mjs +130 -0
- package/fesm2022/nanahoshi-mona-ui-grid-grid-toggle.component-DIUutx9s.mjs +773 -0
- package/fesm2022/nanahoshi-mona-ui-grid-grid-virtual-list.component-DRHycGIh.mjs +240 -0
- package/fesm2022/nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-C3eZIaJK.mjs +5374 -0
- package/fesm2022/nanahoshi-mona-ui-grid.mjs +2 -0
- package/fesm2022/nanahoshi-mona-ui-internal-filter-input.mjs +87 -0
- package/fesm2022/nanahoshi-mona-ui-internal-indicator-icon.mjs +154 -0
- package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +1356 -0
- package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +2263 -0
- package/fesm2022/nanahoshi-mona-ui-internal.mjs +379 -0
- package/fesm2022/nanahoshi-mona-ui-list-box.mjs +630 -0
- package/fesm2022/nanahoshi-mona-ui-list-view.mjs +527 -0
- package/fesm2022/nanahoshi-mona-ui-list.mjs +4 -0
- package/fesm2022/nanahoshi-mona-ui-menubar.mjs +966 -0
- package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +641 -0
- package/fesm2022/nanahoshi-mona-ui-notification.mjs +536 -0
- package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +597 -0
- package/fesm2022/nanahoshi-mona-ui-pager.mjs +790 -0
- package/fesm2022/nanahoshi-mona-ui-placeholder.mjs +83 -0
- package/fesm2022/nanahoshi-mona-ui-popover.mjs +325 -0
- package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +1559 -0
- package/fesm2022/nanahoshi-mona-ui-popup.mjs +1321 -0
- package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +294 -0
- package/fesm2022/nanahoshi-mona-ui-query.mjs +175 -0
- package/fesm2022/nanahoshi-mona-ui-radio-button.mjs +339 -0
- package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +565 -0
- package/fesm2022/nanahoshi-mona-ui-slider.mjs +1049 -0
- package/fesm2022/nanahoshi-mona-ui-split-button.mjs +636 -0
- package/fesm2022/nanahoshi-mona-ui-splitter.mjs +843 -0
- package/fesm2022/nanahoshi-mona-ui-stepper.mjs +537 -0
- package/fesm2022/nanahoshi-mona-ui-switch.mjs +308 -0
- package/fesm2022/nanahoshi-mona-ui-tabs.mjs +664 -0
- package/fesm2022/nanahoshi-mona-ui-text-area.mjs +111 -0
- package/fesm2022/nanahoshi-mona-ui-text-box.mjs +369 -0
- package/fesm2022/nanahoshi-mona-ui-theme.mjs +314 -0
- package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +450 -0
- package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +723 -0
- package/fesm2022/nanahoshi-mona-ui-tooltip.mjs +716 -0
- package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +733 -0
- package/fesm2022/nanahoshi-mona-ui-window.mjs +1329 -0
- package/fesm2022/nanahoshi-mona-ui.mjs +9 -0
- package/package.json +289 -0
- package/types/nanahoshi-mona-ui-auto-complete.d.ts +223 -0
- package/types/nanahoshi-mona-ui-avatar.d.ts +642 -0
- package/types/nanahoshi-mona-ui-breadcrumb.d.ts +70 -0
- package/types/nanahoshi-mona-ui-button-group.d.ts +77 -0
- package/types/nanahoshi-mona-ui-button.d.ts +111 -0
- package/types/nanahoshi-mona-ui-calendar.d.ts +262 -0
- package/types/nanahoshi-mona-ui-check-box.d.ts +133 -0
- package/types/nanahoshi-mona-ui-chip.d.ts +130 -0
- package/types/nanahoshi-mona-ui-circular-progress-bar.d.ts +113 -0
- package/types/nanahoshi-mona-ui-color-gradient.d.ts +201 -0
- package/types/nanahoshi-mona-ui-color-palette.d.ts +102 -0
- package/types/nanahoshi-mona-ui-color-picker.d.ts +156 -0
- package/types/nanahoshi-mona-ui-combo-box.d.ts +232 -0
- package/types/nanahoshi-mona-ui-common.d.ts +386 -0
- package/types/nanahoshi-mona-ui-contextmenu.d.ts +129 -0
- package/types/nanahoshi-mona-ui-date-input.d.ts +60 -0
- package/types/nanahoshi-mona-ui-date-picker.d.ts +177 -0
- package/types/nanahoshi-mona-ui-datetime-picker.d.ts +199 -0
- package/types/nanahoshi-mona-ui-dialog.d.ts +261 -0
- package/types/nanahoshi-mona-ui-dropdown-button.d.ts +159 -0
- package/types/nanahoshi-mona-ui-dropdown-list.d.ts +219 -0
- package/types/nanahoshi-mona-ui-dropdowns.d.ts +176 -0
- package/types/nanahoshi-mona-ui-editor.d.ts +113 -0
- package/types/nanahoshi-mona-ui-expansion-panel.d.ts +87 -0
- package/types/nanahoshi-mona-ui-fieldset.d.ts +68 -0
- package/types/nanahoshi-mona-ui-filter.d.ts +115 -0
- package/types/nanahoshi-mona-ui-grid.d.ts +1114 -0
- package/types/nanahoshi-mona-ui-internal-filter-input.d.ts +25 -0
- package/types/nanahoshi-mona-ui-internal-indicator-icon.d.ts +28 -0
- package/types/nanahoshi-mona-ui-internal-list.d.ts +269 -0
- package/types/nanahoshi-mona-ui-internal-tree.d.ts +391 -0
- package/types/nanahoshi-mona-ui-internal.d.ts +136 -0
- package/types/nanahoshi-mona-ui-list-box.d.ts +225 -0
- package/types/nanahoshi-mona-ui-list-view.d.ts +188 -0
- package/types/nanahoshi-mona-ui-list.d.ts +1 -0
- package/types/nanahoshi-mona-ui-menubar.d.ts +198 -0
- package/types/nanahoshi-mona-ui-multi-select.d.ts +247 -0
- package/types/nanahoshi-mona-ui-notification.d.ts +106 -0
- package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +161 -0
- package/types/nanahoshi-mona-ui-pager.d.ts +238 -0
- package/types/nanahoshi-mona-ui-placeholder.d.ts +35 -0
- package/types/nanahoshi-mona-ui-popover.d.ts +130 -0
- package/types/nanahoshi-mona-ui-popup-menu.d.ts +412 -0
- package/types/nanahoshi-mona-ui-popup.d.ts +485 -0
- package/types/nanahoshi-mona-ui-progress-bar.d.ts +139 -0
- package/types/nanahoshi-mona-ui-query.d.ts +89 -0
- package/types/nanahoshi-mona-ui-radio-button.d.ts +128 -0
- package/types/nanahoshi-mona-ui-scroll-view.d.ts +166 -0
- package/types/nanahoshi-mona-ui-slider.d.ts +305 -0
- package/types/nanahoshi-mona-ui-split-button.d.ts +182 -0
- package/types/nanahoshi-mona-ui-splitter.d.ts +70 -0
- package/types/nanahoshi-mona-ui-stepper.d.ts +173 -0
- package/types/nanahoshi-mona-ui-switch.d.ts +125 -0
- package/types/nanahoshi-mona-ui-tabs.d.ts +158 -0
- package/types/nanahoshi-mona-ui-text-area.d.ts +42 -0
- package/types/nanahoshi-mona-ui-text-box.d.ts +164 -0
- package/types/nanahoshi-mona-ui-theme.d.ts +23 -0
- package/types/nanahoshi-mona-ui-time-picker.d.ts +184 -0
- package/types/nanahoshi-mona-ui-time-selector.d.ts +143 -0
- package/types/nanahoshi-mona-ui-tooltip.d.ts +130 -0
- package/types/nanahoshi-mona-ui-tree-view.d.ts +274 -0
- package/types/nanahoshi-mona-ui-window.d.ts +295 -0
- package/types/nanahoshi-mona-ui.d.ts +2 -0
|
@@ -0,0 +1,1321 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, DestroyRef, DOCUMENT, viewChild, ViewContainerRef, computed, signal, afterNextRender, TemplateRef, Component, Injector, ElementRef, Injectable, input, output, effect } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
|
+
import { rxTimeout } from '@nanahoshi/mona-ui/internal';
|
|
5
|
+
import { take, asapScheduler, Subject, ReplaySubject, asyncScheduler, fromEvent, takeUntil, Subscription, filter, tap, exhaustMap, merge } from 'rxjs';
|
|
6
|
+
import { PreventableEvent } from '@nanahoshi/mona-ui/common';
|
|
7
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
8
|
+
import { Overlay, OverlayConfig } from '@angular/cdk/overlay';
|
|
9
|
+
import { ComponentPortal } from '@angular/cdk/portal';
|
|
10
|
+
import { ScrollDispatcher } from '@angular/cdk/scrolling';
|
|
11
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
12
|
+
|
|
13
|
+
class PopupCloseEvent extends PreventableEvent {
|
|
14
|
+
#options;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
super(options?.type ?? "popupClose", options?.originalEvent);
|
|
17
|
+
this.#options = options;
|
|
18
|
+
}
|
|
19
|
+
get result() {
|
|
20
|
+
return this.#options?.result;
|
|
21
|
+
}
|
|
22
|
+
get via() {
|
|
23
|
+
return this.#options?.via;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
var PopupCloseSource;
|
|
27
|
+
(function (PopupCloseSource) {
|
|
28
|
+
PopupCloseSource["BackdropClick"] = "backdropClick";
|
|
29
|
+
PopupCloseSource["CloseButton"] = "closeButton";
|
|
30
|
+
PopupCloseSource["Escape"] = "escape";
|
|
31
|
+
PopupCloseSource["MouseLeave"] = "mouseLeave";
|
|
32
|
+
PopupCloseSource["Programmatic"] = "programmatic";
|
|
33
|
+
PopupCloseSource["OutsideClick"] = "outsideClick";
|
|
34
|
+
PopupCloseSource["Scroll"] = "scroll";
|
|
35
|
+
})(PopupCloseSource || (PopupCloseSource = {}));
|
|
36
|
+
|
|
37
|
+
const defaultPopupAnimation = {
|
|
38
|
+
enter: "mona-popup-enter",
|
|
39
|
+
leave: "mona-popup-leave"
|
|
40
|
+
};
|
|
41
|
+
const dropdownPopupAnimation = {
|
|
42
|
+
enter: "mona-dropdown-popup-enter",
|
|
43
|
+
leave: "mona-dropdown-popup-leave"
|
|
44
|
+
};
|
|
45
|
+
const fadePopupAnimation = {
|
|
46
|
+
enter: "mona-popup-fade-enter",
|
|
47
|
+
leave: "mona-popup-fade-leave"
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const PopupDataInjectionToken = new InjectionToken("PopupInjectionToken");
|
|
51
|
+
const PopupSettingsInjectionToken = new InjectionToken("PopupSettingsInjectionToken");
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @internal - used by the popup service. Do not use directly or export.
|
|
55
|
+
*/
|
|
56
|
+
const PopupReferenceInjectionToken = new InjectionToken("PopupReferenceInjectionToken");
|
|
57
|
+
|
|
58
|
+
class PopupWrapperComponent {
|
|
59
|
+
#destroyRef;
|
|
60
|
+
#document;
|
|
61
|
+
#popupReference;
|
|
62
|
+
#popupSettings;
|
|
63
|
+
#closeEvent;
|
|
64
|
+
#fallbackTimer;
|
|
65
|
+
#leaveCompleted;
|
|
66
|
+
constructor() {
|
|
67
|
+
this.#destroyRef = inject(DestroyRef);
|
|
68
|
+
this.#document = inject(DOCUMENT);
|
|
69
|
+
this.#popupReference = inject(PopupReferenceInjectionToken);
|
|
70
|
+
this.#popupSettings = inject(PopupSettingsInjectionToken);
|
|
71
|
+
this.#closeEvent = null;
|
|
72
|
+
this.#fallbackTimer = null;
|
|
73
|
+
this.#leaveCompleted = false;
|
|
74
|
+
this.animationElement = viewChild.required("animationElement", /* @ts-ignore */
|
|
75
|
+
...(ngDevMode ? [{ debugName: "animationElement" }] : /* istanbul ignore next */ []));
|
|
76
|
+
this.componentOutlet = viewChild.required("componentOutlet", { ...(ngDevMode ? { debugName: "componentOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
77
|
+
this.hostClasses = computed(() => {
|
|
78
|
+
const wrapperClass = this.wrapperClass();
|
|
79
|
+
return ["mona-popup-wrapper", "w-full", "h-full", wrapperClass].filter(Boolean).join(" ");
|
|
80
|
+
}, /* @ts-ignore */
|
|
81
|
+
...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
82
|
+
this.enterAnimationClasses = computed(() => this.#getAnimationConfig()?.enter ?? "", /* @ts-ignore */
|
|
83
|
+
...(ngDevMode ? [{ debugName: "enterAnimationClasses" }] : /* istanbul ignore next */ []));
|
|
84
|
+
this.leaveAnimationClasses = computed(() => this.#getAnimationConfig()?.leave ?? "", /* @ts-ignore */
|
|
85
|
+
...(ngDevMode ? [{ debugName: "leaveAnimationClasses" }] : /* istanbul ignore next */ []));
|
|
86
|
+
this.templateRef = signal(null, /* @ts-ignore */
|
|
87
|
+
...(ngDevMode ? [{ debugName: "templateRef" }] : /* istanbul ignore next */ []));
|
|
88
|
+
this.visible = signal(true, /* @ts-ignore */
|
|
89
|
+
...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
90
|
+
this.wrapperClass = signal("", /* @ts-ignore */
|
|
91
|
+
...(ngDevMode ? [{ debugName: "wrapperClass" }] : /* istanbul ignore next */ []));
|
|
92
|
+
afterNextRender({
|
|
93
|
+
read: () => {
|
|
94
|
+
if (this.#popupSettings.popupWrapperClass != null) {
|
|
95
|
+
if (this.#popupSettings.popupWrapperClass instanceof Array) {
|
|
96
|
+
this.wrapperClass.set(this.#popupSettings.popupWrapperClass.join(" "));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this.wrapperClass.set(this.#popupSettings.popupWrapperClass);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
this.#popupReference.closeStart$
|
|
103
|
+
.pipe(take(1), takeUntilDestroyed(this.#destroyRef))
|
|
104
|
+
.subscribe(event => {
|
|
105
|
+
this.#closeEvent = event;
|
|
106
|
+
const animationElement = this.animationElement().nativeElement;
|
|
107
|
+
this.visible.set(false);
|
|
108
|
+
if (!this.leaveAnimationClasses()) {
|
|
109
|
+
this.#completeClose();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.#document.defaultView?.setTimeout(() => this.#startFallbackTimer(animationElement));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
this.#destroyRef.onDestroy(() => this.#clearFallbackTimer());
|
|
117
|
+
}
|
|
118
|
+
ngOnInit() { }
|
|
119
|
+
attachContent(content, injector) {
|
|
120
|
+
if (content instanceof TemplateRef) {
|
|
121
|
+
this.templateRef.set(content);
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return this.componentOutlet().createComponent(content, { injector });
|
|
125
|
+
}
|
|
126
|
+
onNativeLeaveComplete(event) {
|
|
127
|
+
if (event.target !== event.currentTarget) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.#completeClose();
|
|
131
|
+
}
|
|
132
|
+
#getAnimationConfig() {
|
|
133
|
+
const config = this.#popupSettings.animation;
|
|
134
|
+
if (config === false) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
if (config == null || config === true) {
|
|
138
|
+
return defaultPopupAnimation;
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
enter: config.enter ?? defaultPopupAnimation.enter,
|
|
142
|
+
leave: config.leave ?? defaultPopupAnimation.leave
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
#clearFallbackTimer() {
|
|
146
|
+
if (this.#fallbackTimer == null) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.#document.defaultView?.clearTimeout(this.#fallbackTimer);
|
|
150
|
+
this.#fallbackTimer = null;
|
|
151
|
+
}
|
|
152
|
+
#completeClose() {
|
|
153
|
+
if (this.#leaveCompleted || this.#closeEvent == null) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
this.#leaveCompleted = true;
|
|
157
|
+
this.#clearFallbackTimer();
|
|
158
|
+
this.#popupReference.completeClose(this.#closeEvent);
|
|
159
|
+
}
|
|
160
|
+
#getLongestCssTime(style) {
|
|
161
|
+
return Math.max(this.#getLongestCssTimeFromProperties(style.animationDuration, style.animationDelay), this.#getLongestCssTimeFromProperties(style.transitionDuration, style.transitionDelay));
|
|
162
|
+
}
|
|
163
|
+
#getLongestCssTimeFromProperties(durations, delays) {
|
|
164
|
+
const durationValues = durations.split(",").map(duration => this.#parseCssTime(duration));
|
|
165
|
+
const delayValues = delays.split(",").map(delay => this.#parseCssTime(delay));
|
|
166
|
+
const valueCount = Math.max(durationValues.length, delayValues.length);
|
|
167
|
+
if (valueCount === 0) {
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
return Math.max(...Array.from({ length: valueCount }, (_, index) => {
|
|
171
|
+
const duration = durationValues[index % durationValues.length] ?? 0;
|
|
172
|
+
const delay = delayValues[index % delayValues.length] ?? 0;
|
|
173
|
+
return duration + delay;
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
#parseCssTime(value) {
|
|
177
|
+
const trimmedValue = value.trim();
|
|
178
|
+
if (!trimmedValue) {
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
181
|
+
if (trimmedValue.endsWith("ms")) {
|
|
182
|
+
return Number.parseFloat(trimmedValue);
|
|
183
|
+
}
|
|
184
|
+
if (trimmedValue.endsWith("s")) {
|
|
185
|
+
return Number.parseFloat(trimmedValue) * 1000;
|
|
186
|
+
}
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
#startFallbackTimer(animationElement) {
|
|
190
|
+
if (this.#leaveCompleted) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const win = this.#document.defaultView;
|
|
194
|
+
if (!win) {
|
|
195
|
+
this.#completeClose();
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const duration = this.#getLongestCssTime(win.getComputedStyle(animationElement));
|
|
199
|
+
if (duration <= 0) {
|
|
200
|
+
this.#completeClose();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
this.#fallbackTimer = win.setTimeout(() => this.#completeClose(), duration + 50);
|
|
204
|
+
}
|
|
205
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PopupWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
206
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: PopupWrapperComponent, isStandalone: true, selector: "mona-popup-wrapper", host: { properties: { "class": "hostClasses()" } }, viewQueries: [{ propertyName: "animationElement", first: true, predicate: ["animationElement"], descendants: true, isSignal: true }, { propertyName: "componentOutlet", first: true, predicate: ["componentOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "@if (visible()) {\r\n <div\r\n #animationElement\r\n class=\"w-full h-full origin-center\"\r\n [animate.enter]=\"enterAnimationClasses()\"\r\n [animate.leave]=\"leaveAnimationClasses()\"\r\n (animationcancel)=\"onNativeLeaveComplete($event)\"\r\n (animationend)=\"onNativeLeaveComplete($event)\"\r\n (transitioncancel)=\"onNativeLeaveComplete($event)\"\r\n (transitionend)=\"onNativeLeaveComplete($event)\">\r\n @if (templateRef()) {\r\n <ng-container [ngTemplateOutlet]=\"templateRef()\"></ng-container>\r\n }\r\n <ng-container #componentOutlet></ng-container>\r\n </div>\r\n}\r\n", styles: [":host{display:block}.mona-popup-enter{animation:mona-popup-scale-in .15s cubic-bezier(.4,0,.2,1)}.mona-popup-leave{animation:mona-popup-scale-out .15s cubic-bezier(.4,0,.2,1)}.mona-dropdown-popup-enter{animation:mona-dropdown-popup-scale-in .15s cubic-bezier(.4,0,.2,1);transform-origin:top center}.mona-dropdown-popup-leave{animation:mona-dropdown-popup-scale-out .15s cubic-bezier(.4,0,.2,1);transform-origin:top center}.mona-popup-fade-enter{animation:mona-popup-fade-in 50ms ease-in}.mona-popup-fade-leave{animation:mona-popup-fade-out .15s ease-out}@keyframes mona-popup-scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes mona-popup-scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes mona-dropdown-popup-scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes mona-dropdown-popup-scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes mona-popup-fade-in{0%{opacity:0}to{opacity:1}}@keyframes mona-popup-fade-out{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.mona-popup-enter,.mona-popup-leave,.mona-dropdown-popup-enter,.mona-dropdown-popup-leave,.mona-popup-fade-enter,.mona-popup-fade-leave{animation-duration:1ms}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
|
|
207
|
+
}
|
|
208
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PopupWrapperComponent, decorators: [{
|
|
209
|
+
type: Component,
|
|
210
|
+
args: [{ selector: "mona-popup-wrapper", imports: [NgTemplateOutlet], host: {
|
|
211
|
+
"[class]": "hostClasses()"
|
|
212
|
+
}, template: "@if (visible()) {\r\n <div\r\n #animationElement\r\n class=\"w-full h-full origin-center\"\r\n [animate.enter]=\"enterAnimationClasses()\"\r\n [animate.leave]=\"leaveAnimationClasses()\"\r\n (animationcancel)=\"onNativeLeaveComplete($event)\"\r\n (animationend)=\"onNativeLeaveComplete($event)\"\r\n (transitioncancel)=\"onNativeLeaveComplete($event)\"\r\n (transitionend)=\"onNativeLeaveComplete($event)\">\r\n @if (templateRef()) {\r\n <ng-container [ngTemplateOutlet]=\"templateRef()\"></ng-container>\r\n }\r\n <ng-container #componentOutlet></ng-container>\r\n </div>\r\n}\r\n", styles: [":host{display:block}.mona-popup-enter{animation:mona-popup-scale-in .15s cubic-bezier(.4,0,.2,1)}.mona-popup-leave{animation:mona-popup-scale-out .15s cubic-bezier(.4,0,.2,1)}.mona-dropdown-popup-enter{animation:mona-dropdown-popup-scale-in .15s cubic-bezier(.4,0,.2,1);transform-origin:top center}.mona-dropdown-popup-leave{animation:mona-dropdown-popup-scale-out .15s cubic-bezier(.4,0,.2,1);transform-origin:top center}.mona-popup-fade-enter{animation:mona-popup-fade-in 50ms ease-in}.mona-popup-fade-leave{animation:mona-popup-fade-out .15s ease-out}@keyframes mona-popup-scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes mona-popup-scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes mona-dropdown-popup-scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes mona-dropdown-popup-scale-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes mona-popup-fade-in{0%{opacity:0}to{opacity:1}}@keyframes mona-popup-fade-out{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.mona-popup-enter,.mona-popup-leave,.mona-dropdown-popup-enter,.mona-dropdown-popup-leave,.mona-popup-fade-enter,.mona-popup-fade-leave{animation-duration:1ms}}\n"] }]
|
|
213
|
+
}], ctorParameters: () => [], propDecorators: { animationElement: [{ type: i0.ViewChild, args: ["animationElement", { isSignal: true }] }], componentOutlet: [{ type: i0.ViewChild, args: ["componentOutlet", { ...{ read: ViewContainerRef }, isSignal: true }] }] } });
|
|
214
|
+
|
|
215
|
+
class PopupRef {
|
|
216
|
+
#options;
|
|
217
|
+
constructor(options) {
|
|
218
|
+
this.#options = options;
|
|
219
|
+
}
|
|
220
|
+
close(result, delay) {
|
|
221
|
+
this.#options.close(result, delay);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Closes the popup after a delay.
|
|
225
|
+
* When the popup is closed, the overlay element is removed from the DOM instantly.
|
|
226
|
+
* This causes the animation of the child elements to not play, therefore,
|
|
227
|
+
* a delay is added to allow the animation to play.
|
|
228
|
+
*
|
|
229
|
+
* @see {@link https://github.com/angular/angular/issues/23302} for more information.
|
|
230
|
+
* @param delay delay in milliseconds
|
|
231
|
+
* @param result optional result to pass to the closed observable
|
|
232
|
+
*/
|
|
233
|
+
closeWithDelay(delay = 100, result) {
|
|
234
|
+
asapScheduler.schedule(() => this.close(result), delay);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* @description Emitted when the popup is about to close.
|
|
238
|
+
* This event can be prevented. If it is prevented, the popup will not close.
|
|
239
|
+
*/
|
|
240
|
+
get beforeClose() {
|
|
241
|
+
return this.#options.beforeClose$;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* @description Emitted when the popup begins closing, before the leave animation completes.
|
|
245
|
+
* Subscribe to this to react at the moment the close sequence starts — for example, to begin
|
|
246
|
+
* coordinating a transition in the consuming component. The `closed` observable fires after
|
|
247
|
+
* the leave animation finishes.
|
|
248
|
+
*/
|
|
249
|
+
get closeStart() {
|
|
250
|
+
return this.#options.closeStart$;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* @description Emitted when the popup is closed.
|
|
254
|
+
* This event is emitted after the animation completes.
|
|
255
|
+
* Preventing this event has no effect.
|
|
256
|
+
*/
|
|
257
|
+
get closed() {
|
|
258
|
+
return this.#options.closed$;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* @description Reference to the component hosted in the popup.
|
|
262
|
+
* This is `null` if the popup does not contain a component.
|
|
263
|
+
*/
|
|
264
|
+
get component() {
|
|
265
|
+
return this.#options.component;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* @description Emitted when the popup is opened.
|
|
269
|
+
*/
|
|
270
|
+
get opened() {
|
|
271
|
+
return this.#options.opened$;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* @description Reference to the underlying CDK overlay.
|
|
275
|
+
* Use this reference to manipulate the overlay directly, such as to set its size or position.
|
|
276
|
+
* @see {@link https://material.angular.io/cdk/overlay/overview} for more information.
|
|
277
|
+
* @example
|
|
278
|
+
* ```ts
|
|
279
|
+
* const overlayRef = popupRef.overlayRef;
|
|
280
|
+
* overlayRef.updateSize({ width: '500px', height: '300px' });
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
get overlayRef() {
|
|
284
|
+
return this.#options.overlayRef;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* @description Returns the position pair of the popup's anchor element.
|
|
288
|
+
* @example
|
|
289
|
+
* ```ts
|
|
290
|
+
* const positionChanges$ = popupRef.positionChanges;
|
|
291
|
+
* positionChanges$.subscribe(pair => {
|
|
292
|
+
* console.log(`Popup position changed to: ${pair.originX} ${pair.originY} -> ${pair.overlayX} ${pair.overlayY}`);
|
|
293
|
+
* });
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
get positionChanges() {
|
|
297
|
+
return this.#options.positionChanges$;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* @internal - used by the popup service. Do not use directly or export.
|
|
303
|
+
*/
|
|
304
|
+
class PopupReference {
|
|
305
|
+
#closed;
|
|
306
|
+
#closing;
|
|
307
|
+
constructor(overlayReference, preventClose) {
|
|
308
|
+
this.overlayReference = overlayReference;
|
|
309
|
+
this.preventClose = preventClose;
|
|
310
|
+
this.beforeClosed$ = new Subject();
|
|
311
|
+
this.closeStart$ = new Subject();
|
|
312
|
+
this.closed$ = new Subject();
|
|
313
|
+
this.opened$ = new ReplaySubject(1);
|
|
314
|
+
this.positionChanges$ = new Subject();
|
|
315
|
+
this.#closed = false;
|
|
316
|
+
this.#closing = false;
|
|
317
|
+
this.popupRef = new PopupRef(this);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Emits {@link beforeClosed$} exactly once and, unless the close is prevented (either by the
|
|
321
|
+
* `preventClose` callback passed to the popup or by a subscriber calling `preventDefault()`
|
|
322
|
+
* on the event), proceeds to close the popup.
|
|
323
|
+
* @returns `true` if the close proceeded, `false` if it was prevented.
|
|
324
|
+
*/
|
|
325
|
+
close(result, delay) {
|
|
326
|
+
if (this.#closing) {
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
const beforeCloseEvent = result instanceof PopupCloseEvent
|
|
330
|
+
? result
|
|
331
|
+
: new PopupCloseEvent({ result, via: PopupCloseSource.Programmatic });
|
|
332
|
+
this.beforeClosed$.next(beforeCloseEvent);
|
|
333
|
+
const prevented = this.preventClose
|
|
334
|
+
? this.preventClose(beforeCloseEvent) || beforeCloseEvent.isDefaultPrevented()
|
|
335
|
+
: beforeCloseEvent.isDefaultPrevented();
|
|
336
|
+
if (prevented) {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
this.#closing = true;
|
|
340
|
+
this.closeStart$.next(beforeCloseEvent);
|
|
341
|
+
if (delay != null) {
|
|
342
|
+
if (delay > 0) {
|
|
343
|
+
asyncScheduler.schedule(() => this.completeClose(beforeCloseEvent), delay);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
this.completeClose(beforeCloseEvent);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
else if (this.wrapperComponentRef == null) {
|
|
350
|
+
this.completeClose(beforeCloseEvent);
|
|
351
|
+
}
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
notifyOpen() {
|
|
355
|
+
this.opened$.next();
|
|
356
|
+
}
|
|
357
|
+
completeClose(event) {
|
|
358
|
+
if (this.#closed) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
this.#closed = true;
|
|
362
|
+
this.closed$.next(event);
|
|
363
|
+
this.closed$.complete();
|
|
364
|
+
this.positionChanges$.complete();
|
|
365
|
+
this.overlayRef.dispose();
|
|
366
|
+
}
|
|
367
|
+
get beforeClose$() {
|
|
368
|
+
return this.beforeClosed$.asObservable();
|
|
369
|
+
}
|
|
370
|
+
get closeStart() {
|
|
371
|
+
return this.closeStart$.asObservable();
|
|
372
|
+
}
|
|
373
|
+
get closed() {
|
|
374
|
+
return this.closed$.asObservable();
|
|
375
|
+
}
|
|
376
|
+
get component() {
|
|
377
|
+
return this.componentRef ?? null;
|
|
378
|
+
}
|
|
379
|
+
get opened() {
|
|
380
|
+
return this.opened$;
|
|
381
|
+
}
|
|
382
|
+
get overlayRef() {
|
|
383
|
+
return this.overlayReference;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const connectionPosition = (anchorConnectionPoint, popupConnectionPoint) => {
|
|
388
|
+
const originMap = {
|
|
389
|
+
topleft: { originX: "start", originY: "top" },
|
|
390
|
+
topcenter: { originX: "center", originY: "top" },
|
|
391
|
+
topright: { originX: "end", originY: "top" },
|
|
392
|
+
centerleft: { originX: "start", originY: "center" },
|
|
393
|
+
center: { originX: "center", originY: "center" },
|
|
394
|
+
centerright: { originX: "end", originY: "center" },
|
|
395
|
+
bottomleft: { originX: "start", originY: "bottom" },
|
|
396
|
+
bottomcenter: { originX: "center", originY: "bottom" },
|
|
397
|
+
bottomright: { originX: "end", originY: "bottom" }
|
|
398
|
+
};
|
|
399
|
+
const overlayMap = {
|
|
400
|
+
topleft: { overlayX: "start", overlayY: "top" },
|
|
401
|
+
topcenter: { overlayX: "center", overlayY: "top" },
|
|
402
|
+
topright: { overlayX: "end", overlayY: "top" },
|
|
403
|
+
centerleft: { overlayX: "start", overlayY: "center" },
|
|
404
|
+
center: { overlayX: "center", overlayY: "center" },
|
|
405
|
+
centerright: { overlayX: "end", overlayY: "center" },
|
|
406
|
+
bottomleft: { overlayX: "start", overlayY: "bottom" },
|
|
407
|
+
bottomcenter: { overlayX: "center", overlayY: "bottom" },
|
|
408
|
+
bottomright: { overlayX: "end", overlayY: "bottom" }
|
|
409
|
+
};
|
|
410
|
+
const primaryPosition = {
|
|
411
|
+
...originMap[anchorConnectionPoint],
|
|
412
|
+
...overlayMap[popupConnectionPoint]
|
|
413
|
+
};
|
|
414
|
+
const fallbackPositions = generateFallbackPositions(primaryPosition);
|
|
415
|
+
return [primaryPosition, ...fallbackPositions];
|
|
416
|
+
};
|
|
417
|
+
/**
|
|
418
|
+
* Generate fallback positions for the given primary position.
|
|
419
|
+
* This function is mostly AI-generated.
|
|
420
|
+
* @param primaryPosition The primary position to generate fallbacks for.
|
|
421
|
+
*/
|
|
422
|
+
const generateFallbackPositions = (primaryPosition) => {
|
|
423
|
+
const { originX, originY, overlayX, overlayY } = primaryPosition;
|
|
424
|
+
const fallbacks = [];
|
|
425
|
+
// 1. Keep the same X, try bottom.
|
|
426
|
+
if (originY !== "bottom" && overlayY !== "bottom") {
|
|
427
|
+
if (originY === "top") {
|
|
428
|
+
fallbacks.push({ originX, originY: "bottom", overlayX, overlayY: "bottom" });
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
//originY is center
|
|
432
|
+
if (overlayY === "top") {
|
|
433
|
+
fallbacks.push({ originX, originY: "center", overlayX, overlayY: "bottom" });
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// 2. Keep same Y, try right
|
|
438
|
+
if (originX !== "end" && overlayX !== "end") {
|
|
439
|
+
if (originX === "start") {
|
|
440
|
+
fallbacks.push({ originX: "end", originY, overlayX: "end", overlayY });
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
// originX is center
|
|
444
|
+
if (overlayX === "start") {
|
|
445
|
+
fallbacks.push({ originX: "center", originY, overlayX: "end", overlayY });
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// 3. Keep X and flip Y to the opposite if possible.
|
|
450
|
+
if (!fallbacks.find(f => f.originX === originX && f.overlayX === overlayX)) {
|
|
451
|
+
if (originY === "top" && overlayY === "top") {
|
|
452
|
+
fallbacks.push({ originX, originY: "bottom", overlayX, overlayY: "bottom" });
|
|
453
|
+
}
|
|
454
|
+
else if (originY === "bottom" && overlayY === "bottom") {
|
|
455
|
+
fallbacks.push({ originX, originY: "top", overlayX, overlayY: "top" });
|
|
456
|
+
}
|
|
457
|
+
else if (originY === "top" && overlayY === "bottom") {
|
|
458
|
+
fallbacks.push({ originX, originY: "bottom", overlayX, overlayY: "top" });
|
|
459
|
+
}
|
|
460
|
+
else if (originY === "bottom" && overlayY === "top") {
|
|
461
|
+
fallbacks.push({ originX, originY: "top", overlayX, overlayY: "bottom" });
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
//originY === 'center'
|
|
465
|
+
if (overlayY === "top") {
|
|
466
|
+
fallbacks.push({ originX, originY: "center", overlayX, overlayY: "bottom" });
|
|
467
|
+
}
|
|
468
|
+
else if (overlayY === "bottom") {
|
|
469
|
+
fallbacks.push({ originX, originY: "center", overlayX, overlayY: "top" });
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// 4. Keep Y and flip X to the opposite if possible
|
|
474
|
+
if (!fallbacks.find(f => f.originY === originY && f.overlayY === overlayY)) {
|
|
475
|
+
if (originX === "start" && overlayX === "start") {
|
|
476
|
+
fallbacks.push({ originX: "end", originY, overlayX: "end", overlayY });
|
|
477
|
+
}
|
|
478
|
+
else if (originX === "end" && overlayX === "end") {
|
|
479
|
+
fallbacks.push({ originX: "start", originY, overlayX: "start", overlayY });
|
|
480
|
+
}
|
|
481
|
+
else if (originX === "start" && overlayX === "end") {
|
|
482
|
+
fallbacks.push({ originX: "end", originY, overlayX: "start", overlayY });
|
|
483
|
+
}
|
|
484
|
+
else if (originX === "end" && overlayX === "start") {
|
|
485
|
+
fallbacks.push({ originX: "start", originY, overlayX: "end", overlayY });
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
if (overlayX === "start") {
|
|
489
|
+
fallbacks.push({ originX: "center", originY, overlayX: "end", overlayY });
|
|
490
|
+
}
|
|
491
|
+
else if (overlayX === "end") {
|
|
492
|
+
fallbacks.push({ originX: "center", originY, overlayX: "start", overlayY });
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
// 5. Diagonal Flips
|
|
497
|
+
if (originX === "start" && originY === "top" && overlayX === "end" && overlayY === "bottom") {
|
|
498
|
+
fallbacks.push({ originX: "end", originY: "bottom", overlayX: "start", overlayY: "top" });
|
|
499
|
+
}
|
|
500
|
+
else if (originX === "end" && originY === "bottom" && overlayX === "start" && overlayY === "top") {
|
|
501
|
+
fallbacks.push({ originX: "start", originY: "top", overlayX: "end", overlayY: "bottom" });
|
|
502
|
+
}
|
|
503
|
+
else if (originX === "start" && originY === "bottom" && overlayX === "end" && overlayY === "top") {
|
|
504
|
+
fallbacks.push({ originX: "end", originY: "top", overlayX: "start", overlayY: "bottom" });
|
|
505
|
+
}
|
|
506
|
+
else if (originX === "end" && originY === "top" && overlayX === "start" && overlayY === "bottom") {
|
|
507
|
+
fallbacks.push({ originX: "start", originY: "bottom", overlayX: "end", overlayY: "top" });
|
|
508
|
+
}
|
|
509
|
+
//6. Complete mirroring:
|
|
510
|
+
if (!fallbacks.find(f => f.originX !== originX && f.overlayX !== overlayX && f.originY !== originY && f.overlayY !== overlayY)) {
|
|
511
|
+
if (originX === "start" && originY === "top") {
|
|
512
|
+
fallbacks.push({ originX: "end", originY: "bottom", overlayX: "end", overlayY: "bottom" });
|
|
513
|
+
}
|
|
514
|
+
else if (originX === "center" && originY === "top") {
|
|
515
|
+
fallbacks.push({ originX: "center", originY: "bottom", overlayX: "center", overlayY: "bottom" });
|
|
516
|
+
}
|
|
517
|
+
else if (originX === "end" && originY === "top") {
|
|
518
|
+
fallbacks.push({ originX: "start", originY: "bottom", overlayX: "start", overlayY: "bottom" });
|
|
519
|
+
}
|
|
520
|
+
else if (originX === "start" && originY === "center") {
|
|
521
|
+
fallbacks.push({ originX: "end", originY: "center", overlayX: "end", overlayY: "center" });
|
|
522
|
+
}
|
|
523
|
+
else if (originX === "center" && originY === "center") {
|
|
524
|
+
fallbacks.push({ originX: "center", originY: "center", overlayX: "center", overlayY: "center" });
|
|
525
|
+
}
|
|
526
|
+
else if (originX === "end" && originY === "center") {
|
|
527
|
+
fallbacks.push({ originX: "start", originY: "center", overlayX: "start", overlayY: "center" });
|
|
528
|
+
}
|
|
529
|
+
else if (originX === "start" && originY === "bottom") {
|
|
530
|
+
fallbacks.push({ originX: "end", originY: "top", overlayX: "end", overlayY: "top" });
|
|
531
|
+
}
|
|
532
|
+
else if (originX === "center" && originY === "bottom") {
|
|
533
|
+
fallbacks.push({ originX: "center", originY: "top", overlayX: "center", overlayY: "top" });
|
|
534
|
+
}
|
|
535
|
+
else if (originX === "end" && originY === "bottom") {
|
|
536
|
+
fallbacks.push({ originX: "start", originY: "top", overlayX: "start", overlayY: "top" });
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return fallbacks;
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
class PopupService {
|
|
543
|
+
#destroyRef = inject(DestroyRef);
|
|
544
|
+
#directionality = inject(Directionality, { optional: true });
|
|
545
|
+
#document = inject(DOCUMENT);
|
|
546
|
+
#injector = inject(Injector);
|
|
547
|
+
#outsideEventsToClose = ["click", "mousedown", "dblclick", "contextmenu", "auxclick"];
|
|
548
|
+
#overlay = inject(Overlay);
|
|
549
|
+
#selectorSubscriptions = new Map();
|
|
550
|
+
#scrollDispatcher = inject(ScrollDispatcher);
|
|
551
|
+
create(settings) {
|
|
552
|
+
if (typeof settings.anchor === "string") {
|
|
553
|
+
return this.createMultiElementPopup(settings);
|
|
554
|
+
}
|
|
555
|
+
return this.createSingleElementPopup(settings);
|
|
556
|
+
}
|
|
557
|
+
attachContent(settings, popupReference, overlayRef, injector) {
|
|
558
|
+
const portal = new ComponentPortal(PopupWrapperComponent, null, injector);
|
|
559
|
+
const wrapperComponentRef = overlayRef.attach(portal);
|
|
560
|
+
popupReference.wrapperComponentRef = wrapperComponentRef;
|
|
561
|
+
wrapperComponentRef.changeDetectorRef.detectChanges();
|
|
562
|
+
popupReference.componentRef =
|
|
563
|
+
wrapperComponentRef.instance.attachContent(settings.content, injector) ?? undefined;
|
|
564
|
+
wrapperComponentRef.changeDetectorRef.detectChanges();
|
|
565
|
+
return wrapperComponentRef.location.nativeElement;
|
|
566
|
+
}
|
|
567
|
+
buildPanelClass(popupClass) {
|
|
568
|
+
if (!popupClass) {
|
|
569
|
+
return "mona-popup-content";
|
|
570
|
+
}
|
|
571
|
+
return ["mona-popup-content"].concat(popupClass);
|
|
572
|
+
}
|
|
573
|
+
captureOriginalFocus(settings) {
|
|
574
|
+
if (typeof settings.anchor === "string" || settings.restoreFocus === false) {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
const activeElement = this.#document.activeElement;
|
|
578
|
+
if (!(activeElement instanceof HTMLElement)) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
if (settings.restoreFocus === "auto") {
|
|
582
|
+
const anchorElement = this.getAnchorElement(settings.anchor);
|
|
583
|
+
return activeElement === anchorElement ? activeElement : null;
|
|
584
|
+
}
|
|
585
|
+
return this.getAnchorElement(settings.anchor);
|
|
586
|
+
}
|
|
587
|
+
cleanupEventDelegation(selector) {
|
|
588
|
+
const subscriptions = this.#selectorSubscriptions.get(selector);
|
|
589
|
+
if (subscriptions) {
|
|
590
|
+
subscriptions.forEach(sub => sub.unsubscribe());
|
|
591
|
+
this.#selectorSubscriptions.delete(selector);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
createInjector(settings, popupReference) {
|
|
595
|
+
return Injector.create({
|
|
596
|
+
parent: this.#injector,
|
|
597
|
+
providers: [
|
|
598
|
+
{ provide: PopupRef, useFactory: () => popupReference.popupRef },
|
|
599
|
+
{ provide: PopupDataInjectionToken, useValue: settings.data },
|
|
600
|
+
{ provide: PopupReferenceInjectionToken, useValue: popupReference },
|
|
601
|
+
{ provide: PopupSettingsInjectionToken, useValue: settings },
|
|
602
|
+
...(settings.providers ?? [])
|
|
603
|
+
]
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
createMultiElementPopup(settings) {
|
|
607
|
+
const selector = settings.anchor;
|
|
608
|
+
// Create a virtual PopupRef that manages multi-element interactions
|
|
609
|
+
const virtualOverlayRef = this.#overlay.create({ hasBackdrop: false });
|
|
610
|
+
const virtualPopupReference = new PopupReference(virtualOverlayRef);
|
|
611
|
+
// Set up the event delegation internally
|
|
612
|
+
this.setupInternalEventDelegation(selector, settings);
|
|
613
|
+
// Clean up when the virtual popup is closed
|
|
614
|
+
virtualPopupReference.popupRef.closed.subscribe(() => {
|
|
615
|
+
this.cleanupEventDelegation(selector);
|
|
616
|
+
});
|
|
617
|
+
return virtualPopupReference.popupRef;
|
|
618
|
+
}
|
|
619
|
+
createOverlay(settings) {
|
|
620
|
+
const positionStrategy = this.createPositionStrategy(settings);
|
|
621
|
+
const panelClass = this.buildPanelClass(settings.popupClass);
|
|
622
|
+
const direction = this.#directionality?.value;
|
|
623
|
+
return this.#overlay.create(new OverlayConfig({
|
|
624
|
+
positionStrategy,
|
|
625
|
+
hasBackdrop: settings.hasBackdrop ?? false,
|
|
626
|
+
height: settings.height,
|
|
627
|
+
maxHeight: settings.maxHeight,
|
|
628
|
+
maxWidth: settings.maxWidth,
|
|
629
|
+
minHeight: settings.minHeight,
|
|
630
|
+
minWidth: settings.minWidth,
|
|
631
|
+
width: settings.width,
|
|
632
|
+
panelClass,
|
|
633
|
+
backdropClass: settings.backdropClass ?? "transparent",
|
|
634
|
+
direction
|
|
635
|
+
}));
|
|
636
|
+
}
|
|
637
|
+
createPositionStrategy(settings) {
|
|
638
|
+
if (settings.positionStrategy === "global") {
|
|
639
|
+
return this.#overlay.position().global();
|
|
640
|
+
}
|
|
641
|
+
const resolvedAnchor = this.resolveAnchor(settings.anchor);
|
|
642
|
+
const position = settings.positions?.length
|
|
643
|
+
? settings.positions
|
|
644
|
+
: this.getPosition(settings.anchorConnectionPoint, settings.popupConnectionPoint);
|
|
645
|
+
const strategy = this.#overlay
|
|
646
|
+
.position()
|
|
647
|
+
.flexibleConnectedTo(resolvedAnchor)
|
|
648
|
+
.withPositions(position)
|
|
649
|
+
.withDefaultOffsetX(settings.offset?.horizontal ?? 0)
|
|
650
|
+
.withDefaultOffsetY(settings.offset?.vertical ?? 0)
|
|
651
|
+
.withPush(settings.withPush ?? true);
|
|
652
|
+
if (settings.withScrollTracking ?? true) {
|
|
653
|
+
const scrollableContainers = this.getScrollableContainers(resolvedAnchor);
|
|
654
|
+
strategy.withScrollableContainers(scrollableContainers);
|
|
655
|
+
}
|
|
656
|
+
return strategy;
|
|
657
|
+
}
|
|
658
|
+
createScrollDispatcherTarget(element) {
|
|
659
|
+
const elementRef = new ElementRef(element);
|
|
660
|
+
return {
|
|
661
|
+
elementScrolled: () => fromEvent(element, "scroll", { passive: true }),
|
|
662
|
+
getElementRef: () => elementRef
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
createSingleElementPopup(settings) {
|
|
666
|
+
const overlayRef = this.createOverlay(settings);
|
|
667
|
+
const popupReference = new PopupReference(overlayRef, settings.preventClose);
|
|
668
|
+
const originallyFocusedElement = this.captureOriginalFocus(settings);
|
|
669
|
+
const injector = this.createInjector(settings, popupReference);
|
|
670
|
+
popupReference.notifyOpen();
|
|
671
|
+
this.attachContent(settings, popupReference, overlayRef, injector);
|
|
672
|
+
const subscription = this.setupCloseSubscriptions(settings, popupReference, overlayRef);
|
|
673
|
+
this.setupCleanupSubscription(popupReference, subscription, settings, originallyFocusedElement);
|
|
674
|
+
if (settings.closeOnScroll) {
|
|
675
|
+
this.setupScrollClosing(settings, popupReference, overlayRef);
|
|
676
|
+
}
|
|
677
|
+
this.setupScrollTracking(settings, overlayRef, popupReference);
|
|
678
|
+
this.setupEscapeKeyListener(settings, popupReference);
|
|
679
|
+
this.setupPositionChangeTracking(settings, overlayRef, popupReference);
|
|
680
|
+
return popupReference.popupRef;
|
|
681
|
+
}
|
|
682
|
+
getAnchorElement(anchor) {
|
|
683
|
+
if (anchor instanceof HTMLElement) {
|
|
684
|
+
return anchor;
|
|
685
|
+
}
|
|
686
|
+
if (typeof anchor === "object" && "nativeElement" in anchor && anchor.nativeElement instanceof HTMLElement) {
|
|
687
|
+
return anchor.nativeElement;
|
|
688
|
+
}
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
getPosition(anchorConnectionPoint, popupConnectionPoint) {
|
|
692
|
+
const anchorPoint = anchorConnectionPoint ?? "bottomleft";
|
|
693
|
+
const popupPoint = popupConnectionPoint ?? "topleft";
|
|
694
|
+
return connectionPosition(anchorPoint, popupPoint);
|
|
695
|
+
}
|
|
696
|
+
getScrollableAncestorElements(anchorElement) {
|
|
697
|
+
const scrollables = [];
|
|
698
|
+
let element = anchorElement.parentElement;
|
|
699
|
+
while (element) {
|
|
700
|
+
if (this.isScrollableElement(element)) {
|
|
701
|
+
scrollables.push(element);
|
|
702
|
+
}
|
|
703
|
+
element = element.parentElement;
|
|
704
|
+
}
|
|
705
|
+
return scrollables;
|
|
706
|
+
}
|
|
707
|
+
getScrollableContainers(anchor) {
|
|
708
|
+
const anchorElement = this.getAnchorElement(anchor);
|
|
709
|
+
if (!anchorElement) {
|
|
710
|
+
return [];
|
|
711
|
+
}
|
|
712
|
+
const scrollablesByElement = new Map();
|
|
713
|
+
const addScrollable = (scrollable) => {
|
|
714
|
+
scrollablesByElement.set(scrollable.getElementRef().nativeElement, scrollable);
|
|
715
|
+
};
|
|
716
|
+
this.#scrollDispatcher
|
|
717
|
+
.getAncestorScrollContainers(anchorElement)
|
|
718
|
+
.forEach(scrollable => addScrollable(scrollable));
|
|
719
|
+
this.getScrollableAncestorElements(anchorElement)
|
|
720
|
+
.map(element => this.createScrollDispatcherTarget(element))
|
|
721
|
+
.forEach(scrollable => addScrollable(scrollable));
|
|
722
|
+
return Array.from(scrollablesByElement.values());
|
|
723
|
+
}
|
|
724
|
+
isScrollableElement(element) {
|
|
725
|
+
const defaultView = this.#document.defaultView;
|
|
726
|
+
if (!defaultView) {
|
|
727
|
+
return false;
|
|
728
|
+
}
|
|
729
|
+
const style = defaultView.getComputedStyle(element);
|
|
730
|
+
const canScrollVertically = (this.isScrollableOverflow(style.overflowY) || this.isScrollableOverflow(style.overflow)) &&
|
|
731
|
+
element.scrollHeight > element.clientHeight;
|
|
732
|
+
const canScrollHorizontally = (this.isScrollableOverflow(style.overflowX) || this.isScrollableOverflow(style.overflow)) &&
|
|
733
|
+
element.scrollWidth > element.clientWidth;
|
|
734
|
+
return canScrollVertically || canScrollHorizontally;
|
|
735
|
+
}
|
|
736
|
+
isScrollableOverflow(value) {
|
|
737
|
+
return value === "auto" || value === "scroll" || value === "overlay";
|
|
738
|
+
}
|
|
739
|
+
handleFocusRestoration(settings, originallyFocusedElement) {
|
|
740
|
+
const restoreFocus = settings.restoreFocus ?? "auto";
|
|
741
|
+
if (restoreFocus === false) {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
if (restoreFocus === "auto") {
|
|
745
|
+
if (originallyFocusedElement) {
|
|
746
|
+
originallyFocusedElement.focus();
|
|
747
|
+
}
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
this.restoreFocusToAnchor(settings.anchor);
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Resolves a PopupAnchor to a FlexibleConnectedPositionStrategyOrigin.
|
|
754
|
+
* This method should only receive actual elements or ElementRefs, not CSS selector strings.
|
|
755
|
+
* CSS selectors are handled by the multi-element popup creation path.
|
|
756
|
+
* @param anchor The anchor to resolve (should be Element or ElementRef)
|
|
757
|
+
* @returns The resolved anchor
|
|
758
|
+
*/
|
|
759
|
+
resolveAnchor(anchor) {
|
|
760
|
+
if (typeof anchor === "string") {
|
|
761
|
+
throw new Error(`CSS selector "${anchor}" should not reach resolveAnchor(). ` +
|
|
762
|
+
`CSS selectors should be handled by createMultiElementPopup().`);
|
|
763
|
+
}
|
|
764
|
+
return anchor;
|
|
765
|
+
}
|
|
766
|
+
restoreFocusToAnchor(anchor) {
|
|
767
|
+
if (typeof anchor === "string") {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
const resolvedAnchor = this.resolveAnchor(anchor);
|
|
771
|
+
const anchorElement = this.getAnchorElement(resolvedAnchor);
|
|
772
|
+
if (anchorElement) {
|
|
773
|
+
anchorElement.focus();
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
setupBackdropCloseSubscription(settings, popupReference, overlayRef) {
|
|
777
|
+
if (!(settings.closeOnBackdropClick ?? true)) {
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
const backdropSubject = new Subject();
|
|
781
|
+
return overlayRef
|
|
782
|
+
.backdropClick()
|
|
783
|
+
.pipe(takeUntil(backdropSubject))
|
|
784
|
+
.subscribe(e => {
|
|
785
|
+
const event = new PopupCloseEvent({
|
|
786
|
+
event: e,
|
|
787
|
+
originalEvent: e,
|
|
788
|
+
via: PopupCloseSource.BackdropClick
|
|
789
|
+
});
|
|
790
|
+
if (!popupReference.close(event)) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
backdropSubject.next();
|
|
794
|
+
backdropSubject.complete();
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
setupCleanupSubscription(popupReference, subscription, settings, originallyFocusedElement) {
|
|
798
|
+
popupReference.closed.pipe(take(1)).subscribe(() => {
|
|
799
|
+
subscription?.unsubscribe();
|
|
800
|
+
this.handleFocusRestoration(settings, originallyFocusedElement);
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
setupCloseSubscriptions(settings, popupReference, overlayRef) {
|
|
804
|
+
const subscriptions = [];
|
|
805
|
+
if (settings.hasBackdrop) {
|
|
806
|
+
const backdropSub = this.setupBackdropCloseSubscription(settings, popupReference, overlayRef);
|
|
807
|
+
if (backdropSub) {
|
|
808
|
+
subscriptions.push(backdropSub);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (settings.closeOnOutsideClick ?? true) {
|
|
812
|
+
const outsideClickSub = this.setupOutsideClickSubscription(settings, popupReference, overlayRef);
|
|
813
|
+
if (outsideClickSub) {
|
|
814
|
+
subscriptions.push(outsideClickSub);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
if (settings.closeOnMouseLeave) {
|
|
818
|
+
const mouseLeaveSubscription = this.setupMouseLeaveSubscription(settings, popupReference);
|
|
819
|
+
if (mouseLeaveSubscription) {
|
|
820
|
+
subscriptions.push(mouseLeaveSubscription);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
if (subscriptions.length === 0) {
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
const combinedSubscription = new Subscription();
|
|
827
|
+
subscriptions.forEach(sub => combinedSubscription.add(sub));
|
|
828
|
+
return combinedSubscription;
|
|
829
|
+
}
|
|
830
|
+
setupEscapeKeyListener(settings, popupReference) {
|
|
831
|
+
if (settings.closeOnEscape === false) {
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
fromEvent(this.#document, "keydown")
|
|
835
|
+
.pipe(filter(() => popupReference.overlayRef.hasAttached()), filter(event => event.key === "Escape"), takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
836
|
+
.subscribe(event => {
|
|
837
|
+
const closeEvent = new PopupCloseEvent({
|
|
838
|
+
event,
|
|
839
|
+
originalEvent: event,
|
|
840
|
+
via: PopupCloseSource.Escape
|
|
841
|
+
});
|
|
842
|
+
popupReference.popupRef.close(closeEvent);
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
setupInternalEventDelegation(selector, settings) {
|
|
846
|
+
this.cleanupEventDelegation(selector);
|
|
847
|
+
let currentPopupRef = null;
|
|
848
|
+
const subscriptions = [];
|
|
849
|
+
const elements = this.#document.querySelectorAll(selector);
|
|
850
|
+
elements.forEach(element => {
|
|
851
|
+
if (!(element instanceof HTMLElement)) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
const pointerEnter$ = fromEvent(element, "pointerenter");
|
|
855
|
+
const pointerLeave$ = fromEvent(element, "pointerleave");
|
|
856
|
+
const subscription = pointerEnter$
|
|
857
|
+
.pipe(filter(() => !currentPopupRef), tap(() => {
|
|
858
|
+
const elementSettings = { ...settings, anchor: element };
|
|
859
|
+
currentPopupRef = this.createSingleElementPopup(elementSettings);
|
|
860
|
+
}), exhaustMap(() => pointerLeave$.pipe(take(1))), tap(() => {
|
|
861
|
+
if (currentPopupRef) {
|
|
862
|
+
currentPopupRef.close();
|
|
863
|
+
currentPopupRef = null;
|
|
864
|
+
}
|
|
865
|
+
}), takeUntilDestroyed(this.#destroyRef))
|
|
866
|
+
.subscribe();
|
|
867
|
+
subscriptions.push(subscription);
|
|
868
|
+
});
|
|
869
|
+
this.#selectorSubscriptions.set(selector, subscriptions);
|
|
870
|
+
}
|
|
871
|
+
setupMouseLeaveSubscription(settings, popupReference) {
|
|
872
|
+
if (typeof settings.anchor === "string") {
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
const resolvedAnchor = this.resolveAnchor(settings.anchor);
|
|
876
|
+
const anchorElement = this.getAnchorElement(resolvedAnchor);
|
|
877
|
+
if (!anchorElement) {
|
|
878
|
+
return null;
|
|
879
|
+
}
|
|
880
|
+
return fromEvent(anchorElement, "pointerleave")
|
|
881
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
882
|
+
.subscribe(event => {
|
|
883
|
+
const closeEvent = new PopupCloseEvent({
|
|
884
|
+
event,
|
|
885
|
+
originalEvent: event,
|
|
886
|
+
via: PopupCloseSource.MouseLeave
|
|
887
|
+
});
|
|
888
|
+
popupReference.close(closeEvent);
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
setupOutsideClickSubscription(settings, popupReference, overlayRef) {
|
|
892
|
+
return overlayRef
|
|
893
|
+
.outsidePointerEvents()
|
|
894
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
895
|
+
.subscribe(event => {
|
|
896
|
+
if (this.shouldIgnoreOutsideClick(settings, event)) {
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
const closeEvent = new PopupCloseEvent({
|
|
900
|
+
event,
|
|
901
|
+
originalEvent: event,
|
|
902
|
+
via: PopupCloseSource.OutsideClick
|
|
903
|
+
});
|
|
904
|
+
popupReference.close(closeEvent);
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
setupPositionChangeTracking(settings, overlayRef, popupReference) {
|
|
908
|
+
if (settings.positionStrategy === "global") {
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
const positionStrategy = overlayRef.getConfig().positionStrategy;
|
|
912
|
+
if (positionStrategy && positionStrategy.positionChanges) {
|
|
913
|
+
positionStrategy.positionChanges
|
|
914
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
915
|
+
.subscribe(change => popupReference.positionChanges$.next(change.connectionPair));
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
setupScrollClosing(settings, popupReference, overlayRef) {
|
|
919
|
+
if (!settings.closeOnScroll) {
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
const scrollableContainers = this.getScrollableContainers(this.resolveAnchor(settings.anchor));
|
|
923
|
+
const subscriptions = [];
|
|
924
|
+
const handleScrollClose = (originalEvent) => {
|
|
925
|
+
if (!overlayRef.hasAttached()) {
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
const closeEvent = new PopupCloseEvent({
|
|
929
|
+
event: originalEvent ?? new Event("scroll"),
|
|
930
|
+
originalEvent: originalEvent ?? new Event("scroll"),
|
|
931
|
+
via: PopupCloseSource.Scroll
|
|
932
|
+
});
|
|
933
|
+
popupReference.close(closeEvent, 0);
|
|
934
|
+
};
|
|
935
|
+
if (scrollableContainers.length === 0) {
|
|
936
|
+
const win = this.#document.defaultView;
|
|
937
|
+
const globalScrollSubscription = merge(fromEvent(win, "scroll", { passive: true }), fromEvent(win, "resize", { passive: true }), fromEvent(this.#document, "scroll", { passive: true }))
|
|
938
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
939
|
+
.subscribe(event => handleScrollClose(event));
|
|
940
|
+
subscriptions.push(globalScrollSubscription);
|
|
941
|
+
}
|
|
942
|
+
else {
|
|
943
|
+
scrollableContainers.forEach(scrollable => {
|
|
944
|
+
const containerScrollSubscription = scrollable
|
|
945
|
+
.elementScrolled()
|
|
946
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
947
|
+
.subscribe(() => handleScrollClose());
|
|
948
|
+
subscriptions.push(containerScrollSubscription);
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
popupReference.closed.pipe(take(1)).subscribe(() => {
|
|
952
|
+
subscriptions.forEach(sub => sub.unsubscribe());
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
setupScrollTracking(settings, overlayRef, popupReference) {
|
|
956
|
+
if (!(settings.withScrollTracking ?? true) || settings.positionStrategy === "global") {
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
if (typeof settings.anchor === "string") {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
const subscriptions = [];
|
|
963
|
+
const updatePosition = () => {
|
|
964
|
+
if (overlayRef.hasAttached()) {
|
|
965
|
+
overlayRef.updatePosition();
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
const win = this.#document.defaultView;
|
|
969
|
+
const windowScrollSubscription = fromEvent(win, "scroll", { passive: true })
|
|
970
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
971
|
+
.subscribe(updatePosition);
|
|
972
|
+
subscriptions.push(windowScrollSubscription);
|
|
973
|
+
const resizeSubscription = fromEvent(win, "resize", { passive: true })
|
|
974
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
975
|
+
.subscribe(updatePosition);
|
|
976
|
+
subscriptions.push(resizeSubscription);
|
|
977
|
+
this.getScrollableContainers(this.resolveAnchor(settings.anchor)).forEach(scrollable => {
|
|
978
|
+
const containerScrollSubscription = scrollable
|
|
979
|
+
.elementScrolled()
|
|
980
|
+
.pipe(takeUntil(popupReference.closed), takeUntilDestroyed(this.#destroyRef))
|
|
981
|
+
.subscribe(updatePosition);
|
|
982
|
+
subscriptions.push(containerScrollSubscription);
|
|
983
|
+
});
|
|
984
|
+
popupReference.closed.pipe(take(1)).subscribe(() => {
|
|
985
|
+
subscriptions.forEach(sub => sub.unsubscribe());
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
shouldIgnoreOutsideClick(settings, event) {
|
|
989
|
+
const eventTarget = event.target;
|
|
990
|
+
if (typeof settings.anchor === "string") {
|
|
991
|
+
return !this.#outsideEventsToClose.includes(event.type);
|
|
992
|
+
}
|
|
993
|
+
const resolvedAnchor = this.resolveAnchor(settings.anchor);
|
|
994
|
+
const anchorElement = this.getAnchorElement(resolvedAnchor);
|
|
995
|
+
const isAnchorClick = anchorElement && anchorElement.contains(eventTarget);
|
|
996
|
+
const isRelevantEventType = this.#outsideEventsToClose.includes(event.type);
|
|
997
|
+
return isAnchorClick || !isRelevantEventType;
|
|
998
|
+
}
|
|
999
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PopupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1000
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PopupService, providedIn: "root" }); }
|
|
1001
|
+
}
|
|
1002
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PopupService, decorators: [{
|
|
1003
|
+
type: Injectable,
|
|
1004
|
+
args: [{
|
|
1005
|
+
providedIn: "root"
|
|
1006
|
+
}]
|
|
1007
|
+
}] });
|
|
1008
|
+
|
|
1009
|
+
class PopupComponent {
|
|
1010
|
+
#destroyRef;
|
|
1011
|
+
#document;
|
|
1012
|
+
#popupService;
|
|
1013
|
+
#popupOpened;
|
|
1014
|
+
#eventListenerCleanup$;
|
|
1015
|
+
constructor() {
|
|
1016
|
+
this.#destroyRef = inject(DestroyRef);
|
|
1017
|
+
this.#document = inject(DOCUMENT);
|
|
1018
|
+
this.#popupService = inject(PopupService);
|
|
1019
|
+
this.#popupOpened = false;
|
|
1020
|
+
this.#eventListenerCleanup$ = new Subject();
|
|
1021
|
+
this.contentTemplate = viewChild.required(TemplateRef, /* @ts-ignore */
|
|
1022
|
+
...(ngDevMode ? [{ debugName: "contentTemplate" }] : /* istanbul ignore next */ []));
|
|
1023
|
+
this.popupRef = null;
|
|
1024
|
+
/**
|
|
1025
|
+
* @description The anchor element or point for the popup.
|
|
1026
|
+
*/
|
|
1027
|
+
this.anchor = input.required(/* @ts-ignore */
|
|
1028
|
+
...(ngDevMode ? [{ debugName: "anchor" }] : /* istanbul ignore next */ []));
|
|
1029
|
+
/**
|
|
1030
|
+
* @description The connection point for the popup anchor.
|
|
1031
|
+
*/
|
|
1032
|
+
this.anchorConnectionPoint = input("bottomcenter", /* @ts-ignore */
|
|
1033
|
+
...(ngDevMode ? [{ debugName: "anchorConnectionPoint" }] : /* istanbul ignore next */ []));
|
|
1034
|
+
/**
|
|
1035
|
+
* @description The animation settings for the popup.
|
|
1036
|
+
*/
|
|
1037
|
+
this.animation = input(true, /* @ts-ignore */
|
|
1038
|
+
...(ngDevMode ? [{ debugName: "animation" }] : /* istanbul ignore next */ []));
|
|
1039
|
+
/**
|
|
1040
|
+
* @description The class or classes to apply to the backdrop of the popup.
|
|
1041
|
+
*/
|
|
1042
|
+
this.backdropClass = input([], /* @ts-ignore */
|
|
1043
|
+
...(ngDevMode ? [{ debugName: "backdropClass" }] : /* istanbul ignore next */ []));
|
|
1044
|
+
/**
|
|
1045
|
+
* @description Emits when the popup is closed.
|
|
1046
|
+
*/
|
|
1047
|
+
this.close = output();
|
|
1048
|
+
/**
|
|
1049
|
+
* @description Whether to close the popup when clicking on the backdrop.
|
|
1050
|
+
* Only applies when the popup has a backdrop.
|
|
1051
|
+
*/
|
|
1052
|
+
this.closeOnBackdropClick = input(true, /* @ts-ignore */
|
|
1053
|
+
...(ngDevMode ? [{ debugName: "closeOnBackdropClick" }] : /* istanbul ignore next */ []));
|
|
1054
|
+
/**
|
|
1055
|
+
* @description Whether to close the popup when the escape key is pressed.
|
|
1056
|
+
*/
|
|
1057
|
+
this.closeOnEscape = input(true, /* @ts-ignore */
|
|
1058
|
+
...(ngDevMode ? [{ debugName: "closeOnEscape" }] : /* istanbul ignore next */ []));
|
|
1059
|
+
/**
|
|
1060
|
+
* @description Whether to close the popup when the mouse leaves the anchor element.
|
|
1061
|
+
*/
|
|
1062
|
+
this.closeOnMouseLeave = input(false, /* @ts-ignore */
|
|
1063
|
+
...(ngDevMode ? [{ debugName: "closeOnMouseLeave" }] : /* istanbul ignore next */ []));
|
|
1064
|
+
/**
|
|
1065
|
+
* @description Whether to close the popup when clicking outside of it.
|
|
1066
|
+
*/
|
|
1067
|
+
this.closeOnOutsideClick = input(true, /* @ts-ignore */
|
|
1068
|
+
...(ngDevMode ? [{ debugName: "closeOnOutsideClick" }] : /* istanbul ignore next */ []));
|
|
1069
|
+
/**
|
|
1070
|
+
* @description Arbitrary data to pass to the popup.
|
|
1071
|
+
*/
|
|
1072
|
+
this.data = input(/* @ts-ignore */
|
|
1073
|
+
...(ngDevMode ? [undefined, { debugName: "data" }] : /* istanbul ignore next */ []));
|
|
1074
|
+
/**
|
|
1075
|
+
* @description Whether the popup should have a backdrop.
|
|
1076
|
+
*/
|
|
1077
|
+
this.hasBackdrop = input(false, /* @ts-ignore */
|
|
1078
|
+
...(ngDevMode ? [{ debugName: "hasBackdrop" }] : /* istanbul ignore next */ []));
|
|
1079
|
+
/**
|
|
1080
|
+
* @description The height of the popup.
|
|
1081
|
+
*/
|
|
1082
|
+
this.height = input(/* @ts-ignore */
|
|
1083
|
+
...(ngDevMode ? [undefined, { debugName: "height" }] : /* istanbul ignore next */ []));
|
|
1084
|
+
/**
|
|
1085
|
+
* @description The maximum height of the popup.
|
|
1086
|
+
*/
|
|
1087
|
+
this.maxHeight = input(/* @ts-ignore */
|
|
1088
|
+
...(ngDevMode ? [undefined, { debugName: "maxHeight" }] : /* istanbul ignore next */ []));
|
|
1089
|
+
/**
|
|
1090
|
+
* @description The maximum width of the popup.
|
|
1091
|
+
*/
|
|
1092
|
+
this.maxWidth = input(/* @ts-ignore */
|
|
1093
|
+
...(ngDevMode ? [undefined, { debugName: "maxWidth" }] : /* istanbul ignore next */ []));
|
|
1094
|
+
/**
|
|
1095
|
+
* @description The minimum height of the popup.
|
|
1096
|
+
*/
|
|
1097
|
+
this.minHeight = input(/* @ts-ignore */
|
|
1098
|
+
...(ngDevMode ? [undefined, { debugName: "minHeight" }] : /* istanbul ignore next */ []));
|
|
1099
|
+
/**
|
|
1100
|
+
* @description The minimum width of the popup.
|
|
1101
|
+
*/
|
|
1102
|
+
this.minWidth = input(/* @ts-ignore */
|
|
1103
|
+
...(ngDevMode ? [undefined, { debugName: "minWidth" }] : /* istanbul ignore next */ []));
|
|
1104
|
+
/**
|
|
1105
|
+
* @description The offset of the popup from the anchor.
|
|
1106
|
+
*/
|
|
1107
|
+
this.offset = input(/* @ts-ignore */
|
|
1108
|
+
...(ngDevMode ? [undefined, { debugName: "offset" }] : /* istanbul ignore next */ []));
|
|
1109
|
+
/**
|
|
1110
|
+
* @description Emits when the popup is opened.
|
|
1111
|
+
*/
|
|
1112
|
+
this.open = output();
|
|
1113
|
+
/**
|
|
1114
|
+
* @description The class or classes to apply to the popup.
|
|
1115
|
+
*/
|
|
1116
|
+
this.popupClass = input([], /* @ts-ignore */
|
|
1117
|
+
...(ngDevMode ? [{ debugName: "popupClass" }] : /* istanbul ignore next */ []));
|
|
1118
|
+
/**
|
|
1119
|
+
* @description The connection point for the popup.
|
|
1120
|
+
*/
|
|
1121
|
+
this.popupConnectionPoint = input("topcenter", /* @ts-ignore */
|
|
1122
|
+
...(ngDevMode ? [{ debugName: "popupConnectionPoint" }] : /* istanbul ignore next */ []));
|
|
1123
|
+
/**
|
|
1124
|
+
* @description The class or classes to apply to the popup wrapper.
|
|
1125
|
+
*/
|
|
1126
|
+
this.popupWrapperClass = input([], /* @ts-ignore */
|
|
1127
|
+
...(ngDevMode ? [{ debugName: "popupWrapperClass" }] : /* istanbul ignore next */ []));
|
|
1128
|
+
/**
|
|
1129
|
+
* @description The strategy for positioning the popup.
|
|
1130
|
+
* `global` means the popup will be positioned relative to the viewport,
|
|
1131
|
+
* `connected` means the popup will be positioned relative to the anchor element.
|
|
1132
|
+
*/
|
|
1133
|
+
this.positionStrategy = input("connected", /* @ts-ignore */
|
|
1134
|
+
...(ngDevMode ? [{ debugName: "positionStrategy" }] : /* istanbul ignore next */ []));
|
|
1135
|
+
/**
|
|
1136
|
+
* @description The positions to use for the popup.
|
|
1137
|
+
* The popup will try to position itself in the first position that fits.
|
|
1138
|
+
* This is only used when the `positionStrategy` is set to `connected`.
|
|
1139
|
+
*/
|
|
1140
|
+
this.positions = input(/* @ts-ignore */
|
|
1141
|
+
...(ngDevMode ? [undefined, { debugName: "positions" }] : /* istanbul ignore next */ []));
|
|
1142
|
+
/**
|
|
1143
|
+
* @description Called when the popup is requested to close.
|
|
1144
|
+
* This can be used to prevent the popup from closing.
|
|
1145
|
+
*/
|
|
1146
|
+
this.preventClose = input(/* @ts-ignore */
|
|
1147
|
+
...(ngDevMode ? [undefined, { debugName: "preventClose" }] : /* istanbul ignore next */ []));
|
|
1148
|
+
/**
|
|
1149
|
+
* @description The providers that will be injected into the popup.
|
|
1150
|
+
*/
|
|
1151
|
+
this.providers = input([], /* @ts-ignore */
|
|
1152
|
+
...(ngDevMode ? [{ debugName: "providers" }] : /* istanbul ignore next */ []));
|
|
1153
|
+
/**
|
|
1154
|
+
* @description The trigger event for opening the popup.
|
|
1155
|
+
*/
|
|
1156
|
+
this.trigger = input("click", /* @ts-ignore */
|
|
1157
|
+
...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
|
|
1158
|
+
/**
|
|
1159
|
+
* @description The width of the popup.
|
|
1160
|
+
*/
|
|
1161
|
+
this.width = input(undefined, /* @ts-ignore */
|
|
1162
|
+
...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
1163
|
+
/**
|
|
1164
|
+
* @description Whether to push the popup into the screen when it is opened.
|
|
1165
|
+
*/
|
|
1166
|
+
this.withPush = input(true, /* @ts-ignore */
|
|
1167
|
+
...(ngDevMode ? [{ debugName: "withPush" }] : /* istanbul ignore next */ []));
|
|
1168
|
+
/**
|
|
1169
|
+
* @description Whether to close the popup when the user scrolls within a scrollable container.
|
|
1170
|
+
*/
|
|
1171
|
+
this.closeOnScroll = input(false, /* @ts-ignore */
|
|
1172
|
+
...(ngDevMode ? [{ debugName: "closeOnScroll" }] : /* istanbul ignore next */ []));
|
|
1173
|
+
/**
|
|
1174
|
+
* @description Controls focus restoration when the popup closes.
|
|
1175
|
+
* - `true`: always restore focus to the anchor element.
|
|
1176
|
+
* - `false`: never restore focus (recommended for tooltips).
|
|
1177
|
+
* - `"auto"`: restore focus only if the anchor was focused when the popup opened.
|
|
1178
|
+
*/
|
|
1179
|
+
this.restoreFocus = input("auto", /* @ts-ignore */
|
|
1180
|
+
...(ngDevMode ? [{ debugName: "restoreFocus" }] : /* istanbul ignore next */ []));
|
|
1181
|
+
/**
|
|
1182
|
+
* @description Whether the popup should track scroll events and reposition itself.
|
|
1183
|
+
*/
|
|
1184
|
+
this.withScrollTracking = input(true, /* @ts-ignore */
|
|
1185
|
+
...(ngDevMode ? [{ debugName: "withScrollTracking" }] : /* istanbul ignore next */ []));
|
|
1186
|
+
effect(() => this.setupEventListeners());
|
|
1187
|
+
}
|
|
1188
|
+
closePopup() {
|
|
1189
|
+
this.popupRef?.close();
|
|
1190
|
+
}
|
|
1191
|
+
ngAfterViewInit() {
|
|
1192
|
+
rxTimeout(this.#destroyRef, () => this.setupEventListeners());
|
|
1193
|
+
}
|
|
1194
|
+
ngOnDestroy() {
|
|
1195
|
+
this.popupRef?.close();
|
|
1196
|
+
this.#eventListenerCleanup$.next();
|
|
1197
|
+
this.#eventListenerCleanup$.complete();
|
|
1198
|
+
}
|
|
1199
|
+
getPopupWidth() {
|
|
1200
|
+
const width = this.width();
|
|
1201
|
+
if (width != null) {
|
|
1202
|
+
return width;
|
|
1203
|
+
}
|
|
1204
|
+
const anchor = this.anchor();
|
|
1205
|
+
if (anchor instanceof HTMLElement) {
|
|
1206
|
+
return anchor.getBoundingClientRect().width;
|
|
1207
|
+
}
|
|
1208
|
+
if (anchor instanceof ElementRef) {
|
|
1209
|
+
return anchor.nativeElement.getBoundingClientRect().width;
|
|
1210
|
+
}
|
|
1211
|
+
return undefined;
|
|
1212
|
+
}
|
|
1213
|
+
setupEventListeners() {
|
|
1214
|
+
// Clean up previous event listeners
|
|
1215
|
+
this.#eventListenerCleanup$.next();
|
|
1216
|
+
const trigger = this.trigger();
|
|
1217
|
+
const anchor = this.anchor();
|
|
1218
|
+
if (!trigger || !anchor) {
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
let pointAnchor = false;
|
|
1222
|
+
let target;
|
|
1223
|
+
if (anchor instanceof ElementRef) {
|
|
1224
|
+
target = anchor.nativeElement;
|
|
1225
|
+
}
|
|
1226
|
+
else if (anchor instanceof HTMLElement) {
|
|
1227
|
+
target = anchor;
|
|
1228
|
+
}
|
|
1229
|
+
else {
|
|
1230
|
+
target = this.#document.body;
|
|
1231
|
+
pointAnchor = true;
|
|
1232
|
+
}
|
|
1233
|
+
const width = this.getPopupWidth();
|
|
1234
|
+
fromEvent(target, trigger)
|
|
1235
|
+
.pipe(takeUntil(this.#eventListenerCleanup$), takeUntilDestroyed(this.#destroyRef))
|
|
1236
|
+
.subscribe(event => {
|
|
1237
|
+
event.preventDefault();
|
|
1238
|
+
if (this.#popupOpened) {
|
|
1239
|
+
this.#popupOpened = false;
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
if (this.popupRef !== null) {
|
|
1243
|
+
this.popupRef.close();
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
const popupSettings = {
|
|
1247
|
+
anchor,
|
|
1248
|
+
anchorConnectionPoint: this.anchorConnectionPoint(),
|
|
1249
|
+
animation: this.animation(),
|
|
1250
|
+
backdropClass: this.backdropClass(),
|
|
1251
|
+
closeOnBackdropClick: this.closeOnBackdropClick(),
|
|
1252
|
+
closeOnEscape: this.closeOnEscape(),
|
|
1253
|
+
closeOnMouseLeave: this.closeOnMouseLeave(),
|
|
1254
|
+
closeOnOutsideClick: this.closeOnOutsideClick(),
|
|
1255
|
+
closeOnScroll: this.closeOnScroll(),
|
|
1256
|
+
content: this.contentTemplate(),
|
|
1257
|
+
data: this.data(),
|
|
1258
|
+
hasBackdrop: this.hasBackdrop(),
|
|
1259
|
+
height: this.height(),
|
|
1260
|
+
maxHeight: this.maxHeight(),
|
|
1261
|
+
maxWidth: this.maxWidth(),
|
|
1262
|
+
minHeight: this.minHeight(),
|
|
1263
|
+
minWidth: this.minWidth(),
|
|
1264
|
+
offset: this.offset(),
|
|
1265
|
+
popupClass: this.popupClass(),
|
|
1266
|
+
popupConnectionPoint: this.popupConnectionPoint(),
|
|
1267
|
+
popupWrapperClass: this.popupWrapperClass(),
|
|
1268
|
+
positionStrategy: this.positionStrategy(),
|
|
1269
|
+
positions: this.positions(),
|
|
1270
|
+
preventClose: this.preventClose(),
|
|
1271
|
+
providers: this.providers(),
|
|
1272
|
+
restoreFocus: this.restoreFocus(),
|
|
1273
|
+
width,
|
|
1274
|
+
withPush: this.withPush(),
|
|
1275
|
+
withScrollTracking: this.withScrollTracking()
|
|
1276
|
+
};
|
|
1277
|
+
this.popupRef = this.#popupService.create(popupSettings);
|
|
1278
|
+
this.popupRef.closed.pipe(take(1)).subscribe(result => {
|
|
1279
|
+
this.popupRef = null;
|
|
1280
|
+
this.close.emit();
|
|
1281
|
+
if (result instanceof PopupCloseEvent) {
|
|
1282
|
+
if (!result.originalEvent) {
|
|
1283
|
+
this.#popupOpened = false;
|
|
1284
|
+
}
|
|
1285
|
+
else if (result.originalEvent instanceof PointerEvent &&
|
|
1286
|
+
result.originalEvent.type === trigger) {
|
|
1287
|
+
this.#popupOpened =
|
|
1288
|
+
target instanceof HTMLElement &&
|
|
1289
|
+
target.contains(result.originalEvent.target);
|
|
1290
|
+
}
|
|
1291
|
+
else if (result.originalEvent instanceof PointerEvent &&
|
|
1292
|
+
pointAnchor &&
|
|
1293
|
+
result.originalEvent.type !== trigger) {
|
|
1294
|
+
this.#popupOpened = false;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
if (pointAnchor) {
|
|
1299
|
+
this.#popupOpened = true;
|
|
1300
|
+
}
|
|
1301
|
+
this.open.emit(this.popupRef);
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1305
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: PopupComponent, isStandalone: true, selector: "mona-popup", inputs: { anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: true, transformFunction: null }, anchorConnectionPoint: { classPropertyName: "anchorConnectionPoint", publicName: "anchorConnectionPoint", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClick: { classPropertyName: "closeOnBackdropClick", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnMouseLeave: { classPropertyName: "closeOnMouseLeave", publicName: "closeOnMouseLeave", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsideClick: { classPropertyName: "closeOnOutsideClick", publicName: "closeOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, popupClass: { classPropertyName: "popupClass", publicName: "popupClass", isSignal: true, isRequired: false, transformFunction: null }, popupConnectionPoint: { classPropertyName: "popupConnectionPoint", publicName: "popupConnectionPoint", isSignal: true, isRequired: false, transformFunction: null }, popupWrapperClass: { classPropertyName: "popupWrapperClass", publicName: "popupWrapperClass", isSignal: true, isRequired: false, transformFunction: null }, positionStrategy: { classPropertyName: "positionStrategy", publicName: "positionStrategy", isSignal: true, isRequired: false, transformFunction: null }, positions: { classPropertyName: "positions", publicName: "positions", isSignal: true, isRequired: false, transformFunction: null }, preventClose: { classPropertyName: "preventClose", publicName: "preventClose", isSignal: true, isRequired: false, transformFunction: null }, providers: { classPropertyName: "providers", publicName: "providers", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, withPush: { classPropertyName: "withPush", publicName: "withPush", isSignal: true, isRequired: false, transformFunction: null }, closeOnScroll: { classPropertyName: "closeOnScroll", publicName: "closeOnScroll", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, withScrollTracking: { classPropertyName: "withScrollTracking", publicName: "withScrollTracking", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", open: "open" }, viewQueries: [{ propertyName: "contentTemplate", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template>\r\n <ng-content></ng-content>\r\n</ng-template>\r\n" }); }
|
|
1306
|
+
}
|
|
1307
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PopupComponent, decorators: [{
|
|
1308
|
+
type: Component,
|
|
1309
|
+
args: [{ selector: "mona-popup", template: "<ng-template>\r\n <ng-content></ng-content>\r\n</ng-template>\r\n" }]
|
|
1310
|
+
}], ctorParameters: () => [], propDecorators: { contentTemplate: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }], anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: true }] }], anchorConnectionPoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchorConnectionPoint", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], backdropClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClass", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], closeOnBackdropClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdropClick", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeOnMouseLeave: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnMouseLeave", required: false }] }], closeOnOutsideClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsideClick", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], hasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], open: [{ type: i0.Output, args: ["open"] }], popupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupClass", required: false }] }], popupConnectionPoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupConnectionPoint", required: false }] }], popupWrapperClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupWrapperClass", required: false }] }], positionStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "positionStrategy", required: false }] }], positions: [{ type: i0.Input, args: [{ isSignal: true, alias: "positions", required: false }] }], preventClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventClose", required: false }] }], providers: [{ type: i0.Input, args: [{ isSignal: true, alias: "providers", required: false }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], withPush: [{ type: i0.Input, args: [{ isSignal: true, alias: "withPush", required: false }] }], closeOnScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnScroll", required: false }] }], restoreFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocus", required: false }] }], withScrollTracking: [{ type: i0.Input, args: [{ isSignal: true, alias: "withScrollTracking", required: false }] }] } });
|
|
1311
|
+
|
|
1312
|
+
/*
|
|
1313
|
+
* Public API Surface of @nanahoshi/mona-ui/popup
|
|
1314
|
+
*/
|
|
1315
|
+
|
|
1316
|
+
/**
|
|
1317
|
+
* Generated bundle index. Do not edit.
|
|
1318
|
+
*/
|
|
1319
|
+
|
|
1320
|
+
export { PopupCloseEvent, PopupCloseSource, PopupComponent, PopupDataInjectionToken, PopupRef, PopupService, defaultPopupAnimation, dropdownPopupAnimation, fadePopupAnimation };
|
|
1321
|
+
//# sourceMappingURL=nanahoshi-mona-ui-popup.mjs.map
|