@filip.mazev/modal 0.1.48 → 0.1.50

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.
@@ -1,261 +1,384 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, output, signal, effect, ViewContainerRef, ViewChildren, ViewChild, Component, input, computed, Injector, ApplicationRef, EnvironmentInjector, RendererFactory2, createComponent, Injectable, TemplateRef, Directive, InjectionToken } from '@angular/core';
3
- import { Subject, fromEvent, filter, Observable, from, of, take, BehaviorSubject, skip, map } from 'rxjs';
4
- import { NgTemplateOutlet, NgClass, DOCUMENT } from '@angular/common';
5
- import { ModalService as ModalService$1 } from '@modal/services/modal.service';
6
- import { ModalBackdrop as ModalBackdrop$1 } from '@modal/components/shared/ui/backdrop/modal-backdrop';
7
- import { ModalCentered as ModalCentered$1 } from '@modal/components/views/centered/modal-centered';
8
- import { ModalSide as ModalSide$1 } from '@modal/components/views/side/modal-side';
9
- import { WindowDimensionsService, ScrollLockService, uuidv4 } from '@filip.mazev/blocks-core';
10
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
- import * as animConst from '@modal/constants/modal-animation.constants';
12
- import * as bottomSheetConst from '@modal/constants/modal-bottom-sheet.constants';
13
- import { ModalBanner as ModalBanner$1 } from '@modal/components/shared/ui/banner/modal-banner';
14
- import { ModalBottomSheet as ModalBottomSheet$1 } from '@modal/components/views/bottom-sheet/modal-bottom-sheet';
15
- import { ModalDefaultCloseButton } from '@modal/components/shared/ui/default-close-button/default-close-button';
2
+ import { InjectionToken, inject, Injector, ApplicationRef, EnvironmentInjector, RendererFactory2, createComponent, Injectable, input, output, Component, signal, computed, ViewChild, ViewChildren, effect, ViewContainerRef, TemplateRef, Directive } from '@angular/core';
3
+ import { BehaviorSubject, Subject, filter, skip, fromEvent, Observable, from, of, take, map } from 'rxjs';
4
+ import { DOCUMENT, NgClass, NgTemplateOutlet } from '@angular/common';
16
5
  import { Router, NavigationEnd } from '@angular/router';
17
- import { ModalConfig as ModalConfig$1 } from '@modal/classes/modal-config';
18
- import { ModalRef as ModalRef$1 } from '@modal/classes/modal-ref';
19
- import { ModalCore as ModalCore$1 } from '@modal/components/modal-core';
20
- import { MODAL_DATA as MODAL_DATA$1 } from '@modal/tokens/modal-data.token';
21
- import { ModalStyleConfig as ModalStyleConfig$1 } from '@modal/classes/modal-style.config';
22
- import { ModalState as ModalState$1 } from '@modal/enums/modal-state.enum';
23
- import { ModalWarnings as ModalWarnings$1 } from '@modal/enums/modal-warnings.enum';
24
- import { ModalCloseGuard as ModalCloseGuard$1 } from '@modal/classes/modal-close-guard';
6
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
+ import { WindowDimensionsService, ScrollLockService, uuidv4 } from '@filip.mazev/blocks-core';
25
8
 
26
- class ModalCore {
27
- modalService = inject(ModalService$1);
28
- windowDimensionsService = inject(WindowDimensionsService);
29
- scrollLockService = inject(ScrollLockService);
30
- afterClose = output();
31
- animationDuration = animConst.MODAL_DEFAULT_ANIM_DURATION;
32
- componentRef = {};
33
- config;
34
- closeFunction;
35
- backdropClickSubject = new Subject();
36
- backdropClick = this.backdropClickSubject.asObservable();
37
- isOpen = signal(true, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
38
- effectiveLayout = signal('center', ...(ngDevMode ? [{ debugName: "effectiveLayout" }] : []));
39
- isCentered = signal(false, ...(ngDevMode ? [{ debugName: "isCentered" }] : []));
40
- isSide = signal(false, ...(ngDevMode ? [{ debugName: "isSide" }] : []));
41
- headerTemplate = signal(null, ...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
42
- footerTemplate = signal(null, ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
43
- id = signal(null, ...(ngDevMode ? [{ debugName: "id" }] : []));
44
- isBottomSheetModalActive = signal(false, ...(ngDevMode ? [{ debugName: "isBottomSheetModalActive" }] : []));
45
- isAnimated = false;
46
- hasBanner = false;
47
- hasDefaultContentWrapperClass = false;
48
- isConfirmCloseModalOpen = false;
49
- scrollLockId = uuidv4();
50
- _sortedBreakpoints = [];
51
- windowDimensions = this.windowDimensionsService.dimensions;
52
- _currentVcr = null;
53
- set dynamicContainer(vcr) {
54
- if (vcr && this.componentRef) {
55
- this._currentVcr = vcr;
56
- vcr.insert(this.componentRef.hostView);
57
- }
9
+ class ModalStyleConfig {
10
+ layout;
11
+ breakpoints;
12
+ animate;
13
+ hasBackdrop;
14
+ closeDelay;
15
+ showCloseButton;
16
+ mobileConfig;
17
+ contentWrapper;
18
+ wrapperClasses;
19
+ wrapperStyles;
20
+ overrideFullHeight;
21
+ constructor(config) {
22
+ this.layout = config?.layout ?? "center";
23
+ this.breakpoints = config?.breakpoints;
24
+ this.animate = config?.animate ?? true;
25
+ this.hasBackdrop = config?.hasBackdrop ?? true;
26
+ this.closeDelay = config?.closeDelay;
27
+ this.showCloseButton = config?.showCloseButton ?? true;
28
+ this.mobileConfig = config?.mobileConfig ?? {};
29
+ this.contentWrapper = config?.contentWrapper ?? true;
30
+ this.wrapperClasses = config?.wrapperClasses ?? "";
31
+ this.wrapperStyles = config?.wrapperStyles ?? "";
32
+ this.overrideFullHeight = config?.overrideFullHeight ?? false;
58
33
  }
59
- modalContainer;
60
- contentTemplate;
61
- sideModalComponents;
62
- centeredModalComponents;
63
- constructor() {
64
- this.initKeyboardSubscription();
65
- effect(() => {
66
- const width = this.windowDimensions().width;
67
- this.handleLayout(width);
68
- });
34
+ }
35
+
36
+ class ModalConfig {
37
+ open;
38
+ afterClose;
39
+ closeGuard;
40
+ closeGuardOnlyOnCancel;
41
+ disableClose;
42
+ disableCloseOnBackdropClick;
43
+ disableCloseOnNavigation;
44
+ data;
45
+ style;
46
+ bannerText;
47
+ contentClasses;
48
+ contentStyles;
49
+ disableConsoleWarnings;
50
+ disableConsoleInfo;
51
+ id;
52
+ constructor(config) {
53
+ this.open = config?.open ?? true;
54
+ this.afterClose = config?.afterClose;
55
+ this.closeGuard = config?.closeGuard;
56
+ this.closeGuardOnlyOnCancel = config?.closeGuardOnlyOnCancel ?? true;
57
+ this.disableClose = config?.disableClose ?? false;
58
+ this.disableCloseOnBackdropClick = config?.disableCloseOnBackdropClick ?? false;
59
+ this.disableCloseOnNavigation = config?.disableCloseOnNavigation ?? false;
60
+ this.data = config?.data ?? null;
61
+ this.style = new ModalStyleConfig(config?.style);
62
+ this.bannerText = config?.bannerText ?? "";
63
+ this.contentClasses = config?.contentClasses ?? "";
64
+ this.contentStyles = config?.contentStyles ?? "";
65
+ this.disableConsoleWarnings = config?.disableConsoleWarnings ?? false;
66
+ this.disableConsoleInfo = config?.disableConsoleInfo ?? false;
67
+ this.id = config?.id;
69
68
  }
70
- ngOnInit() {
71
- this.initParamsFromConfig();
72
- this.initBreakpointCache();
73
- this.scrollLockService.disableScroll(this.scrollLockId, {
74
- animationDuration: this.animationDuration,
75
- handleTouchInput: true,
76
- mobileOnlyTouchPrevention: true,
77
- });
69
+ }
70
+
71
+ var ModalState;
72
+ (function (ModalState) {
73
+ ModalState["OPEN"] = "open";
74
+ ModalState["OPENING"] = "opening";
75
+ ModalState["CLOSED"] = "closed";
76
+ ModalState["CLOSING"] = "closing";
77
+ })(ModalState || (ModalState = {}));
78
+
79
+ class ModalRef {
80
+ componentType;
81
+ modalService;
82
+ //#region Modal Container
83
+ _modalContainer = {};
84
+ set modalContainer(modalContainer) {
85
+ this._modalContainer = modalContainer;
78
86
  }
79
- ngAfterViewInit() {
80
- if (!this.componentRef)
81
- return;
82
- this.dynamicContainer?.insert(this.componentRef.hostView);
83
- const width = this.windowDimensionsService.dimensions().width;
84
- this.handleLayout(width);
87
+ get modalContainer() {
88
+ return this._modalContainer;
85
89
  }
86
- ngOnDestroy() {
87
- this.componentRef?.destroy();
88
- this.dynamicContainer?.clear();
89
- this.scrollLockService.enableScroll(this.scrollLockId);
90
+ _modalContainerRef = {};
91
+ set modalContainerRef(modalContainerRef) {
92
+ this._modalContainerRef = modalContainerRef;
90
93
  }
91
- //#region Subscription Methods
92
- initKeyboardSubscription() {
93
- fromEvent(document, "keydown")
94
- .pipe(filter((event) => event.key === "Escape"), takeUntilDestroyed())
95
- .subscribe(() => {
96
- if (!this.isConfirmCloseModalOpen) {
97
- this.close("cancel", undefined, true);
98
- }
99
- });
94
+ get modalContainerRef() {
95
+ return this._modalContainerRef;
100
96
  }
101
- //#endregion
102
- //#region Initialization Methods
103
- initParamsFromConfig() {
104
- this.id.set(this.config?.id ?? this.scrollLockId);
105
- this.hasBanner =
106
- this.config !== undefined &&
107
- ((this.config.bannerText !== undefined && this.config.bannerText.length > 0) ||
108
- (this.config.disableClose !== true && this.config.style.showCloseButton !== false && this.headerTemplate() === null));
109
- this.hasDefaultContentWrapperClass = this.config?.style.contentWrapper !== false;
110
- this.isAnimated = this.config?.style.animate === true;
97
+ _modalContainerElement = {};
98
+ set modalContainerElement(modalContainerElement) {
99
+ this._modalContainerElement = modalContainerElement;
111
100
  }
112
- initBreakpointCache() {
113
- const definedBreakpoints = this.config?.style?.breakpoints;
114
- if (definedBreakpoints && Object.keys(definedBreakpoints).length > 0) {
115
- const serviceBreakpoints = this.windowDimensionsService.breakpoints;
116
- this._sortedBreakpoints = Object.keys(definedBreakpoints)
117
- .map(key => ({
118
- width: serviceBreakpoints[key],
119
- layout: definedBreakpoints[key]
120
- }))
121
- .sort((a, b) => a.width - b.width);
122
- }
101
+ get modalContainerElement() {
102
+ return this._modalContainerElement;
103
+ }
104
+ _parentElement = undefined;
105
+ set parentElement(parentElement) {
106
+ this._parentElement = parentElement;
107
+ }
108
+ get parentElement() {
109
+ return this._parentElement;
123
110
  }
124
111
  //#endregion
125
- //#region Public Template Methods
126
- setHeaderTemplate(template) {
127
- this.headerTemplate.set(template);
112
+ //#region Component
113
+ _componentRef = {};
114
+ set componentRef(componentRef) {
115
+ this._componentRef = componentRef;
128
116
  }
129
- setFooterTemplate(template) {
130
- this.footerTemplate.set(template);
117
+ get componentRef() {
118
+ return this._componentRef;
131
119
  }
132
120
  //#endregion
133
- //#region Closing Methods
134
- close(state = "cancel", result = undefined, fromInsideInteraction = false, forceClose = false) {
135
- if (forceClose) {
136
- this.handleClose(state, result);
137
- return;
138
- }
139
- if ((this.config?.disableClose === true) && fromInsideInteraction) {
140
- return;
141
- }
142
- const shouldCheckCloseGuard = this.config?.closeGuardOnlyOnCancel !== true || state !== "confirm";
143
- if (shouldCheckCloseGuard && this.config?.closeGuard) {
144
- const guardResult = this.config.closeGuard.canClose(this.modalService);
145
- const canClose$ = guardResult instanceof Observable ? guardResult :
146
- guardResult instanceof Promise ? from(guardResult) :
147
- of(guardResult);
148
- if (this.isBottomSheetModalActive()) {
149
- this.resetBottomSheetModalLayout();
150
- }
151
- canClose$.pipe(take(1)).subscribe((canClose) => {
152
- if (canClose) {
153
- this.handleClose(state, result);
154
- }
155
- });
156
- return;
157
- }
158
- this.handleClose(state, result);
121
+ //#region Self
122
+ _modalState = ModalState.CLOSED;
123
+ modalState = new BehaviorSubject(this.getStatus());
124
+ modalState$() {
125
+ return this.modalState.asObservable();
159
126
  }
160
- async handleClose(state, result) {
161
- this.isOpen.set(false);
162
- this.setBottomSheetModalFinishedState(true);
163
- const returnResult = {
164
- data: result,
165
- state: state,
166
- };
167
- if (this.closeFunction) {
168
- this.closeFunction(returnResult);
169
- }
127
+ getStatus() {
128
+ return this._modalState;
170
129
  }
171
- onBackdropClick(event) {
172
- event.preventDefault();
173
- event.stopPropagation();
174
- if (!this.isOpen()) {
175
- return;
176
- }
177
- this.backdropClickSubject.next(event);
178
- if (this.config?.style?.hasBackdrop && this.config?.disableCloseOnBackdropClick !== true) {
179
- this.close("cancel", undefined, true);
180
- }
130
+ _modalConfig = undefined;
131
+ set modalConfig(modalConfig) {
132
+ this._modalConfig = modalConfig;
133
+ }
134
+ get modalConfig() {
135
+ return this._modalConfig;
181
136
  }
182
137
  //#endregion
183
- //#region Helper Methods
184
- handleLayout(width) {
185
- if (!this.config)
186
- return;
187
- let resolvedLayout = this.config.style.layout;
188
- for (const bp of this._sortedBreakpoints) {
189
- if (width <= bp.width) {
190
- resolvedLayout = bp.layout;
191
- break;
138
+ //#region Observables
139
+ backdropClickSubject = new Subject();
140
+ backdropClick() {
141
+ return this.backdropClickSubject.asObservable();
142
+ }
143
+ backdropClicked(event) {
144
+ this.backdropClickSubject.next(event);
145
+ }
146
+ afterCloseSubject = new Subject();
147
+ /**
148
+ * Observable that emits when the modal has been closed.
149
+ * @returns An Observable that emits an IModalCloseResult<R> when the modal is closed.
150
+ */
151
+ afterClosed() {
152
+ return this.afterCloseSubject.asObservable();
153
+ }
154
+ afterClose(result) {
155
+ this.afterCloseSubject.next(result);
156
+ }
157
+ //#endregion
158
+ constructor(componentRef, componentType, modalContainerRef, modalService, modalConfig) {
159
+ this.componentType = componentType;
160
+ this.modalService = modalService;
161
+ this.modalConfig = modalConfig;
162
+ this.modalContainerRef = modalContainerRef;
163
+ this.modalContainerElement = modalContainerRef.location.nativeElement;
164
+ this.componentRef = componentRef;
165
+ }
166
+ //#region Public Methods
167
+ async open() {
168
+ this._modalState = ModalState.OPENING;
169
+ this.modalState.next(ModalState.OPENING);
170
+ this.modalContainerRef.instance.componentRef = this._componentRef;
171
+ const config = new ModalConfig(this.modalConfig);
172
+ this.modalContainerRef.instance.config = config;
173
+ this.modalContainerRef.instance.closeFunction = this.handleClose.bind(this);
174
+ this.parentElement?.appendChild(this.modalContainerElement);
175
+ this.modalContainerRef.instance.backdropClick.subscribe((event) => {
176
+ this.backdropClicked(event);
177
+ });
178
+ this._modalState = ModalState.OPEN;
179
+ this.modalState.next(ModalState.OPEN);
180
+ }
181
+ close(state = "cancel", result = undefined, forceClose = false) {
182
+ this.modalContainerRef.instance.close(state, result, false, forceClose);
183
+ }
184
+ //#endregion
185
+ //#region Private Methods
186
+ handleClose(result) {
187
+ this._modalState = ModalState.CLOSING;
188
+ this.modalState.next(ModalState.CLOSING);
189
+ setTimeout(() => {
190
+ if (this.modalConfig?.afterClose) {
191
+ this.modalConfig.afterClose();
192
192
  }
193
- }
194
- const prevIsSide = this.isSide();
195
- const nextIsSide = resolvedLayout === 'left' || resolvedLayout === 'right';
196
- const layoutTypeChanged = prevIsSide !== nextIsSide;
197
- if (layoutTypeChanged && this._currentVcr && this.componentRef) {
198
- const index = this._currentVcr.indexOf(this.componentRef.hostView);
199
- if (index !== -1) {
200
- this._currentVcr.detach(index);
193
+ this.modalContainerRef.destroy();
194
+ this._modalState = ModalState.CLOSED;
195
+ this.modalState.next(ModalState.CLOSED);
196
+ this.afterClose(result);
197
+ this.modalService?.unregister(this);
198
+ }, this.modalContainerRef.instance.animationDuration);
199
+ }
200
+ }
201
+
202
+ const MODAL_DATA = new InjectionToken("MODAL_DATA");
203
+
204
+ class ModalService {
205
+ router = inject(Router);
206
+ injector = inject(Injector);
207
+ appRef = inject(ApplicationRef);
208
+ environmentInjector = inject(EnvironmentInjector);
209
+ rendererFactory = inject(RendererFactory2);
210
+ renderer;
211
+ document = inject(DOCUMENT);
212
+ //#region Properties
213
+ modals = new Set();
214
+ modalsSubject = new BehaviorSubject(this.modals);
215
+ //#endregion
216
+ constructor() {
217
+ this.renderer = this.rendererFactory.createRenderer(null, null);
218
+ this.createSubscriptions();
219
+ }
220
+ //#region Subscription Methods
221
+ createSubscriptions() {
222
+ this.router.events
223
+ .pipe(filter((event) => event instanceof NavigationEnd), skip(1), takeUntilDestroyed())
224
+ .subscribe(() => {
225
+ if (this.modalsCount() > 0) {
226
+ this.closeAll(true);
201
227
  }
228
+ });
229
+ }
230
+ //#endregion
231
+ //#region Public Methods
232
+ /**
233
+ * Opens a modal with the specified component and configuration.
234
+ * @param component The component to be displayed in the modal.
235
+ * @param config Optional configuration for the modal.
236
+ * @returns A ModalRef instance representing the opened modal.
237
+ */
238
+ open(component, config) {
239
+ const dataInjector = Injector.create({
240
+ providers: [{ provide: MODAL_DATA, useValue: config?.data }],
241
+ parent: this.injector,
242
+ });
243
+ const wrapperRef = createComponent((ModalCore), {
244
+ environmentInjector: this.environmentInjector,
245
+ elementInjector: dataInjector
246
+ });
247
+ const contentInjector = Injector.create({
248
+ providers: [
249
+ { provide: ModalCore, useValue: wrapperRef.instance }
250
+ ],
251
+ parent: wrapperRef.injector,
252
+ });
253
+ const contentRef = createComponent(component, {
254
+ environmentInjector: this.environmentInjector,
255
+ elementInjector: contentInjector
256
+ });
257
+ wrapperRef.instance.componentRef = contentRef;
258
+ wrapperRef.instance.config = new ModalConfig(config);
259
+ this.appRef.attachView(wrapperRef.hostView);
260
+ this.document.body.appendChild(wrapperRef.location.nativeElement);
261
+ const modal = new ModalRef(contentRef, component, wrapperRef, this, new ModalConfig(config));
262
+ if (this.isIModal(contentRef.instance)) {
263
+ contentRef.instance.modal = modal;
264
+ contentRef.instance.onModalInit();
202
265
  }
203
- this.effectiveLayout.set(resolvedLayout);
204
- this.isSide.set(nextIsSide);
205
- this.isCentered.set(resolvedLayout === 'center' || resolvedLayout === 'bottom-sheet');
206
- const shouldBeBottomSheet = resolvedLayout === 'bottom-sheet';
207
- const currentSwipeState = this.isBottomSheetModalActive();
208
- if (shouldBeBottomSheet && !currentSwipeState) {
209
- this.isBottomSheetModalActive.set(true);
210
- }
211
- else if (!shouldBeBottomSheet && currentSwipeState) {
212
- this.isBottomSheetModalActive.set(false);
213
- }
266
+ wrapperRef.onDestroy(() => {
267
+ this.appRef.detachView(wrapperRef.hostView);
268
+ wrapperRef.location.nativeElement.remove();
269
+ });
270
+ const modalElement = modal.componentRef.location.nativeElement;
271
+ this.renderer.setStyle(modalElement, 'height', '97%');
272
+ this.renderer.setStyle(modalElement, 'width', '100%');
273
+ this.renderer.setStyle(modalElement, 'display', 'flex');
274
+ this.renderer.setStyle(modalElement, 'flex-grow', '1');
275
+ this.modals.add(modal);
276
+ this.modalsSubject.next(this.modals);
277
+ modal.open();
278
+ return modal;
214
279
  }
215
- getBottomSheetModal() {
216
- return this.sideModalComponents?.first?.bottomSheet?.first
217
- ?? this.centeredModalComponents?.first?.bottomSheet?.first;
280
+ /**
281
+ * Closes the specified modal.
282
+ * @param modal The ModalRef instance representing the modal to be closed.
283
+ */
284
+ close(modal) {
285
+ modal.close();
218
286
  }
219
- resetBottomSheetModalLayout() {
220
- const bottomSheet = this.getBottomSheetModal();
221
- if (bottomSheet) {
222
- bottomSheet.currentTranslateY.set(0);
223
- }
287
+ /**
288
+ * Unregisters the specified modal from the service.
289
+ * @param modal The ModalRef instance representing the modal to be unregistered.
290
+ */
291
+ unregister(modal) {
292
+ this.modals.delete(modal);
293
+ this.modalsSubject.next(this.modals);
224
294
  }
225
- setBottomSheetModalFinishedState(isFinished) {
226
- const bottomSheet = this.getBottomSheetModal();
227
- if (bottomSheet) {
228
- bottomSheet.isSwipingVerticallyFinished.set(isFinished);
295
+ /**
296
+ * Closes all open modals.
297
+ * @param onNavigate Indicates if the closeAll is triggered by navigation event.
298
+ */
299
+ closeAll(onNavigate = false) {
300
+ this.modals.forEach((modal) => {
301
+ if (modal.modalConfig?.disableCloseOnNavigation !== true || !onNavigate) {
302
+ modal.close("cancel", undefined, true);
303
+ }
304
+ });
305
+ }
306
+ /**
307
+ * Finds if a modal with the specified component type is currently open.
308
+ * @param componentType The component type to search for.
309
+ * @returns True if a modal with the specified component type is open, false otherwise.
310
+ */
311
+ find(componentType) {
312
+ for (const modal of this.modals) {
313
+ if (modal.componentRef.componentType === componentType) {
314
+ return true;
315
+ }
229
316
  }
230
- this.isBottomSheetModalActive.set(false);
317
+ return false;
231
318
  }
232
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCore, deps: [], target: i0.ɵɵFactoryTarget.Component });
233
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalCore, isStandalone: true, selector: "modal", outputs: { afterClose: "afterClose" }, viewQueries: [{ propertyName: "dynamicContainer", first: true, predicate: ["dynamicContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "modalContainer", first: true, predicate: ["modalContainer"], descendants: true }, { propertyName: "contentTemplate", first: true, predicate: ["contentTemplate"], descendants: true }, { propertyName: "sideModalComponents", predicate: ModalSide$1, descendants: true }, { propertyName: "centeredModalComponents", predicate: ModalCentered$1, descendants: true }], ngImport: i0, template: "@if (config?.style?.hasBackdrop && (isSide() || isBottomSheetModalActive())) {\n<modal-backdrop [isAnimated]=\"isAnimated\" [isOpen]=\"isOpen()\" (click)=\"onBackdropClick($event)\">\n</modal-backdrop>\n}\n\n<ng-container #modalContainer>\n @switch (true) {\n @case (isSide()) {\n <modal-side \n [layout]=\"effectiveLayout()\"\n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-side>\n } \n @case (isCentered()) {\n <modal-centered \n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\"\n (onBackdropClick)=\"onBackdropClick($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-centered>\n }\n }\n</ng-container>\n\n<ng-template #contentTemplate>\n <ng-container #dynamicContainer></ng-container>\n</ng-template>", styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalCentered$1, selector: "modal-centered", inputs: ["headerTemplate", "footerTemplate", "config", "id", "isOpen", "isAnimated", "isBottomSheetModalActive", "animationDuration", "hasDefaultContentWrapperClass", "hasBanner"], outputs: ["close", "onBackdropClick"] }, { kind: "component", type: ModalSide$1, selector: "modal-side", inputs: ["layout", "headerTemplate", "footerTemplate", "config", "id", "isOpen", "isAnimated", "isBottomSheetModalActive", "animationDuration", "hasDefaultContentWrapperClass", "hasBanner"], outputs: ["close"] }, { kind: "component", type: ModalBackdrop$1, selector: "modal-backdrop", inputs: ["isAnimated", "isOpen"], outputs: ["click"] }] });
319
+ /**
320
+ * Gets the count of currently open modals.
321
+ * @returns The number of open modals.
322
+ */
323
+ modalsCount() {
324
+ return this.modals.size;
325
+ }
326
+ //#endregion
327
+ //#region Helper Methods
328
+ isIModal(component) {
329
+ return (typeof component === 'object' &&
330
+ component !== null &&
331
+ 'onModalInit' in component &&
332
+ typeof component.onModalInit === 'function');
333
+ }
334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
335
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalService, providedIn: "root" });
234
336
  }
235
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCore, decorators: [{
337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalService, decorators: [{
338
+ type: Injectable,
339
+ args: [{
340
+ providedIn: "root",
341
+ }]
342
+ }], ctorParameters: () => [] });
343
+
344
+ class ModalBackdrop {
345
+ isAnimated = input(false, ...(ngDevMode ? [{ debugName: "isAnimated" }] : []));
346
+ isOpen = input(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
347
+ click = output();
348
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Component });
349
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.3", type: ModalBackdrop, isStandalone: true, selector: "modal-backdrop", inputs: { isAnimated: { classPropertyName: "isAnimated", publicName: "isAnimated", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { click: "click" }, ngImport: i0, template: "<div class=\"modal-backdrop\" [class.backdrop-fade-in]=\"isAnimated() && isOpen()\"\n [class.backdrop-fade-out]=\"isAnimated() && !isOpen()\" (click)=\"click.emit($event)\">\n</div>", styles: [".modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}\n"] });
350
+ }
351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBackdrop, decorators: [{
236
352
  type: Component,
237
- args: [{ selector: 'modal', imports: [
238
- NgTemplateOutlet,
239
- ModalCentered$1,
240
- ModalSide$1,
241
- ModalBackdrop$1
242
- ], template: "@if (config?.style?.hasBackdrop && (isSide() || isBottomSheetModalActive())) {\n<modal-backdrop [isAnimated]=\"isAnimated\" [isOpen]=\"isOpen()\" (click)=\"onBackdropClick($event)\">\n</modal-backdrop>\n}\n\n<ng-container #modalContainer>\n @switch (true) {\n @case (isSide()) {\n <modal-side \n [layout]=\"effectiveLayout()\"\n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-side>\n } \n @case (isCentered()) {\n <modal-centered \n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\"\n (onBackdropClick)=\"onBackdropClick($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-centered>\n }\n }\n</ng-container>\n\n<ng-template #contentTemplate>\n <ng-container #dynamicContainer></ng-container>\n</ng-template>" }]
243
- }], ctorParameters: () => [], propDecorators: { afterClose: [{ type: i0.Output, args: ["afterClose"] }], dynamicContainer: [{
244
- type: ViewChild,
245
- args: ["dynamicContainer", { read: ViewContainerRef }]
246
- }], modalContainer: [{
247
- type: ViewChild,
248
- args: ["modalContainer", { static: false }]
249
- }], contentTemplate: [{
250
- type: ViewChild,
251
- args: ["contentTemplate"]
252
- }], sideModalComponents: [{
253
- type: ViewChildren,
254
- args: [ModalSide$1]
255
- }], centeredModalComponents: [{
256
- type: ViewChildren,
257
- args: [ModalCentered$1]
258
- }] } });
353
+ args: [{ selector: 'modal-backdrop', imports: [], template: "<div class=\"modal-backdrop\" [class.backdrop-fade-in]=\"isAnimated() && isOpen()\"\n [class.backdrop-fade-out]=\"isAnimated() && !isOpen()\" (click)=\"click.emit($event)\">\n</div>", styles: [".modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}\n"] }]
354
+ }], propDecorators: { isAnimated: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAnimated", required: false }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }], click: [{ type: i0.Output, args: ["click"] }] } });
355
+
356
+ class ModalDefaultCloseButton {
357
+ config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
358
+ close = output();
359
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalDefaultCloseButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
360
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalDefaultCloseButton, isStandalone: true, selector: "modal-default-close-button", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close" }, ngImport: i0, template: " @if (config()?.disableClose !== true && config()?.style?.showCloseButton !== false) {\n <svg (click)=\"close.emit('cancel')\" aria-label=\"Close\" class=\"default-close-button\" viewBox=\"0 0 24 24\"\n fill=\"#ffffff\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2.4 24L0 21.6L9.6 12L0 2.4L2.4 0L12 9.6L21.6 0L24 2.4L14.4 12L24 21.6L21.6 24L12 14.4L2.4 24Z\"\n fill=\"#ffffff\" />\n </svg>\n }", styles: [".default-close-button{-webkit-user-select:none;user-select:none;background-repeat:no-repeat;display:inline-block;fill:currentColor;height:1.35rem;width:1.35rem;overflow:hidden;cursor:pointer;pointer-events:fill}.default-close-button path{transition:all .3s ease-in-out}.default-close-button path{fill:var(--modal-text, #000000)}\n"] });
361
+ }
362
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalDefaultCloseButton, decorators: [{
363
+ type: Component,
364
+ args: [{ selector: 'modal-default-close-button', imports: [], template: " @if (config()?.disableClose !== true && config()?.style?.showCloseButton !== false) {\n <svg (click)=\"close.emit('cancel')\" aria-label=\"Close\" class=\"default-close-button\" viewBox=\"0 0 24 24\"\n fill=\"#ffffff\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2.4 24L0 21.6L9.6 12L0 2.4L2.4 0L12 9.6L21.6 0L24 2.4L14.4 12L24 21.6L21.6 24L12 14.4L2.4 24Z\"\n fill=\"#ffffff\" />\n </svg>\n }", styles: [".default-close-button{-webkit-user-select:none;user-select:none;background-repeat:no-repeat;display:inline-block;fill:currentColor;height:1.35rem;width:1.35rem;overflow:hidden;cursor:pointer;pointer-events:fill}.default-close-button path{transition:all .3s ease-in-out}.default-close-button path{fill:var(--modal-text, #000000)}\n"] }]
365
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], close: [{ type: i0.Output, args: ["close"] }] } });
366
+
367
+ class ModalBanner {
368
+ config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
369
+ close = output();
370
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBanner, deps: [], target: i0.ɵɵFactoryTarget.Component });
371
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalBanner, isStandalone: true, selector: "modal-banner", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"modal-top-banner-container\">\n <div class=\"modal-top-banner-title-container\">\n @if (config() && config()?.bannerText && (config() && config()!.bannerText.length > 0)) {\n {{ config()?.bannerText }}\n }\n </div>\n \n <modal-default-close-button [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-default-close-button>\n</div>", styles: [".modal-top-banner-container{display:flex;flex-direction:row;gap:2rem;justify-content:space-between;align-items:center;color:var(--modal-text, #000000);top:0;min-height:2rem;border-top-left-radius:.75rem;border-top-right-radius:.75rem}.modal-top-banner-title-container{display:flex;flex-direction:row;justify-content:flex-start;gap:1.5rem;align-items:center;width:100%}@keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-webkit-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-moz-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}\n"], dependencies: [{ kind: "component", type: ModalDefaultCloseButton, selector: "modal-default-close-button", inputs: ["config"], outputs: ["close"] }] });
372
+ }
373
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBanner, decorators: [{
374
+ type: Component,
375
+ args: [{ selector: 'modal-banner', imports: [
376
+ ModalDefaultCloseButton
377
+ ], template: "<div class=\"modal-top-banner-container\">\n <div class=\"modal-top-banner-title-container\">\n @if (config() && config()?.bannerText && (config() && config()!.bannerText.length > 0)) {\n {{ config()?.bannerText }}\n }\n </div>\n \n <modal-default-close-button [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-default-close-button>\n</div>", styles: [".modal-top-banner-container{display:flex;flex-direction:row;gap:2rem;justify-content:space-between;align-items:center;color:var(--modal-text, #000000);top:0;min-height:2rem;border-top-left-radius:.75rem;border-top-right-radius:.75rem}.modal-top-banner-title-container{display:flex;flex-direction:row;justify-content:flex-start;gap:1.5rem;align-items:center;width:100%}@keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-webkit-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-moz-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}\n"] }]
378
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], close: [{ type: i0.Output, args: ["close"] }] } });
379
+
380
+ const MODAL_DOWN_SWIPE_LIMIT = 3;
381
+ const MODAL_SWIPE_VELOCITY_THRESHOLD = 80;
259
382
 
260
383
  class ModalBottomSheet {
261
384
  id = input.required(...(ngDevMode ? [{ debugName: "id" }] : []));
@@ -336,7 +459,7 @@ class ModalBottomSheet {
336
459
  const deltaY = event.clientY - startY;
337
460
  const duration = event.timeStamp - startTime || 1;
338
461
  const velocityY = deltaY / duration;
339
- if (deltaY > limit || (velocityY > bottomSheetConst.MODAL_SWIPE_VELOCITY_THRESHOLD && deltaY > 0)) {
462
+ if (deltaY > limit || (velocityY > MODAL_SWIPE_VELOCITY_THRESHOLD && deltaY > 0)) {
340
463
  this.close.emit('cancel');
341
464
  }
342
465
  else {
@@ -371,7 +494,7 @@ class ModalBottomSheet {
371
494
  const style = config?.style?.mobileConfig;
372
495
  this.downSwipeLimit = style?.downSwipeLimit && style.downSwipeLimit > 0
373
496
  ? style.downSwipeLimit
374
- : bottomSheetConst.MODAL_DOWN_SWIPE_LIMIT;
497
+ : MODAL_DOWN_SWIPE_LIMIT;
375
498
  }
376
499
  monitorInputType() {
377
500
  if (this.globalResizeCleanup)
@@ -407,6 +530,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
407
530
  args: ["elementRef", { static: true }]
408
531
  }] } });
409
532
 
533
+ class ModalCentered {
534
+ headerTemplate = input.required(...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
535
+ footerTemplate = input.required(...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
536
+ config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
537
+ id = input.required(...(ngDevMode ? [{ debugName: "id" }] : []));
538
+ isOpen = input.required(...(ngDevMode ? [{ debugName: "isOpen" }] : []));
539
+ isAnimated = input.required(...(ngDevMode ? [{ debugName: "isAnimated" }] : []));
540
+ isBottomSheetModalActive = input.required(...(ngDevMode ? [{ debugName: "isBottomSheetModalActive" }] : []));
541
+ animationDuration = input.required(...(ngDevMode ? [{ debugName: "animationDuration" }] : []));
542
+ hasDefaultContentWrapperClass = input.required(...(ngDevMode ? [{ debugName: "hasDefaultContentWrapperClass" }] : []));
543
+ hasBanner = input.required(...(ngDevMode ? [{ debugName: "hasBanner" }] : []));
544
+ close = output();
545
+ onBackdropClick = output();
546
+ bottomSheet;
547
+ modalClasses = computed(() => {
548
+ return {
549
+ 'centered-modal-content-wrapper': true,
550
+ 'centered-modal-default-style': this.hasDefaultContentWrapperClass() || this.hasBanner(),
551
+ 'centered-modal-animate-in': this.isAnimated() && this.isOpen(),
552
+ 'centered-modal-animate-out': this.isAnimated() && !this.isOpen(),
553
+ };
554
+ }, ...(ngDevMode ? [{ debugName: "modalClasses" }] : []));
555
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCentered, deps: [], target: i0.ɵɵFactoryTarget.Component });
556
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalCentered, isStandalone: true, selector: "modal-centered", inputs: { headerTemplate: { classPropertyName: "headerTemplate", publicName: "headerTemplate", isSignal: true, isRequired: true, transformFunction: null }, footerTemplate: { classPropertyName: "footerTemplate", publicName: "footerTemplate", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: true, transformFunction: null }, isAnimated: { classPropertyName: "isAnimated", publicName: "isAnimated", isSignal: true, isRequired: true, transformFunction: null }, isBottomSheetModalActive: { classPropertyName: "isBottomSheetModalActive", publicName: "isBottomSheetModalActive", isSignal: true, isRequired: true, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: true, transformFunction: null }, hasDefaultContentWrapperClass: { classPropertyName: "hasDefaultContentWrapperClass", publicName: "hasDefaultContentWrapperClass", isSignal: true, isRequired: true, transformFunction: null }, hasBanner: { classPropertyName: "hasBanner", publicName: "hasBanner", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close", onBackdropClick: "onBackdropClick" }, viewQueries: [{ propertyName: "bottomSheet", predicate: ModalBottomSheet, descendants: true }], ngImport: i0, template: "@if(!isBottomSheetModalActive()) {\n<div class=\"modal-overlay\" [ngClass]=\"{'modal-backdrop': config()?.style?.hasBackdrop}\" [id]=\"id() ?? ''\"\n (click)=\"config()?.style?.hasBackdrop ? onBackdropClick.emit($event) : null\">\n <div class=\"modal-overlay-wrapper\">\n <div [ngClass]=\"modalClasses()\" (click)=\"$event.stopPropagation()\">\n <div class=\"centered-modal-inner-content-container\" [class]=\"config()?.style?.wrapperClasses ?? ''\"\n [style]=\"config()?.style?.wrapperStyles ?? ''\">\n\n <div class=\"centered-modal-top-group\">\n @if (hasBanner()) {\n <modal-banner [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-banner>\n }\n @if (headerTemplate()) {\n <div class=\"centered-modal-header\">\n <ng-container *ngTemplateOutlet=\"headerTemplate()\"></ng-container>\n @if(!hasBanner()) {\n <modal-default-close-button [config]=\"config()\"\n (close)=\"close.emit('cancel')\"></modal-default-close-button>\n }\n </div>\n }\n <div class=\"centered-modal-main-content-container\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n\n @if (footerTemplate()) {\n <div class=\"centered-modal-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n} @else {\n<modal-bottom-sheet [headerTemplate]=\"headerTemplate()\" [footerTemplate]=\"footerTemplate()\" [config]=\"config()\"\n [id]=\"id()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\" [animationDuration]=\"animationDuration()\"\n (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-bottom-sheet>\n}\n\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>", styles: [".modal-overlay-wrapper{display:flex;position:absolute;z-index:3;justify-content:center;align-items:center;width:100%;height:100%}.modal-overlay{position:absolute;inset:0;z-index:2}.modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}.centered-modal-content-wrapper{display:flex;flex-direction:column;max-width:90vw;max-width:90dvw;max-height:95vh;max-height:95dvh;overflow:hidden}.centered-modal-default-style{border-radius:.75rem;box-shadow:0 8px 20px #0000001f;color:var(--modal-text, #000000);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid transparent;background-color:var(--modal-bg, #ffffff)}.centered-modal-default-content-container{padding:1rem 1.5rem;max-height:85vh;max-height:85dvh;overflow-y:auto}.centered-modal-inner-content-container{display:flex;flex-direction:column;height:100%;padding:1rem 1.5rem;gap:1.5rem;box-sizing:border-box}.centered-modal-top-group{display:flex;flex-direction:column;gap:1rem;flex-grow:1;min-height:0}.centered-modal-main-content-container{flex-grow:1;overflow-y:auto;min-height:0}.centered-modal-header{flex-shrink:0;width:100%;display:flex;justify-content:space-between;gap:.5rem}.centered-modal-footer{flex-shrink:0;width:100%;display:flex;justify-content:center;gap:.5rem}.centered-modal-animate-in{scale:0;animation:centered-modal-animate-in .15s ease-in-out forwards}.centered-modal-animate-out{animation:centered-modal-animate-out .15s ease-in-out forwards}@keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-webkit-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-moz-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-webkit-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-moz-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ModalBottomSheet, selector: "modal-bottom-sheet", inputs: ["id", "headerTemplate", "footerTemplate", "config", "isOpen", "isAnimated", "animationDuration"], outputs: ["close"] }, { kind: "component", type: ModalBanner, selector: "modal-banner", inputs: ["config"], outputs: ["close"] }, { kind: "component", type: ModalDefaultCloseButton, selector: "modal-default-close-button", inputs: ["config"], outputs: ["close"] }] });
557
+ }
558
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCentered, decorators: [{
559
+ type: Component,
560
+ args: [{ selector: 'modal-centered', imports: [
561
+ NgTemplateOutlet,
562
+ NgClass,
563
+ ModalBottomSheet,
564
+ ModalBanner,
565
+ ModalDefaultCloseButton
566
+ ], template: "@if(!isBottomSheetModalActive()) {\n<div class=\"modal-overlay\" [ngClass]=\"{'modal-backdrop': config()?.style?.hasBackdrop}\" [id]=\"id() ?? ''\"\n (click)=\"config()?.style?.hasBackdrop ? onBackdropClick.emit($event) : null\">\n <div class=\"modal-overlay-wrapper\">\n <div [ngClass]=\"modalClasses()\" (click)=\"$event.stopPropagation()\">\n <div class=\"centered-modal-inner-content-container\" [class]=\"config()?.style?.wrapperClasses ?? ''\"\n [style]=\"config()?.style?.wrapperStyles ?? ''\">\n\n <div class=\"centered-modal-top-group\">\n @if (hasBanner()) {\n <modal-banner [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-banner>\n }\n @if (headerTemplate()) {\n <div class=\"centered-modal-header\">\n <ng-container *ngTemplateOutlet=\"headerTemplate()\"></ng-container>\n @if(!hasBanner()) {\n <modal-default-close-button [config]=\"config()\"\n (close)=\"close.emit('cancel')\"></modal-default-close-button>\n }\n </div>\n }\n <div class=\"centered-modal-main-content-container\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n\n @if (footerTemplate()) {\n <div class=\"centered-modal-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n} @else {\n<modal-bottom-sheet [headerTemplate]=\"headerTemplate()\" [footerTemplate]=\"footerTemplate()\" [config]=\"config()\"\n [id]=\"id()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\" [animationDuration]=\"animationDuration()\"\n (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-bottom-sheet>\n}\n\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>", styles: [".modal-overlay-wrapper{display:flex;position:absolute;z-index:3;justify-content:center;align-items:center;width:100%;height:100%}.modal-overlay{position:absolute;inset:0;z-index:2}.modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}.centered-modal-content-wrapper{display:flex;flex-direction:column;max-width:90vw;max-width:90dvw;max-height:95vh;max-height:95dvh;overflow:hidden}.centered-modal-default-style{border-radius:.75rem;box-shadow:0 8px 20px #0000001f;color:var(--modal-text, #000000);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid transparent;background-color:var(--modal-bg, #ffffff)}.centered-modal-default-content-container{padding:1rem 1.5rem;max-height:85vh;max-height:85dvh;overflow-y:auto}.centered-modal-inner-content-container{display:flex;flex-direction:column;height:100%;padding:1rem 1.5rem;gap:1.5rem;box-sizing:border-box}.centered-modal-top-group{display:flex;flex-direction:column;gap:1rem;flex-grow:1;min-height:0}.centered-modal-main-content-container{flex-grow:1;overflow-y:auto;min-height:0}.centered-modal-header{flex-shrink:0;width:100%;display:flex;justify-content:space-between;gap:.5rem}.centered-modal-footer{flex-shrink:0;width:100%;display:flex;justify-content:center;gap:.5rem}.centered-modal-animate-in{scale:0;animation:centered-modal-animate-in .15s ease-in-out forwards}.centered-modal-animate-out{animation:centered-modal-animate-out .15s ease-in-out forwards}@keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-webkit-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-moz-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-webkit-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-moz-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}\n"] }]
567
+ }], propDecorators: { headerTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTemplate", required: true }] }], footerTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerTemplate", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: true }] }], isAnimated: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAnimated", required: true }] }], isBottomSheetModalActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isBottomSheetModalActive", required: true }] }], animationDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: true }] }], hasDefaultContentWrapperClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDefaultContentWrapperClass", required: true }] }], hasBanner: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBanner", required: true }] }], close: [{ type: i0.Output, args: ["close"] }], onBackdropClick: [{ type: i0.Output, args: ["onBackdropClick"] }], bottomSheet: [{
568
+ type: ViewChildren,
569
+ args: [ModalBottomSheet]
570
+ }] } });
571
+
410
572
  class ModalSide {
411
573
  layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : []));
412
574
  headerTemplate = input.required(...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
@@ -452,231 +614,266 @@ class ModalSide {
452
614
  });
453
615
  }
454
616
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalSide, deps: [], target: i0.ɵɵFactoryTarget.Component });
455
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalSide, isStandalone: true, selector: "modal-side", inputs: { layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, headerTemplate: { classPropertyName: "headerTemplate", publicName: "headerTemplate", isSignal: true, isRequired: true, transformFunction: null }, footerTemplate: { classPropertyName: "footerTemplate", publicName: "footerTemplate", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: true, transformFunction: null }, isAnimated: { classPropertyName: "isAnimated", publicName: "isAnimated", isSignal: true, isRequired: true, transformFunction: null }, isBottomSheetModalActive: { classPropertyName: "isBottomSheetModalActive", publicName: "isBottomSheetModalActive", isSignal: true, isRequired: true, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: true, transformFunction: null }, hasDefaultContentWrapperClass: { classPropertyName: "hasDefaultContentWrapperClass", publicName: "hasDefaultContentWrapperClass", isSignal: true, isRequired: true, transformFunction: null }, hasBanner: { classPropertyName: "hasBanner", publicName: "hasBanner", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close" }, viewQueries: [{ propertyName: "bottomSheet", predicate: ModalBottomSheet$1, descendants: true }], ngImport: i0, template: "@if(!isBottomSheetModalActive()) {\n<div [ngClass]=\"modalClasses()\" (click)=\"$event.stopPropagation()\" [id]=\"id() ?? ''\"\n [style.--anim-duration.ms]=\"animationDuration()\">\n <div class=\"side-modal-inner-content-container\"\n [class]=\"config() && config()?.style?.wrapperClasses ? config()?.style?.wrapperClasses : ''\"\n [style]=\"config() && config()?.style?.wrapperStyles ? config()?.style?.wrapperStyles : ''\">\n @if (hasBanner()) {\n <modal-banner [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-banner>\n }\n @if (headerTemplate()) {\n <div class=\"side-modal-header\">\n <ng-container *ngTemplateOutlet=\"headerTemplate()\"></ng-container>\n @if(!hasBanner()) {\n <modal-default-close-button [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-default-close-button>\n }\n </div>\n }\n <div class=\"side-modal-main-content-container\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n\n @if (footerTemplate()) {\n <div class=\"side-modal-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()\"></ng-container>\n </div>\n }\n</div>\n} @else {\n<modal-bottom-sheet [headerTemplate]=\"headerTemplate()\" [footerTemplate]=\"footerTemplate()\" [config]=\"config()\"\n [id]=\"id()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\" [animationDuration]=\"animationDuration()\"\n (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-bottom-sheet>\n}\n\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>", styles: [".side-modal-content-wrapper{position:fixed;top:0;height:100vh;height:100dvh;z-index:3;display:flex;flex-direction:column;padding:1rem;gap:1rem;box-sizing:border-box;overflow:hidden;transition:transform var(--anim-duration, 175ms) ease-in-out}.side-modal-content-wrapper.left{left:0}.side-modal-content-wrapper.right{right:0}.side-modal-content-wrapper.side-modal-animate-in{transform:translate(0)!important}.side-modal-content-wrapper.side-modal-animate-out.left{transform:translate(-100%)}.side-modal-content-wrapper.side-modal-animate-out.right{transform:translate(100%)}.side-modal-content-wrapper.with-footer{justify-content:space-between}.side-modal-content-wrapper .side-modal-inner-content-container{flex-grow:1;display:flex;flex-direction:column;gap:1rem;min-height:0}@media(max-width:768px){.side-modal-content-wrapper{max-width:90vw;max-width:95dvw}}.side-modal-default-style{background:var(--modal-bg, #ffffff);color:var(--modal-text, #000000);box-shadow:0 0 15px #0000004d;max-width:85vw;max-width:85dvw}.side-modal-main-content-container{flex-grow:1;overflow-y:auto;min-height:0;max-height:none}.side-modal-header{flex-shrink:0;width:100%;display:flex;justify-content:space-between;gap:.5rem;padding-top:.75rem}.side-modal-footer{flex-shrink:0;width:100%;display:flex;justify-content:flex-end;gap:.5rem;padding-bottom:.75rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalBottomSheet$1, selector: "modal-bottom-sheet", inputs: ["id", "headerTemplate", "footerTemplate", "config", "isOpen", "isAnimated", "animationDuration"], outputs: ["close"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ModalBanner$1, selector: "modal-banner", inputs: ["config"], outputs: ["close"] }, { kind: "component", type: ModalDefaultCloseButton, selector: "modal-default-close-button", inputs: ["config"], outputs: ["close"] }] });
617
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalSide, isStandalone: true, selector: "modal-side", inputs: { layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, headerTemplate: { classPropertyName: "headerTemplate", publicName: "headerTemplate", isSignal: true, isRequired: true, transformFunction: null }, footerTemplate: { classPropertyName: "footerTemplate", publicName: "footerTemplate", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: true, transformFunction: null }, isAnimated: { classPropertyName: "isAnimated", publicName: "isAnimated", isSignal: true, isRequired: true, transformFunction: null }, isBottomSheetModalActive: { classPropertyName: "isBottomSheetModalActive", publicName: "isBottomSheetModalActive", isSignal: true, isRequired: true, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: true, transformFunction: null }, hasDefaultContentWrapperClass: { classPropertyName: "hasDefaultContentWrapperClass", publicName: "hasDefaultContentWrapperClass", isSignal: true, isRequired: true, transformFunction: null }, hasBanner: { classPropertyName: "hasBanner", publicName: "hasBanner", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close" }, viewQueries: [{ propertyName: "bottomSheet", predicate: ModalBottomSheet, descendants: true }], ngImport: i0, template: "@if(!isBottomSheetModalActive()) {\n<div [ngClass]=\"modalClasses()\" (click)=\"$event.stopPropagation()\" [id]=\"id() ?? ''\"\n [style.--anim-duration.ms]=\"animationDuration()\">\n <div class=\"side-modal-inner-content-container\"\n [class]=\"config() && config()?.style?.wrapperClasses ? config()?.style?.wrapperClasses : ''\"\n [style]=\"config() && config()?.style?.wrapperStyles ? config()?.style?.wrapperStyles : ''\">\n @if (hasBanner()) {\n <modal-banner [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-banner>\n }\n @if (headerTemplate()) {\n <div class=\"side-modal-header\">\n <ng-container *ngTemplateOutlet=\"headerTemplate()\"></ng-container>\n @if(!hasBanner()) {\n <modal-default-close-button [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-default-close-button>\n }\n </div>\n }\n <div class=\"side-modal-main-content-container\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n\n @if (footerTemplate()) {\n <div class=\"side-modal-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()\"></ng-container>\n </div>\n }\n</div>\n} @else {\n<modal-bottom-sheet [headerTemplate]=\"headerTemplate()\" [footerTemplate]=\"footerTemplate()\" [config]=\"config()\"\n [id]=\"id()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\" [animationDuration]=\"animationDuration()\"\n (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-bottom-sheet>\n}\n\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>", styles: [".side-modal-content-wrapper{position:fixed;top:0;height:100vh;height:100dvh;z-index:3;display:flex;flex-direction:column;padding:1rem;gap:1rem;box-sizing:border-box;overflow:hidden;transition:transform var(--anim-duration, 175ms) ease-in-out}.side-modal-content-wrapper.left{left:0}.side-modal-content-wrapper.right{right:0}.side-modal-content-wrapper.side-modal-animate-in{transform:translate(0)!important}.side-modal-content-wrapper.side-modal-animate-out.left{transform:translate(-100%)}.side-modal-content-wrapper.side-modal-animate-out.right{transform:translate(100%)}.side-modal-content-wrapper.with-footer{justify-content:space-between}.side-modal-content-wrapper .side-modal-inner-content-container{flex-grow:1;display:flex;flex-direction:column;gap:1rem;min-height:0}@media(max-width:768px){.side-modal-content-wrapper{max-width:90vw;max-width:95dvw}}.side-modal-default-style{background:var(--modal-bg, #ffffff);color:var(--modal-text, #000000);box-shadow:0 0 15px #0000004d;max-width:85vw;max-width:85dvw}.side-modal-main-content-container{flex-grow:1;overflow-y:auto;min-height:0;max-height:none}.side-modal-header{flex-shrink:0;width:100%;display:flex;justify-content:space-between;gap:.5rem;padding-top:.75rem}.side-modal-footer{flex-shrink:0;width:100%;display:flex;justify-content:flex-end;gap:.5rem;padding-bottom:.75rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalBottomSheet, selector: "modal-bottom-sheet", inputs: ["id", "headerTemplate", "footerTemplate", "config", "isOpen", "isAnimated", "animationDuration"], outputs: ["close"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ModalBanner, selector: "modal-banner", inputs: ["config"], outputs: ["close"] }, { kind: "component", type: ModalDefaultCloseButton, selector: "modal-default-close-button", inputs: ["config"], outputs: ["close"] }] });
456
618
  }
457
619
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalSide, decorators: [{
458
620
  type: Component,
459
621
  args: [{ selector: 'modal-side', imports: [
460
622
  NgTemplateOutlet,
461
- ModalBottomSheet$1,
623
+ ModalBottomSheet,
462
624
  NgClass,
463
- ModalBanner$1,
625
+ ModalBanner,
464
626
  ModalDefaultCloseButton
465
627
  ], template: "@if(!isBottomSheetModalActive()) {\n<div [ngClass]=\"modalClasses()\" (click)=\"$event.stopPropagation()\" [id]=\"id() ?? ''\"\n [style.--anim-duration.ms]=\"animationDuration()\">\n <div class=\"side-modal-inner-content-container\"\n [class]=\"config() && config()?.style?.wrapperClasses ? config()?.style?.wrapperClasses : ''\"\n [style]=\"config() && config()?.style?.wrapperStyles ? config()?.style?.wrapperStyles : ''\">\n @if (hasBanner()) {\n <modal-banner [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-banner>\n }\n @if (headerTemplate()) {\n <div class=\"side-modal-header\">\n <ng-container *ngTemplateOutlet=\"headerTemplate()\"></ng-container>\n @if(!hasBanner()) {\n <modal-default-close-button [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-default-close-button>\n }\n </div>\n }\n <div class=\"side-modal-main-content-container\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n\n @if (footerTemplate()) {\n <div class=\"side-modal-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()\"></ng-container>\n </div>\n }\n</div>\n} @else {\n<modal-bottom-sheet [headerTemplate]=\"headerTemplate()\" [footerTemplate]=\"footerTemplate()\" [config]=\"config()\"\n [id]=\"id()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\" [animationDuration]=\"animationDuration()\"\n (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-bottom-sheet>\n}\n\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>", styles: [".side-modal-content-wrapper{position:fixed;top:0;height:100vh;height:100dvh;z-index:3;display:flex;flex-direction:column;padding:1rem;gap:1rem;box-sizing:border-box;overflow:hidden;transition:transform var(--anim-duration, 175ms) ease-in-out}.side-modal-content-wrapper.left{left:0}.side-modal-content-wrapper.right{right:0}.side-modal-content-wrapper.side-modal-animate-in{transform:translate(0)!important}.side-modal-content-wrapper.side-modal-animate-out.left{transform:translate(-100%)}.side-modal-content-wrapper.side-modal-animate-out.right{transform:translate(100%)}.side-modal-content-wrapper.with-footer{justify-content:space-between}.side-modal-content-wrapper .side-modal-inner-content-container{flex-grow:1;display:flex;flex-direction:column;gap:1rem;min-height:0}@media(max-width:768px){.side-modal-content-wrapper{max-width:90vw;max-width:95dvw}}.side-modal-default-style{background:var(--modal-bg, #ffffff);color:var(--modal-text, #000000);box-shadow:0 0 15px #0000004d;max-width:85vw;max-width:85dvw}.side-modal-main-content-container{flex-grow:1;overflow-y:auto;min-height:0;max-height:none}.side-modal-header{flex-shrink:0;width:100%;display:flex;justify-content:space-between;gap:.5rem;padding-top:.75rem}.side-modal-footer{flex-shrink:0;width:100%;display:flex;justify-content:flex-end;gap:.5rem;padding-bottom:.75rem}\n"] }]
466
628
  }], ctorParameters: () => [], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], headerTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTemplate", required: true }] }], footerTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerTemplate", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: true }] }], isAnimated: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAnimated", required: true }] }], isBottomSheetModalActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isBottomSheetModalActive", required: true }] }], animationDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: true }] }], hasDefaultContentWrapperClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDefaultContentWrapperClass", required: true }] }], hasBanner: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBanner", required: true }] }], close: [{ type: i0.Output, args: ["close"] }], bottomSheet: [{
467
629
  type: ViewChildren,
468
- args: [ModalBottomSheet$1]
469
- }] } });
470
-
471
- class ModalCentered {
472
- headerTemplate = input.required(...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
473
- footerTemplate = input.required(...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
474
- config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
475
- id = input.required(...(ngDevMode ? [{ debugName: "id" }] : []));
476
- isOpen = input.required(...(ngDevMode ? [{ debugName: "isOpen" }] : []));
477
- isAnimated = input.required(...(ngDevMode ? [{ debugName: "isAnimated" }] : []));
478
- isBottomSheetModalActive = input.required(...(ngDevMode ? [{ debugName: "isBottomSheetModalActive" }] : []));
479
- animationDuration = input.required(...(ngDevMode ? [{ debugName: "animationDuration" }] : []));
480
- hasDefaultContentWrapperClass = input.required(...(ngDevMode ? [{ debugName: "hasDefaultContentWrapperClass" }] : []));
481
- hasBanner = input.required(...(ngDevMode ? [{ debugName: "hasBanner" }] : []));
482
- close = output();
483
- onBackdropClick = output();
484
- bottomSheet;
485
- modalClasses = computed(() => {
486
- return {
487
- 'centered-modal-content-wrapper': true,
488
- 'centered-modal-default-style': this.hasDefaultContentWrapperClass() || this.hasBanner(),
489
- 'centered-modal-animate-in': this.isAnimated() && this.isOpen(),
490
- 'centered-modal-animate-out': this.isAnimated() && !this.isOpen(),
491
- };
492
- }, ...(ngDevMode ? [{ debugName: "modalClasses" }] : []));
493
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCentered, deps: [], target: i0.ɵɵFactoryTarget.Component });
494
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalCentered, isStandalone: true, selector: "modal-centered", inputs: { headerTemplate: { classPropertyName: "headerTemplate", publicName: "headerTemplate", isSignal: true, isRequired: true, transformFunction: null }, footerTemplate: { classPropertyName: "footerTemplate", publicName: "footerTemplate", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: true, transformFunction: null }, isAnimated: { classPropertyName: "isAnimated", publicName: "isAnimated", isSignal: true, isRequired: true, transformFunction: null }, isBottomSheetModalActive: { classPropertyName: "isBottomSheetModalActive", publicName: "isBottomSheetModalActive", isSignal: true, isRequired: true, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: true, transformFunction: null }, hasDefaultContentWrapperClass: { classPropertyName: "hasDefaultContentWrapperClass", publicName: "hasDefaultContentWrapperClass", isSignal: true, isRequired: true, transformFunction: null }, hasBanner: { classPropertyName: "hasBanner", publicName: "hasBanner", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close", onBackdropClick: "onBackdropClick" }, viewQueries: [{ propertyName: "bottomSheet", predicate: ModalBottomSheet$1, descendants: true }], ngImport: i0, template: "@if(!isBottomSheetModalActive()) {\n<div class=\"modal-overlay\" [ngClass]=\"{'modal-backdrop': config()?.style?.hasBackdrop}\" [id]=\"id() ?? ''\"\n (click)=\"config()?.style?.hasBackdrop ? onBackdropClick.emit($event) : null\">\n <div class=\"modal-overlay-wrapper\">\n <div [ngClass]=\"modalClasses()\" (click)=\"$event.stopPropagation()\">\n <div class=\"centered-modal-inner-content-container\" [class]=\"config()?.style?.wrapperClasses ?? ''\"\n [style]=\"config()?.style?.wrapperStyles ?? ''\">\n\n <div class=\"centered-modal-top-group\">\n @if (hasBanner()) {\n <modal-banner [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-banner>\n }\n @if (headerTemplate()) {\n <div class=\"centered-modal-header\">\n <ng-container *ngTemplateOutlet=\"headerTemplate()\"></ng-container>\n @if(!hasBanner()) {\n <modal-default-close-button [config]=\"config()\"\n (close)=\"close.emit('cancel')\"></modal-default-close-button>\n }\n </div>\n }\n <div class=\"centered-modal-main-content-container\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n\n @if (footerTemplate()) {\n <div class=\"centered-modal-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n} @else {\n<modal-bottom-sheet [headerTemplate]=\"headerTemplate()\" [footerTemplate]=\"footerTemplate()\" [config]=\"config()\"\n [id]=\"id()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\" [animationDuration]=\"animationDuration()\"\n (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-bottom-sheet>\n}\n\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>", styles: [".modal-overlay-wrapper{display:flex;position:absolute;z-index:3;justify-content:center;align-items:center;width:100%;height:100%}.modal-overlay{position:absolute;inset:0;z-index:2}.modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}.centered-modal-content-wrapper{display:flex;flex-direction:column;max-width:90vw;max-width:90dvw;max-height:95vh;max-height:95dvh;overflow:hidden}.centered-modal-default-style{border-radius:.75rem;box-shadow:0 8px 20px #0000001f;color:var(--modal-text, #000000);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid transparent;background-color:var(--modal-bg, #ffffff)}.centered-modal-default-content-container{padding:1rem 1.5rem;max-height:85vh;max-height:85dvh;overflow-y:auto}.centered-modal-inner-content-container{display:flex;flex-direction:column;height:100%;padding:1rem 1.5rem;gap:1.5rem;box-sizing:border-box}.centered-modal-top-group{display:flex;flex-direction:column;gap:1rem;flex-grow:1;min-height:0}.centered-modal-main-content-container{flex-grow:1;overflow-y:auto;min-height:0}.centered-modal-header{flex-shrink:0;width:100%;display:flex;justify-content:space-between;gap:.5rem}.centered-modal-footer{flex-shrink:0;width:100%;display:flex;justify-content:center;gap:.5rem}.centered-modal-animate-in{scale:0;animation:centered-modal-animate-in .15s ease-in-out forwards}.centered-modal-animate-out{animation:centered-modal-animate-out .15s ease-in-out forwards}@keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-webkit-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-moz-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-webkit-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-moz-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ModalBottomSheet$1, selector: "modal-bottom-sheet", inputs: ["id", "headerTemplate", "footerTemplate", "config", "isOpen", "isAnimated", "animationDuration"], outputs: ["close"] }, { kind: "component", type: ModalBanner$1, selector: "modal-banner", inputs: ["config"], outputs: ["close"] }, { kind: "component", type: ModalDefaultCloseButton, selector: "modal-default-close-button", inputs: ["config"], outputs: ["close"] }] });
495
- }
496
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCentered, decorators: [{
497
- type: Component,
498
- args: [{ selector: 'modal-centered', imports: [
499
- NgTemplateOutlet,
500
- NgClass,
501
- ModalBottomSheet$1,
502
- ModalBanner$1,
503
- ModalDefaultCloseButton
504
- ], template: "@if(!isBottomSheetModalActive()) {\n<div class=\"modal-overlay\" [ngClass]=\"{'modal-backdrop': config()?.style?.hasBackdrop}\" [id]=\"id() ?? ''\"\n (click)=\"config()?.style?.hasBackdrop ? onBackdropClick.emit($event) : null\">\n <div class=\"modal-overlay-wrapper\">\n <div [ngClass]=\"modalClasses()\" (click)=\"$event.stopPropagation()\">\n <div class=\"centered-modal-inner-content-container\" [class]=\"config()?.style?.wrapperClasses ?? ''\"\n [style]=\"config()?.style?.wrapperStyles ?? ''\">\n\n <div class=\"centered-modal-top-group\">\n @if (hasBanner()) {\n <modal-banner [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-banner>\n }\n @if (headerTemplate()) {\n <div class=\"centered-modal-header\">\n <ng-container *ngTemplateOutlet=\"headerTemplate()\"></ng-container>\n @if(!hasBanner()) {\n <modal-default-close-button [config]=\"config()\"\n (close)=\"close.emit('cancel')\"></modal-default-close-button>\n }\n </div>\n }\n <div class=\"centered-modal-main-content-container\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n\n @if (footerTemplate()) {\n <div class=\"centered-modal-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate()\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n} @else {\n<modal-bottom-sheet [headerTemplate]=\"headerTemplate()\" [footerTemplate]=\"footerTemplate()\" [config]=\"config()\"\n [id]=\"id()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\" [animationDuration]=\"animationDuration()\"\n (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-bottom-sheet>\n}\n\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>", styles: [".modal-overlay-wrapper{display:flex;position:absolute;z-index:3;justify-content:center;align-items:center;width:100%;height:100%}.modal-overlay{position:absolute;inset:0;z-index:2}.modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}.centered-modal-content-wrapper{display:flex;flex-direction:column;max-width:90vw;max-width:90dvw;max-height:95vh;max-height:95dvh;overflow:hidden}.centered-modal-default-style{border-radius:.75rem;box-shadow:0 8px 20px #0000001f;color:var(--modal-text, #000000);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid transparent;background-color:var(--modal-bg, #ffffff)}.centered-modal-default-content-container{padding:1rem 1.5rem;max-height:85vh;max-height:85dvh;overflow-y:auto}.centered-modal-inner-content-container{display:flex;flex-direction:column;height:100%;padding:1rem 1.5rem;gap:1.5rem;box-sizing:border-box}.centered-modal-top-group{display:flex;flex-direction:column;gap:1rem;flex-grow:1;min-height:0}.centered-modal-main-content-container{flex-grow:1;overflow-y:auto;min-height:0}.centered-modal-header{flex-shrink:0;width:100%;display:flex;justify-content:space-between;gap:.5rem}.centered-modal-footer{flex-shrink:0;width:100%;display:flex;justify-content:center;gap:.5rem}.centered-modal-animate-in{scale:0;animation:centered-modal-animate-in .15s ease-in-out forwards}.centered-modal-animate-out{animation:centered-modal-animate-out .15s ease-in-out forwards}@keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-webkit-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@-moz-keyframes centered-modal-animate-in{0%{scale:0}to{scale:1}}@keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-webkit-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}@-moz-keyframes centered-modal-animate-out{0%{scale:1}to{scale:0}}\n"] }]
505
- }], propDecorators: { headerTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTemplate", required: true }] }], footerTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerTemplate", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: true }] }], isAnimated: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAnimated", required: true }] }], isBottomSheetModalActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isBottomSheetModalActive", required: true }] }], animationDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: true }] }], hasDefaultContentWrapperClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDefaultContentWrapperClass", required: true }] }], hasBanner: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBanner", required: true }] }], close: [{ type: i0.Output, args: ["close"] }], onBackdropClick: [{ type: i0.Output, args: ["onBackdropClick"] }], bottomSheet: [{
506
- type: ViewChildren,
507
- args: [ModalBottomSheet$1]
630
+ args: [ModalBottomSheet]
508
631
  }] } });
509
632
 
510
- class ModalBackdrop {
511
- isAnimated = input(false, ...(ngDevMode ? [{ debugName: "isAnimated" }] : []));
512
- isOpen = input(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
513
- click = output();
514
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Component });
515
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.3", type: ModalBackdrop, isStandalone: true, selector: "modal-backdrop", inputs: { isAnimated: { classPropertyName: "isAnimated", publicName: "isAnimated", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { click: "click" }, ngImport: i0, template: "<div class=\"modal-backdrop\" [class.backdrop-fade-in]=\"isAnimated() && isOpen()\"\n [class.backdrop-fade-out]=\"isAnimated() && !isOpen()\" (click)=\"click.emit($event)\">\n</div>", styles: [".modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}\n"] });
516
- }
517
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBackdrop, decorators: [{
518
- type: Component,
519
- args: [{ selector: 'modal-backdrop', imports: [], template: "<div class=\"modal-backdrop\" [class.backdrop-fade-in]=\"isAnimated() && isOpen()\"\n [class.backdrop-fade-out]=\"isAnimated() && !isOpen()\" (click)=\"click.emit($event)\">\n</div>", styles: [".modal-backdrop{position:fixed;inset:0;z-index:3;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:#00000040;backface-visibility:hidden;-webkit-font-smoothing:subpixel-antialiased;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d;transform-origin:center}\n"] }]
520
- }], propDecorators: { isAnimated: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAnimated", required: false }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }], click: [{ type: i0.Output, args: ["click"] }] } });
521
-
522
- class ModalBanner {
523
- config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
524
- close = output();
525
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBanner, deps: [], target: i0.ɵɵFactoryTarget.Component });
526
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalBanner, isStandalone: true, selector: "modal-banner", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"modal-top-banner-container\">\n <div class=\"modal-top-banner-title-container\">\n @if (config() && config()?.bannerText && (config() && config()!.bannerText.length > 0)) {\n {{ config()?.bannerText }}\n }\n </div>\n \n <modal-default-close-button [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-default-close-button>\n</div>", styles: [".modal-top-banner-container{display:flex;flex-direction:row;gap:2rem;justify-content:space-between;align-items:center;color:var(--modal-text, #000000);top:0;min-height:2rem;border-top-left-radius:.75rem;border-top-right-radius:.75rem}.modal-top-banner-title-container{display:flex;flex-direction:row;justify-content:flex-start;gap:1.5rem;align-items:center;width:100%}@keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-webkit-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-moz-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}\n"], dependencies: [{ kind: "component", type: ModalDefaultCloseButton, selector: "modal-default-close-button", inputs: ["config"], outputs: ["close"] }] });
527
- }
528
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalBanner, decorators: [{
529
- type: Component,
530
- args: [{ selector: 'modal-banner', imports: [
531
- ModalDefaultCloseButton
532
- ], template: "<div class=\"modal-top-banner-container\">\n <div class=\"modal-top-banner-title-container\">\n @if (config() && config()?.bannerText && (config() && config()!.bannerText.length > 0)) {\n {{ config()?.bannerText }}\n }\n </div>\n \n <modal-default-close-button [config]=\"config()\" (close)=\"close.emit('cancel')\"></modal-default-close-button>\n</div>", styles: [".modal-top-banner-container{display:flex;flex-direction:row;gap:2rem;justify-content:space-between;align-items:center;color:var(--modal-text, #000000);top:0;min-height:2rem;border-top-left-radius:.75rem;border-top-right-radius:.75rem}.modal-top-banner-title-container{display:flex;flex-direction:row;justify-content:flex-start;gap:1.5rem;align-items:center;width:100%}@keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-webkit-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}@-moz-keyframes banner-display{0%{opacity:0;height:0}to{opacity:1;height:auto}}\n"] }]
533
- }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], close: [{ type: i0.Output, args: ["close"] }] } });
633
+ const MODAL_DEFAULT_ANIM_DURATION = 175;
634
+ const MODAL_DEFAULT_INTERNAL_ANIM_DURATION = 350;
635
+ const MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_SMALL = 0.65;
636
+ const MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_LARGE = 0.85;
534
637
 
535
- class ModalService {
536
- router = inject(Router);
537
- injector = inject(Injector);
538
- appRef = inject(ApplicationRef);
539
- environmentInjector = inject(EnvironmentInjector);
540
- rendererFactory = inject(RendererFactory2);
541
- renderer;
542
- document = inject(DOCUMENT);
543
- //#region Properties
544
- modals = new Set();
545
- modalsSubject = new BehaviorSubject(this.modals);
546
- //#endregion
638
+ class ModalCore {
639
+ modalService = inject(ModalService);
640
+ windowDimensionsService = inject(WindowDimensionsService);
641
+ scrollLockService = inject(ScrollLockService);
642
+ afterClose = output();
643
+ animationDuration = MODAL_DEFAULT_ANIM_DURATION;
644
+ componentRef = {};
645
+ config;
646
+ closeFunction;
647
+ backdropClickSubject = new Subject();
648
+ backdropClick = this.backdropClickSubject.asObservable();
649
+ isOpen = signal(true, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
650
+ effectiveLayout = signal('center', ...(ngDevMode ? [{ debugName: "effectiveLayout" }] : []));
651
+ isCentered = signal(false, ...(ngDevMode ? [{ debugName: "isCentered" }] : []));
652
+ isSide = signal(false, ...(ngDevMode ? [{ debugName: "isSide" }] : []));
653
+ headerTemplate = signal(null, ...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
654
+ footerTemplate = signal(null, ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
655
+ id = signal(null, ...(ngDevMode ? [{ debugName: "id" }] : []));
656
+ isBottomSheetModalActive = signal(false, ...(ngDevMode ? [{ debugName: "isBottomSheetModalActive" }] : []));
657
+ isAnimated = false;
658
+ hasBanner = false;
659
+ hasDefaultContentWrapperClass = false;
660
+ isConfirmCloseModalOpen = false;
661
+ scrollLockId = uuidv4();
662
+ _sortedBreakpoints = [];
663
+ windowDimensions = this.windowDimensionsService.dimensions;
664
+ _currentVcr = null;
665
+ set dynamicContainer(vcr) {
666
+ if (vcr && this.componentRef) {
667
+ this._currentVcr = vcr;
668
+ vcr.insert(this.componentRef.hostView);
669
+ }
670
+ }
671
+ modalContainer;
672
+ contentTemplate;
673
+ sideModalComponents;
674
+ centeredModalComponents;
547
675
  constructor() {
548
- this.renderer = this.rendererFactory.createRenderer(null, null);
549
- this.createSubscriptions();
676
+ this.initKeyboardSubscription();
677
+ effect(() => {
678
+ const width = this.windowDimensions().width;
679
+ this.handleLayout(width);
680
+ });
681
+ }
682
+ ngOnInit() {
683
+ this.initParamsFromConfig();
684
+ this.initBreakpointCache();
685
+ this.scrollLockService.disableScroll(this.scrollLockId, {
686
+ animationDuration: this.animationDuration,
687
+ handleTouchInput: true,
688
+ mobileOnlyTouchPrevention: true,
689
+ });
690
+ }
691
+ ngAfterViewInit() {
692
+ if (!this.componentRef)
693
+ return;
694
+ this.dynamicContainer?.insert(this.componentRef.hostView);
695
+ const width = this.windowDimensionsService.dimensions().width;
696
+ this.handleLayout(width);
697
+ }
698
+ ngOnDestroy() {
699
+ this.componentRef?.destroy();
700
+ this.dynamicContainer?.clear();
701
+ this.scrollLockService.enableScroll(this.scrollLockId);
550
702
  }
551
703
  //#region Subscription Methods
552
- createSubscriptions() {
553
- this.router.events
554
- .pipe(filter((event) => event instanceof NavigationEnd), skip(1), takeUntilDestroyed())
704
+ initKeyboardSubscription() {
705
+ fromEvent(document, "keydown")
706
+ .pipe(filter((event) => event.key === "Escape"), takeUntilDestroyed())
555
707
  .subscribe(() => {
556
- if (this.modalsCount() > 0) {
557
- this.closeAll(true);
708
+ if (!this.isConfirmCloseModalOpen) {
709
+ this.close("cancel", undefined, true);
558
710
  }
559
711
  });
560
712
  }
561
713
  //#endregion
562
- //#region Public Methods
563
- /**
564
- * Opens a modal with the specified component and configuration.
565
- * @param component The component to be displayed in the modal.
566
- * @param config Optional configuration for the modal.
567
- * @returns A ModalRef instance representing the opened modal.
568
- */
569
- open(component, config) {
570
- const dataInjector = Injector.create({
571
- providers: [{ provide: MODAL_DATA$1, useValue: config?.data }],
572
- parent: this.injector,
573
- });
574
- const wrapperRef = createComponent((ModalCore$1), {
575
- environmentInjector: this.environmentInjector,
576
- elementInjector: dataInjector
577
- });
578
- const contentInjector = Injector.create({
579
- providers: [
580
- { provide: ModalCore$1, useValue: wrapperRef.instance }
581
- ],
582
- parent: wrapperRef.injector,
583
- });
584
- const contentRef = createComponent(component, {
585
- environmentInjector: this.environmentInjector,
586
- elementInjector: contentInjector
587
- });
588
- wrapperRef.instance.componentRef = contentRef;
589
- wrapperRef.instance.config = new ModalConfig$1(config);
590
- this.appRef.attachView(wrapperRef.hostView);
591
- this.document.body.appendChild(wrapperRef.location.nativeElement);
592
- const modal = new ModalRef$1(contentRef, component, wrapperRef, this, new ModalConfig$1(config));
593
- if (this.isIModal(contentRef.instance)) {
594
- contentRef.instance.modal = modal;
595
- contentRef.instance.onModalInit();
714
+ //#region Initialization Methods
715
+ initParamsFromConfig() {
716
+ this.id.set(this.config?.id ?? this.scrollLockId);
717
+ this.hasBanner =
718
+ this.config !== undefined &&
719
+ ((this.config.bannerText !== undefined && this.config.bannerText.length > 0) ||
720
+ (this.config.disableClose !== true && this.config.style.showCloseButton !== false && this.headerTemplate() === null));
721
+ this.hasDefaultContentWrapperClass = this.config?.style.contentWrapper !== false;
722
+ this.isAnimated = this.config?.style.animate === true;
723
+ }
724
+ initBreakpointCache() {
725
+ const definedBreakpoints = this.config?.style?.breakpoints;
726
+ if (definedBreakpoints && Object.keys(definedBreakpoints).length > 0) {
727
+ const serviceBreakpoints = this.windowDimensionsService.breakpoints;
728
+ this._sortedBreakpoints = Object.keys(definedBreakpoints)
729
+ .map(key => ({
730
+ width: serviceBreakpoints[key],
731
+ layout: definedBreakpoints[key]
732
+ }))
733
+ .sort((a, b) => a.width - b.width);
596
734
  }
597
- wrapperRef.onDestroy(() => {
598
- this.appRef.detachView(wrapperRef.hostView);
599
- wrapperRef.location.nativeElement.remove();
600
- });
601
- const modalElement = modal.componentRef.location.nativeElement;
602
- this.renderer.setStyle(modalElement, 'height', '97%');
603
- this.renderer.setStyle(modalElement, 'width', '100%');
604
- this.renderer.setStyle(modalElement, 'display', 'flex');
605
- this.renderer.setStyle(modalElement, 'flex-grow', '1');
606
- this.modals.add(modal);
607
- this.modalsSubject.next(this.modals);
608
- modal.open();
609
- return modal;
610
735
  }
611
- /**
612
- * Closes the specified modal.
613
- * @param modal The ModalRef instance representing the modal to be closed.
614
- */
615
- close(modal) {
616
- modal.close();
736
+ //#endregion
737
+ //#region Public Template Methods
738
+ setHeaderTemplate(template) {
739
+ this.headerTemplate.set(template);
617
740
  }
618
- /**
619
- * Unregisters the specified modal from the service.
620
- * @param modal The ModalRef instance representing the modal to be unregistered.
621
- */
622
- unregister(modal) {
623
- this.modals.delete(modal);
624
- this.modalsSubject.next(this.modals);
741
+ setFooterTemplate(template) {
742
+ this.footerTemplate.set(template);
625
743
  }
626
- /**
627
- * Closes all open modals.
628
- * @param onNavigate Indicates if the closeAll is triggered by navigation event.
629
- */
630
- closeAll(onNavigate = false) {
631
- this.modals.forEach((modal) => {
632
- if (modal.modalConfig?.disableCloseOnNavigation !== true || !onNavigate) {
633
- modal.close("cancel", undefined, true);
744
+ //#endregion
745
+ //#region Closing Methods
746
+ close(state = "cancel", result = undefined, fromInsideInteraction = false, forceClose = false) {
747
+ if (forceClose) {
748
+ this.handleClose(state, result);
749
+ return;
750
+ }
751
+ if ((this.config?.disableClose === true) && fromInsideInteraction) {
752
+ return;
753
+ }
754
+ const shouldCheckCloseGuard = this.config?.closeGuardOnlyOnCancel !== true || state !== "confirm";
755
+ if (shouldCheckCloseGuard && this.config?.closeGuard) {
756
+ const guardResult = this.config.closeGuard.canClose(this.modalService);
757
+ const canClose$ = guardResult instanceof Observable ? guardResult :
758
+ guardResult instanceof Promise ? from(guardResult) :
759
+ of(guardResult);
760
+ if (this.isBottomSheetModalActive()) {
761
+ this.resetBottomSheetModalLayout();
634
762
  }
635
- });
763
+ canClose$.pipe(take(1)).subscribe((canClose) => {
764
+ if (canClose) {
765
+ this.handleClose(state, result);
766
+ }
767
+ });
768
+ return;
769
+ }
770
+ this.handleClose(state, result);
636
771
  }
637
- /**
638
- * Finds if a modal with the specified component type is currently open.
639
- * @param componentType The component type to search for.
640
- * @returns True if a modal with the specified component type is open, false otherwise.
641
- */
642
- find(componentType) {
643
- for (const modal of this.modals) {
644
- if (modal.componentRef.componentType === componentType) {
645
- return true;
772
+ async handleClose(state, result) {
773
+ this.isOpen.set(false);
774
+ this.setBottomSheetModalFinishedState(true);
775
+ const returnResult = {
776
+ data: result,
777
+ state: state,
778
+ };
779
+ if (this.closeFunction) {
780
+ this.closeFunction(returnResult);
781
+ }
782
+ }
783
+ onBackdropClick(event) {
784
+ event.preventDefault();
785
+ event.stopPropagation();
786
+ if (!this.isOpen()) {
787
+ return;
788
+ }
789
+ this.backdropClickSubject.next(event);
790
+ if (this.config?.style?.hasBackdrop && this.config?.disableCloseOnBackdropClick !== true) {
791
+ this.close("cancel", undefined, true);
792
+ }
793
+ }
794
+ //#endregion
795
+ //#region Helper Methods
796
+ handleLayout(width) {
797
+ if (!this.config)
798
+ return;
799
+ let resolvedLayout = this.config.style.layout;
800
+ for (const bp of this._sortedBreakpoints) {
801
+ if (width <= bp.width) {
802
+ resolvedLayout = bp.layout;
803
+ break;
804
+ }
805
+ }
806
+ const prevIsSide = this.isSide();
807
+ const nextIsSide = resolvedLayout === 'left' || resolvedLayout === 'right';
808
+ const layoutTypeChanged = prevIsSide !== nextIsSide;
809
+ if (layoutTypeChanged && this._currentVcr && this.componentRef) {
810
+ const index = this._currentVcr.indexOf(this.componentRef.hostView);
811
+ if (index !== -1) {
812
+ this._currentVcr.detach(index);
646
813
  }
647
814
  }
648
- return false;
815
+ this.effectiveLayout.set(resolvedLayout);
816
+ this.isSide.set(nextIsSide);
817
+ this.isCentered.set(resolvedLayout === 'center' || resolvedLayout === 'bottom-sheet');
818
+ const shouldBeBottomSheet = resolvedLayout === 'bottom-sheet';
819
+ const currentSwipeState = this.isBottomSheetModalActive();
820
+ if (shouldBeBottomSheet && !currentSwipeState) {
821
+ this.isBottomSheetModalActive.set(true);
822
+ }
823
+ else if (!shouldBeBottomSheet && currentSwipeState) {
824
+ this.isBottomSheetModalActive.set(false);
825
+ }
649
826
  }
650
- /**
651
- * Gets the count of currently open modals.
652
- * @returns The number of open modals.
653
- */
654
- modalsCount() {
655
- return this.modals.size;
827
+ getBottomSheetModal() {
828
+ return this.sideModalComponents?.first?.bottomSheet?.first
829
+ ?? this.centeredModalComponents?.first?.bottomSheet?.first;
656
830
  }
657
- //#endregion
658
- //#region Helper Methods
659
- isIModal(component) {
660
- return (typeof component === 'object' &&
661
- component !== null &&
662
- 'onModalInit' in component &&
663
- typeof component.onModalInit === 'function');
831
+ resetBottomSheetModalLayout() {
832
+ const bottomSheet = this.getBottomSheetModal();
833
+ if (bottomSheet) {
834
+ bottomSheet.currentTranslateY.set(0);
835
+ }
664
836
  }
665
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
666
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalService, providedIn: "root" });
837
+ setBottomSheetModalFinishedState(isFinished) {
838
+ const bottomSheet = this.getBottomSheetModal();
839
+ if (bottomSheet) {
840
+ bottomSheet.isSwipingVerticallyFinished.set(isFinished);
841
+ }
842
+ this.isBottomSheetModalActive.set(false);
843
+ }
844
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCore, deps: [], target: i0.ɵɵFactoryTarget.Component });
845
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ModalCore, isStandalone: true, selector: "modal", outputs: { afterClose: "afterClose" }, viewQueries: [{ propertyName: "dynamicContainer", first: true, predicate: ["dynamicContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "modalContainer", first: true, predicate: ["modalContainer"], descendants: true }, { propertyName: "contentTemplate", first: true, predicate: ["contentTemplate"], descendants: true }, { propertyName: "sideModalComponents", predicate: ModalSide, descendants: true }, { propertyName: "centeredModalComponents", predicate: ModalCentered, descendants: true }], ngImport: i0, template: "@if (config?.style?.hasBackdrop && (isSide() || isBottomSheetModalActive())) {\n<modal-backdrop [isAnimated]=\"isAnimated\" [isOpen]=\"isOpen()\" (click)=\"onBackdropClick($event)\">\n</modal-backdrop>\n}\n\n<ng-container #modalContainer>\n @switch (true) {\n @case (isSide()) {\n <modal-side \n [layout]=\"effectiveLayout()\"\n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-side>\n } \n @case (isCentered()) {\n <modal-centered \n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\"\n (onBackdropClick)=\"onBackdropClick($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-centered>\n }\n }\n</ng-container>\n\n<ng-template #contentTemplate>\n <ng-container #dynamicContainer></ng-container>\n</ng-template>", styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalCentered, selector: "modal-centered", inputs: ["headerTemplate", "footerTemplate", "config", "id", "isOpen", "isAnimated", "isBottomSheetModalActive", "animationDuration", "hasDefaultContentWrapperClass", "hasBanner"], outputs: ["close", "onBackdropClick"] }, { kind: "component", type: ModalSide, selector: "modal-side", inputs: ["layout", "headerTemplate", "footerTemplate", "config", "id", "isOpen", "isAnimated", "isBottomSheetModalActive", "animationDuration", "hasDefaultContentWrapperClass", "hasBanner"], outputs: ["close"] }, { kind: "component", type: ModalBackdrop, selector: "modal-backdrop", inputs: ["isAnimated", "isOpen"], outputs: ["click"] }] });
667
846
  }
668
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalService, decorators: [{
669
- type: Injectable,
670
- args: [{
671
- providedIn: "root",
672
- }]
673
- }], ctorParameters: () => [] });
847
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalCore, decorators: [{
848
+ type: Component,
849
+ args: [{ selector: 'modal', imports: [
850
+ NgTemplateOutlet,
851
+ ModalCentered,
852
+ ModalSide,
853
+ ModalBackdrop
854
+ ], template: "@if (config?.style?.hasBackdrop && (isSide() || isBottomSheetModalActive())) {\n<modal-backdrop [isAnimated]=\"isAnimated\" [isOpen]=\"isOpen()\" (click)=\"onBackdropClick($event)\">\n</modal-backdrop>\n}\n\n<ng-container #modalContainer>\n @switch (true) {\n @case (isSide()) {\n <modal-side \n [layout]=\"effectiveLayout()\"\n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-side>\n } \n @case (isCentered()) {\n <modal-centered \n [headerTemplate]=\"headerTemplate()\" \n [footerTemplate]=\"footerTemplate()\" \n [config]=\"config\" \n [id]=\"id()\"\n [isOpen]=\"isOpen()\" \n [isAnimated]=\"isAnimated\"\n [isBottomSheetModalActive]=\"isBottomSheetModalActive()\" \n [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" \n [hasBanner]=\"hasBanner\" \n (close)=\"close($event)\"\n (onBackdropClick)=\"onBackdropClick($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"></ng-container>\n </modal-centered>\n }\n }\n</ng-container>\n\n<ng-template #contentTemplate>\n <ng-container #dynamicContainer></ng-container>\n</ng-template>" }]
855
+ }], ctorParameters: () => [], propDecorators: { afterClose: [{ type: i0.Output, args: ["afterClose"] }], dynamicContainer: [{
856
+ type: ViewChild,
857
+ args: ["dynamicContainer", { read: ViewContainerRef }]
858
+ }], modalContainer: [{
859
+ type: ViewChild,
860
+ args: ["modalContainer", { static: false }]
861
+ }], contentTemplate: [{
862
+ type: ViewChild,
863
+ args: ["contentTemplate"]
864
+ }], sideModalComponents: [{
865
+ type: ViewChildren,
866
+ args: [ModalSide]
867
+ }], centeredModalComponents: [{
868
+ type: ViewChildren,
869
+ args: [ModalCentered]
870
+ }] } });
674
871
 
675
872
  class Modal {
676
873
  /**
677
874
  * Data injected into the modal component.
678
875
  */
679
- data = inject(MODAL_DATA$1);
876
+ data = inject(MODAL_DATA);
680
877
  /**
681
878
  * Reference to the ModalRef instance associated with this modal.
682
879
  */
@@ -699,199 +896,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
699
896
  type: Injectable
700
897
  }] });
701
898
 
702
- class ModalConfig {
703
- open;
704
- afterClose;
705
- closeGuard;
706
- closeGuardOnlyOnCancel;
707
- disableClose;
708
- disableCloseOnBackdropClick;
709
- disableCloseOnNavigation;
710
- data;
711
- style;
712
- bannerText;
713
- contentClasses;
714
- contentStyles;
715
- disableConsoleWarnings;
716
- disableConsoleInfo;
717
- id;
718
- constructor(config) {
719
- this.open = config?.open ?? true;
720
- this.afterClose = config?.afterClose;
721
- this.closeGuard = config?.closeGuard;
722
- this.closeGuardOnlyOnCancel = config?.closeGuardOnlyOnCancel ?? true;
723
- this.disableClose = config?.disableClose ?? false;
724
- this.disableCloseOnBackdropClick = config?.disableCloseOnBackdropClick ?? false;
725
- this.disableCloseOnNavigation = config?.disableCloseOnNavigation ?? false;
726
- this.data = config?.data ?? null;
727
- this.style = new ModalStyleConfig$1(config?.style);
728
- this.bannerText = config?.bannerText ?? "";
729
- this.contentClasses = config?.contentClasses ?? "";
730
- this.contentStyles = config?.contentStyles ?? "";
731
- this.disableConsoleWarnings = config?.disableConsoleWarnings ?? false;
732
- this.disableConsoleInfo = config?.disableConsoleInfo ?? false;
733
- this.id = config?.id;
734
- }
735
- }
736
-
737
- class ModalRef {
738
- componentType;
739
- modalService;
740
- //#region Modal Container
741
- _modalContainer = {};
742
- set modalContainer(modalContainer) {
743
- this._modalContainer = modalContainer;
744
- }
745
- get modalContainer() {
746
- return this._modalContainer;
747
- }
748
- _modalContainerRef = {};
749
- set modalContainerRef(modalContainerRef) {
750
- this._modalContainerRef = modalContainerRef;
751
- }
752
- get modalContainerRef() {
753
- return this._modalContainerRef;
754
- }
755
- _modalContainerElement = {};
756
- set modalContainerElement(modalContainerElement) {
757
- this._modalContainerElement = modalContainerElement;
758
- }
759
- get modalContainerElement() {
760
- return this._modalContainerElement;
761
- }
762
- _parentElement = undefined;
763
- set parentElement(parentElement) {
764
- this._parentElement = parentElement;
765
- }
766
- get parentElement() {
767
- return this._parentElement;
768
- }
769
- //#endregion
770
- //#region Component
771
- _componentRef = {};
772
- set componentRef(componentRef) {
773
- this._componentRef = componentRef;
774
- }
775
- get componentRef() {
776
- return this._componentRef;
777
- }
778
- //#endregion
779
- //#region Self
780
- _modalState = ModalState$1.CLOSED;
781
- modalState = new BehaviorSubject(this.getStatus());
782
- modalState$() {
783
- return this.modalState.asObservable();
784
- }
785
- getStatus() {
786
- return this._modalState;
787
- }
788
- _modalConfig = undefined;
789
- set modalConfig(modalConfig) {
790
- this._modalConfig = modalConfig;
791
- }
792
- get modalConfig() {
793
- return this._modalConfig;
794
- }
795
- //#endregion
796
- //#region Observables
797
- backdropClickSubject = new Subject();
798
- backdropClick() {
799
- return this.backdropClickSubject.asObservable();
800
- }
801
- backdropClicked(event) {
802
- this.backdropClickSubject.next(event);
803
- }
804
- afterCloseSubject = new Subject();
805
- /**
806
- * Observable that emits when the modal has been closed.
807
- * @returns An Observable that emits an IModalCloseResult<R> when the modal is closed.
808
- */
809
- afterClosed() {
810
- return this.afterCloseSubject.asObservable();
811
- }
812
- afterClose(result) {
813
- this.afterCloseSubject.next(result);
814
- }
815
- //#endregion
816
- constructor(componentRef, componentType, modalContainerRef, modalService, modalConfig) {
817
- this.componentType = componentType;
818
- this.modalService = modalService;
819
- this.modalConfig = modalConfig;
820
- this.modalContainerRef = modalContainerRef;
821
- this.modalContainerElement = modalContainerRef.location.nativeElement;
822
- this.componentRef = componentRef;
823
- }
824
- //#region Public Methods
825
- async open() {
826
- this._modalState = ModalState$1.OPENING;
827
- this.modalState.next(ModalState$1.OPENING);
828
- this.modalContainerRef.instance.componentRef = this._componentRef;
829
- const config = new ModalConfig$1(this.modalConfig);
830
- this.modalContainerRef.instance.config = config;
831
- this.modalContainerRef.instance.closeFunction = this.handleClose.bind(this);
832
- this.parentElement?.appendChild(this.modalContainerElement);
833
- this.modalContainerRef.instance.backdropClick.subscribe((event) => {
834
- this.backdropClicked(event);
835
- });
836
- this._modalState = ModalState$1.OPEN;
837
- this.modalState.next(ModalState$1.OPEN);
838
- }
839
- close(state = "cancel", result = undefined, forceClose = false) {
840
- this.modalContainerRef.instance.close(state, result, false, forceClose);
841
- }
842
- //#endregion
843
- //#region Private Methods
844
- handleClose(result) {
845
- this._modalState = ModalState$1.CLOSING;
846
- this.modalState.next(ModalState$1.CLOSING);
847
- setTimeout(() => {
848
- if (this.modalConfig?.afterClose) {
849
- this.modalConfig.afterClose();
850
- }
851
- this.modalContainerRef.destroy();
852
- this._modalState = ModalState$1.CLOSED;
853
- this.modalState.next(ModalState$1.CLOSED);
854
- this.afterClose(result);
855
- this.modalService?.unregister(this);
856
- }, this.modalContainerRef.instance.animationDuration);
857
- }
858
- }
859
-
860
- class ModalStyleConfig {
861
- layout;
862
- breakpoints;
863
- animate;
864
- hasBackdrop;
865
- closeDelay;
866
- showCloseButton;
867
- mobileConfig;
868
- contentWrapper;
869
- wrapperClasses;
870
- wrapperStyles;
871
- overrideFullHeight;
872
- constructor(config) {
873
- this.layout = config?.layout ?? "center";
874
- this.breakpoints = config?.breakpoints;
875
- this.animate = config?.animate ?? true;
876
- this.hasBackdrop = config?.hasBackdrop ?? true;
877
- this.closeDelay = config?.closeDelay;
878
- this.showCloseButton = config?.showCloseButton ?? true;
879
- this.mobileConfig = config?.mobileConfig ?? {};
880
- this.contentWrapper = config?.contentWrapper ?? true;
881
- this.wrapperClasses = config?.wrapperClasses ?? "";
882
- this.wrapperStyles = config?.wrapperStyles ?? "";
883
- this.overrideFullHeight = config?.overrideFullHeight ?? false;
884
- }
885
- }
886
-
887
- const MODAL_DEFAULT_ANIM_DURATION = 175;
888
- const MODAL_DEFAULT_INTERNAL_ANIM_DURATION = 350;
889
- const MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_SMALL = 0.65;
890
- const MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_LARGE = 0.85;
891
-
892
- const MODAL_DOWN_SWIPE_LIMIT = 3;
893
- const MODAL_SWIPE_VELOCITY_THRESHOLD = 80;
894
-
895
899
  var ModalWarnings;
896
900
  (function (ModalWarnings) {
897
901
  //#region Directive usage
@@ -900,23 +904,15 @@ var ModalWarnings;
900
904
  //#endregion
901
905
  })(ModalWarnings || (ModalWarnings = {}));
902
906
 
903
- var ModalState;
904
- (function (ModalState) {
905
- ModalState["OPEN"] = "open";
906
- ModalState["OPENING"] = "opening";
907
- ModalState["CLOSED"] = "closed";
908
- ModalState["CLOSING"] = "closing";
909
- })(ModalState || (ModalState = {}));
910
-
911
907
  class ModalHeaderDirective {
912
908
  templateRef = inject(TemplateRef);
913
- modal = inject(ModalCore$1, { optional: true });
909
+ modal = inject(ModalCore, { optional: true });
914
910
  constructor() {
915
911
  if (this.modal) {
916
912
  this.modal.setHeaderTemplate(this.templateRef);
917
913
  }
918
914
  else {
919
- console.warn(ModalWarnings$1.HEADER_DIRECTIVE_OUTSIDE_MODAL);
915
+ console.warn(ModalWarnings.HEADER_DIRECTIVE_OUTSIDE_MODAL);
920
916
  }
921
917
  }
922
918
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
@@ -932,13 +928,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
932
928
 
933
929
  class ModalFooterDirective {
934
930
  templateRef = inject(TemplateRef);
935
- modal = inject(ModalCore$1, { optional: true });
931
+ modal = inject(ModalCore, { optional: true });
936
932
  constructor() {
937
933
  if (this.modal) {
938
934
  this.modal.setFooterTemplate(this.templateRef);
939
935
  }
940
936
  else {
941
- console.warn(ModalWarnings$1.FOOTER_DIRECTIVE_OUTSIDE_MODAL);
937
+ console.warn(ModalWarnings.FOOTER_DIRECTIVE_OUTSIDE_MODAL);
942
938
  }
943
939
  }
944
940
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModalFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
@@ -952,8 +948,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
952
948
  }]
953
949
  }], ctorParameters: () => [] });
954
950
 
955
- const MODAL_DATA = new InjectionToken("MODAL_DATA");
956
-
957
951
  /**
958
952
  * Abstract class representing a modal close guard.
959
953
  */
@@ -965,7 +959,7 @@ class ModalCloseGuard {
965
959
  * @param component The component to use for the confirmation modal.
966
960
  * @param config The configuration for the confirmation modal.
967
961
  */
968
- class ModalConfirmCloseGuard extends ModalCloseGuard$1 {
962
+ class ModalConfirmCloseGuard extends ModalCloseGuard {
969
963
  component;
970
964
  config;
971
965
  constructor(component, config) {