@raintonic/formaui 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +145 -0
- package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs +806 -0
- package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-cdk-form-field.mjs +86 -0
- package/fesm2022/raintonic-formaui-cdk-form-field.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-cdk-overlay.mjs +1757 -0
- package/fesm2022/raintonic-formaui-cdk-overlay.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs +287 -0
- package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-accordion.mjs +217 -0
- package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-alert.mjs +161 -0
- package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs +726 -0
- package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-avatar.mjs +92 -0
- package/fesm2022/raintonic-formaui-components-avatar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-badge.mjs +107 -0
- package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-big-menu.mjs +68 -0
- package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +55 -0
- package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-button-group.mjs +103 -0
- package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-button.mjs +241 -0
- package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-card.mjs +270 -0
- package/fesm2022/raintonic-formaui-components-card.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-checkbox.mjs +295 -0
- package/fesm2022/raintonic-formaui-components-checkbox.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-data-table.mjs +631 -0
- package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-date-picker.mjs +1331 -0
- package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-divider.mjs +41 -0
- package/fesm2022/raintonic-formaui-components-divider.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-drawer.mjs +190 -0
- package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-dynamic-form.mjs +266 -0
- package/fesm2022/raintonic-formaui-components-dynamic-form.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-empty-state.mjs +33 -0
- package/fesm2022/raintonic-formaui-components-empty-state.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-file-upload.mjs +246 -0
- package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-form-field.mjs +482 -0
- package/fesm2022/raintonic-formaui-components-form-field.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-icon.mjs +117 -0
- package/fesm2022/raintonic-formaui-components-icon.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-input.mjs +327 -0
- package/fesm2022/raintonic-formaui-components-input.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-list.mjs +149 -0
- package/fesm2022/raintonic-formaui-components-list.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-menu.mjs +896 -0
- package/fesm2022/raintonic-formaui-components-menu.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-number-input.mjs +345 -0
- package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-paginator.mjs +139 -0
- package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-password-input.mjs +306 -0
- package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-popover.mjs +451 -0
- package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-progressbar.mjs +148 -0
- package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-radio.mjs +260 -0
- package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-select.mjs +1011 -0
- package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-side-panel.mjs +150 -0
- package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-sidebar.mjs +257 -0
- package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-skeleton.mjs +50 -0
- package/fesm2022/raintonic-formaui-components-skeleton.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-slider.mjs +347 -0
- package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-spinner.mjs +63 -0
- package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-stepper.mjs +317 -0
- package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tab.mjs +197 -0
- package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tag.mjs +78 -0
- package/fesm2022/raintonic-formaui-components-tag.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-time-picker.mjs +644 -0
- package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-toggle.mjs +171 -0
- package/fesm2022/raintonic-formaui-components-toggle.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-toolbar.mjs +140 -0
- package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tooltip.mjs +555 -0
- package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tree-select.mjs +314 -0
- package/fesm2022/raintonic-formaui-components-tree-select.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tree-table.mjs +103 -0
- package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-components-tree.mjs +430 -0
- package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-core.mjs +62 -0
- package/fesm2022/raintonic-formaui-core.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-services-dialog.mjs +798 -0
- package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-services-notification.mjs +391 -0
- package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-services-theme.mjs +248 -0
- package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -0
- package/fesm2022/raintonic-formaui-test-utils.mjs +66 -0
- package/fesm2022/raintonic-formaui-test-utils.mjs.map +1 -0
- package/fesm2022/raintonic-formaui.mjs +15 -0
- package/fesm2022/raintonic-formaui.mjs.map +1 -0
- package/llms-full.txt +1627 -0
- package/llms.txt +60 -0
- package/package.json +251 -0
- package/styles/_fonts-entry.scss +3 -0
- package/styles/fonts/dm-mono-400-latin.woff2 +0 -0
- package/styles/fonts/inter-tight-latin-italic.woff2 +0 -0
- package/styles/fonts/inter-tight-latin.woff2 +0 -0
- package/styles/index.scss +127 -0
- package/styles/partials/_constants.scss +29 -0
- package/styles/partials/_fonts.scss +36 -0
- package/styles/partials/_grid.scss +171 -0
- package/styles/partials/_mixins.scss +145 -0
- package/styles/partials/_motion.scss +252 -0
- package/styles/partials/_theme.scss +275 -0
- package/styles/partials/_typography.scss +112 -0
- package/styles/partials/_utilities.scss +480 -0
- package/styles/partials/themes/_dark.scss +254 -0
- package/styles/partials/themes/_light.scss +254 -0
- package/types/raintonic-formaui-cdk-drag-drop.d.ts +196 -0
- package/types/raintonic-formaui-cdk-drag-drop.d.ts.map +1 -0
- package/types/raintonic-formaui-cdk-form-field.d.ts +62 -0
- package/types/raintonic-formaui-cdk-form-field.d.ts.map +1 -0
- package/types/raintonic-formaui-cdk-overlay.d.ts +843 -0
- package/types/raintonic-formaui-cdk-overlay.d.ts.map +1 -0
- package/types/raintonic-formaui-cdk-virtual-scroll.d.ts +112 -0
- package/types/raintonic-formaui-cdk-virtual-scroll.d.ts.map +1 -0
- package/types/raintonic-formaui-components-accordion.d.ts +124 -0
- package/types/raintonic-formaui-components-accordion.d.ts.map +1 -0
- package/types/raintonic-formaui-components-alert.d.ts +143 -0
- package/types/raintonic-formaui-components-alert.d.ts.map +1 -0
- package/types/raintonic-formaui-components-autocomplete.d.ts +193 -0
- package/types/raintonic-formaui-components-autocomplete.d.ts.map +1 -0
- package/types/raintonic-formaui-components-avatar.d.ts +52 -0
- package/types/raintonic-formaui-components-avatar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-badge.d.ts +47 -0
- package/types/raintonic-formaui-components-badge.d.ts.map +1 -0
- package/types/raintonic-formaui-components-big-menu.d.ts +62 -0
- package/types/raintonic-formaui-components-big-menu.d.ts.map +1 -0
- package/types/raintonic-formaui-components-breadcrumb.d.ts +26 -0
- package/types/raintonic-formaui-components-breadcrumb.d.ts.map +1 -0
- package/types/raintonic-formaui-components-button-group.d.ts +61 -0
- package/types/raintonic-formaui-components-button-group.d.ts.map +1 -0
- package/types/raintonic-formaui-components-button.d.ts +116 -0
- package/types/raintonic-formaui-components-button.d.ts.map +1 -0
- package/types/raintonic-formaui-components-card.d.ts +191 -0
- package/types/raintonic-formaui-components-card.d.ts.map +1 -0
- package/types/raintonic-formaui-components-checkbox.d.ts +132 -0
- package/types/raintonic-formaui-components-checkbox.d.ts.map +1 -0
- package/types/raintonic-formaui-components-data-table.d.ts +368 -0
- package/types/raintonic-formaui-components-data-table.d.ts.map +1 -0
- package/types/raintonic-formaui-components-date-picker.d.ts +341 -0
- package/types/raintonic-formaui-components-date-picker.d.ts.map +1 -0
- package/types/raintonic-formaui-components-divider.d.ts +21 -0
- package/types/raintonic-formaui-components-divider.d.ts.map +1 -0
- package/types/raintonic-formaui-components-drawer.d.ts +48 -0
- package/types/raintonic-formaui-components-drawer.d.ts.map +1 -0
- package/types/raintonic-formaui-components-dynamic-form.d.ts +412 -0
- package/types/raintonic-formaui-components-dynamic-form.d.ts.map +1 -0
- package/types/raintonic-formaui-components-empty-state.d.ts +14 -0
- package/types/raintonic-formaui-components-empty-state.d.ts.map +1 -0
- package/types/raintonic-formaui-components-file-upload.d.ts +77 -0
- package/types/raintonic-formaui-components-file-upload.d.ts.map +1 -0
- package/types/raintonic-formaui-components-form-field.d.ts +271 -0
- package/types/raintonic-formaui-components-form-field.d.ts.map +1 -0
- package/types/raintonic-formaui-components-icon.d.ts +61 -0
- package/types/raintonic-formaui-components-icon.d.ts.map +1 -0
- package/types/raintonic-formaui-components-input.d.ts +149 -0
- package/types/raintonic-formaui-components-input.d.ts.map +1 -0
- package/types/raintonic-formaui-components-list.d.ts +48 -0
- package/types/raintonic-formaui-components-list.d.ts.map +1 -0
- package/types/raintonic-formaui-components-menu.d.ts +403 -0
- package/types/raintonic-formaui-components-menu.d.ts.map +1 -0
- package/types/raintonic-formaui-components-number-input.d.ts +127 -0
- package/types/raintonic-formaui-components-number-input.d.ts.map +1 -0
- package/types/raintonic-formaui-components-paginator.d.ts +37 -0
- package/types/raintonic-formaui-components-paginator.d.ts.map +1 -0
- package/types/raintonic-formaui-components-password-input.d.ts +111 -0
- package/types/raintonic-formaui-components-password-input.d.ts.map +1 -0
- package/types/raintonic-formaui-components-popover.d.ts +131 -0
- package/types/raintonic-formaui-components-popover.d.ts.map +1 -0
- package/types/raintonic-formaui-components-progressbar.d.ts +111 -0
- package/types/raintonic-formaui-components-progressbar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-radio.d.ts +95 -0
- package/types/raintonic-formaui-components-radio.d.ts.map +1 -0
- package/types/raintonic-formaui-components-select.d.ts +307 -0
- package/types/raintonic-formaui-components-select.d.ts.map +1 -0
- package/types/raintonic-formaui-components-side-panel.d.ts +51 -0
- package/types/raintonic-formaui-components-side-panel.d.ts.map +1 -0
- package/types/raintonic-formaui-components-sidebar.d.ts +174 -0
- package/types/raintonic-formaui-components-sidebar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-skeleton.d.ts +20 -0
- package/types/raintonic-formaui-components-skeleton.d.ts.map +1 -0
- package/types/raintonic-formaui-components-slider.d.ts +108 -0
- package/types/raintonic-formaui-components-slider.d.ts.map +1 -0
- package/types/raintonic-formaui-components-spinner.d.ts +42 -0
- package/types/raintonic-formaui-components-spinner.d.ts.map +1 -0
- package/types/raintonic-formaui-components-stepper.d.ts +126 -0
- package/types/raintonic-formaui-components-stepper.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tab.d.ts +96 -0
- package/types/raintonic-formaui-components-tab.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tag.d.ts +34 -0
- package/types/raintonic-formaui-components-tag.d.ts.map +1 -0
- package/types/raintonic-formaui-components-time-picker.d.ts +172 -0
- package/types/raintonic-formaui-components-time-picker.d.ts.map +1 -0
- package/types/raintonic-formaui-components-toggle.d.ts +70 -0
- package/types/raintonic-formaui-components-toggle.d.ts.map +1 -0
- package/types/raintonic-formaui-components-toolbar.d.ts +128 -0
- package/types/raintonic-formaui-components-toolbar.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tooltip.d.ts +268 -0
- package/types/raintonic-formaui-components-tooltip.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tree-select.d.ts +80 -0
- package/types/raintonic-formaui-components-tree-select.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tree-table.d.ts +90 -0
- package/types/raintonic-formaui-components-tree-table.d.ts.map +1 -0
- package/types/raintonic-formaui-components-tree.d.ts +104 -0
- package/types/raintonic-formaui-components-tree.d.ts.map +1 -0
- package/types/raintonic-formaui-core.d.ts +115 -0
- package/types/raintonic-formaui-core.d.ts.map +1 -0
- package/types/raintonic-formaui-services-dialog.d.ts +451 -0
- package/types/raintonic-formaui-services-dialog.d.ts.map +1 -0
- package/types/raintonic-formaui-services-notification.d.ts +221 -0
- package/types/raintonic-formaui-services-notification.d.ts.map +1 -0
- package/types/raintonic-formaui-services-theme.d.ts +126 -0
- package/types/raintonic-formaui-services-theme.d.ts.map +1 -0
- package/types/raintonic-formaui-test-utils.d.ts +24 -0
- package/types/raintonic-formaui-test-utils.d.ts.map +1 -0
- package/types/raintonic-formaui.d.ts +4 -0
- package/types/raintonic-formaui.d.ts.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-services-dialog.mjs","sources":["../../../lib/services/dialog/dialog.types.ts","../../../lib/services/dialog/dialog-ref.ts","../../../lib/services/dialog/dialog-container.component.ts","../../../lib/services/dialog/confirm-dialog.component.ts","../../../lib/services/dialog/confirm-dialog.component.html","../../../lib/services/dialog/dialog.service.ts","../../../lib/services/dialog/raintonic-formaui-services-dialog.ts"],"sourcesContent":["import { InjectionToken, Injector, Type, ViewContainerRef } from '@angular/core';\nimport { Observable } from 'rxjs';\n\n/**\n * Injection token for dialog data passed to the dialog component\n */\nexport const FUI_DIALOG_DATA = new InjectionToken<unknown>('FuiDialogData');\n\n/**\n * Injection token for the dialog scroll strategy\n */\nexport const FUI_DIALOG_DEFAULT_OPTIONS = new InjectionToken<FuiDialogConfig>('FuiDialogDefaultOptions');\n\n/**\n * Role attribute for the dialog\n */\nexport type FuiDialogRole = 'dialog' | 'alertdialog';\n\n/**\n * Configuration for opening a dialog\n */\nexport interface FuiDialogConfig<D = unknown> {\n /** ID for the dialog. If omitted, a unique one will be generated */\n id?: string;\n\n /** Role attribute for the dialog element */\n role?: FuiDialogRole;\n\n /** CSS class(es) to apply to the overlay pane */\n panelClass?: string | string[];\n\n /** Whether the dialog has a backdrop */\n hasBackdrop?: boolean;\n\n /** CSS class(es) to apply to the backdrop */\n backdropClass?: string | string[];\n\n /** Whether the user can close the dialog by clicking on the backdrop */\n disableClose?: boolean;\n\n /** Width of the dialog */\n width?: string;\n\n /** Height of the dialog */\n height?: string;\n\n /** Min-width of the dialog */\n minWidth?: string | number;\n\n /** Min-height of the dialog */\n minHeight?: string | number;\n\n /** Max-width of the dialog. Defaults to 80vw */\n maxWidth?: string | number;\n\n /** Max-height of the dialog */\n maxHeight?: string | number;\n\n /** Position of the dialog */\n position?: FuiDialogPosition;\n\n /** Data to pass to the dialog component */\n data?: D | null;\n\n /** Layout direction for the dialog content */\n direction?: 'ltr' | 'rtl';\n\n /** ARIA label for the dialog */\n ariaLabel?: string | null;\n\n /** ID of the element that labels the dialog */\n ariaLabelledBy?: string | null;\n\n /** ID of the element that describes the dialog */\n ariaDescribedBy?: string | null;\n\n /** Whether to focus the first focusable element on open */\n autoFocus?: FuiAutoFocusTarget | string | boolean;\n\n /** Whether to restore focus to the previously focused element on close */\n restoreFocus?: boolean;\n\n /** Whether the dialog should close when the user goes backwards/forwards in history */\n closeOnNavigation?: boolean;\n\n /** Duration of the enter animation in ms */\n enterAnimationDuration?: string | number;\n\n /** Duration of the exit animation in ms */\n exitAnimationDuration?: string | number;\n\n /** Alternate ViewContainerRef to use for creating the dialog */\n viewContainerRef?: ViewContainerRef;\n\n /** Injector used for the dialog component */\n injector?: Injector;\n\n /** Component to instantiate as the dialog container (internal use) */\n containerComponent?: Type<FuiDialogContainerBase>;\n\n /** Whether to delay the focus trap */\n delayFocusTrap?: boolean;\n}\n\n/**\n * Target for auto focus within the dialog\n */\nexport type FuiAutoFocusTarget = 'dialog' | 'first-tabbable' | 'first-heading';\n\n/**\n * Position of the dialog\n */\nexport interface FuiDialogPosition {\n /** Override for the dialog's top position */\n top?: string;\n /** Override for the dialog's bottom position */\n bottom?: string;\n /** Override for the dialog's left position */\n left?: string;\n /** Override for the dialog's right position */\n right?: string;\n}\n\n/**\n * State of the dialog animation\n */\nexport type FuiDialogState = 'void' | 'enter' | 'exit';\n\n/**\n * Base interface for dialog container\n */\nexport interface FuiDialogContainerBase {\n /** Starts the dialog exit animation */\n _startExitAnimation(): void;\n}\n\n/**\n * Reference to an opened dialog\n */\nexport interface IFuiDialogRef<T = unknown, R = unknown> {\n /** Unique ID for this dialog instance */\n readonly id: string;\n\n /** The component instance if the dialog was created with a component */\n readonly componentInstance: T | null;\n\n /** Whether the user is allowed to close the dialog */\n disableClose: boolean;\n\n /** Observable that emits when the dialog has been opened */\n readonly afterOpened: Observable<void>;\n\n /** Observable that emits when the dialog has started closing */\n readonly beforeClosed: Observable<R | undefined>;\n\n /** Observable that emits when the dialog has finished closing */\n readonly afterClosed: Observable<R | undefined>;\n\n /** Observable that emits when the backdrop is clicked */\n readonly backdropClick: Observable<MouseEvent>;\n\n /** Observable that emits when a keydown event occurs on the overlay */\n readonly keydownEvents: Observable<KeyboardEvent>;\n\n /**\n * Closes the dialog with an optional result\n * @param dialogResult Result to return to the dialog opener\n */\n close(dialogResult?: R): void;\n\n /**\n * Updates the dialog's position\n * @param position New position configuration\n */\n updatePosition(position?: FuiDialogPosition): void;\n\n /**\n * Updates the dialog's dimensions\n * @param width New width\n * @param height New height\n */\n updateSize(width?: string, height?: string): void;\n\n /**\n * Adds CSS classes to the dialog panel\n * @param classes Classes to add\n */\n addPanelClass(classes: string | string[]): void;\n\n /**\n * Removes CSS classes from the dialog panel\n * @param classes Classes to remove\n */\n removePanelClass(classes: string | string[]): void;\n\n /**\n * Gets the current state of the dialog's lifecycle\n */\n getState(): FuiDialogState;\n}\n\n/**\n * Result from opening a dialog\n */\nexport interface FuiDialogOpenResult<T, R> {\n /** Reference to the opened dialog */\n dialogRef: IFuiDialogRef<T, R>;\n /** Reference to the component instance if dialog was created with a component */\n componentRef?: T;\n}\n\n// Confirm Dialog types\nexport type FuiConfirmDialogVariant = 'info' | 'warning' | 'danger';\n\nexport interface FuiConfirmDialogConfig {\n title: string;\n message: string;\n confirmText?: string;\n cancelText?: string;\n variant?: FuiConfirmDialogVariant;\n}\n","import { Observable, Subject } from 'rxjs';\nimport { filter } from 'rxjs/operators';\nimport { FuiOverlayRef, FuiGlobalPositionStrategy } from '@raintonic/formaui/cdk/overlay';\nimport { FuiDialogConfig, FuiDialogPosition, IFuiDialogRef, FuiDialogState } from './dialog.types';\n\n/**\n * # FuiDialogRefImpl\n *\n * Implementation of the FuiDialogRef interface. This class manages the lifecycle\n * of an individual dialog instance, providing methods to close, update position/size,\n * and observe dialog events.\n *\n * ## Features\n * - Dialog result handling\n * - Position and size updates\n * - Event observables (backdrop click, keydown, lifecycle)\n * - CSS class management\n * - Focus management integration\n */\nexport class FuiDialogRef<T = unknown, R = unknown> implements IFuiDialogRef<T, R> {\n private readonly _id: string;\n private _componentInstance: T | null = null;\n private _result: R | undefined;\n private _state: FuiDialogState = 'enter';\n\n // Event subjects\n private readonly _afterOpened = new Subject<void>();\n private readonly _beforeClosed = new Subject<R | undefined>();\n private readonly _afterClosed = new Subject<R | undefined>();\n\n // Configuration\n disableClose: boolean;\n\n constructor(\n private readonly _overlayRef: FuiOverlayRef,\n private _config: FuiDialogConfig,\n id?: string,\n ) {\n this._id = id ?? this._generateId();\n this.disableClose = _config.disableClose ?? false;\n\n this._setupEventHandlers();\n }\n\n /** Unique ID for this dialog instance */\n get id(): string {\n return this._id;\n }\n\n /** The component instance if the dialog was created with a component */\n get componentInstance(): T | null {\n return this._componentInstance;\n }\n\n /** Sets the component instance (internal use) */\n set componentInstance(instance: T | null) {\n this._componentInstance = instance;\n }\n\n /** Observable that emits when the dialog has been opened */\n get afterOpened(): Observable<void> {\n return this._afterOpened.asObservable();\n }\n\n /** Observable that emits when the dialog has started closing */\n get beforeClosed(): Observable<R | undefined> {\n return this._beforeClosed.asObservable();\n }\n\n /** Observable that emits when the dialog has finished closing */\n get afterClosed(): Observable<R | undefined> {\n return this._afterClosed.asObservable();\n }\n\n /** Observable that emits when the backdrop is clicked */\n get backdropClick(): Observable<MouseEvent> {\n return this._overlayRef.backdropClick;\n }\n\n /** Observable that emits when a keydown event occurs on the overlay */\n get keydownEvents(): Observable<KeyboardEvent> {\n return this._overlayRef.keydownEvents;\n }\n\n /**\n * Closes the dialog with an optional result\n */\n close(dialogResult?: R): void {\n if (this._state === 'exit') {\n return;\n }\n\n this._result = dialogResult;\n this._state = 'exit';\n\n // Emit before closed event\n this._beforeClosed.next(dialogResult);\n this._beforeClosed.complete();\n\n // Get animation duration from config\n const exitDuration = this._parseAnimationDuration(this._config.exitAnimationDuration);\n\n if (exitDuration > 0) {\n // Add exit animation class\n this._overlayRef.addPanelClass('fui-dialog-exit');\n\n // Wait for animation then dispose\n setTimeout(() => {\n this._finishDialogClose();\n }, exitDuration);\n } else {\n this._finishDialogClose();\n }\n }\n\n /**\n * Updates the dialog's position\n */\n updatePosition(position?: FuiDialogPosition): void {\n const strategy = this._overlayRef.getConfig().positionStrategy as FuiGlobalPositionStrategy;\n\n if (strategy) {\n if (position?.left || position?.right) {\n if (position?.left) {\n strategy.left(position.left);\n } else if (position?.right) {\n strategy.right(position.right);\n }\n } else {\n strategy.centerHorizontally();\n }\n\n if (position?.top || position?.bottom) {\n if (position?.top) {\n strategy.top(position.top);\n } else if (position?.bottom) {\n strategy.bottom(position.bottom);\n }\n } else {\n strategy.centerVertically();\n }\n\n this._overlayRef.updatePosition();\n }\n }\n\n /**\n * Updates the dialog's dimensions\n */\n updateSize(width?: string, height?: string): void {\n this._overlayRef.updateSize({\n width: width ?? undefined,\n height: height ?? undefined,\n });\n }\n\n /**\n * Adds CSS classes to the dialog panel\n */\n addPanelClass(classes: string | string[]): void {\n this._overlayRef.addPanelClass(classes);\n }\n\n /**\n * Removes CSS classes from the dialog panel\n */\n removePanelClass(classes: string | string[]): void {\n this._overlayRef.removePanelClass(classes);\n }\n\n /**\n * Gets the current state of the dialog's lifecycle\n */\n getState(): FuiDialogState {\n return this._state;\n }\n\n /**\n * Notifies that the dialog has been opened (internal use)\n */\n _notifyOpened(): void {\n this._afterOpened.next();\n this._afterOpened.complete();\n }\n\n private _setupEventHandlers(): void {\n // Handle backdrop clicks\n this._overlayRef.backdropClick.subscribe(() => {\n if (!this.disableClose) {\n this.close();\n }\n });\n\n // Handle escape key\n this._overlayRef.keydownEvents\n .pipe(filter((event) => event.key === 'Escape' && !this.disableClose))\n .subscribe((event) => {\n event.preventDefault();\n this.close();\n });\n }\n\n private _finishDialogClose(): void {\n // Dispose the overlay\n this._overlayRef.dispose();\n\n // Emit after closed event\n this._afterClosed.next(this._result);\n this._afterClosed.complete();\n }\n\n private _parseAnimationDuration(duration: string | number | undefined): number {\n if (duration === undefined) {\n return 200; // Default 200ms\n }\n\n if (typeof duration === 'number') {\n return duration;\n }\n\n // Parse CSS duration string (e.g., '200ms', '0.2s')\n const match = /^(\\d+(?:\\.\\d+)?)(ms|s)$/.exec(duration);\n if (match) {\n const value = parseFloat(match[1]);\n const unit = match[2];\n return unit === 's' ? value * 1000 : value;\n }\n\n return 200;\n }\n\n private _generateId(): string {\n return `fui-dialog-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n","import {\n Component,\n ElementRef,\n ViewChild,\n AfterViewInit,\n OnDestroy,\n inject,\n ChangeDetectionStrategy,\n signal,\n computed,\n HostListener,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { FuiDialogConfig, FuiDialogContainerBase } from './dialog.types';\n\n/**\n * # FuiDialogContainerComponent\n *\n * Internal container component that hosts the dialog content. This component\n * handles focus trapping, animations, and accessibility attributes.\n *\n * ## Features\n * - Focus trapping within the dialog\n * - Configurable ARIA attributes\n * - Enter/exit animations\n * - Focus restoration on close\n */\n@Component({\n selector: 'fui-dialog-container',\n standalone: true,\n imports: [],\n template: `\n <div\n #dialogContainer\n class=\"fui-dialog-container\"\n [class.fui-dialog-enter]=\"animationState() === 'enter'\"\n [class.fui-dialog-exit]=\"animationState() === 'exit'\"\n [attr.role]=\"config.role || 'dialog'\"\n [attr.aria-modal]=\"true\"\n [attr.aria-label]=\"config.ariaLabel\"\n [attr.aria-labelledby]=\"config.ariaLabelledBy\"\n [attr.aria-describedby]=\"config.ariaDescribedBy\"\n tabindex=\"-1\"\n >\n <div class=\"fui-dialog-content\" aria-live=\"polite\">\n <ng-content></ng-content>\n </div>\n </div>\n `,\n styles: [\n `\n :host {\n display: block;\n outline: 0;\n }\n\n .fui-dialog-container {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n overflow: auto;\n outline: 0;\n max-height: inherit;\n border: 1px solid var(--fui-border-color);\n border-radius: var(--fui-border-radius-md);\n background: var(--fui-surface-00);\n box-shadow: var(--fui-dialog-box-shadow, var(--fui-shadow-05));\n }\n\n .fui-dialog-content {\n display: contents;\n }\n\n .fui-dialog-enter {\n animation: fui-dialog-enter var(--fui-duration-moderate-02) var(--fui-ease-entrance);\n }\n\n .fui-dialog-exit {\n animation: fui-dialog-exit var(--fui-duration-moderate-01) var(--fui-ease-exit);\n }\n\n @keyframes fui-dialog-enter {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n @keyframes fui-dialog-exit {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.95);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .fui-dialog-enter,\n .fui-dialog-exit {\n animation: none;\n }\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'fui-dialog-container-host',\n },\n})\nexport class FuiDialogContainerComponent implements FuiDialogContainerBase, AfterViewInit, OnDestroy {\n private readonly _document = inject(DOCUMENT);\n private readonly _elementRef = inject(ElementRef<HTMLElement>);\n\n @ViewChild('dialogContainer', { static: true })\n private _dialogContainer!: ElementRef<HTMLElement>;\n\n /** Configuration for the dialog */\n config!: FuiDialogConfig;\n\n /** The previously focused element before the dialog was opened */\n private _elementFocusedBeforeDialogWasOpened: HTMLElement | null = null;\n\n /** Animation state of the dialog */\n readonly animationState = signal<'void' | 'enter' | 'exit'>('void');\n\n /** Whether the dialog is currently animating */\n readonly isAnimating = computed(() => this.animationState() !== 'void');\n\n ngAfterViewInit(): void {\n this._trapFocus();\n }\n\n ngOnDestroy(): void {\n this._restoreFocus();\n }\n\n /**\n * Handles keydown events for focus trap cycling within the dialog.\n * Tab loops from last to first focusable element, Shift+Tab from first to last.\n */\n @HostListener('keydown', ['$event'])\n _onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Tab') {\n const focusableElements = this._getFocusableElements();\n if (focusableElements.length === 0) {\n event.preventDefault();\n return;\n }\n\n const firstFocusable = focusableElements[0];\n const lastFocusable = focusableElements[focusableElements.length - 1];\n const activeElement = this._document.activeElement;\n\n if (event.shiftKey) {\n // Shift+Tab: if on first element, wrap to last\n if (activeElement === firstFocusable || activeElement === this._dialogContainer.nativeElement) {\n event.preventDefault();\n lastFocusable.focus();\n }\n } else {\n // Tab: if on last element, wrap to first\n if (activeElement === lastFocusable) {\n event.preventDefault();\n firstFocusable.focus();\n }\n }\n }\n }\n\n /**\n * Initializes the dialog container with the given configuration\n */\n _initializeWithConfig(config: FuiDialogConfig): void {\n this.config = config;\n }\n\n /**\n * Starts the enter animation\n */\n _startEnterAnimation(): void {\n this.animationState.set('enter');\n }\n\n /**\n * Starts the exit animation\n */\n _startExitAnimation(): void {\n this.animationState.set('exit');\n }\n\n /**\n * Gets the native element of the container\n */\n _getHostElement(): HTMLElement {\n return this._elementRef.nativeElement;\n }\n\n /**\n * Saves the element that was focused before the dialog opened and traps focus\n */\n private _trapFocus(): void {\n // Store the currently focused element\n this._elementFocusedBeforeDialogWasOpened = this._document.activeElement as HTMLElement;\n\n // Focus the dialog container\n const autoFocus = this.config?.autoFocus ?? 'first-tabbable';\n\n if (autoFocus === false || autoFocus === 'dialog') {\n // Focus the dialog container itself\n this._dialogContainer.nativeElement.focus();\n } else if (autoFocus === 'first-tabbable') {\n this._focusFirstTabbableElement();\n } else if (autoFocus === 'first-heading') {\n this._focusFirstHeading();\n } else if (typeof autoFocus === 'string') {\n // Focus a specific element by selector\n this._focusBySelector(autoFocus);\n } else {\n // Default: focus first tabbable\n this._focusFirstTabbableElement();\n }\n }\n\n /**\n * Focuses the first tabbable element within the dialog\n */\n private _focusFirstTabbableElement(): void {\n const focusableElements = this._getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n } else {\n // Fallback to container\n this._dialogContainer.nativeElement.focus();\n }\n }\n\n /**\n * Focuses the first heading element within the dialog\n */\n private _focusFirstHeading(): void {\n const heading = this._dialogContainer.nativeElement.querySelector<HTMLElement>(\n 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]',\n );\n\n if (heading) {\n // Make heading focusable if it's not already\n if (!heading.hasAttribute('tabindex')) {\n heading.setAttribute('tabindex', '-1');\n }\n heading.focus();\n } else {\n this._focusFirstTabbableElement();\n }\n }\n\n /**\n * Focuses an element matching the given selector\n */\n private _focusBySelector(selector: string): void {\n const element = this._dialogContainer.nativeElement.querySelector<HTMLElement>(selector);\n if (element) {\n element.focus();\n } else {\n this._focusFirstTabbableElement();\n }\n }\n\n /**\n * Gets all focusable elements within the dialog\n */\n private _getFocusableElements(): HTMLElement[] {\n const focusableSelectors = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n ].join(',');\n\n return Array.from(this._dialogContainer.nativeElement.querySelectorAll<HTMLElement>(focusableSelectors)).filter(\n (el) => {\n // Filter out elements that are not visible\n return el.offsetParent !== null;\n },\n );\n }\n\n /**\n * Restores focus to the element that was focused before the dialog opened\n */\n private _restoreFocus(): void {\n const shouldRestoreFocus = this.config?.restoreFocus !== false;\n\n if (shouldRestoreFocus && this._elementFocusedBeforeDialogWasOpened) {\n // Check if the element is still in the DOM and can receive focus\n if (typeof this._elementFocusedBeforeDialogWasOpened.focus === 'function') {\n this._elementFocusedBeforeDialogWasOpened.focus();\n }\n }\n\n this._elementFocusedBeforeDialogWasOpened = null;\n }\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed, inject } from '@angular/core';\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\nimport { FuiButtonDirective } from '@raintonic/formaui/components/button';\nimport { FUI_DIALOG_DATA, FuiConfirmDialogConfig } from './dialog.types';\nimport { FuiDialogRef } from './dialog-ref';\n\n@Component({\n selector: 'fui-confirm-dialog',\n standalone: true,\n imports: [FuiIconComponent, FuiButtonDirective],\n templateUrl: './confirm-dialog.component.html',\n styleUrls: ['./confirm-dialog.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'fui-confirm-dialog' },\n})\nexport class FuiConfirmDialogComponent {\n private readonly data = inject(FUI_DIALOG_DATA) as FuiConfirmDialogConfig;\n private readonly dialogRef = inject(FuiDialogRef);\n\n readonly title = this.data.title;\n readonly message = this.data.message;\n readonly confirmText = this.data.confirmText ?? 'Confirm';\n readonly cancelText = this.data.cancelText ?? 'Cancel';\n readonly variant = this.data.variant ?? 'info';\n\n readonly icon = computed(() => {\n switch (this.variant) {\n case 'warning':\n return 'warning-diamond';\n case 'danger':\n return 'warning-octagon';\n default:\n return 'info';\n }\n });\n\n readonly confirmButtonVariant = computed(() => {\n switch (this.variant) {\n case 'danger':\n return 'danger';\n case 'warning':\n return 'primary';\n default:\n return 'primary';\n }\n });\n\n onConfirm(): void {\n this.dialogRef.close(true);\n }\n\n onCancel(): void {\n this.dialogRef.close(false);\n }\n}\n","<div class=\"fui-confirm-dialog__header\">\n <fui-icon class=\"fui-confirm-dialog__icon fui-confirm-dialog__icon--{{ variant }}\" [name]=\"icon()\" size=\"lg\" />\n <h2 class=\"fui-confirm-dialog__title\" id=\"confirm-dialog-title\">{{ title }}</h2>\n</div>\n\n<div class=\"fui-confirm-dialog__body\" id=\"confirm-dialog-description\">\n <p class=\"fui-confirm-dialog__message\">{{ message }}</p>\n</div>\n\n<div class=\"fui-confirm-dialog__actions\">\n <button fuiButton variant=\"ghost\" (click)=\"onCancel()\">{{ cancelText }}</button>\n <button fuiButton [variant]=\"confirmButtonVariant()\" (click)=\"onConfirm()\">{{ confirmText }}</button>\n</div>\n","import {\n Injectable,\n Injector,\n ComponentRef,\n TemplateRef,\n Type,\n createComponent,\n EnvironmentInjector,\n inject,\n EmbeddedViewRef,\n StaticProvider,\n ApplicationRef,\n} from '@angular/core';\nimport { Observable, Subject, defer } from 'rxjs';\nimport { map, startWith } from 'rxjs/operators';\nimport { FuiOverlayService, FuiOverlayRef, FuiOverlayConfig } from '@raintonic/formaui/cdk/overlay';\nimport { FuiDialogConfig, IFuiDialogRef, FUI_DIALOG_DATA, FuiConfirmDialogConfig } from './dialog.types';\nimport { FuiDialogRef } from './dialog-ref';\nimport { FuiDialogContainerComponent } from './dialog-container.component';\nimport { FuiConfirmDialogComponent } from './confirm-dialog.component';\n\n/**\n * # FuiDialogService\n *\n * Service for opening modal dialogs. This service provides a comprehensive\n * dialog system similar to Angular Material's MatDialog, built on top of\n * the FuiOverlayService.\n *\n * ## Features\n * - Open dialogs with components or templates\n * - Pass data to dialog components\n * - Configure positioning, sizing, and behavior\n * - Get results from dialogs via observables\n * - Manage multiple open dialogs\n * - Automatic focus management and accessibility\n *\n * ## Usage\n *\n * ### Opening a Component Dialog\n * ```typescript\n * const dialogRef = this.dialog.open(MyDialogComponent, {\n * width: '400px',\n * data: { name: 'John' }\n * });\n *\n * dialogRef.afterClosed().subscribe(result => {\n * console.log('Dialog result:', result);\n * });\n * ```\n *\n * ### Opening a Template Dialog\n * ```typescript\n * const dialogRef = this.dialog.open(myTemplateRef, {\n * width: '300px',\n * hasBackdrop: true\n * });\n * ```\n *\n * ### Accessing Data in Dialog Component\n * ```typescript\n * export class MyDialogComponent {\n * private readonly data = inject(FUI_DIALOG_DATA);\n * private readonly dialogRef = inject(FuiDialogRef);\n *\n * onClose() {\n * this.dialogRef.close('result');\n * }\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class FuiDialogService {\n private readonly _overlayService = inject(FuiOverlayService);\n private readonly _environmentInjector = inject(EnvironmentInjector);\n private readonly _injector = inject(Injector);\n private readonly _appRef = inject(ApplicationRef);\n\n private readonly _openDialogs: IFuiDialogRef[] = [];\n private readonly _afterOpenedSubject = new Subject<IFuiDialogRef>();\n private readonly _afterAllClosedSubject = new Subject<void>();\n\n private _nextUniqueId = 0;\n\n /**\n * Observable that emits when a dialog is opened\n */\n readonly afterOpened: Observable<IFuiDialogRef> = this._afterOpenedSubject.asObservable();\n\n /**\n * Observable that emits when all dialogs are closed\n */\n readonly afterAllClosed: Observable<void> = defer(() =>\n this._openDialogs.length ? this._getAfterAllClosed() : this._getAfterAllClosed().pipe(startWith(undefined)),\n );\n\n /**\n * Gets all currently open dialogs\n */\n get openDialogs(): IFuiDialogRef[] {\n return this._openDialogs.slice();\n }\n\n /**\n * Opens a dialog containing the given component or template\n * @param componentOrTemplateRef Component type or TemplateRef to display\n * @param config Configuration options for the dialog\n * @returns Reference to the opened dialog\n */\n open<T, D = unknown, R = unknown>(\n componentOrTemplateRef: Type<T> | TemplateRef<T>,\n config?: FuiDialogConfig<D>,\n ): FuiDialogRef<T, R> {\n const mergedConfig = this._applyConfigDefaults(config);\n const overlayRef = this._createOverlay(mergedConfig);\n const dialogContainer = this._attachDialogContainer(overlayRef, mergedConfig);\n const dialogRef = this._createDialogRef<T, R>(overlayRef, dialogContainer, mergedConfig);\n\n if (componentOrTemplateRef instanceof TemplateRef) {\n this._attachTemplateContent(dialogContainer, componentOrTemplateRef, dialogRef);\n } else {\n const componentRef = this._attachComponentContent<T, R>(\n dialogContainer,\n componentOrTemplateRef,\n dialogRef,\n mergedConfig,\n );\n dialogRef.componentInstance = componentRef.instance;\n }\n\n // Track open dialogs\n this._openDialogs.push(dialogRef);\n\n // Handle dialog close\n dialogRef.afterClosed.subscribe(() => {\n this._removeOpenDialog(dialogRef);\n });\n\n // Start enter animation and notify opened\n dialogContainer._startEnterAnimation();\n\n // Notify that dialog has been opened\n requestAnimationFrame(() => {\n dialogRef._notifyOpened();\n this._afterOpenedSubject.next(dialogRef);\n });\n\n return dialogRef;\n }\n\n /**\n * Closes all open dialogs\n */\n closeAll(): void {\n const dialogs = this._openDialogs.slice();\n dialogs.forEach((dialog) => {\n dialog.close();\n });\n }\n\n /**\n * Gets a dialog by its ID\n * @param id Dialog ID\n * @returns The dialog reference or undefined\n */\n getDialogById(id: string): IFuiDialogRef | undefined {\n return this._openDialogs.find((dialog) => dialog.id === id);\n }\n\n private _createOverlay(config: FuiDialogConfig): FuiOverlayRef {\n const overlayConfig = this._getOverlayConfig(config);\n return this._overlayService.create(overlayConfig);\n }\n\n private _getOverlayConfig(config: FuiDialogConfig): FuiOverlayConfig {\n // Create position strategy\n const positionStrategy = this._overlayService.position().global();\n\n // Apply positioning\n if (config.position?.left || config.position?.right) {\n if (config.position.left) {\n positionStrategy.left(config.position.left);\n } else if (config.position.right) {\n positionStrategy.right(config.position.right);\n }\n } else {\n positionStrategy.centerHorizontally();\n }\n\n if (config.position?.top || config.position?.bottom) {\n if (config.position.top) {\n positionStrategy.top(config.position.top);\n } else if (config.position.bottom) {\n positionStrategy.bottom(config.position.bottom);\n }\n } else {\n positionStrategy.centerVertically();\n }\n\n return {\n positionStrategy,\n scrollStrategy: this._overlayService.scrollStrategies.block(),\n hasBackdrop: config.hasBackdrop ?? true,\n backdropClass: this._getBackdropClass(config),\n backdropClickBehavior: config.disableClose ? 'ignore' : 'close',\n panelClass: this._getPanelClass(config),\n width: config.width,\n height: config.height,\n minWidth: config.minWidth,\n minHeight: config.minHeight,\n maxWidth: config.maxWidth,\n maxHeight: config.maxHeight,\n direction: config.direction,\n };\n }\n\n private _getBackdropClass(config: FuiDialogConfig): string[] {\n const baseClass = 'fui-dialog-backdrop';\n let customClasses: string[] = [];\n if (config.backdropClass) {\n customClasses = Array.isArray(config.backdropClass) ? config.backdropClass : [config.backdropClass];\n }\n\n return [baseClass, ...customClasses];\n }\n\n private _getPanelClass(config: FuiDialogConfig): string[] {\n const baseClass = 'fui-dialog-panel';\n let customPanelClasses: string[] = [];\n if (config.panelClass) {\n customPanelClasses = Array.isArray(config.panelClass) ? config.panelClass : [config.panelClass];\n }\n\n return [baseClass, ...customPanelClasses];\n }\n\n private _attachDialogContainer(overlayRef: FuiOverlayRef, config: FuiDialogConfig): FuiDialogContainerComponent {\n const containerRef = createComponent(FuiDialogContainerComponent, {\n environmentInjector: this._environmentInjector,\n });\n\n // Initialize the container with config\n containerRef.instance._initializeWithConfig(config);\n\n // Trigger change detection\n containerRef.changeDetectorRef.detectChanges();\n\n // Attach to overlay\n overlayRef.attach(containerRef);\n\n return containerRef.instance;\n }\n\n private _createDialogRef<T, R>(\n overlayRef: FuiOverlayRef,\n container: FuiDialogContainerComponent,\n config: FuiDialogConfig,\n ): FuiDialogRef<T, R> {\n const dialogId = config.id ?? `fui-dialog-${this._nextUniqueId++}`;\n return new FuiDialogRef<T, R>(overlayRef, config, dialogId);\n }\n\n private _attachComponentContent<T, R>(\n container: FuiDialogContainerComponent,\n component: Type<T>,\n dialogRef: FuiDialogRef<T, R>,\n config: FuiDialogConfig,\n ): ComponentRef<T> {\n // Create custom injector with dialog data and ref\n const providers: StaticProvider[] = [\n { provide: FUI_DIALOG_DATA, useValue: config.data },\n { provide: FuiDialogRef, useValue: dialogRef },\n ];\n\n const injector = Injector.create({\n parent: config.injector ?? this._injector,\n providers,\n });\n\n // Create the component\n const componentRef = createComponent(component, {\n environmentInjector: this._environmentInjector,\n elementInjector: injector,\n });\n\n // Attach to ApplicationRef to connect it to Angular's change detection tree\n // This is crucial for form controls and event bindings to work properly\n this._appRef.attachView(componentRef.hostView);\n\n // Append to container\n const hostElement = container._getHostElement();\n const containerElement = hostElement.querySelector('.fui-dialog-container');\n if (containerElement) {\n containerElement.appendChild(componentRef.location.nativeElement);\n }\n\n // Trigger change detection\n componentRef.changeDetectorRef.detectChanges();\n\n return componentRef;\n }\n\n private _attachTemplateContent<T, R>(\n container: FuiDialogContainerComponent,\n template: TemplateRef<T>,\n dialogRef: FuiDialogRef<T, R>,\n ): EmbeddedViewRef<T> {\n // Create the embedded view\n const context = { $implicit: dialogRef } as Record<string, unknown>;\n const viewRef = template.createEmbeddedView(context as T);\n\n // Attach to ApplicationRef to connect it to Angular's change detection tree\n this._appRef.attachView(viewRef);\n\n // Append to container\n const hostElement = container._getHostElement();\n const containerElement = hostElement.querySelector('.fui-dialog-container');\n if (containerElement) {\n viewRef.rootNodes.forEach((node) => {\n containerElement.appendChild(node);\n });\n }\n\n // Mark for check\n viewRef.detectChanges();\n\n return viewRef;\n }\n\n private _removeOpenDialog(dialogRef: IFuiDialogRef): void {\n const index = this._openDialogs.indexOf(dialogRef);\n if (index > -1) {\n this._openDialogs.splice(index, 1);\n\n // Emit if all dialogs are closed\n if (this._openDialogs.length === 0) {\n this._afterAllClosedSubject.next();\n }\n }\n }\n\n private _getAfterAllClosed(): Observable<void> {\n return this._afterAllClosedSubject.asObservable();\n }\n\n /**\n * Opens a confirmation dialog and returns an Observable<boolean>.\n * Resolves to `true` when confirmed, `false` when cancelled, ESC, or backdrop click.\n */\n confirm(config: FuiConfirmDialogConfig): Observable<boolean> {\n const dialogRef = this.open(FuiConfirmDialogComponent, {\n width: '28rem',\n maxWidth: '90vw',\n data: config,\n role: config.variant === 'danger' ? 'alertdialog' : 'dialog',\n ariaLabelledBy: 'confirm-dialog-title',\n ariaDescribedBy: 'confirm-dialog-description',\n disableClose: false,\n });\n\n return dialogRef.afterClosed.pipe(map((result) => result === true));\n }\n\n private _applyConfigDefaults(config?: FuiDialogConfig): FuiDialogConfig {\n return {\n role: 'dialog',\n hasBackdrop: true,\n disableClose: false,\n maxWidth: '80vw',\n autoFocus: 'first-tabbable',\n restoreFocus: true,\n closeOnNavigation: true,\n enterAnimationDuration: 200,\n exitAnimationDuration: 150,\n ...config,\n };\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, effect, ViewEncapsulation, ChangeDetectionStrategy, Component, inject, RendererFactory2, EnvironmentInjector, ApplicationRef, createComponent, Injectable } from '@angular/core';
|
|
3
|
+
import { DOCUMENT } from '@angular/common';
|
|
4
|
+
import { Subject } from 'rxjs';
|
|
5
|
+
import { FuiAlertComponent } from '@raintonic/formaui/components/alert';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Reference to a notification instance.
|
|
9
|
+
* Provides control over the notification and observables for lifecycle events.
|
|
10
|
+
*/
|
|
11
|
+
class FuiNotificationRef {
|
|
12
|
+
id;
|
|
13
|
+
config;
|
|
14
|
+
_afterClosed = new Subject();
|
|
15
|
+
_afterDismissed = new Subject();
|
|
16
|
+
/**
|
|
17
|
+
* Observable that emits when the notification is closed
|
|
18
|
+
*/
|
|
19
|
+
afterClosed = this._afterClosed.asObservable();
|
|
20
|
+
/**
|
|
21
|
+
* Observable that emits when the notification is dismissed (after animation)
|
|
22
|
+
*/
|
|
23
|
+
afterDismissed = this._afterDismissed.asObservable();
|
|
24
|
+
constructor(id, config) {
|
|
25
|
+
this.id = id;
|
|
26
|
+
this.config = config;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Close the notification
|
|
30
|
+
*/
|
|
31
|
+
close() {
|
|
32
|
+
this._afterClosed.next();
|
|
33
|
+
this._afterClosed.complete();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Called internally when the notification is fully dismissed
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
_dismiss() {
|
|
40
|
+
this._afterDismissed.next();
|
|
41
|
+
this._afterDismissed.complete();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Container component for displaying stacked notifications.
|
|
47
|
+
* This component is created by the notification service and managed internally.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
class FuiNotificationContainerComponent {
|
|
51
|
+
/**
|
|
52
|
+
* List of active notifications
|
|
53
|
+
*/
|
|
54
|
+
notifications = signal([], ...(ngDevMode ? [{ debugName: "notifications" }] : /* istanbul ignore next */ []));
|
|
55
|
+
/**
|
|
56
|
+
* Progress values for each notification (0-100)
|
|
57
|
+
*/
|
|
58
|
+
progressValues = signal(new Map(), ...(ngDevMode ? [{ debugName: "progressValues" }] : /* istanbul ignore next */ []));
|
|
59
|
+
/**
|
|
60
|
+
* Timers for auto-dismiss
|
|
61
|
+
*/
|
|
62
|
+
timers = new Map();
|
|
63
|
+
constructor() {
|
|
64
|
+
// Set up effect to manage timers when notifications change
|
|
65
|
+
effect(() => {
|
|
66
|
+
this.notifications();
|
|
67
|
+
// This will react to changes in the notifications signal
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Add a notification to the container
|
|
72
|
+
*/
|
|
73
|
+
addNotification(notification) {
|
|
74
|
+
this.notifications.update((notifications) => [...notifications, notification]);
|
|
75
|
+
// Set up auto-dismiss if duration is specified
|
|
76
|
+
const duration = notification.config.duration ?? 5000;
|
|
77
|
+
if (duration > 0) {
|
|
78
|
+
this._setupAutoDismiss(notification, duration);
|
|
79
|
+
}
|
|
80
|
+
// Listen for manual close
|
|
81
|
+
notification.afterClosed.subscribe(() => {
|
|
82
|
+
this._removeNotification(notification);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Remove a notification from the container
|
|
87
|
+
*/
|
|
88
|
+
removeNotification(notificationId) {
|
|
89
|
+
const notification = this.notifications().find((n) => n.id === notificationId);
|
|
90
|
+
if (notification) {
|
|
91
|
+
this._removeNotification(notification);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Handle notification close button click
|
|
96
|
+
*/
|
|
97
|
+
onNotificationClose(notification) {
|
|
98
|
+
notification.close();
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the progress value for a notification
|
|
102
|
+
*/
|
|
103
|
+
getProgress(notificationId) {
|
|
104
|
+
return this.progressValues().get(notificationId) ?? 100;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Check if notification should show progress bar
|
|
108
|
+
*/
|
|
109
|
+
shouldShowProgress(notification) {
|
|
110
|
+
const duration = notification.config.duration ?? 5000;
|
|
111
|
+
return duration > 0;
|
|
112
|
+
}
|
|
113
|
+
_setupAutoDismiss(notification, duration) {
|
|
114
|
+
const startTime = Date.now();
|
|
115
|
+
const updateInterval = 50; // Update progress every 50ms for smooth animation
|
|
116
|
+
// Update progress bar
|
|
117
|
+
const interval = setInterval(() => {
|
|
118
|
+
const elapsed = Date.now() - startTime;
|
|
119
|
+
const progress = Math.max(0, 100 - (elapsed / duration) * 100);
|
|
120
|
+
this.progressValues.update((values) => {
|
|
121
|
+
const newValues = new Map(values);
|
|
122
|
+
newValues.set(notification.id, progress);
|
|
123
|
+
return newValues;
|
|
124
|
+
});
|
|
125
|
+
if (progress <= 0) {
|
|
126
|
+
clearInterval(interval);
|
|
127
|
+
}
|
|
128
|
+
}, updateInterval);
|
|
129
|
+
// Auto-dismiss after duration
|
|
130
|
+
const timeout = setTimeout(() => {
|
|
131
|
+
notification.close();
|
|
132
|
+
}, duration);
|
|
133
|
+
this.timers.set(notification.id, { interval, timeout });
|
|
134
|
+
}
|
|
135
|
+
_removeNotification(notification) {
|
|
136
|
+
// Clear timers
|
|
137
|
+
const timers = this.timers.get(notification.id);
|
|
138
|
+
if (timers) {
|
|
139
|
+
clearInterval(timers.interval);
|
|
140
|
+
clearTimeout(timers.timeout);
|
|
141
|
+
this.timers.delete(notification.id);
|
|
142
|
+
}
|
|
143
|
+
// Remove from progress map
|
|
144
|
+
this.progressValues.update((values) => {
|
|
145
|
+
const newValues = new Map(values);
|
|
146
|
+
newValues.delete(notification.id);
|
|
147
|
+
return newValues;
|
|
148
|
+
});
|
|
149
|
+
// Remove from notifications list
|
|
150
|
+
this.notifications.update((notifications) => notifications.filter((n) => n.id !== notification.id));
|
|
151
|
+
// Notify that notification is dismissed
|
|
152
|
+
notification._dismiss();
|
|
153
|
+
}
|
|
154
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNotificationContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
155
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiNotificationContainerComponent, isStandalone: true, selector: "fui-notification-container", host: { attributes: { "role": "log", "aria-live": "polite", "aria-atomic": "false" }, classAttribute: "fui-notification-container" }, ngImport: i0, template: "<div class=\"fui-notification-container__stack\">\n @for (notification of notifications(); track notification.id) {\n <div class=\"fui-notification-container__item\" role=\"alert\" aria-atomic=\"true\">\n <fui-alert\n [variant]=\"notification.config.variant\"\n [title]=\"notification.config.title\"\n [description]=\"notification.config.description ?? null\"\n [closeable]=\"notification.config.closeable ?? true\"\n [icon]=\"notification.config.icon ?? null\"\n [progress]=\"shouldShowProgress(notification) ? getProgress(notification.id) : -1\"\n (closed)=\"onNotificationClose(notification)\"\n />\n </div>\n }\n</div>\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-notification-container{--fui-notification-bg: transparent;--fui-notification-radius: var(--fui-border-radius-md);--fui-notification-shadow: var(--fui-shadow-03);--fui-notification-shadow-hover: var(--fui-shadow-lg);--fui-notification-z-index: 9999;--fui-notification-padding: var(--fui-spacing-05);--fui-notification-gap: var(--fui-spacing-04);--fui-notification-min-width: 320px;--fui-notification-max-width: 500px;position:fixed;pointer-events:none;z-index:var(--fui-notification-z-index);display:flex;flex-direction:column;padding:var(--fui-notification-padding);gap:var(--fui-notification-gap)}.fui-notification-container__stack{display:flex;flex-direction:column;gap:var(--fui-spacing-04)}.fui-notification-container__item{pointer-events:auto;min-width:var(--fui-notification-min-width);max-width:var(--fui-notification-max-width);background-color:var(--fui-notification-bg);border-radius:var(--fui-notification-radius);box-shadow:var(--fui-notification-shadow);animation:slideIn .3s ease-out;transition:all var(--fui-duration-moderate-01) var(--fui-ease-standard) 0ms}.fui-notification-container__item:hover{transform:translateY(-2px);box-shadow:var(--fui-notification-shadow-hover)}.fui-notification-container__progress{margin-top:calc(-1 * var(--fui-spacing-04));padding:0 var(--fui-spacing-05) var(--fui-spacing-03)}@media(prefers-reduced-motion:reduce){.fui-notification-container .fui-notification-container__item{animation:none;transition:none}.fui-notification-container .fui-notification-container__item:hover{transform:none}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fui-notification-container--top-left{top:0;left:0;align-items:flex-start}.fui-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--top-right{top:0;right:0;align-items:flex-end}.fui-notification-container--bottom-left{bottom:0;left:0;align-items:flex-start}.fui-notification-container--bottom-left .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-left .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--bottom-center .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-center .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-right{bottom:0;right:0;align-items:flex-end}.fui-notification-container--bottom-right .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-right .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}@keyframes slideInFromBottom{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: FuiAlertComponent, selector: "fui-alert", inputs: ["variant", "title", "progress", "description", "closeable", "icon"], outputs: ["closed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
156
|
+
}
|
|
157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNotificationContainerComponent, decorators: [{
|
|
158
|
+
type: Component,
|
|
159
|
+
args: [{ selector: 'fui-notification-container', standalone: true, imports: [FuiAlertComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
160
|
+
class: 'fui-notification-container',
|
|
161
|
+
role: 'log',
|
|
162
|
+
'aria-live': 'polite',
|
|
163
|
+
'aria-atomic': 'false',
|
|
164
|
+
}, template: "<div class=\"fui-notification-container__stack\">\n @for (notification of notifications(); track notification.id) {\n <div class=\"fui-notification-container__item\" role=\"alert\" aria-atomic=\"true\">\n <fui-alert\n [variant]=\"notification.config.variant\"\n [title]=\"notification.config.title\"\n [description]=\"notification.config.description ?? null\"\n [closeable]=\"notification.config.closeable ?? true\"\n [icon]=\"notification.config.icon ?? null\"\n [progress]=\"shouldShowProgress(notification) ? getProgress(notification.id) : -1\"\n (closed)=\"onNotificationClose(notification)\"\n />\n </div>\n }\n</div>\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-notification-container{--fui-notification-bg: transparent;--fui-notification-radius: var(--fui-border-radius-md);--fui-notification-shadow: var(--fui-shadow-03);--fui-notification-shadow-hover: var(--fui-shadow-lg);--fui-notification-z-index: 9999;--fui-notification-padding: var(--fui-spacing-05);--fui-notification-gap: var(--fui-spacing-04);--fui-notification-min-width: 320px;--fui-notification-max-width: 500px;position:fixed;pointer-events:none;z-index:var(--fui-notification-z-index);display:flex;flex-direction:column;padding:var(--fui-notification-padding);gap:var(--fui-notification-gap)}.fui-notification-container__stack{display:flex;flex-direction:column;gap:var(--fui-spacing-04)}.fui-notification-container__item{pointer-events:auto;min-width:var(--fui-notification-min-width);max-width:var(--fui-notification-max-width);background-color:var(--fui-notification-bg);border-radius:var(--fui-notification-radius);box-shadow:var(--fui-notification-shadow);animation:slideIn .3s ease-out;transition:all var(--fui-duration-moderate-01) var(--fui-ease-standard) 0ms}.fui-notification-container__item:hover{transform:translateY(-2px);box-shadow:var(--fui-notification-shadow-hover)}.fui-notification-container__progress{margin-top:calc(-1 * var(--fui-spacing-04));padding:0 var(--fui-spacing-05) var(--fui-spacing-03)}@media(prefers-reduced-motion:reduce){.fui-notification-container .fui-notification-container__item{animation:none;transition:none}.fui-notification-container .fui-notification-container__item:hover{transform:none}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fui-notification-container--top-left{top:0;left:0;align-items:flex-start}.fui-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--top-right{top:0;right:0;align-items:flex-end}.fui-notification-container--bottom-left{bottom:0;left:0;align-items:flex-start}.fui-notification-container--bottom-left .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-left .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--bottom-center .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-center .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-right{bottom:0;right:0;align-items:flex-end}.fui-notification-container--bottom-right .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-right .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}@keyframes slideInFromBottom{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
165
|
+
}], ctorParameters: () => [] });
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* # FuiNotificationService
|
|
169
|
+
*
|
|
170
|
+
* Service for displaying toast-style notifications using overlays.
|
|
171
|
+
* Notifications can be displayed at various positions on the screen and will
|
|
172
|
+
* auto-dismiss after a configurable duration with a visual countdown.
|
|
173
|
+
*
|
|
174
|
+
* ## Features
|
|
175
|
+
* - Multiple notification variants (success, info, warning, error, primary, generic)
|
|
176
|
+
* - Configurable positioning (top-left, top-center, top-right, bottom-left, bottom-center, bottom-right)
|
|
177
|
+
* - Auto-dismiss with progress bar countdown
|
|
178
|
+
* - Manual dismiss via close button
|
|
179
|
+
* - Stack multiple notifications
|
|
180
|
+
* - Convenient shorthand methods for common variants
|
|
181
|
+
*
|
|
182
|
+
* ## Usage
|
|
183
|
+
*
|
|
184
|
+
* ### Success Notification
|
|
185
|
+
* ```typescript
|
|
186
|
+
* this.notificationService.success('Changes saved successfully!');
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* ### Error Notification with Description
|
|
190
|
+
* ```typescript
|
|
191
|
+
* this.notificationService.error('Failed to save', {
|
|
192
|
+
* description: 'Please check your connection and try again.'
|
|
193
|
+
* });
|
|
194
|
+
* ```
|
|
195
|
+
*
|
|
196
|
+
* ### Custom Duration and Position
|
|
197
|
+
* ```typescript
|
|
198
|
+
* this.notificationService.info('New message received', {
|
|
199
|
+
* description: 'Click to view',
|
|
200
|
+
* duration: 10000,
|
|
201
|
+
* position: 'bottom-right'
|
|
202
|
+
* });
|
|
203
|
+
* ```
|
|
204
|
+
*
|
|
205
|
+
* ### No Auto-Dismiss
|
|
206
|
+
* ```typescript
|
|
207
|
+
* this.notificationService.warning('Important notice', {
|
|
208
|
+
* duration: 0, // Won't auto-dismiss
|
|
209
|
+
* closeable: true
|
|
210
|
+
* });
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* ### Full Configuration
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const ref = this.notificationService.show({
|
|
216
|
+
* variant: 'success',
|
|
217
|
+
* title: 'Success!',
|
|
218
|
+
* description: 'Your operation completed successfully.',
|
|
219
|
+
* duration: 5000,
|
|
220
|
+
* closeable: true,
|
|
221
|
+
* icon: 'custom-icon',
|
|
222
|
+
* position: 'top-center'
|
|
223
|
+
* });
|
|
224
|
+
*
|
|
225
|
+
* // Programmatically close
|
|
226
|
+
* ref.close();
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
class FuiNotificationService {
|
|
230
|
+
_document = inject(DOCUMENT);
|
|
231
|
+
_rendererFactory = inject(RendererFactory2);
|
|
232
|
+
_environmentInjector = inject(EnvironmentInjector);
|
|
233
|
+
_applicationRef = inject(ApplicationRef);
|
|
234
|
+
_renderer;
|
|
235
|
+
/**
|
|
236
|
+
* Map of container components by position
|
|
237
|
+
*/
|
|
238
|
+
_containers = new Map();
|
|
239
|
+
/**
|
|
240
|
+
* Default position for notifications
|
|
241
|
+
*/
|
|
242
|
+
_defaultPosition = 'bottom-right';
|
|
243
|
+
/**
|
|
244
|
+
* Next unique notification ID
|
|
245
|
+
*/
|
|
246
|
+
_nextId = 0;
|
|
247
|
+
constructor() {
|
|
248
|
+
this._renderer = this._rendererFactory.createRenderer(null, null);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Set the default position for notifications
|
|
252
|
+
*/
|
|
253
|
+
setDefaultPosition(position) {
|
|
254
|
+
this._defaultPosition = position;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Show a success notification
|
|
258
|
+
*/
|
|
259
|
+
success(title, options) {
|
|
260
|
+
return this.show({
|
|
261
|
+
variant: 'success',
|
|
262
|
+
title,
|
|
263
|
+
...options,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Show an info notification
|
|
268
|
+
*/
|
|
269
|
+
info(title, options) {
|
|
270
|
+
return this.show({
|
|
271
|
+
variant: 'info',
|
|
272
|
+
title,
|
|
273
|
+
...options,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Show a warning notification
|
|
278
|
+
*/
|
|
279
|
+
warning(title, options) {
|
|
280
|
+
return this.show({
|
|
281
|
+
variant: 'warning',
|
|
282
|
+
title,
|
|
283
|
+
...options,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Show an error notification
|
|
288
|
+
*/
|
|
289
|
+
error(title, options) {
|
|
290
|
+
return this.show({
|
|
291
|
+
variant: 'error',
|
|
292
|
+
title,
|
|
293
|
+
...options,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Show a primary notification
|
|
298
|
+
*/
|
|
299
|
+
primary(title, options) {
|
|
300
|
+
return this.show({
|
|
301
|
+
variant: 'primary',
|
|
302
|
+
title,
|
|
303
|
+
...options,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Show a generic notification
|
|
308
|
+
*/
|
|
309
|
+
generic(title, options) {
|
|
310
|
+
return this.show({
|
|
311
|
+
variant: 'generic',
|
|
312
|
+
title,
|
|
313
|
+
...options,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Show a notification with full configuration
|
|
318
|
+
*/
|
|
319
|
+
show(config) {
|
|
320
|
+
const position = config.position ?? this._defaultPosition;
|
|
321
|
+
const container = this._getOrCreateContainer(position);
|
|
322
|
+
// Create notification reference
|
|
323
|
+
const notificationId = `fui-notification-${this._nextId++}`;
|
|
324
|
+
const notificationRef = new FuiNotificationRef(notificationId, config);
|
|
325
|
+
// Add to container
|
|
326
|
+
container.instance.addNotification(notificationRef);
|
|
327
|
+
return notificationRef;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Clear all notifications at a specific position
|
|
331
|
+
*/
|
|
332
|
+
clearPosition(position) {
|
|
333
|
+
const container = this._containers.get(position);
|
|
334
|
+
if (container) {
|
|
335
|
+
// Clear all notifications
|
|
336
|
+
const notifications = container.instance.notifications();
|
|
337
|
+
notifications.forEach((notification) => {
|
|
338
|
+
container.instance.removeNotification(notification.id);
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Clear all notifications
|
|
344
|
+
*/
|
|
345
|
+
clearAll() {
|
|
346
|
+
this._containers.forEach((container) => {
|
|
347
|
+
const notifications = container.instance.notifications();
|
|
348
|
+
notifications.forEach((notification) => {
|
|
349
|
+
container.instance.removeNotification(notification.id);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
_getOrCreateContainer(position) {
|
|
354
|
+
let container = this._containers.get(position);
|
|
355
|
+
if (!container) {
|
|
356
|
+
container = this._createContainer(position);
|
|
357
|
+
this._containers.set(position, container);
|
|
358
|
+
}
|
|
359
|
+
return container;
|
|
360
|
+
}
|
|
361
|
+
_createContainer(position) {
|
|
362
|
+
// Create the container component
|
|
363
|
+
const containerRef = createComponent(FuiNotificationContainerComponent, {
|
|
364
|
+
environmentInjector: this._environmentInjector,
|
|
365
|
+
});
|
|
366
|
+
// Add position class
|
|
367
|
+
const positionClass = `fui-notification-container--${position}`;
|
|
368
|
+
this._renderer.addClass(containerRef.location.nativeElement, positionClass);
|
|
369
|
+
// Attach to the application
|
|
370
|
+
this._applicationRef.attachView(containerRef.hostView);
|
|
371
|
+
// Append to document body
|
|
372
|
+
const containerElement = containerRef.location.nativeElement;
|
|
373
|
+
this._renderer.appendChild(this._document.body, containerElement);
|
|
374
|
+
return containerRef;
|
|
375
|
+
}
|
|
376
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
377
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNotificationService, providedIn: 'root' });
|
|
378
|
+
}
|
|
379
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNotificationService, decorators: [{
|
|
380
|
+
type: Injectable,
|
|
381
|
+
args: [{
|
|
382
|
+
providedIn: 'root',
|
|
383
|
+
}]
|
|
384
|
+
}], ctorParameters: () => [] });
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Generated bundle index. Do not edit.
|
|
388
|
+
*/
|
|
389
|
+
|
|
390
|
+
export { FuiNotificationContainerComponent, FuiNotificationRef, FuiNotificationService };
|
|
391
|
+
//# sourceMappingURL=raintonic-formaui-services-notification.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raintonic-formaui-services-notification.mjs","sources":["../../../lib/services/notification/notification-ref.ts","../../../lib/services/notification/notification-container.component.ts","../../../lib/services/notification/notification-container.component.html","../../../lib/services/notification/notification.service.ts","../../../lib/services/notification/raintonic-formaui-services-notification.ts"],"sourcesContent":["import { Observable, Subject } from 'rxjs';\nimport { FuiNotificationConfig } from '@raintonic/formaui/components/alert';\n\n/**\n * Reference to a notification instance.\n * Provides control over the notification and observables for lifecycle events.\n */\nexport class FuiNotificationRef {\n private readonly _afterClosed = new Subject<void>();\n private readonly _afterDismissed = new Subject<void>();\n\n /**\n * Observable that emits when the notification is closed\n */\n readonly afterClosed: Observable<void> = this._afterClosed.asObservable();\n\n /**\n * Observable that emits when the notification is dismissed (after animation)\n */\n readonly afterDismissed: Observable<void> = this._afterDismissed.asObservable();\n\n constructor(\n public readonly id: string,\n public readonly config: FuiNotificationConfig,\n ) {}\n\n /**\n * Close the notification\n */\n close(): void {\n this._afterClosed.next();\n this._afterClosed.complete();\n }\n\n /**\n * Called internally when the notification is fully dismissed\n * @internal\n */\n _dismiss(): void {\n this._afterDismissed.next();\n this._afterDismissed.complete();\n }\n}\n","import { ChangeDetectionStrategy, Component, effect, signal, ViewEncapsulation } from '@angular/core';\nimport { FuiAlertComponent } from '@raintonic/formaui/components/alert';\nimport { FuiNotificationRef } from './notification-ref';\n\n/**\n * Container component for displaying stacked notifications.\n * This component is created by the notification service and managed internally.\n * @internal\n */\n@Component({\n selector: 'fui-notification-container',\n standalone: true,\n imports: [FuiAlertComponent],\n templateUrl: './notification-container.component.html',\n styleUrls: ['./notification-container.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'fui-notification-container',\n role: 'log',\n 'aria-live': 'polite',\n 'aria-atomic': 'false',\n },\n})\nexport class FuiNotificationContainerComponent {\n /**\n * List of active notifications\n */\n readonly notifications = signal<FuiNotificationRef[]>([]);\n\n /**\n * Progress values for each notification (0-100)\n */\n readonly progressValues = signal(new Map());\n\n /**\n * Timers for auto-dismiss\n */\n private readonly timers = new Map<\n string,\n { interval: ReturnType<typeof setInterval>; timeout: ReturnType<typeof setTimeout> }\n >();\n\n constructor() {\n // Set up effect to manage timers when notifications change\n effect(() => {\n this.notifications();\n // This will react to changes in the notifications signal\n });\n }\n\n /**\n * Add a notification to the container\n */\n addNotification(notification: FuiNotificationRef): void {\n this.notifications.update((notifications) => [...notifications, notification]);\n\n // Set up auto-dismiss if duration is specified\n const duration = notification.config.duration ?? 5000;\n if (duration > 0) {\n this._setupAutoDismiss(notification, duration);\n }\n\n // Listen for manual close\n notification.afterClosed.subscribe(() => {\n this._removeNotification(notification);\n });\n }\n\n /**\n * Remove a notification from the container\n */\n removeNotification(notificationId: string): void {\n const notification = this.notifications().find((n) => n.id === notificationId);\n if (notification) {\n this._removeNotification(notification);\n }\n }\n\n /**\n * Handle notification close button click\n */\n onNotificationClose(notification: FuiNotificationRef): void {\n notification.close();\n }\n\n /**\n * Get the progress value for a notification\n */\n getProgress(notificationId: string): number {\n return this.progressValues().get(notificationId) ?? 100;\n }\n\n /**\n * Check if notification should show progress bar\n */\n shouldShowProgress(notification: FuiNotificationRef): boolean {\n const duration = notification.config.duration ?? 5000;\n return duration > 0;\n }\n\n private _setupAutoDismiss(notification: FuiNotificationRef, duration: number): void {\n const startTime = Date.now();\n const updateInterval = 50; // Update progress every 50ms for smooth animation\n\n // Update progress bar\n const interval = setInterval(() => {\n const elapsed = Date.now() - startTime;\n const progress = Math.max(0, 100 - (elapsed / duration) * 100);\n\n this.progressValues.update((values) => {\n const newValues = new Map(values);\n newValues.set(notification.id, progress);\n return newValues;\n });\n\n if (progress <= 0) {\n clearInterval(interval);\n }\n }, updateInterval);\n\n // Auto-dismiss after duration\n const timeout = setTimeout(() => {\n notification.close();\n }, duration);\n\n this.timers.set(notification.id, { interval, timeout });\n }\n\n private _removeNotification(notification: FuiNotificationRef): void {\n // Clear timers\n const timers = this.timers.get(notification.id);\n if (timers) {\n clearInterval(timers.interval);\n clearTimeout(timers.timeout);\n this.timers.delete(notification.id);\n }\n\n // Remove from progress map\n this.progressValues.update((values) => {\n const newValues = new Map(values);\n newValues.delete(notification.id);\n return newValues;\n });\n\n // Remove from notifications list\n this.notifications.update((notifications) => notifications.filter((n) => n.id !== notification.id));\n\n // Notify that notification is dismissed\n notification._dismiss();\n }\n}\n","<div class=\"fui-notification-container__stack\">\n @for (notification of notifications(); track notification.id) {\n <div class=\"fui-notification-container__item\" role=\"alert\" aria-atomic=\"true\">\n <fui-alert\n [variant]=\"notification.config.variant\"\n [title]=\"notification.config.title\"\n [description]=\"notification.config.description ?? null\"\n [closeable]=\"notification.config.closeable ?? true\"\n [icon]=\"notification.config.icon ?? null\"\n [progress]=\"shouldShowProgress(notification) ? getProgress(notification.id) : -1\"\n (closed)=\"onNotificationClose(notification)\"\n />\n </div>\n }\n</div>\n","import {\n Injectable,\n Renderer2,\n RendererFactory2,\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n inject,\n ApplicationRef,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { FuiNotificationConfig, FuiNotificationPosition } from '@raintonic/formaui/components/alert';\nimport { FuiNotificationRef } from './notification-ref';\nimport { FuiNotificationContainerComponent } from './notification-container.component';\n\n/**\n * # FuiNotificationService\n *\n * Service for displaying toast-style notifications using overlays.\n * Notifications can be displayed at various positions on the screen and will\n * auto-dismiss after a configurable duration with a visual countdown.\n *\n * ## Features\n * - Multiple notification variants (success, info, warning, error, primary, generic)\n * - Configurable positioning (top-left, top-center, top-right, bottom-left, bottom-center, bottom-right)\n * - Auto-dismiss with progress bar countdown\n * - Manual dismiss via close button\n * - Stack multiple notifications\n * - Convenient shorthand methods for common variants\n *\n * ## Usage\n *\n * ### Success Notification\n * ```typescript\n * this.notificationService.success('Changes saved successfully!');\n * ```\n *\n * ### Error Notification with Description\n * ```typescript\n * this.notificationService.error('Failed to save', {\n * description: 'Please check your connection and try again.'\n * });\n * ```\n *\n * ### Custom Duration and Position\n * ```typescript\n * this.notificationService.info('New message received', {\n * description: 'Click to view',\n * duration: 10000,\n * position: 'bottom-right'\n * });\n * ```\n *\n * ### No Auto-Dismiss\n * ```typescript\n * this.notificationService.warning('Important notice', {\n * duration: 0, // Won't auto-dismiss\n * closeable: true\n * });\n * ```\n *\n * ### Full Configuration\n * ```typescript\n * const ref = this.notificationService.show({\n * variant: 'success',\n * title: 'Success!',\n * description: 'Your operation completed successfully.',\n * duration: 5000,\n * closeable: true,\n * icon: 'custom-icon',\n * position: 'top-center'\n * });\n *\n * // Programmatically close\n * ref.close();\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class FuiNotificationService {\n private readonly _document = inject(DOCUMENT);\n private readonly _rendererFactory = inject(RendererFactory2);\n private readonly _environmentInjector = inject(EnvironmentInjector);\n private readonly _applicationRef = inject(ApplicationRef);\n private readonly _renderer: Renderer2;\n\n /**\n * Map of container components by position\n */\n private readonly _containers = new Map<FuiNotificationPosition, ComponentRef<FuiNotificationContainerComponent>>();\n\n /**\n * Default position for notifications\n */\n private _defaultPosition: FuiNotificationPosition = 'bottom-right';\n\n /**\n * Next unique notification ID\n */\n private _nextId = 0;\n\n constructor() {\n this._renderer = this._rendererFactory.createRenderer(null, null);\n }\n\n /**\n * Set the default position for notifications\n */\n setDefaultPosition(position: FuiNotificationPosition): void {\n this._defaultPosition = position;\n }\n\n /**\n * Show a success notification\n */\n success(\n title: string,\n options?: Partial<Omit<FuiNotificationConfig, 'variant' | 'title'>> & {\n position?: FuiNotificationPosition;\n },\n ): FuiNotificationRef {\n return this.show({\n variant: 'success',\n title,\n ...options,\n });\n }\n\n /**\n * Show an info notification\n */\n info(\n title: string,\n options?: Partial<Omit<FuiNotificationConfig, 'variant' | 'title'>> & {\n position?: FuiNotificationPosition;\n },\n ): FuiNotificationRef {\n return this.show({\n variant: 'info',\n title,\n ...options,\n });\n }\n\n /**\n * Show a warning notification\n */\n warning(\n title: string,\n options?: Partial<Omit<FuiNotificationConfig, 'variant' | 'title'>> & {\n position?: FuiNotificationPosition;\n },\n ): FuiNotificationRef {\n return this.show({\n variant: 'warning',\n title,\n ...options,\n });\n }\n\n /**\n * Show an error notification\n */\n error(\n title: string,\n options?: Partial<Omit<FuiNotificationConfig, 'variant' | 'title'>> & {\n position?: FuiNotificationPosition;\n },\n ): FuiNotificationRef {\n return this.show({\n variant: 'error',\n title,\n ...options,\n });\n }\n\n /**\n * Show a primary notification\n */\n primary(\n title: string,\n options?: Partial<Omit<FuiNotificationConfig, 'variant' | 'title'>> & {\n position?: FuiNotificationPosition;\n },\n ): FuiNotificationRef {\n return this.show({\n variant: 'primary',\n title,\n ...options,\n });\n }\n\n /**\n * Show a generic notification\n */\n generic(\n title: string,\n options?: Partial<Omit<FuiNotificationConfig, 'variant' | 'title'>> & {\n position?: FuiNotificationPosition;\n },\n ): FuiNotificationRef {\n return this.show({\n variant: 'generic',\n title,\n ...options,\n });\n }\n\n /**\n * Show a notification with full configuration\n */\n show(config: FuiNotificationConfig & { position?: FuiNotificationPosition }): FuiNotificationRef {\n const position = config.position ?? this._defaultPosition;\n const container = this._getOrCreateContainer(position);\n\n // Create notification reference\n const notificationId = `fui-notification-${this._nextId++}`;\n const notificationRef = new FuiNotificationRef(notificationId, config);\n\n // Add to container\n container.instance.addNotification(notificationRef);\n\n return notificationRef;\n }\n\n /**\n * Clear all notifications at a specific position\n */\n clearPosition(position: FuiNotificationPosition): void {\n const container = this._containers.get(position);\n if (container) {\n // Clear all notifications\n const notifications = container.instance.notifications();\n notifications.forEach((notification) => {\n container.instance.removeNotification(notification.id);\n });\n }\n }\n\n /**\n * Clear all notifications\n */\n clearAll(): void {\n this._containers.forEach((container) => {\n const notifications = container.instance.notifications();\n notifications.forEach((notification) => {\n container.instance.removeNotification(notification.id);\n });\n });\n }\n\n private _getOrCreateContainer(position: FuiNotificationPosition): ComponentRef<FuiNotificationContainerComponent> {\n let container = this._containers.get(position);\n\n if (!container) {\n container = this._createContainer(position);\n this._containers.set(position, container);\n }\n\n return container;\n }\n\n private _createContainer(position: FuiNotificationPosition): ComponentRef<FuiNotificationContainerComponent> {\n // Create the container component\n const containerRef = createComponent(FuiNotificationContainerComponent, {\n environmentInjector: this._environmentInjector,\n });\n\n // Add position class\n const positionClass = `fui-notification-container--${position}`;\n this._renderer.addClass(containerRef.location.nativeElement, positionClass);\n\n // Attach to the application\n this._applicationRef.attachView(containerRef.hostView);\n\n // Append to document body\n const containerElement = containerRef.location.nativeElement;\n this._renderer.appendChild(this._document.body, containerElement);\n\n return containerRef;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAGA;;;AAGG;MACU,kBAAkB,CAAA;AAeX,IAAA,EAAA;AACA,IAAA,MAAA;AAfD,IAAA,YAAY,GAAG,IAAI,OAAO,EAAQ;AAClC,IAAA,eAAe,GAAG,IAAI,OAAO,EAAQ;AAEtD;;AAEG;AACM,IAAA,WAAW,GAAqB,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE;AAEzE;;AAEG;AACM,IAAA,cAAc,GAAqB,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE;IAE/E,WAAA,CACkB,EAAU,EACV,MAA6B,EAAA;QAD7B,IAAA,CAAA,EAAE,GAAF,EAAE;QACF,IAAA,CAAA,MAAM,GAAN,MAAM;IACrB;AAEH;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;AACxB,QAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;IAC9B;AAEA;;;AAGG;IACH,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE;AAC3B,QAAA,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE;IACjC;AACD;;ACtCD;;;;AAIG;MAgBU,iCAAiC,CAAA;AAC5C;;AAEG;AACM,IAAA,aAAa,GAAG,MAAM,CAAuB,EAAE,oFAAC;AAEzD;;AAEG;AACM,IAAA,cAAc,GAAG,MAAM,CAAC,IAAI,GAAG,EAAE,qFAAC;AAE3C;;AAEG;AACc,IAAA,MAAM,GAAG,IAAI,GAAG,EAG9B;AAEH,IAAA,WAAA,GAAA;;QAEE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,aAAa,EAAE;;AAEtB,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;AACH,IAAA,eAAe,CAAC,YAAgC,EAAA;AAC9C,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,aAAa,KAAK,CAAC,GAAG,aAAa,EAAE,YAAY,CAAC,CAAC;;QAG9E,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI;AACrD,QAAA,IAAI,QAAQ,GAAG,CAAC,EAAE;AAChB,YAAA,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,QAAQ,CAAC;QAChD;;AAGA,QAAA,YAAY,CAAC,WAAW,CAAC,SAAS,CAAC,MAAK;AACtC,YAAA,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC;AACxC,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;AACH,IAAA,kBAAkB,CAAC,cAAsB,EAAA;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC;QAC9E,IAAI,YAAY,EAAE;AAChB,YAAA,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC;QACxC;IACF;AAEA;;AAEG;AACH,IAAA,mBAAmB,CAAC,YAAgC,EAAA;QAClD,YAAY,CAAC,KAAK,EAAE;IACtB;AAEA;;AAEG;AACH,IAAA,WAAW,CAAC,cAAsB,EAAA;QAChC,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG;IACzD;AAEA;;AAEG;AACH,IAAA,kBAAkB,CAAC,YAAgC,EAAA;QACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI;QACrD,OAAO,QAAQ,GAAG,CAAC;IACrB;IAEQ,iBAAiB,CAAC,YAAgC,EAAE,QAAgB,EAAA;AAC1E,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;AAC5B,QAAA,MAAM,cAAc,GAAG,EAAE,CAAC;;AAG1B,QAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAK;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;AACtC,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,GAAG,QAAQ,IAAI,GAAG,CAAC;YAE9D,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AACpC,gBAAA,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;gBACjC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC;AACxC,gBAAA,OAAO,SAAS;AAClB,YAAA,CAAC,CAAC;AAEF,YAAA,IAAI,QAAQ,IAAI,CAAC,EAAE;gBACjB,aAAa,CAAC,QAAQ,CAAC;YACzB;QACF,CAAC,EAAE,cAAc,CAAC;;AAGlB,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,MAAK;YAC9B,YAAY,CAAC,KAAK,EAAE;QACtB,CAAC,EAAE,QAAQ,CAAC;AAEZ,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACzD;AAEQ,IAAA,mBAAmB,CAAC,YAAgC,EAAA;;AAE1D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/C,IAAI,MAAM,EAAE;AACV,YAAA,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC9B,YAAA,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QACrC;;QAGA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AACpC,YAAA,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AACjC,YAAA,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;AACjC,YAAA,OAAO,SAAS;AAClB,QAAA,CAAC,CAAC;;AAGF,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,aAAa,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,EAAE,CAAC,CAAC;;QAGnG,YAAY,CAAC,QAAQ,EAAE;IACzB;uGA9HW,iCAAiC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjC,iCAAiC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,KAAA,EAAA,WAAA,EAAA,QAAA,EAAA,aAAA,EAAA,OAAA,EAAA,EAAA,cAAA,EAAA,4BAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECxB9C,qrBAeA,EAAA,MAAA,EAAA,CAAA,o7IAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDHY,iBAAiB,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,UAAA,EAAA,aAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAYhB,iCAAiC,EAAA,UAAA,EAAA,CAAA;kBAf7C,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,4BAA4B,EAAA,UAAA,EAC1B,IAAI,EAAA,OAAA,EACP,CAAC,iBAAiB,CAAC,EAAA,eAAA,EAGX,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACJ,wBAAA,KAAK,EAAE,4BAA4B;AACnC,wBAAA,IAAI,EAAE,KAAK;AACX,wBAAA,WAAW,EAAE,QAAQ;AACrB,wBAAA,aAAa,EAAE,OAAO;AACvB,qBAAA,EAAA,QAAA,EAAA,qrBAAA,EAAA,MAAA,EAAA,CAAA,o7IAAA,CAAA,EAAA;;;AEPH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DG;MAIU,sBAAsB,CAAA;AAChB,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC5B,IAAA,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC3C,IAAA,oBAAoB,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAClD,IAAA,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC;AACxC,IAAA,SAAS;AAE1B;;AAEG;AACc,IAAA,WAAW,GAAG,IAAI,GAAG,EAA4E;AAElH;;AAEG;IACK,gBAAgB,GAA4B,cAAc;AAElE;;AAEG;IACK,OAAO,GAAG,CAAC;AAEnB,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC;IACnE;AAEA;;AAEG;AACH,IAAA,kBAAkB,CAAC,QAAiC,EAAA;AAClD,QAAA,IAAI,CAAC,gBAAgB,GAAG,QAAQ;IAClC;AAEA;;AAEG;IACH,OAAO,CACL,KAAa,EACb,OAEC,EAAA;QAED,OAAO,IAAI,CAAC,IAAI,CAAC;AACf,YAAA,OAAO,EAAE,SAAS;YAClB,KAAK;AACL,YAAA,GAAG,OAAO;AACX,SAAA,CAAC;IACJ;AAEA;;AAEG;IACH,IAAI,CACF,KAAa,EACb,OAEC,EAAA;QAED,OAAO,IAAI,CAAC,IAAI,CAAC;AACf,YAAA,OAAO,EAAE,MAAM;YACf,KAAK;AACL,YAAA,GAAG,OAAO;AACX,SAAA,CAAC;IACJ;AAEA;;AAEG;IACH,OAAO,CACL,KAAa,EACb,OAEC,EAAA;QAED,OAAO,IAAI,CAAC,IAAI,CAAC;AACf,YAAA,OAAO,EAAE,SAAS;YAClB,KAAK;AACL,YAAA,GAAG,OAAO;AACX,SAAA,CAAC;IACJ;AAEA;;AAEG;IACH,KAAK,CACH,KAAa,EACb,OAEC,EAAA;QAED,OAAO,IAAI,CAAC,IAAI,CAAC;AACf,YAAA,OAAO,EAAE,OAAO;YAChB,KAAK;AACL,YAAA,GAAG,OAAO;AACX,SAAA,CAAC;IACJ;AAEA;;AAEG;IACH,OAAO,CACL,KAAa,EACb,OAEC,EAAA;QAED,OAAO,IAAI,CAAC,IAAI,CAAC;AACf,YAAA,OAAO,EAAE,SAAS;YAClB,KAAK;AACL,YAAA,GAAG,OAAO;AACX,SAAA,CAAC;IACJ;AAEA;;AAEG;IACH,OAAO,CACL,KAAa,EACb,OAEC,EAAA;QAED,OAAO,IAAI,CAAC,IAAI,CAAC;AACf,YAAA,OAAO,EAAE,SAAS;YAClB,KAAK;AACL,YAAA,GAAG,OAAO;AACX,SAAA,CAAC;IACJ;AAEA;;AAEG;AACH,IAAA,IAAI,CAAC,MAAsE,EAAA;QACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC;;QAGtD,MAAM,cAAc,GAAG,CAAA,iBAAA,EAAoB,IAAI,CAAC,OAAO,EAAE,EAAE;QAC3D,MAAM,eAAe,GAAG,IAAI,kBAAkB,CAAC,cAAc,EAAE,MAAM,CAAC;;AAGtE,QAAA,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,eAAe,CAAC;AAEnD,QAAA,OAAO,eAAe;IACxB;AAEA;;AAEG;AACH,IAAA,aAAa,CAAC,QAAiC,EAAA;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;QAChD,IAAI,SAAS,EAAE;;YAEb,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE;AACxD,YAAA,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,KAAI;gBACrC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;AACxD,YAAA,CAAC,CAAC;QACJ;IACF;AAEA;;AAEG;IACH,QAAQ,GAAA;QACN,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,KAAI;YACrC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE;AACxD,YAAA,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,KAAI;gBACrC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;AACxD,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,qBAAqB,CAAC,QAAiC,EAAA;QAC7D,IAAI,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;QAE9C,IAAI,CAAC,SAAS,EAAE;AACd,YAAA,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;YAC3C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC;QAC3C;AAEA,QAAA,OAAO,SAAS;IAClB;AAEQ,IAAA,gBAAgB,CAAC,QAAiC,EAAA;;AAExD,QAAA,MAAM,YAAY,GAAG,eAAe,CAAC,iCAAiC,EAAE;YACtE,mBAAmB,EAAE,IAAI,CAAC,oBAAoB;AAC/C,SAAA,CAAC;;AAGF,QAAA,MAAM,aAAa,GAAG,CAAA,4BAAA,EAA+B,QAAQ,EAAE;AAC/D,QAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;;QAG3E,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC;;AAGtD,QAAA,MAAM,gBAAgB,GAAG,YAAY,CAAC,QAAQ,CAAC,aAAa;AAC5D,QAAA,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,gBAAgB,CAAC;AAEjE,QAAA,OAAO,YAAY;IACrB;uGAzMW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,sBAAsB,cAFrB,MAAM,EAAA,CAAA;;2FAEP,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAHlC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;AC/ED;;AAEG;;;;"}
|