@filip.mazev/modal 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +63 -0
  2. package/fesm2022/filip.mazev-modal.mjs +932 -0
  3. package/fesm2022/filip.mazev-modal.mjs.map +1 -0
  4. package/index.d.ts +5 -0
  5. package/lib/classes/generic-modal-config.d.ts +26 -0
  6. package/lib/classes/generic-modal-ref.d.ts +52 -0
  7. package/lib/classes/generic-modal-style.config.d.ts +17 -0
  8. package/lib/classes/generic-modal.d.ts +19 -0
  9. package/lib/components/generic-modal.d.ts +60 -0
  10. package/lib/components/views/backdrop/modal-backdrop.d.ts +8 -0
  11. package/lib/components/views/banner/modal-banner.d.ts +9 -0
  12. package/lib/components/views/centered/modal-centered.d.ts +23 -0
  13. package/lib/components/views/side/modal-side.d.ts +26 -0
  14. package/lib/components/views/swipeable/modal-swipeable.d.ts +32 -0
  15. package/lib/constants/generic-modal-animation.constants.d.ts +4 -0
  16. package/lib/constants/generic-modal-common.constants.d.ts +1 -0
  17. package/lib/constants/generic-modal-swipe.constants.d.ts +3 -0
  18. package/lib/constants/generic-modal-text.constants.d.ts +4 -0
  19. package/lib/enums/generic-modal-errors.enum.d.ts +6 -0
  20. package/lib/enums/generic-modal-state.enum.d.ts +6 -0
  21. package/lib/enums/generic-modal-warnings.enum.d.ts +7 -0
  22. package/lib/interfaces/igeneric-close-result.interface.d.ts +5 -0
  23. package/lib/interfaces/igeneric-confirm-close.interface.d.ts +24 -0
  24. package/lib/interfaces/igeneric-confirm-modal-data.interface.d.ts +3 -0
  25. package/lib/interfaces/igeneric-modal-component.interface.d.ts +28 -0
  26. package/lib/interfaces/igeneric-modal-config.interface.d.ts +45 -0
  27. package/lib/interfaces/igeneric-modal-ref.interface.d.ts +25 -0
  28. package/lib/interfaces/igeneric-modal-service.interface.d.ts +22 -0
  29. package/lib/interfaces/igeneric-modal-style-config.interface.d.ts +28 -0
  30. package/lib/interfaces/igeneric-modal-view.interface.d.ts +18 -0
  31. package/lib/interfaces/igeneric-swipeable-modal-config.d.ts +5 -0
  32. package/lib/services/generic-modal.service.d.ts +40 -0
  33. package/lib/tokens/generic-modal-data.token.d.ts +2 -0
  34. package/lib/types/modal.types.d.ts +2 -0
  35. package/package.json +24 -0
  36. package/public-api.d.ts +30 -0
  37. package/src/assets/default-theme.css +5 -0
@@ -0,0 +1,932 @@
1
+ import { NgClass, NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, Injectable, InjectionToken, Injector, input, output, Component, ViewChild, ViewChildren, effect, ChangeDetectorRef, ViewContainerRef } from '@angular/core';
4
+ import { BehaviorSubject, Subject, takeUntil, filter, map, take, fromEvent } from 'rxjs';
5
+ import { Router, NavigationEnd } from '@angular/router';
6
+ import { uuidv4, WindowDimensionsService, ScrollLockService, DeviceTypeService } from 'common-parts';
7
+
8
+ const EMPTY_STRING = '';
9
+
10
+ var GenericModalWarnings;
11
+ (function (GenericModalWarnings) {
12
+ //#region Multi-level modals
13
+ GenericModalWarnings["NO_PARENT_PROVIDED"] = "No parent modal provided for multilevel modal. Please provide a parent modal or set openAsMultilevel to false.";
14
+ GenericModalWarnings["MULTILEVEL_INLINE_NOT_SUPPORTED"] = "As of this version, opening a multi-level modal from inline HTML is not possible. Please set openAsMultilevel to false or open your modal through the GenericModalService! Opening modal as normal modal.";
15
+ GenericModalWarnings["MULTILEVEL_NO_PARENT"] = "Cannot open a multilevel modal with only one modal open. Please open another modal before opening a multilevel modal or set openAsMultilevel to false.";
16
+ GenericModalWarnings["PARENT_MODAL_NOT_SET"] = "Error setting parent modal. Opening modal as normal modal";
17
+ //#endregion
18
+ //#region Confirm close
19
+ GenericModalWarnings["CONFIRM_MODAL_NESTING_NOT_SUPPORTED"] = "Cannot open a confirm modal from within a confirm modal. If you want to allow this behaviour, set bypassSelfCheck to true in the confirmCloseConfig.";
20
+ //#endregion
21
+ })(GenericModalWarnings || (GenericModalWarnings = {}));
22
+
23
+ class GenericModalStyleConfig {
24
+ position;
25
+ handleMobile;
26
+ animate;
27
+ hasBackdrop;
28
+ closeDelay;
29
+ showCloseButton;
30
+ mobileConfig;
31
+ contentWrapper;
32
+ wrapperClasses;
33
+ wrapperStyles;
34
+ overrideFullHeight;
35
+ constructor(config) {
36
+ this.position = config?.position ?? "center";
37
+ this.handleMobile = config?.handleMobile ?? true;
38
+ this.animate = config?.animate ?? true;
39
+ this.hasBackdrop = config?.hasBackdrop ?? true;
40
+ this.closeDelay = config?.closeDelay;
41
+ this.showCloseButton = config?.showCloseButton ?? true;
42
+ this.mobileConfig = config?.mobileConfig ?? {};
43
+ this.contentWrapper = config?.contentWrapper ?? true;
44
+ this.wrapperClasses = config?.wrapperClasses ?? EMPTY_STRING;
45
+ this.wrapperStyles = config?.wrapperStyles ?? EMPTY_STRING;
46
+ this.overrideFullHeight = config?.overrideFullHeight ?? false;
47
+ }
48
+ }
49
+
50
+ class GenericModalConfig {
51
+ open;
52
+ afterClose;
53
+ confirmCloseConfig;
54
+ disableClose;
55
+ disableCloseOnBackdropClick;
56
+ disableCloseOnNavigation;
57
+ enableExtremeOverflowHandling;
58
+ webkitOnlyOverflowMobileHandling;
59
+ closeOnSwipeBack;
60
+ data;
61
+ style;
62
+ bannerText;
63
+ bannerTextAnnotatedString;
64
+ bannerIcons;
65
+ contentClasses;
66
+ contentStyles;
67
+ disableConsoleWarnings;
68
+ disableConsoleInfo;
69
+ id;
70
+ constructor(config) {
71
+ this.open = config?.open ?? true;
72
+ this.afterClose = config?.afterClose;
73
+ this.confirmCloseConfig = config?.confirmCloseConfig;
74
+ this.disableClose = config?.disableClose ?? false;
75
+ this.disableCloseOnBackdropClick = config?.disableCloseOnBackdropClick ?? false;
76
+ this.disableCloseOnNavigation = config?.disableCloseOnNavigation ?? false;
77
+ this.enableExtremeOverflowHandling = config?.enableExtremeOverflowHandling ?? false;
78
+ this.webkitOnlyOverflowMobileHandling = config?.webkitOnlyOverflowMobileHandling ?? true;
79
+ this.closeOnSwipeBack = config?.closeOnSwipeBack ?? false;
80
+ this.data = config?.data ?? null;
81
+ this.style = new GenericModalStyleConfig(config?.style);
82
+ this.bannerText = config?.bannerText ?? EMPTY_STRING;
83
+ this.bannerTextAnnotatedString = config?.bannerTextAnnotatedString ?? EMPTY_STRING;
84
+ this.bannerIcons = config?.bannerIcons ?? [];
85
+ this.contentClasses = config?.contentClasses ?? EMPTY_STRING;
86
+ this.contentStyles = config?.contentStyles ?? EMPTY_STRING;
87
+ this.disableConsoleWarnings = config?.disableConsoleWarnings ?? false;
88
+ this.disableConsoleInfo = config?.disableConsoleInfo ?? false;
89
+ this.id = config?.id ?? uuidv4();
90
+ }
91
+ }
92
+
93
+ var GenericModalState;
94
+ (function (GenericModalState) {
95
+ GenericModalState["OPEN"] = "open";
96
+ GenericModalState["OPENING"] = "opening";
97
+ GenericModalState["CLOSED"] = "closed";
98
+ GenericModalState["CLOSING"] = "closing";
99
+ })(GenericModalState || (GenericModalState = {}));
100
+
101
+ class GenericModalRef {
102
+ modalService;
103
+ //#region Modal Container
104
+ _modalContainer = {};
105
+ set modalContainer(modalContainer) {
106
+ this._modalContainer = modalContainer;
107
+ }
108
+ get modalContainer() {
109
+ return this._modalContainer;
110
+ }
111
+ _modalContainerRef = {};
112
+ set modalContainerRef(modalContainerRef) {
113
+ this._modalContainerRef = modalContainerRef;
114
+ }
115
+ get modalContainerRef() {
116
+ return this._modalContainerRef;
117
+ }
118
+ _modalContainerElement = {};
119
+ set modalContainerElement(modalContainerElement) {
120
+ this._modalContainerElement = modalContainerElement;
121
+ }
122
+ get modalContainerElement() {
123
+ return this._modalContainerElement;
124
+ }
125
+ _parentElement = undefined;
126
+ set parentElement(parentElement) {
127
+ this._parentElement = parentElement;
128
+ }
129
+ get parentElement() {
130
+ return this._parentElement;
131
+ }
132
+ //#endregion
133
+ //#region Component
134
+ _componentRef = {};
135
+ set componentRef(componentRef) {
136
+ this._componentRef = componentRef;
137
+ }
138
+ get componentRef() {
139
+ return this._componentRef;
140
+ }
141
+ //#endregion
142
+ //#region Self
143
+ _modalState = GenericModalState.CLOSED;
144
+ modalState = new BehaviorSubject(this.getStatus());
145
+ modalState$() {
146
+ return this.modalState.asObservable();
147
+ }
148
+ getStatus() {
149
+ return this._modalState;
150
+ }
151
+ _selfIdentifier = {};
152
+ set selfIdentifier(selfIdentifier) {
153
+ this._selfIdentifier = selfIdentifier;
154
+ }
155
+ get selfIdentifier() {
156
+ return this._selfIdentifier;
157
+ }
158
+ _modalConfig = undefined;
159
+ set modalConfig(modalConfig) {
160
+ this._modalConfig = modalConfig;
161
+ }
162
+ get modalConfig() {
163
+ return this._modalConfig;
164
+ }
165
+ //#endregion
166
+ //#region Observables
167
+ backdropClickSubject = new Subject();
168
+ backdropClick() {
169
+ return this.backdropClickSubject.asObservable();
170
+ }
171
+ backdropClicked(event) {
172
+ this.backdropClickSubject.next(event);
173
+ }
174
+ afterCloseSubject = new Subject();
175
+ afterClosed() {
176
+ return this.afterCloseSubject.asObservable();
177
+ }
178
+ afterClose(result) {
179
+ this.afterCloseSubject.next(result);
180
+ }
181
+ //#endregion
182
+ constructor(componentRef, selfIdentifier, modalContainerRef, modalService, modalConfig) {
183
+ this.modalService = modalService;
184
+ this.modalConfig = modalConfig;
185
+ this.modalContainerRef = modalContainerRef;
186
+ this.modalContainerElement = modalContainerRef.location.nativeElement;
187
+ this.componentRef = componentRef;
188
+ this.selfIdentifier = selfIdentifier;
189
+ }
190
+ //#region Public Methods
191
+ async open() {
192
+ this._modalState = GenericModalState.OPENING;
193
+ this.modalState.next(GenericModalState.OPENING);
194
+ this.modalContainerRef.instance.componentRef = this._componentRef;
195
+ const config = new GenericModalConfig(this.modalConfig);
196
+ this.modalContainerRef.instance.config = config;
197
+ this.modalContainerRef.instance.closeFunction = this.handleClose.bind(this);
198
+ this.parentElement?.appendChild(this.modalContainerElement);
199
+ this.modalContainerRef.instance.backdropClick.subscribe((event) => {
200
+ this.backdropClicked(event);
201
+ });
202
+ this._modalState = GenericModalState.OPEN;
203
+ this.modalState.next(GenericModalState.OPEN);
204
+ }
205
+ close(state = "cancel", result = undefined, forceClose = false) {
206
+ this.modalContainerRef.instance.close(state, result, false, forceClose);
207
+ }
208
+ //#endregion
209
+ //#region Private Methods
210
+ handleClose(result) {
211
+ this._modalState = GenericModalState.CLOSING;
212
+ this.modalState.next(GenericModalState.CLOSING);
213
+ setTimeout(() => {
214
+ if (this.modalConfig?.afterClose) {
215
+ this.modalConfig.afterClose();
216
+ }
217
+ this.modalContainerRef.destroy();
218
+ this._modalState = GenericModalState.CLOSED;
219
+ this.modalState.next(GenericModalState.CLOSED);
220
+ this.afterClose(result);
221
+ this.modalService?.close(this.selfIdentifier, true);
222
+ }, this.modalContainerRef.instance.animationDuration);
223
+ }
224
+ }
225
+
226
+ class GenericModal {
227
+ genericModalService = inject(GenericModalService);
228
+ modal;
229
+ modalGetSubscription$ = new Subject();
230
+ constructor() {
231
+ this.createModalSubscription();
232
+ }
233
+ ngOnDestroy() {
234
+ this.onDestroy();
235
+ this.unsubscribeModalGet();
236
+ }
237
+ createModalSubscription() {
238
+ this.modalGetSubscription$ = new Subject();
239
+ this.genericModalService
240
+ .getSubscribe(this.constructor)
241
+ .pipe(takeUntil(this.modalGetSubscription$))
242
+ .subscribe((modal) => {
243
+ if (modal instanceof GenericModalRef) {
244
+ this.modal = modal;
245
+ this.afterModalGet();
246
+ this.modalGetSubscription$.next();
247
+ this.modalGetSubscription$.complete();
248
+ }
249
+ });
250
+ }
251
+ unsubscribeModalGet() {
252
+ this.modalGetSubscription$.next();
253
+ this.modalGetSubscription$.complete();
254
+ }
255
+ close() {
256
+ this.modal?.close();
257
+ }
258
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModal, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
259
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModal });
260
+ }
261
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModal, decorators: [{
262
+ type: Injectable
263
+ }], ctorParameters: () => [] });
264
+
265
+ var GenericModalErrors;
266
+ (function (GenericModalErrors) {
267
+ //#region General
268
+ GenericModalErrors["MODAL_DOESNT_MATCH_THE_REQUESTED_TYPES"] = "The modal doesn't match the requested types.";
269
+ //#endregion
270
+ //#region Multi-level modals
271
+ GenericModalErrors["PARENT_MODAL_CANT_BE_THE_SAME_AS_CHILD"] = "Parent modal cannot be the same as the child modal";
272
+ GenericModalErrors["PARENT_MODAL_NOT_FOUND"] = "Parent modal does not exist";
273
+ GenericModalErrors["PARENT_MODAL_NOT_PROVIDED"] = "No parent modal provided for multilevel modal";
274
+ //#endregion
275
+ })(GenericModalErrors || (GenericModalErrors = {}));
276
+
277
+ const GENERIC_MODAL_DATA = new InjectionToken("GENERIC_MODAL_DATA");
278
+
279
+ class GenericModalService {
280
+ router = inject(Router);
281
+ injector = inject(Injector);
282
+ //#region Properties
283
+ modals = new Map();
284
+ modalsSubject = new BehaviorSubject(this.modals);
285
+ viewContainer;
286
+ renderer;
287
+ unsubscribe$ = new Subject();
288
+ //#endregion
289
+ constructor() {
290
+ this.createSubscriptions();
291
+ }
292
+ ngOnDestroy() {
293
+ this.unsubscribe$.next();
294
+ this.unsubscribe$.complete();
295
+ }
296
+ //#region Private Methods
297
+ createSubscriptions() {
298
+ this.router.events
299
+ .pipe(filter((event) => event instanceof NavigationEnd))
300
+ .pipe(takeUntil(this.unsubscribe$))
301
+ .subscribe(() => {
302
+ if (this.modalsCount() > 0) {
303
+ this.closeAll(true);
304
+ }
305
+ });
306
+ }
307
+ //#endregion
308
+ //#region Public Methods
309
+ register(viewContainer, renderer) {
310
+ this.viewContainer = viewContainer;
311
+ this.renderer = renderer;
312
+ }
313
+ open(component, config) {
314
+ if (!this.viewContainer || !this.renderer) {
315
+ throw new Error("ViewContainer and Renderer not set, please set the view container in the constructor of app.module.ts (by calling register), before opening a modal");
316
+ }
317
+ const createInjector = Injector.create({
318
+ providers: [{ provide: GENERIC_MODAL_DATA, useValue: config?.data }],
319
+ parent: this.injector,
320
+ });
321
+ const modal = new GenericModalRef(this.viewContainer.createComponent(component, {
322
+ injector: createInjector,
323
+ }), component, this.viewContainer.createComponent((GenericModalComponent), {
324
+ injector: createInjector,
325
+ }), this, new GenericModalConfig(config));
326
+ const modalElement = modal.componentRef.location.nativeElement;
327
+ this.renderer.setStyle(modalElement, 'height', '97%');
328
+ this.renderer.setStyle(modalElement, 'width', '100%');
329
+ this.renderer.setStyle(modalElement, 'display', 'flex');
330
+ this.renderer.setStyle(modalElement, 'flex-grow', '1');
331
+ this.modals.set(modal.selfIdentifier, modal);
332
+ this.modalsSubject.next(this.modals);
333
+ modal.open();
334
+ return modal;
335
+ }
336
+ close(self, fromCloseFunction = false) {
337
+ if (this.modals.has(self)) {
338
+ if (fromCloseFunction !== true) {
339
+ const modal = this.modals.get(self);
340
+ if (modal && modal instanceof GenericModalRef) {
341
+ modal.close();
342
+ }
343
+ }
344
+ this.modals.delete(self);
345
+ this.modalsSubject.next(this.modals);
346
+ }
347
+ }
348
+ closeAll(onNavigate = false) {
349
+ this.modals.forEach((modal) => {
350
+ if (modal instanceof GenericModalRef) {
351
+ if (modal.modalConfig?.disableCloseOnNavigation !== true || !onNavigate) {
352
+ modal.close("cancel", undefined, true);
353
+ }
354
+ }
355
+ });
356
+ this.modals.clear();
357
+ this.modalsSubject.next(this.modals);
358
+ }
359
+ get(self) {
360
+ const modal = this.modals.get(self);
361
+ this.modalRequestedTypeCheck(modal);
362
+ return modal;
363
+ }
364
+ getSubscribe(self) {
365
+ return this.modalsSubject.asObservable().pipe(map((modals) => {
366
+ const modal = modals.get(self);
367
+ this.modalRequestedTypeCheck(modal);
368
+ return modal;
369
+ }));
370
+ }
371
+ modalsCount() {
372
+ return this.modals.size;
373
+ }
374
+ find(self) {
375
+ return this.modals.has(self);
376
+ }
377
+ //#endregion
378
+ //#region Helper Methods
379
+ modalRequestedTypeCheck(modal) {
380
+ if (modal) {
381
+ if (modal instanceof GenericModalRef) {
382
+ if (!(modal.componentRef.instance instanceof GenericModal)) {
383
+ throw new Error(GenericModalErrors.MODAL_DOESNT_MATCH_THE_REQUESTED_TYPES);
384
+ }
385
+ }
386
+ else if (!(modal instanceof GenericModalComponent)) {
387
+ throw new Error(GenericModalErrors.MODAL_DOESNT_MATCH_THE_REQUESTED_TYPES);
388
+ }
389
+ }
390
+ return true;
391
+ }
392
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
393
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModalService, providedIn: "root" });
394
+ }
395
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModalService, decorators: [{
396
+ type: Injectable,
397
+ args: [{
398
+ providedIn: "root",
399
+ }]
400
+ }], ctorParameters: () => [] });
401
+
402
+ class ModalBackdrop {
403
+ isAnimated = input(false);
404
+ isOpen = input(false);
405
+ click = output();
406
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Component });
407
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.18", 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:absolute;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"] });
408
+ }
409
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalBackdrop, decorators: [{
410
+ type: Component,
411
+ 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:absolute;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"] }]
412
+ }] });
413
+
414
+ class ModalBanner {
415
+ config = input.required();
416
+ close = output();
417
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalBanner, deps: [], target: i0.ɵɵFactoryTarget.Component });
418
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", 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()?.bannerIcons && (config() && config()!.bannerIcons.length > 0)) {\n @for (icon of config()?.bannerIcons; track icon) {\n <img src=\"{{ icon }}\" class=\"icon-style custom-svg-icon-color-dark-green\" alt=\"\" />\n }\n }\n\n @if (config() && config()?.bannerText && (config() && config()!.bannerText.length > 0)) {\n <div class=\"modal-banner-default-style\">\n <div class=\"generic-modal-banner-text\">\n <div>\n {{ config()?.bannerText }}\n <b> {{ config()?.bannerTextAnnotatedString }} </b>\n </div>\n </div>\n </div>\n }\n </div>\n\n @if (config()?.disableClose !== true && config()?.style?.showCloseButton !== false) {\n <svg (click)=\"close.emit('cancel')\" aria-label=\"Close\" class=\"banner-svg-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 }\n</div>", styles: [".modal-banner-default-style{font:lighter;font-size:1.25rem;line-height:1.25rem}.modal-top-banner-container{display:flex;flex-direction:row;gap:2rem;justify-content:space-between;align-items:center;color:var(--text_primary, #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%}.banner-svg-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}.banner-svg-close-button path{transition:all .3s ease-in-out}.banner-svg-close-button path{fill:var(--text_primary, #000000)}@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"] });
419
+ }
420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalBanner, decorators: [{
421
+ type: Component,
422
+ args: [{ selector: 'modal-banner', template: "<div class=\"modal-top-banner-container\">\n <div class=\"modal-top-banner-title-container\">\n @if (config() && config()?.bannerIcons && (config() && config()!.bannerIcons.length > 0)) {\n @for (icon of config()?.bannerIcons; track icon) {\n <img src=\"{{ icon }}\" class=\"icon-style custom-svg-icon-color-dark-green\" alt=\"\" />\n }\n }\n\n @if (config() && config()?.bannerText && (config() && config()!.bannerText.length > 0)) {\n <div class=\"modal-banner-default-style\">\n <div class=\"generic-modal-banner-text\">\n <div>\n {{ config()?.bannerText }}\n <b> {{ config()?.bannerTextAnnotatedString }} </b>\n </div>\n </div>\n </div>\n }\n </div>\n\n @if (config()?.disableClose !== true && config()?.style?.showCloseButton !== false) {\n <svg (click)=\"close.emit('cancel')\" aria-label=\"Close\" class=\"banner-svg-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 }\n</div>", styles: [".modal-banner-default-style{font:lighter;font-size:1.25rem;line-height:1.25rem}.modal-top-banner-container{display:flex;flex-direction:row;gap:2rem;justify-content:space-between;align-items:center;color:var(--text_primary, #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%}.banner-svg-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}.banner-svg-close-button path{transition:all .3s ease-in-out}.banner-svg-close-button path{fill:var(--text_primary, #000000)}@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"] }]
423
+ }] });
424
+
425
+ const GENERIC_MODAL_DOWN_SWIPE_LIMIT = 2;
426
+ const GENERIC_MODAL_UP_SWIPE_LIMIT = 1;
427
+ const GENERIC_MODAL_SWIPE_VELOCITY_THRESHOLD = 80;
428
+
429
+ class ModalSwipeable {
430
+ config = input.required();
431
+ isOpen = input.required();
432
+ isAnimated = input.required();
433
+ animationDuration = input.required();
434
+ close = output();
435
+ currentTranslateY = 0;
436
+ isSwipingVerticallyFinished = false;
437
+ isSwipingVertically = false;
438
+ downSwipeLimit = 0;
439
+ upSwipeLimit = 0;
440
+ windowInnerHeight = window.innerHeight;
441
+ isTrackingSwipe = false;
442
+ isTouchActive = false;
443
+ swipeableModalInitiated = false;
444
+ globalPointerListenerAdded = false;
445
+ touchDetectionUnsubscribe$ = new Subject();
446
+ verticalSwipeTarget;
447
+ modalContent;
448
+ ngOnInit() {
449
+ this.startVerticalSwipeDetection();
450
+ this.monitorInputType();
451
+ }
452
+ ngOnDestroy() {
453
+ this.stopVerticalSwipeDetection();
454
+ }
455
+ //#region Swipe Methods
456
+ startVerticalSwipeDetection() {
457
+ if (this.isTrackingSwipe)
458
+ return;
459
+ const hasTouch = window.matchMedia('(pointer: coarse)').matches || navigator.maxTouchPoints > 0;
460
+ if (!hasTouch)
461
+ return;
462
+ this.initSwipeableModalParams();
463
+ this.touchDetectionUnsubscribe$ = new Subject();
464
+ this.isTrackingSwipe = true;
465
+ const target = this.verticalSwipeTarget?.nativeElement;
466
+ if (!target)
467
+ return;
468
+ const limit = document.body.offsetHeight / this.downSwipeLimit;
469
+ let startY = 0;
470
+ let currentY = 0;
471
+ let isPointerDown = false;
472
+ const pointerDown = (event) => {
473
+ isPointerDown = true;
474
+ startY = event.clientY;
475
+ this.isSwipingVertically = true;
476
+ };
477
+ const pointerMove = (event) => {
478
+ if (!isPointerDown)
479
+ return;
480
+ currentY = event.clientY - startY;
481
+ event.preventDefault();
482
+ this.currentTranslateY = currentY;
483
+ };
484
+ const pointerUp = (event) => {
485
+ if (!isPointerDown)
486
+ return;
487
+ isPointerDown = false;
488
+ this.isSwipingVertically = false;
489
+ const deltaY = event.clientY - startY;
490
+ const velocityY = (event.clientY - startY) / (event.timeStamp - event.startTime || 1);
491
+ if (Math.abs(deltaY) > limit || velocityY > GENERIC_MODAL_SWIPE_VELOCITY_THRESHOLD) {
492
+ this.close.emit('cancel');
493
+ }
494
+ else {
495
+ this.currentTranslateY = 0;
496
+ }
497
+ };
498
+ target.addEventListener('pointerdown', pointerDown);
499
+ target.addEventListener('pointermove', pointerMove);
500
+ target.addEventListener('pointerup', pointerUp);
501
+ target.addEventListener('pointercancel', pointerUp);
502
+ this.touchDetectionUnsubscribe$.pipe(take(1)).subscribe(() => {
503
+ target.removeEventListener('pointerdown', pointerDown);
504
+ target.removeEventListener('pointermove', pointerMove);
505
+ target.removeEventListener('pointerup', pointerUp);
506
+ target.removeEventListener('pointercancel', pointerUp);
507
+ });
508
+ }
509
+ stopVerticalSwipeDetection() {
510
+ if (!this.isTrackingSwipe)
511
+ return;
512
+ this.isTrackingSwipe = false;
513
+ this.touchDetectionUnsubscribe$.next();
514
+ this.touchDetectionUnsubscribe$.complete();
515
+ }
516
+ initSwipeableModalParams() {
517
+ if (!this.swipeableModalInitiated) {
518
+ this.swipeableModalInitiated = true;
519
+ const config = this.config();
520
+ this.downSwipeLimit = config?.style.mobileConfig?.downSwipeLimit
521
+ ? config.style.mobileConfig.downSwipeLimit > 0
522
+ ? config.style.mobileConfig.downSwipeLimit
523
+ : 1
524
+ : GENERIC_MODAL_DOWN_SWIPE_LIMIT;
525
+ const configValue = this.config();
526
+ this.upSwipeLimit = configValue?.style.mobileConfig?.upSwipeLimit
527
+ ? configValue.style.mobileConfig.upSwipeLimit > 0
528
+ ? configValue.style.mobileConfig.upSwipeLimit
529
+ : GENERIC_MODAL_UP_SWIPE_LIMIT
530
+ : window.innerHeight;
531
+ }
532
+ }
533
+ monitorInputType() {
534
+ if (this.globalPointerListenerAdded)
535
+ return;
536
+ this.globalPointerListenerAdded = true;
537
+ window.addEventListener('pointerdown', (event) => {
538
+ const isTouch = event.pointerType === 'touch';
539
+ if (isTouch && !this.isTouchActive) {
540
+ this.isTouchActive = true;
541
+ this.startVerticalSwipeDetection();
542
+ }
543
+ else if (!isTouch && this.isTouchActive) {
544
+ this.isTouchActive = false;
545
+ this.stopVerticalSwipeDetection();
546
+ }
547
+ });
548
+ }
549
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalSwipeable, deps: [], target: i0.ɵɵFactoryTarget.Component });
550
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.18", type: ModalSwipeable, isStandalone: true, selector: "modal-swipeable", inputs: { config: { classPropertyName: "config", publicName: "config", 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 }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close" }, viewQueries: [{ propertyName: "verticalSwipeTarget", first: true, predicate: ["verticalSwipeTarget"], descendants: true, static: true }, { propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], ngImport: i0, template: "<div (click)=\"$event.stopPropagation()\" [id]=\"config()?.id ?? ''\"\n [class]=\"config()?.style?.wrapperClasses !== undefined ? config()!.style.wrapperClasses! : ''\"\n [style]=\"config()?.style?.wrapperStyles !== undefined ? config()!.style.wrapperStyles! : ''\"\n [style.max-height]=\"config() && config()?.style?.mobileConfig && config()?.style?.mobileConfig?.customHeight ? config()?.style?.mobileConfig?.customHeight : ''\"\n [style.transform]=\"!isSwipingVerticallyFinished\n ? 'translateY(' + (currentTranslateY * -1 > windowInnerHeight / upSwipeLimit ? (windowInnerHeight / upSwipeLimit) * -1 : currentTranslateY) + 'px)'\n : 'translateY(100%)'\"\n [style.transition]=\"isAnimated() && !isSwipingVertically ? '300ms ease-in-out' : ''\" [ngClass]=\"{\n 'opened-swipeable-modal': isAnimated()\n }\" data-horizontal-swipe-target=\"swipeable-modal\" class=\"swipeable-modal-style\">\n <div #verticalSwipeTarget class=\"touch-hitbox\" class=\"swipeable-modal-top-bar\"\n (click)=\"isTrackingSwipe ? null : close.emit('cancel')\">\n <div class=\"swipe-line\"></div>\n </div>\n\n <div class=\"swipeable-modal-content-container\"\n [style.animationDuration]=\"isAnimated() ? animationDuration().toString() + 'ms' : '0ms'\">\n <ng-content></ng-content>\n </div>\n</div>", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
551
+ }
552
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalSwipeable, decorators: [{
553
+ type: Component,
554
+ args: [{ selector: 'modal-swipeable', imports: [
555
+ NgClass
556
+ ], template: "<div (click)=\"$event.stopPropagation()\" [id]=\"config()?.id ?? ''\"\n [class]=\"config()?.style?.wrapperClasses !== undefined ? config()!.style.wrapperClasses! : ''\"\n [style]=\"config()?.style?.wrapperStyles !== undefined ? config()!.style.wrapperStyles! : ''\"\n [style.max-height]=\"config() && config()?.style?.mobileConfig && config()?.style?.mobileConfig?.customHeight ? config()?.style?.mobileConfig?.customHeight : ''\"\n [style.transform]=\"!isSwipingVerticallyFinished\n ? 'translateY(' + (currentTranslateY * -1 > windowInnerHeight / upSwipeLimit ? (windowInnerHeight / upSwipeLimit) * -1 : currentTranslateY) + 'px)'\n : 'translateY(100%)'\"\n [style.transition]=\"isAnimated() && !isSwipingVertically ? '300ms ease-in-out' : ''\" [ngClass]=\"{\n 'opened-swipeable-modal': isAnimated()\n }\" data-horizontal-swipe-target=\"swipeable-modal\" class=\"swipeable-modal-style\">\n <div #verticalSwipeTarget class=\"touch-hitbox\" class=\"swipeable-modal-top-bar\"\n (click)=\"isTrackingSwipe ? null : close.emit('cancel')\">\n <div class=\"swipe-line\"></div>\n </div>\n\n <div class=\"swipeable-modal-content-container\"\n [style.animationDuration]=\"isAnimated() ? animationDuration().toString() + 'ms' : '0ms'\">\n <ng-content></ng-content>\n </div>\n</div>" }]
557
+ }], propDecorators: { verticalSwipeTarget: [{
558
+ type: ViewChild,
559
+ args: ["verticalSwipeTarget", { static: true }]
560
+ }], modalContent: [{
561
+ type: ViewChild,
562
+ args: ["modalContent", { static: true }]
563
+ }] } });
564
+
565
+ class ModalCentered {
566
+ config = input.required();
567
+ isOpen = input.required();
568
+ isAnimated = input.required();
569
+ isSwipeableModalActive = input.required();
570
+ animationDuration = input.required();
571
+ hasDefaultContentWrapperClass = input.required();
572
+ hasBanner = input.required();
573
+ close = output();
574
+ onBackdropClick = output();
575
+ swipeableComponents;
576
+ get modalClasses() {
577
+ return {
578
+ 'centered-modal-content-wrapper': true,
579
+ 'centered-modal-default-style': this.hasDefaultContentWrapperClass() || this.hasBanner(),
580
+ 'centered-modal-animate-in': this.isAnimated() && this.isOpen(),
581
+ 'centered-modal-animate-out': this.isAnimated() && !this.isOpen(),
582
+ };
583
+ }
584
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalCentered, deps: [], target: i0.ɵɵFactoryTarget.Component });
585
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: ModalCentered, isStandalone: true, selector: "modal-centered", inputs: { config: { classPropertyName: "config", publicName: "config", 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 }, isSwipeableModalActive: { classPropertyName: "isSwipeableModalActive", publicName: "isSwipeableModalActive", 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: "swipeableComponents", predicate: ModalSwipeable, descendants: true }], ngImport: i0, template: "@if(!isSwipeableModalActive()) {\n<div class=\"modal-overlay\" [ngClass]=\"{'modal-backdrop': config()?.style?.hasBackdrop}\" (click)=\"\n 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\"\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 <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n </div>\n</div>\n} @else {\n<modal-swipeable [config]=\"config()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\"\n [animationDuration]=\"animationDuration()\" (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-swipeable>\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:absolute;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{max-width:90vw;max-width:90dvw;max-height:95vh;max-height:95dvh}.centered-modal-default-style{border-radius:.75rem;box-shadow:0 8px 20px #0000001f;color:var(--text_primary, #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;padding:1rem 1.5rem;gap:2rem}.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: ModalSwipeable, selector: "modal-swipeable", inputs: ["config", "isOpen", "isAnimated", "animationDuration"], outputs: ["close"] }, { kind: "component", type: ModalBanner, selector: "modal-banner", inputs: ["config"], outputs: ["close"] }] });
586
+ }
587
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalCentered, decorators: [{
588
+ type: Component,
589
+ args: [{ selector: 'modal-centered', imports: [
590
+ NgTemplateOutlet,
591
+ NgClass,
592
+ ModalSwipeable,
593
+ ModalBanner,
594
+ ], template: "@if(!isSwipeableModalActive()) {\n<div class=\"modal-overlay\" [ngClass]=\"{'modal-backdrop': config()?.style?.hasBackdrop}\" (click)=\"\n 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\"\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 <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n </div>\n</div>\n} @else {\n<modal-swipeable [config]=\"config()\" [isOpen]=\"isOpen()\" [isAnimated]=\"isAnimated()\"\n [animationDuration]=\"animationDuration()\" (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-swipeable>\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:absolute;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{max-width:90vw;max-width:90dvw;max-height:95vh;max-height:95dvh}.centered-modal-default-style{border-radius:.75rem;box-shadow:0 8px 20px #0000001f;color:var(--text_primary, #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;padding:1rem 1.5rem;gap:2rem}.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"] }]
595
+ }], propDecorators: { swipeableComponents: [{
596
+ type: ViewChildren,
597
+ args: [ModalSwipeable]
598
+ }] } });
599
+
600
+ const GENERIC_MODAL_DEFAULT_ANIM_DURATION = 175;
601
+ const GENERIC_MODAL_DEFAULT_INTERNAL_ANIM_DURATION = 350;
602
+ const GENERIC_MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_SMALL = 0.65;
603
+ const GENERIC_MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_LARGE = 0.85;
604
+
605
+ class ModalSide {
606
+ config = input.required();
607
+ isOpen = input.required();
608
+ _innerIsOpen = false;
609
+ set innerIsOpen(value) {
610
+ if (value) {
611
+ this._innerIsOpen = false;
612
+ setTimeout(() => {
613
+ this._innerIsOpen = true;
614
+ }, GENERIC_MODAL_DEFAULT_ANIM_DURATION);
615
+ }
616
+ else {
617
+ this._innerIsOpen = false;
618
+ }
619
+ }
620
+ get innerIsOpen() {
621
+ return this._innerIsOpen;
622
+ }
623
+ isAnimated = input.required();
624
+ isSwipeableModalActive = input.required();
625
+ animationDuration = input.required();
626
+ hasDefaultContentWrapperClass = input.required();
627
+ hasBanner = input.required();
628
+ close = output();
629
+ swipeableComponents;
630
+ constructor() {
631
+ effect(() => {
632
+ this.innerIsOpen = this.isOpen();
633
+ });
634
+ }
635
+ get modalClasses() {
636
+ const config = this.config();
637
+ const positionLeft = config?.style?.position === 'left';
638
+ const positionRight = config?.style?.position === 'right';
639
+ return {
640
+ 'side-modal-content-wrapper': true,
641
+ 'side-modal-default-style': this.hasDefaultContentWrapperClass() || this.hasBanner(),
642
+ 'left': positionLeft,
643
+ 'right': positionRight,
644
+ 'side-modal-animate-in': this.isAnimated() && this.innerIsOpen,
645
+ 'side-modal-animate-out': this.isAnimated() && !this.innerIsOpen,
646
+ };
647
+ }
648
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalSide, deps: [], target: i0.ɵɵFactoryTarget.Component });
649
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: ModalSide, isStandalone: true, selector: "modal-side", inputs: { config: { classPropertyName: "config", publicName: "config", 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 }, isSwipeableModalActive: { classPropertyName: "isSwipeableModalActive", publicName: "isSwipeableModalActive", 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: "swipeableComponents", predicate: ModalSwipeable, descendants: true }], ngImport: i0, template: "@if(!isSwipeableModalActive()) {\n<div [ngClass]=\"modalClasses\" (click)=\"$event.stopPropagation()\">\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 <div class=\"side-moda-content-wrapper\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n</div>\n} @else {\n<modal-swipeable [config]=\"config()\" [isOpen]=\"innerIsOpen\" [isAnimated]=\"isAnimated()\"\n [animationDuration]=\"animationDuration()\" (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-swipeable>\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;background:var(--modal_bg, #ffffff);box-shadow:0 0 15px #0000004d;z-index:1050;overflow-y:auto;max-width:85vw;max-width:85dvw;display:flex;flex-direction:column;transition:transform .3s ease-in-out}.side-modal-content-wrapper.left{left:0;transform:translate(-100%)}.side-modal-content-wrapper.right{right:0;transform:translate(100%)}.side-modal-content-wrapper.side-modal-animate-in.left,.side-modal-content-wrapper.side-modal-animate-in.right{transform:translate(0)}.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 .side-modal-inner-content-container{flex-grow:1;display:flex;flex-direction:column;padding:1rem;gap:2rem}@media (max-width: 768px){.side-modal-content-wrapper{max-width:90vw;max-width:95dvw}}.side-moda-content-wrapper{max-height:89vh;max-height:89dvh;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ModalSwipeable, selector: "modal-swipeable", inputs: ["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"] }] });
650
+ }
651
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ModalSide, decorators: [{
652
+ type: Component,
653
+ args: [{ selector: 'modal-side', imports: [
654
+ NgTemplateOutlet,
655
+ ModalSwipeable,
656
+ NgClass,
657
+ ModalBanner
658
+ ], template: "@if(!isSwipeableModalActive()) {\n<div [ngClass]=\"modalClasses\" (click)=\"$event.stopPropagation()\">\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 <div class=\"side-moda-content-wrapper\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n </div>\n </div>\n</div>\n} @else {\n<modal-swipeable [config]=\"config()\" [isOpen]=\"innerIsOpen\" [isAnimated]=\"isAnimated()\"\n [animationDuration]=\"animationDuration()\" (close)=\"close.emit('cancel')\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"> </ng-container>\n</modal-swipeable>\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;background:var(--modal_bg, #ffffff);box-shadow:0 0 15px #0000004d;z-index:1050;overflow-y:auto;max-width:85vw;max-width:85dvw;display:flex;flex-direction:column;transition:transform .3s ease-in-out}.side-modal-content-wrapper.left{left:0;transform:translate(-100%)}.side-modal-content-wrapper.right{right:0;transform:translate(100%)}.side-modal-content-wrapper.side-modal-animate-in.left,.side-modal-content-wrapper.side-modal-animate-in.right{transform:translate(0)}.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 .side-modal-inner-content-container{flex-grow:1;display:flex;flex-direction:column;padding:1rem;gap:2rem}@media (max-width: 768px){.side-modal-content-wrapper{max-width:90vw;max-width:95dvw}}.side-moda-content-wrapper{max-height:89vh;max-height:89dvh;overflow-y:auto}\n"] }]
659
+ }], ctorParameters: () => [], propDecorators: { swipeableComponents: [{
660
+ type: ViewChildren,
661
+ args: [ModalSwipeable]
662
+ }] } });
663
+
664
+ class GenericModalComponent {
665
+ modalService = inject(GenericModalService);
666
+ windowDimensionService = inject(WindowDimensionsService);
667
+ scrollLockService = inject(ScrollLockService);
668
+ deviceTypeService = inject(DeviceTypeService);
669
+ cdr = inject(ChangeDetectorRef);
670
+ afterClose = output();
671
+ animationDuration = GENERIC_MODAL_DEFAULT_ANIM_DURATION;
672
+ componentRef = {};
673
+ config;
674
+ closeFunction;
675
+ backdropClickSubject = new Subject();
676
+ backdropClick = this.backdropClickSubject.asObservable();
677
+ _isOpen = true;
678
+ get isOpen() {
679
+ return this._isOpen;
680
+ }
681
+ set isOpen(value) {
682
+ this._isOpen = value;
683
+ this.cdr.detectChanges();
684
+ }
685
+ isSwipeableModalActive = false;
686
+ isAnimated = false;
687
+ isCentered = false;
688
+ isSide = false;
689
+ hasBanner = false;
690
+ hasDefaultContentWrapperClass = false;
691
+ isConfirmCloseModalOpen = false;
692
+ isSpecialMobileOverflowHandlingEnabled = false;
693
+ isScrollDisabled = false;
694
+ windowDimensions;
695
+ unsubscribe$ = new Subject();
696
+ modalContainer;
697
+ sideModalComponents;
698
+ centeredModalComponents;
699
+ contentTemplate;
700
+ dynamicContainer;
701
+ constructor() {
702
+ this.windowDimensions = this.windowDimensionService.getWindowDimensions();
703
+ }
704
+ ngOnInit() {
705
+ this.initParamsFromConfig();
706
+ this.createSubscriptions();
707
+ if (this.config?.style.handleMobile !== false && this.windowDimensions.width < this.windowDimensions.threshold_sm) {
708
+ this.isSwipeableModalActive = true;
709
+ }
710
+ else {
711
+ this.isSwipeableModalActive = false;
712
+ }
713
+ }
714
+ ngAfterViewInit() {
715
+ if (!this.componentRef)
716
+ return;
717
+ this.dynamicContainer?.insert(this.componentRef.hostView);
718
+ }
719
+ ngOnDestroy() {
720
+ this.componentRef?.destroy();
721
+ this.dynamicContainer?.clear();
722
+ this.unsubscribe$.next();
723
+ this.unsubscribe$.complete();
724
+ }
725
+ //#region Subscription Methods
726
+ createSubscriptions() {
727
+ this.windowDimensionService
728
+ .getWindowDimensions$()
729
+ .pipe(takeUntil(this.unsubscribe$))
730
+ .subscribe((dimensions) => {
731
+ this.windowDimensions = dimensions;
732
+ this.handleWindowDimensionChange();
733
+ });
734
+ fromEvent(document, "keydown")
735
+ .pipe(filter((event) => event.key === "Escape"), takeUntil(this.unsubscribe$))
736
+ .subscribe(() => {
737
+ if (!this.isConfirmCloseModalOpen) {
738
+ this.close("cancel", undefined, true);
739
+ }
740
+ });
741
+ }
742
+ handleWindowDimensionChange() {
743
+ if (this.config?.style.handleMobile !== false) {
744
+ if (this.windowDimensions.width < this.windowDimensions.threshold_sm && !this.isSwipeableModalActive) {
745
+ this.isSwipeableModalActive = true;
746
+ if (this.isOpen) {
747
+ if (this.isSpecialMobileOverflowHandlingEnabled) {
748
+ this.scrollLockService.disableScroll({
749
+ mainContainer: this.modalContainer?.nativeElement,
750
+ handleExtremeOverflow: this.config?.enableExtremeOverflowHandling ?? false,
751
+ animationDuration: this.animationDuration,
752
+ handleTouchInput: true,
753
+ mobileOnlyTouchPrevention: true,
754
+ });
755
+ this.isScrollDisabled = true;
756
+ }
757
+ }
758
+ }
759
+ if (this.windowDimensions.width >= this.windowDimensions.threshold_sm && this.isSwipeableModalActive) {
760
+ this.isSwipeableModalActive = false;
761
+ if (this.isOpen) {
762
+ if (this.isSpecialMobileOverflowHandlingEnabled) {
763
+ this.scrollLockService.enableScroll(this.config?.enableExtremeOverflowHandling ?? false);
764
+ this.isScrollDisabled = false;
765
+ }
766
+ }
767
+ }
768
+ }
769
+ }
770
+ //#endregion
771
+ //#region Initialization Methods
772
+ initParamsFromConfig() {
773
+ this.isSpecialMobileOverflowHandlingEnabled = (this.deviceTypeService.getDeviceState().isAppleDevice || this.config?.webkitOnlyOverflowMobileHandling === false);
774
+ this.hasBanner =
775
+ this.config !== undefined &&
776
+ ((this.config.bannerText !== undefined && this.config.bannerText.length > 0) ||
777
+ (this.config.bannerIcons && this.config.bannerIcons.length > 0) ||
778
+ this.config.disableClose !== true &&
779
+ this.config.style.showCloseButton !== false);
780
+ this.hasDefaultContentWrapperClass = this.config?.style.contentWrapper !== false;
781
+ this.isAnimated = this.config?.style.animate === true && (this.config?.style.contentWrapper !== false || this.hasBanner);
782
+ this.isCentered = this.config?.style.position === "center";
783
+ this.isSide = this.config?.style.position === "left" || this.config?.style.position === "right";
784
+ }
785
+ //#endregion
786
+ //#region Closing Methods
787
+ close(state = "cancel", result = undefined, fromInsideInteraction = false, forceClose = false) {
788
+ if (this.isConfirmCloseModalOpen)
789
+ return;
790
+ if (this.isScrollDisabled) {
791
+ this.scrollLockService.enableScroll(this.config?.enableExtremeOverflowHandling ?? false);
792
+ }
793
+ if ((this.config && this.config?.disableClose !== true) || !fromInsideInteraction || forceClose) {
794
+ if (this.config?.confirmCloseConfig && this.shouldOpenConfirmCloseModal(forceClose, state)) {
795
+ if (this.shouldOpenConfirmCloseModalSelfCheck()) {
796
+ const modal = this.modalService.open(this.config.confirmCloseConfig.confirmModalComponent, {
797
+ style: this.config.confirmCloseConfig.style ?? {
798
+ handleMobile: false,
799
+ },
800
+ disableClose: true,
801
+ bannerText: this.config.confirmCloseConfig.bannerText ?? EMPTY_STRING,
802
+ bannerIcons: this.config.confirmCloseConfig.bannerIcons ?? [],
803
+ data: this.config.confirmCloseConfig.data ?? null,
804
+ });
805
+ this.isConfirmCloseModalOpen = true;
806
+ if (this.isSwipeableModalActive) {
807
+ this.resetSwipeableModalPosition();
808
+ }
809
+ modal.afterClosed()
810
+ .pipe(take(1))
811
+ .subscribe((_result) => {
812
+ this.isConfirmCloseModalOpen = false;
813
+ if (_result.state === 'confirm') {
814
+ this.handleClose(state, result);
815
+ }
816
+ });
817
+ }
818
+ else {
819
+ if (this.config?.disableConsoleWarnings !== true) {
820
+ console.warn(GenericModalWarnings.CONFIRM_MODAL_NESTING_NOT_SUPPORTED);
821
+ }
822
+ this.handleClose(state, result);
823
+ }
824
+ }
825
+ else {
826
+ this.handleClose(state, result);
827
+ }
828
+ }
829
+ else if (this.isSwipeableModalActive) {
830
+ this.resetSwipeableModalPosition();
831
+ }
832
+ }
833
+ async handleClose(state, result) {
834
+ this.isOpen = false;
835
+ this.setSwipeableModalFinishedState(true);
836
+ const returnResult = {
837
+ data: result,
838
+ state: state,
839
+ };
840
+ if (this.closeFunction) {
841
+ this.closeFunction(returnResult);
842
+ }
843
+ }
844
+ onBackdropClick(event) {
845
+ this.backdropClickSubject.next(event);
846
+ if (this.config?.style?.hasBackdrop && this.config?.disableCloseOnBackdropClick !== true) {
847
+ this.close("cancel", undefined, true);
848
+ }
849
+ }
850
+ //#endregion
851
+ //#region Logical Assertions
852
+ shouldOpenConfirmCloseModal(forceClose, state) {
853
+ if (this.config?.confirmCloseConfig) {
854
+ const closeNotCalledWithForceClose = !forceClose;
855
+ if (closeNotCalledWithForceClose) {
856
+ const configuredForConfirmClose = this.config.confirmCloseConfig.confirmClose === true;
857
+ const closeCalledWithCancelState = state === "cancel";
858
+ const configuredForConfirmCloseOnSubmit = this.config.confirmCloseConfig.confirmOnSubmit === true;
859
+ return configuredForConfirmClose && (closeCalledWithCancelState || configuredForConfirmCloseOnSubmit);
860
+ }
861
+ }
862
+ return false;
863
+ }
864
+ shouldOpenConfirmCloseModalSelfCheck() {
865
+ if (this.config?.confirmCloseConfig) {
866
+ const hasSelfIdentifier = this.componentRef && this.componentRef.instance && this.componentRef.instance.modal && this.componentRef.instance.modal.selfIdentifier !== EMPTY_STRING;
867
+ const bypassSelfCheck = this.config.confirmCloseConfig.bypassSelfCheck === true;
868
+ return hasSelfIdentifier || bypassSelfCheck;
869
+ }
870
+ return false;
871
+ }
872
+ //#endregion
873
+ //#region Helper Methods
874
+ getSwipeableModal() {
875
+ return this.sideModalComponents?.first?.swipeableComponents?.first
876
+ ?? this.centeredModalComponents?.first?.swipeableComponents?.first;
877
+ }
878
+ resetSwipeableModalPosition() {
879
+ const swipeableModal = this.getSwipeableModal();
880
+ if (swipeableModal) {
881
+ swipeableModal.currentTranslateY = 0;
882
+ }
883
+ }
884
+ setSwipeableModalFinishedState(isFinished) {
885
+ const swipeableModal = this.getSwipeableModal();
886
+ if (swipeableModal) {
887
+ swipeableModal.isSwipingVerticallyFinished = isFinished;
888
+ }
889
+ }
890
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
891
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: GenericModalComponent, isStandalone: true, selector: "generic-modal", outputs: { afterClose: "afterClose" }, viewQueries: [{ propertyName: "modalContainer", first: true, predicate: ["modalContainer"], descendants: true, static: true }, { propertyName: "contentTemplate", first: true, predicate: ["contentTemplate"], descendants: true }, { propertyName: "dynamicContainer", first: true, predicate: ["dynamicContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "sideModalComponents", predicate: ModalSide, descendants: true }, { propertyName: "centeredModalComponents", predicate: ModalCentered, descendants: true }], ngImport: i0, template: "@if (config?.style?.hasBackdrop && (isSide || isSwipeableModalActive)) {\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 [config]=\"config\" [isOpen]=\"isOpen\" [isAnimated]=\"isAnimated\"\n [isSwipeableModalActive]=\"isSwipeableModalActive\" [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" [hasBanner]=\"hasBanner\" (close)=\"close($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\">\n </ng-container>\n </modal-side>\n }\n @case (isCentered) {\n <modal-centered [config]=\"config\" [isOpen]=\"isOpen\" [isAnimated]=\"isAnimated\"\n [isSwipeableModalActive]=\"isSwipeableModalActive\" [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" [hasBanner]=\"hasBanner\" (close)=\"close($event)\"\n (onBackdropClick)=\"onBackdropClick($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\">\n </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: ["config", "isOpen", "isAnimated", "isSwipeableModalActive", "animationDuration", "hasDefaultContentWrapperClass", "hasBanner"], outputs: ["close", "onBackdropClick"] }, { kind: "component", type: ModalSide, selector: "modal-side", inputs: ["config", "isOpen", "isAnimated", "isSwipeableModalActive", "animationDuration", "hasDefaultContentWrapperClass", "hasBanner"], outputs: ["close"] }, { kind: "component", type: ModalBackdrop, selector: "modal-backdrop", inputs: ["isAnimated", "isOpen"], outputs: ["click"] }] });
892
+ }
893
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GenericModalComponent, decorators: [{
894
+ type: Component,
895
+ args: [{ selector: "generic-modal", imports: [
896
+ NgTemplateOutlet,
897
+ ModalCentered,
898
+ ModalSide,
899
+ ModalBackdrop
900
+ ], template: "@if (config?.style?.hasBackdrop && (isSide || isSwipeableModalActive)) {\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 [config]=\"config\" [isOpen]=\"isOpen\" [isAnimated]=\"isAnimated\"\n [isSwipeableModalActive]=\"isSwipeableModalActive\" [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" [hasBanner]=\"hasBanner\" (close)=\"close($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\">\n </ng-container>\n </modal-side>\n }\n @case (isCentered) {\n <modal-centered [config]=\"config\" [isOpen]=\"isOpen\" [isAnimated]=\"isAnimated\"\n [isSwipeableModalActive]=\"isSwipeableModalActive\" [animationDuration]=\"animationDuration\"\n [hasDefaultContentWrapperClass]=\"hasDefaultContentWrapperClass\" [hasBanner]=\"hasBanner\" (close)=\"close($event)\"\n (onBackdropClick)=\"onBackdropClick($event)\">\n <ng-container [ngTemplateOutlet]=\"contentTemplate\">\n </ng-container>\n </modal-centered>\n }\n }\n</ng-container>\n\n<ng-template #contentTemplate>\n <ng-container #dynamicContainer></ng-container>\n</ng-template>" }]
901
+ }], ctorParameters: () => [], propDecorators: { modalContainer: [{
902
+ type: ViewChild,
903
+ args: ["modalContainer", { static: true }]
904
+ }], sideModalComponents: [{
905
+ type: ViewChildren,
906
+ args: [ModalSide]
907
+ }], centeredModalComponents: [{
908
+ type: ViewChildren,
909
+ args: [ModalCentered]
910
+ }], contentTemplate: [{
911
+ type: ViewChild,
912
+ args: ["contentTemplate"]
913
+ }], dynamicContainer: [{
914
+ type: ViewChild,
915
+ args: ["dynamicContainer", { read: ViewContainerRef }]
916
+ }] } });
917
+
918
+ const LOWEST_CHARACTER_CAP = 23;
919
+ const LOWER_CHARACTER_CAP = 33;
920
+ const MID_CHARACTER_CAP = 49;
921
+ const UPPER_CHARACTER_CAP = 60;
922
+
923
+ /*
924
+ * Public API Surface of modal
925
+ */
926
+
927
+ /**
928
+ * Generated bundle index. Do not edit.
929
+ */
930
+
931
+ export { EMPTY_STRING, GENERIC_MODAL_DATA, GENERIC_MODAL_DEFAULT_ANIM_DURATION, GENERIC_MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_LARGE, GENERIC_MODAL_DEFAULT_ANIM_DURATION_MULTIPLIER_SMALL, GENERIC_MODAL_DEFAULT_INTERNAL_ANIM_DURATION, GENERIC_MODAL_DOWN_SWIPE_LIMIT, GENERIC_MODAL_SWIPE_VELOCITY_THRESHOLD, GENERIC_MODAL_UP_SWIPE_LIMIT, GenericModal, GenericModalComponent, GenericModalConfig, GenericModalErrors, GenericModalRef, GenericModalService, GenericModalState, GenericModalStyleConfig, GenericModalWarnings, LOWER_CHARACTER_CAP, LOWEST_CHARACTER_CAP, MID_CHARACTER_CAP, ModalBackdrop, ModalBanner, ModalCentered, ModalSide, ModalSwipeable, UPPER_CHARACTER_CAP };
932
+ //# sourceMappingURL=filip.mazev-modal.mjs.map