@frame-kit/ui-ng 0.0.2 → 0.0.4
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/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +6 -32
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +72 -91
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +56 -82
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +10 -3
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng.mjs +0 -1
- package/fesm2022/frame-kit-ui-ng.mjs.map +1 -1
- package/package.json +1 -5
- package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +5 -8
- package/types/frame-kit-ui-ng-ui-dialog.d.ts +25 -24
- package/types/frame-kit-ui-ng-ui-drawer.d.ts +20 -14
- package/types/frame-kit-ui-ng-ui-nav-group.d.ts +8 -1
- package/types/frame-kit-ui-ng.d.ts +0 -1
- package/ui/dialog/README.md +0 -4
- package/ui/drawer/README.md +0 -4
- package/ui/nav-group/README.md +25 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +0 -133
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +0 -1
- package/services/overlay-orchestrator/README.md +0 -184
- package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +0 -96
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input,
|
|
3
|
+
import { input, signal, computed, inject, DestroyRef, afterNextRender, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
-
import { OverlayOrchestrator, OVERLAY_PRIORITY } from '@frame-kit/ui-ng/services/overlay-orchestrator';
|
|
6
5
|
|
|
7
6
|
class AppShellComponent {
|
|
8
7
|
// ===== INPUTS =====
|
|
@@ -24,9 +23,6 @@ class AppShellComponent {
|
|
|
24
23
|
endWidth = input('320px', ...(ngDevMode ? [{ debugName: "endWidth" }] : /* istanbul ignore next */ []));
|
|
25
24
|
/** Width of the end panel when collapsed to icon-rail mode. */
|
|
26
25
|
endCollapsedWidth = input('64px', ...(ngDevMode ? [{ debugName: "endCollapsedWidth" }] : /* istanbul ignore next */ []));
|
|
27
|
-
orchestrator = inject(OverlayOrchestrator);
|
|
28
|
-
navOverlayId = null;
|
|
29
|
-
endOverlayId = null;
|
|
30
26
|
// ===== INTERNAL STATE =====
|
|
31
27
|
stickyPreference = signal(null, ...(ngDevMode ? [{ debugName: "stickyPreference" }] : /* istanbul ignore next */ []));
|
|
32
28
|
tempOpen = signal(false, ...(ngDevMode ? [{ debugName: "tempOpen" }] : /* istanbul ignore next */ []));
|
|
@@ -141,28 +137,19 @@ class AppShellComponent {
|
|
|
141
137
|
});
|
|
142
138
|
}
|
|
143
139
|
// ===== METHODS =====
|
|
144
|
-
/** Open the primary sidenav
|
|
140
|
+
/** Open the primary sidenav (temporary overlay on mobile). */
|
|
145
141
|
openSidenav() {
|
|
146
142
|
this.animate.set(true);
|
|
147
143
|
this.stickyPreference.set(null);
|
|
148
144
|
if (this.isMobile()) {
|
|
149
145
|
this.tempOpen.set(true);
|
|
150
|
-
this.navOverlayId = this.orchestrator.register({
|
|
151
|
-
priority: OVERLAY_PRIORITY.NAVIGATION,
|
|
152
|
-
type: 'navigation',
|
|
153
|
-
close: () => this.closeSidenav(),
|
|
154
|
-
});
|
|
155
146
|
}
|
|
156
147
|
}
|
|
157
|
-
/** Close the primary sidenav
|
|
148
|
+
/** Close the primary sidenav. */
|
|
158
149
|
closeSidenav() {
|
|
159
150
|
this.animate.set(true);
|
|
160
151
|
this.stickyPreference.set('closed');
|
|
161
152
|
this.tempOpen.set(false);
|
|
162
|
-
if (this.navOverlayId) {
|
|
163
|
-
this.orchestrator.unregister(this.navOverlayId);
|
|
164
|
-
this.navOverlayId = null;
|
|
165
|
-
}
|
|
166
153
|
}
|
|
167
154
|
/** Toggle the primary sidenav between open and closed. */
|
|
168
155
|
toggleSidenav() {
|
|
@@ -178,28 +165,19 @@ class AppShellComponent {
|
|
|
178
165
|
this.animate.set(true);
|
|
179
166
|
this.tempOpen.set(false);
|
|
180
167
|
}
|
|
181
|
-
/** Open the end panel
|
|
168
|
+
/** Open the end panel (temporary overlay on mobile). */
|
|
182
169
|
openEnd() {
|
|
183
170
|
this.animate.set(true);
|
|
184
171
|
this.endStickyPreference.set(null);
|
|
185
172
|
if (this.isMobile()) {
|
|
186
173
|
this.endTempOpen.set(true);
|
|
187
|
-
this.endOverlayId = this.orchestrator.register({
|
|
188
|
-
priority: OVERLAY_PRIORITY.NAVIGATION,
|
|
189
|
-
type: 'navigation',
|
|
190
|
-
close: () => this.closeEnd(),
|
|
191
|
-
});
|
|
192
174
|
}
|
|
193
175
|
}
|
|
194
|
-
/** Close the end panel
|
|
176
|
+
/** Close the end panel. */
|
|
195
177
|
closeEnd() {
|
|
196
178
|
this.animate.set(true);
|
|
197
179
|
this.endStickyPreference.set('closed');
|
|
198
180
|
this.endTempOpen.set(false);
|
|
199
|
-
if (this.endOverlayId) {
|
|
200
|
-
this.orchestrator.unregister(this.endOverlayId);
|
|
201
|
-
this.endOverlayId = null;
|
|
202
|
-
}
|
|
203
181
|
}
|
|
204
182
|
/** Toggle the end panel between open and closed. */
|
|
205
183
|
toggleEnd() {
|
|
@@ -210,15 +188,11 @@ class AppShellComponent {
|
|
|
210
188
|
this.openEnd();
|
|
211
189
|
}
|
|
212
190
|
}
|
|
213
|
-
/** Dismiss the end panel overlay
|
|
191
|
+
/** Dismiss the end panel overlay. */
|
|
214
192
|
dismissEnd() {
|
|
215
193
|
this.animate.set(true);
|
|
216
194
|
this.endStickyPreference.set('closed');
|
|
217
195
|
this.endTempOpen.set(false);
|
|
218
|
-
if (this.endOverlayId) {
|
|
219
|
-
this.orchestrator.unregister(this.endOverlayId);
|
|
220
|
-
this.endOverlayId = null;
|
|
221
|
-
}
|
|
222
196
|
}
|
|
223
197
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AppShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
224
198
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AppShellComponent, isStandalone: true, selector: "fk-app-shell", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, sidenavWidth: { classPropertyName: "sidenavWidth", publicName: "sidenavWidth", isSignal: true, isRequired: false, transformFunction: null }, collapsedWidth: { classPropertyName: "collapsedWidth", publicName: "collapsedWidth", isSignal: true, isRequired: false, transformFunction: null }, breakpoint: { classPropertyName: "breakpoint", publicName: "breakpoint", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, collapseOnMobile: { classPropertyName: "collapseOnMobile", publicName: "collapseOnMobile", isSignal: true, isRequired: false, transformFunction: null }, endMode: { classPropertyName: "endMode", publicName: "endMode", isSignal: true, isRequired: false, transformFunction: null }, endWidth: { classPropertyName: "endWidth", publicName: "endWidth", isSignal: true, isRequired: false, transformFunction: null }, endCollapsedWidth: { classPropertyName: "endCollapsedWidth", publicName: "endCollapsedWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style": "this.hostStyle" } }, ngImport: i0, template: "<div [class]=\"classes()\">\n <header class=\"fk-app-shell__header\">\n <ng-content select=\"[appShellHeader]\" />\n </header>\n\n <div class=\"fk-app-shell__body\">\n @if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-app-shell__overlay\" (click)=\"dismissSidenav()\"></div>\n }\n\n <aside\n class=\"fk-app-shell__aside\"\n [class.fk-app-shell__aside--open]=\"sidenavOpen()\"\n [class.fk-app-shell__aside--collapsed]=\"isCollapsed()\"\n >\n <ng-content select=\"[appShellSidenav]\" />\n </aside>\n\n <main class=\"fk-app-shell__content\">\n <ng-content select=\"[appShellContent]\" />\n </main>\n\n @if (showEndOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-app-shell__end-overlay\" (click)=\"dismissEnd()\"></div>\n }\n\n <aside\n class=\"fk-app-shell__end\"\n [class.fk-app-shell__end--open]=\"endOpen()\"\n [class.fk-app-shell__end--collapsed]=\"isEndCollapsed()\"\n >\n <ng-content select=\"[appShellEnd]\" />\n </aside>\n </div>\n\n <footer class=\"fk-app-shell__footer\">\n <ng-content select=\"[appShellFooter]\" />\n </footer>\n</div>\n", styles: [":host{display:block;height:100%;flex:1;min-height:0}.fk-app-shell{display:flex;flex-direction:column;height:100%;overflow:hidden}.fk-app-shell--animate .fk-app-shell__aside,.fk-app-shell--animate .fk-app-shell__end{transition:width .25s cubic-bezier(.4,0,.2,1),transform .25s cubic-bezier(.4,0,.2,1)}.fk-app-shell__header{position:relative;z-index:var(--fk-app-shell-header-z-index, 100);flex-shrink:0}.fk-app-shell__body{display:flex;flex:1;position:relative;min-height:0}.fk-app-shell__overlay{position:fixed;inset:0;z-index:var(--fk-app-shell-overlay-z-index, 200);background:var(--fk-app-shell-overlay-bg, var(--fk-black-50, rgba(0, 0, 0, .5)))}.fk-app-shell__aside{display:flex;flex-direction:column;width:var(--fk-app-shell-sidenav-width);flex-shrink:0;overflow:hidden}.fk-app-shell__content{flex:1;min-width:0;overflow-y:auto;overscroll-behavior:contain}.fk-app-shell__footer{flex-shrink:0}.fk-app-shell--side .fk-app-shell__aside{position:relative}.fk-app-shell--side:not(.fk-app-shell--mobile):not(.fk-app-shell--open) .fk-app-shell__aside{width:0;overflow:hidden}.fk-app-shell--mobile .fk-app-shell__aside,.fk-app-shell--over .fk-app-shell__aside{position:fixed;top:0;left:0;bottom:0;z-index:var(--fk-app-shell-aside-z-index, 201);width:var(--fk-app-shell-sidenav-width);transform:translate(-100%);background:var(--fk-app-shell-aside-bg, var(--fk-color-surface, #ffffff))}.fk-app-shell--mobile .fk-app-shell__aside{width:var(--fk-app-shell-mobile-sidenav-width, 100%)}.fk-app-shell--mobile .fk-app-shell__aside--open,.fk-app-shell--over .fk-app-shell__aside--open{transform:translate(0)}.fk-app-shell--icon:not(.fk-app-shell--mobile) .fk-app-shell__aside{position:relative}.fk-app-shell--icon:not(.fk-app-shell--mobile) .fk-app-shell__aside--collapsed{width:var(--fk-app-shell-collapsed-width)}.fk-app-shell--mobile .fk-app-shell__aside--collapsed{position:relative;top:auto;left:auto;bottom:auto;width:var(--fk-app-shell-collapsed-width);transform:none;z-index:auto}.fk-app-shell__end-overlay{position:fixed;inset:0;z-index:var(--fk-app-shell-overlay-z-index, 200);background:var(--fk-app-shell-overlay-bg, var(--fk-black-50, rgba(0, 0, 0, .5)))}.fk-app-shell__end{display:flex;flex-direction:column;width:var(--fk-app-shell-end-width);flex-shrink:0;overflow:hidden;background:var(--fk-app-shell-end-bg, var(--fk-color-surface, #ffffff));border-radius:var(--fk-app-shell-end-radius, 0)}.fk-app-shell--end-side .fk-app-shell__end{position:relative}.fk-app-shell--end-side:not(.fk-app-shell--mobile):not(.fk-app-shell--end-open) .fk-app-shell__end{width:0;overflow:hidden}.fk-app-shell--mobile .fk-app-shell__end,.fk-app-shell--end-over .fk-app-shell__end{position:fixed;top:0;right:0;bottom:0;z-index:var(--fk-app-shell-end-z-index, 201);width:var(--fk-app-shell-end-width);transform:translate(100%);background:var(--fk-app-shell-end-bg, var(--fk-color-surface, #ffffff))}.fk-app-shell--mobile .fk-app-shell__end--open,.fk-app-shell--end-over .fk-app-shell__end--open{box-shadow:var(--fk-app-shell-end-shadow, -4px 0 16px rgba(0, 0, 0, .08))}.fk-app-shell--mobile .fk-app-shell__end--open,.fk-app-shell--end-over .fk-app-shell__end--open{transform:translate(0)}.fk-app-shell--end-icon:not(.fk-app-shell--mobile) .fk-app-shell__end{position:relative}.fk-app-shell--end-icon:not(.fk-app-shell--mobile) .fk-app-shell__end--collapsed{width:var(--fk-app-shell-end-collapsed-width)}@media(prefers-reduced-motion:reduce){.fk-app-shell--animate .fk-app-shell__aside,.fk-app-shell--animate .fk-app-shell__end{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-kit-ui-ng-layouts-app-shell.mjs","sources":["../../../../packages/ui-ng/layouts/app-shell/app-shell.component.ts","../../../../packages/ui-ng/layouts/app-shell/app-shell.component.html","../../../../packages/ui-ng/layouts/app-shell/frame-kit-ui-ng-layouts-app-shell.ts"],"sourcesContent":["import { BreakpointObserver } from '@angular/cdk/layout';\nimport {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n HostBinding,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { OverlayOrchestrator } from '@frame-kit/ui-ng/services/overlay-orchestrator';\nimport { OVERLAY_PRIORITY } from '@frame-kit/ui-ng/services/overlay-orchestrator';\nimport type { AppShellMode } from './app-shell.types';\n\n@Component({\n selector: 'fk-app-shell',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './app-shell.component.html',\n styleUrl: './app-shell.component.scss',\n})\nexport class AppShellComponent {\n // ===== INPUTS =====\n /** Layout mode for the primary sidenav — `\"side\"` pushes content, `\"over\"` floats above it, `\"icon\"` collapses to an icon rail. */\n readonly mode = input<AppShellMode>('side');\n /** Width of the primary sidenav when fully open. */\n readonly sidenavWidth = input<string>('260px');\n /** Width of the primary sidenav when collapsed to icon-rail mode. */\n readonly collapsedWidth = input<string>('64px');\n /** CSS media query used to determine mobile breakpoint for the primary sidenav. */\n readonly breakpoint = input<string>('(min-width: 48em)');\n /** When true, the main header sticks to the top of the viewport during scroll. */\n readonly sticky = input<boolean>(true);\n /** When true and on mobile, the sidenav collapses to the icon rail instead of hiding entirely. */\n readonly collapseOnMobile = input<boolean>(false);\n\n /** Layout mode for the end (trailing) panel. */\n readonly endMode = input<AppShellMode>('over');\n /** Width of the end panel when fully open. */\n readonly endWidth = input<string>('320px');\n /** Width of the end panel when collapsed to icon-rail mode. */\n readonly endCollapsedWidth = input<string>('64px');\n\n private readonly orchestrator = inject(OverlayOrchestrator);\n private navOverlayId: string | null = null;\n private endOverlayId: string | null = null;\n\n // ===== INTERNAL STATE =====\n readonly stickyPreference = signal<'closed' | null>(null);\n readonly tempOpen = signal<boolean>(false);\n readonly isMobile = signal<boolean>(false);\n\n readonly endStickyPreference = signal<'closed' | null>('closed');\n readonly endTempOpen = signal<boolean>(false);\n\n /**\n * Transitions are opt-in: only enabled after a user action (toggle, open,\n * close, dismiss). Viewport changes clear this flag so layout shifts are\n * always instant — no flash of the aside sliding in/out on resize.\n */\n readonly animate = signal<boolean>(false);\n\n // ===== COMPUTED =====\n readonly sidenavOpen = computed(() => {\n if (this.stickyPreference() === 'closed') {\n return false;\n }\n\n if (this.tempOpen()) {\n return true;\n }\n\n return !this.isMobile();\n });\n\n readonly showOverlay = computed(() => {\n if (!this.sidenavOpen()) {\n return false;\n }\n\n if (this.mode() === 'over') {\n return true;\n }\n\n return this.isMobile();\n });\n\n readonly isCollapsed = computed(() => {\n if (this.mode() !== 'icon') {\n return false;\n }\n\n if (this.sidenavOpen()) {\n return false;\n }\n\n if (this.isMobile()) {\n return this.collapseOnMobile();\n }\n\n return true;\n });\n\n readonly endOpen = computed(() => {\n if (this.endStickyPreference() === 'closed') {\n return false;\n }\n\n if (this.endTempOpen()) {\n return true;\n }\n\n return !this.isMobile();\n });\n\n readonly showEndOverlay = computed(() => {\n if (!this.endOpen()) {\n return false;\n }\n\n if (this.endMode() === 'over') {\n return true;\n }\n\n return this.isMobile();\n });\n\n readonly isEndCollapsed = computed(() => {\n return this.endMode() === 'icon' && !this.endOpen() && !this.isMobile();\n });\n\n readonly classes = computed(() => {\n const mode = this.mode();\n\n const endMode = this.endMode();\n\n return [\n 'fk-app-shell',\n `fk-app-shell--${mode}`,\n this.sticky() ? 'fk-app-shell--sticky' : '',\n this.sidenavOpen() ? 'fk-app-shell--open' : '',\n this.isCollapsed() ? 'fk-app-shell--collapsed' : '',\n this.isMobile() ? 'fk-app-shell--mobile' : '',\n this.animate() ? 'fk-app-shell--animate' : '',\n `fk-app-shell--end-${endMode}`,\n this.endOpen() ? 'fk-app-shell--end-open' : '',\n this.isEndCollapsed() ? 'fk-app-shell--end-collapsed' : '',\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('style')\n get hostStyle() {\n return {\n '--fk-app-shell-sidenav-width': this.sidenavWidth(),\n '--fk-app-shell-collapsed-width': this.collapsedWidth(),\n '--fk-app-shell-end-width': this.endWidth(),\n '--fk-app-shell-end-collapsed-width': this.endCollapsedWidth(),\n };\n }\n\n // ===== BREAKPOINT =====\n private readonly breakpointObserver = inject(BreakpointObserver);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n // Defer the breakpoint subscription until the first client-side render.\n // During SSR, CDK's MediaMatcher returns `{ matches: false }` for every\n // query, which would flip `isMobile` to true and produce a mobile-layout\n // HTML in the server output, causing a visible flash of the overlay\n // sidebar before the client corrects it on hydration. `afterNextRender`\n // only runs in the browser, so `isMobile` stays at its `false` default\n // through SSR and the real viewport check happens post-hydration.\n afterNextRender(() => {\n this.breakpointObserver\n .observe(this.breakpoint())\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((result) => {\n this.animate.set(false);\n this.isMobile.set(!result.matches);\n this.tempOpen.set(false);\n this.endTempOpen.set(false);\n });\n });\n }\n\n // ===== METHODS =====\n /** Open the primary sidenav, registering it with the overlay orchestrator on mobile. */\n openSidenav(): void {\n this.animate.set(true);\n this.stickyPreference.set(null);\n\n if (this.isMobile()) {\n this.tempOpen.set(true);\n\n this.navOverlayId = this.orchestrator.register({\n priority: OVERLAY_PRIORITY.NAVIGATION,\n type: 'navigation',\n close: () => this.closeSidenav(),\n });\n }\n }\n\n /** Close the primary sidenav and unregister it from the overlay orchestrator. */\n closeSidenav(): void {\n this.animate.set(true);\n this.stickyPreference.set('closed');\n this.tempOpen.set(false);\n\n if (this.navOverlayId) {\n this.orchestrator.unregister(this.navOverlayId);\n this.navOverlayId = null;\n }\n }\n\n /** Toggle the primary sidenav between open and closed. */\n toggleSidenav(): void {\n if (this.sidenavOpen()) {\n this.closeSidenav();\n } else {\n this.openSidenav();\n }\n }\n\n /** Dismiss the sidenav overlay on mobile without marking it as permanently closed. */\n dismissSidenav(): void {\n this.animate.set(true);\n this.tempOpen.set(false);\n }\n\n /** Open the end panel, registering it with the overlay orchestrator on mobile. */\n openEnd(): void {\n this.animate.set(true);\n this.endStickyPreference.set(null);\n\n if (this.isMobile()) {\n this.endTempOpen.set(true);\n\n this.endOverlayId = this.orchestrator.register({\n priority: OVERLAY_PRIORITY.NAVIGATION,\n type: 'navigation',\n close: () => this.closeEnd(),\n });\n }\n }\n\n /** Close the end panel and unregister it from the overlay orchestrator. */\n closeEnd(): void {\n this.animate.set(true);\n this.endStickyPreference.set('closed');\n this.endTempOpen.set(false);\n\n if (this.endOverlayId) {\n this.orchestrator.unregister(this.endOverlayId);\n this.endOverlayId = null;\n }\n }\n\n /** Toggle the end panel between open and closed. */\n toggleEnd(): void {\n if (this.endOpen()) {\n this.closeEnd();\n } else {\n this.openEnd();\n }\n }\n\n /** Dismiss the end panel overlay and unregister it from the overlay orchestrator. */\n dismissEnd(): void {\n this.animate.set(true);\n this.endStickyPreference.set('closed');\n this.endTempOpen.set(false);\n\n if (this.endOverlayId) {\n this.orchestrator.unregister(this.endOverlayId);\n this.endOverlayId = null;\n }\n }\n}\n","<div [class]=\"classes()\">\n <header class=\"fk-app-shell__header\">\n <ng-content select=\"[appShellHeader]\" />\n </header>\n\n <div class=\"fk-app-shell__body\">\n @if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-app-shell__overlay\" (click)=\"dismissSidenav()\"></div>\n }\n\n <aside\n class=\"fk-app-shell__aside\"\n [class.fk-app-shell__aside--open]=\"sidenavOpen()\"\n [class.fk-app-shell__aside--collapsed]=\"isCollapsed()\"\n >\n <ng-content select=\"[appShellSidenav]\" />\n </aside>\n\n <main class=\"fk-app-shell__content\">\n <ng-content select=\"[appShellContent]\" />\n </main>\n\n @if (showEndOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-app-shell__end-overlay\" (click)=\"dismissEnd()\"></div>\n }\n\n <aside\n class=\"fk-app-shell__end\"\n [class.fk-app-shell__end--open]=\"endOpen()\"\n [class.fk-app-shell__end--collapsed]=\"isEndCollapsed()\"\n >\n <ng-content select=\"[appShellEnd]\" />\n </aside>\n </div>\n\n <footer class=\"fk-app-shell__footer\">\n <ng-content select=\"[appShellFooter]\" />\n </footer>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-layouts-app-shell.mjs","sources":["../../../../packages/ui-ng/layouts/app-shell/app-shell.component.ts","../../../../packages/ui-ng/layouts/app-shell/app-shell.component.html","../../../../packages/ui-ng/layouts/app-shell/frame-kit-ui-ng-layouts-app-shell.ts"],"sourcesContent":["import { BreakpointObserver } from '@angular/cdk/layout';\nimport {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n HostBinding,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport type { AppShellMode } from './app-shell.types';\n\n@Component({\n selector: 'fk-app-shell',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './app-shell.component.html',\n styleUrl: './app-shell.component.scss',\n})\nexport class AppShellComponent {\n // ===== INPUTS =====\n /** Layout mode for the primary sidenav — `\"side\"` pushes content, `\"over\"` floats above it, `\"icon\"` collapses to an icon rail. */\n readonly mode = input<AppShellMode>('side');\n /** Width of the primary sidenav when fully open. */\n readonly sidenavWidth = input<string>('260px');\n /** Width of the primary sidenav when collapsed to icon-rail mode. */\n readonly collapsedWidth = input<string>('64px');\n /** CSS media query used to determine mobile breakpoint for the primary sidenav. */\n readonly breakpoint = input<string>('(min-width: 48em)');\n /** When true, the main header sticks to the top of the viewport during scroll. */\n readonly sticky = input<boolean>(true);\n /** When true and on mobile, the sidenav collapses to the icon rail instead of hiding entirely. */\n readonly collapseOnMobile = input<boolean>(false);\n\n /** Layout mode for the end (trailing) panel. */\n readonly endMode = input<AppShellMode>('over');\n /** Width of the end panel when fully open. */\n readonly endWidth = input<string>('320px');\n /** Width of the end panel when collapsed to icon-rail mode. */\n readonly endCollapsedWidth = input<string>('64px');\n\n // ===== INTERNAL STATE =====\n readonly stickyPreference = signal<'closed' | null>(null);\n readonly tempOpen = signal<boolean>(false);\n readonly isMobile = signal<boolean>(false);\n\n readonly endStickyPreference = signal<'closed' | null>('closed');\n readonly endTempOpen = signal<boolean>(false);\n\n /**\n * Transitions are opt-in: only enabled after a user action (toggle, open,\n * close, dismiss). Viewport changes clear this flag so layout shifts are\n * always instant — no flash of the aside sliding in/out on resize.\n */\n readonly animate = signal<boolean>(false);\n\n // ===== COMPUTED =====\n readonly sidenavOpen = computed(() => {\n if (this.stickyPreference() === 'closed') {\n return false;\n }\n\n if (this.tempOpen()) {\n return true;\n }\n\n return !this.isMobile();\n });\n\n readonly showOverlay = computed(() => {\n if (!this.sidenavOpen()) {\n return false;\n }\n\n if (this.mode() === 'over') {\n return true;\n }\n\n return this.isMobile();\n });\n\n readonly isCollapsed = computed(() => {\n if (this.mode() !== 'icon') {\n return false;\n }\n\n if (this.sidenavOpen()) {\n return false;\n }\n\n if (this.isMobile()) {\n return this.collapseOnMobile();\n }\n\n return true;\n });\n\n readonly endOpen = computed(() => {\n if (this.endStickyPreference() === 'closed') {\n return false;\n }\n\n if (this.endTempOpen()) {\n return true;\n }\n\n return !this.isMobile();\n });\n\n readonly showEndOverlay = computed(() => {\n if (!this.endOpen()) {\n return false;\n }\n\n if (this.endMode() === 'over') {\n return true;\n }\n\n return this.isMobile();\n });\n\n readonly isEndCollapsed = computed(() => {\n return this.endMode() === 'icon' && !this.endOpen() && !this.isMobile();\n });\n\n readonly classes = computed(() => {\n const mode = this.mode();\n\n const endMode = this.endMode();\n\n return [\n 'fk-app-shell',\n `fk-app-shell--${mode}`,\n this.sticky() ? 'fk-app-shell--sticky' : '',\n this.sidenavOpen() ? 'fk-app-shell--open' : '',\n this.isCollapsed() ? 'fk-app-shell--collapsed' : '',\n this.isMobile() ? 'fk-app-shell--mobile' : '',\n this.animate() ? 'fk-app-shell--animate' : '',\n `fk-app-shell--end-${endMode}`,\n this.endOpen() ? 'fk-app-shell--end-open' : '',\n this.isEndCollapsed() ? 'fk-app-shell--end-collapsed' : '',\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('style')\n get hostStyle() {\n return {\n '--fk-app-shell-sidenav-width': this.sidenavWidth(),\n '--fk-app-shell-collapsed-width': this.collapsedWidth(),\n '--fk-app-shell-end-width': this.endWidth(),\n '--fk-app-shell-end-collapsed-width': this.endCollapsedWidth(),\n };\n }\n\n // ===== BREAKPOINT =====\n private readonly breakpointObserver = inject(BreakpointObserver);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n // Defer the breakpoint subscription until the first client-side render.\n // During SSR, CDK's MediaMatcher returns `{ matches: false }` for every\n // query, which would flip `isMobile` to true and produce a mobile-layout\n // HTML in the server output, causing a visible flash of the overlay\n // sidebar before the client corrects it on hydration. `afterNextRender`\n // only runs in the browser, so `isMobile` stays at its `false` default\n // through SSR and the real viewport check happens post-hydration.\n afterNextRender(() => {\n this.breakpointObserver\n .observe(this.breakpoint())\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((result) => {\n this.animate.set(false);\n this.isMobile.set(!result.matches);\n this.tempOpen.set(false);\n this.endTempOpen.set(false);\n });\n });\n }\n\n // ===== METHODS =====\n /** Open the primary sidenav (temporary overlay on mobile). */\n openSidenav(): void {\n this.animate.set(true);\n this.stickyPreference.set(null);\n\n if (this.isMobile()) {\n this.tempOpen.set(true);\n }\n }\n\n /** Close the primary sidenav. */\n closeSidenav(): void {\n this.animate.set(true);\n this.stickyPreference.set('closed');\n this.tempOpen.set(false);\n }\n\n /** Toggle the primary sidenav between open and closed. */\n toggleSidenav(): void {\n if (this.sidenavOpen()) {\n this.closeSidenav();\n } else {\n this.openSidenav();\n }\n }\n\n /** Dismiss the sidenav overlay on mobile without marking it as permanently closed. */\n dismissSidenav(): void {\n this.animate.set(true);\n this.tempOpen.set(false);\n }\n\n /** Open the end panel (temporary overlay on mobile). */\n openEnd(): void {\n this.animate.set(true);\n this.endStickyPreference.set(null);\n\n if (this.isMobile()) {\n this.endTempOpen.set(true);\n }\n }\n\n /** Close the end panel. */\n closeEnd(): void {\n this.animate.set(true);\n this.endStickyPreference.set('closed');\n this.endTempOpen.set(false);\n }\n\n /** Toggle the end panel between open and closed. */\n toggleEnd(): void {\n if (this.endOpen()) {\n this.closeEnd();\n } else {\n this.openEnd();\n }\n }\n\n /** Dismiss the end panel overlay. */\n dismissEnd(): void {\n this.animate.set(true);\n this.endStickyPreference.set('closed');\n this.endTempOpen.set(false);\n }\n}\n","<div [class]=\"classes()\">\n <header class=\"fk-app-shell__header\">\n <ng-content select=\"[appShellHeader]\" />\n </header>\n\n <div class=\"fk-app-shell__body\">\n @if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-app-shell__overlay\" (click)=\"dismissSidenav()\"></div>\n }\n\n <aside\n class=\"fk-app-shell__aside\"\n [class.fk-app-shell__aside--open]=\"sidenavOpen()\"\n [class.fk-app-shell__aside--collapsed]=\"isCollapsed()\"\n >\n <ng-content select=\"[appShellSidenav]\" />\n </aside>\n\n <main class=\"fk-app-shell__content\">\n <ng-content select=\"[appShellContent]\" />\n </main>\n\n @if (showEndOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-app-shell__end-overlay\" (click)=\"dismissEnd()\"></div>\n }\n\n <aside\n class=\"fk-app-shell__end\"\n [class.fk-app-shell__end--open]=\"endOpen()\"\n [class.fk-app-shell__end--collapsed]=\"isEndCollapsed()\"\n >\n <ng-content select=\"[appShellEnd]\" />\n </aside>\n </div>\n\n <footer class=\"fk-app-shell__footer\">\n <ng-content select=\"[appShellFooter]\" />\n </footer>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,10 @@ import * as i1 from '@angular/cdk/a11y';
|
|
|
2
2
|
import { A11yModule } from '@angular/cdk/a11y';
|
|
3
3
|
import { DOCUMENT } from '@angular/common';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { Directive, input, contentChild, output, inject,
|
|
6
|
-
import {
|
|
5
|
+
import { Directive, input, contentChild, output, inject, signal, computed, effect, HostBinding, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, Injector, createComponent, Injectable } from '@angular/core';
|
|
6
|
+
import { ESCAPE } from '@angular/cdk/keycodes';
|
|
7
|
+
import { Overlay } from '@angular/cdk/overlay';
|
|
8
|
+
import { ComponentPortal } from '@angular/cdk/portal';
|
|
7
9
|
import { Subject } from 'rxjs';
|
|
8
10
|
import { take } from 'rxjs/operators';
|
|
9
11
|
|
|
@@ -20,18 +22,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
20
22
|
}] });
|
|
21
23
|
|
|
22
24
|
let nextDialogId = 0;
|
|
25
|
+
/**
|
|
26
|
+
* Dialog panel chrome.
|
|
27
|
+
*
|
|
28
|
+
* Hosted inside a CDK overlay by `DialogService`, so the overlay layer owns
|
|
29
|
+
* the backdrop, scroll blocking, positioning, stacking, and Escape / outside
|
|
30
|
+
* dispatch. This component renders the panel itself: header / body / footer
|
|
31
|
+
* projection, sizing, the enter animation, focus trapping, and the close
|
|
32
|
+
* guard.
|
|
33
|
+
*/
|
|
23
34
|
class DialogComponent {
|
|
24
35
|
// ===== INPUTS =====
|
|
25
36
|
/** Controls whether the dialog is open. */
|
|
26
37
|
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
27
|
-
/** When true,
|
|
38
|
+
/** When true, marks the panel `aria-modal` and traps focus. */
|
|
28
39
|
modal = input(true, ...(ngDevMode ? [{ debugName: "modal" }] : /* istanbul ignore next */ []));
|
|
29
40
|
/** When true, shows the close button in the dialog header. */
|
|
30
41
|
closable = input(true, ...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
|
|
31
|
-
/** When true, pressing Escape closes the dialog. */
|
|
32
|
-
closeOnEscape = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscape" }] : /* istanbul ignore next */ []));
|
|
33
|
-
/** When true, clicking the backdrop overlay closes the dialog. */
|
|
34
|
-
closeOnBackdrop = input(false, ...(ngDevMode ? [{ debugName: "closeOnBackdrop" }] : /* istanbul ignore next */ []));
|
|
35
42
|
/** Size variant that controls the dialog's max-width. */
|
|
36
43
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
37
44
|
/** Where the dialog is anchored on screen. */
|
|
@@ -72,10 +79,8 @@ class DialogComponent {
|
|
|
72
79
|
closed = output();
|
|
73
80
|
// ===== INTERNAL STATE =====
|
|
74
81
|
doc = inject(DOCUMENT);
|
|
75
|
-
destroyRef = inject(DestroyRef);
|
|
76
82
|
titleId = `fk-dialog-title-${nextDialogId++}`;
|
|
77
83
|
previouslyFocusedElement = null;
|
|
78
|
-
bodyScrollLocked = false;
|
|
79
84
|
closeGuardRunning = false;
|
|
80
85
|
/** Whether the dialog DOM is rendered (stays true during exit animation). */
|
|
81
86
|
visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
@@ -101,9 +106,6 @@ class DialogComponent {
|
|
|
101
106
|
this.onDialogClose();
|
|
102
107
|
}
|
|
103
108
|
});
|
|
104
|
-
this.destroyRef.onDestroy(() => {
|
|
105
|
-
this.unlockBodyScroll();
|
|
106
|
-
});
|
|
107
109
|
}
|
|
108
110
|
get hostClass() {
|
|
109
111
|
return this.classes();
|
|
@@ -111,12 +113,6 @@ class DialogComponent {
|
|
|
111
113
|
get hostId() {
|
|
112
114
|
return this.id();
|
|
113
115
|
}
|
|
114
|
-
// ===== KEYBOARD =====
|
|
115
|
-
onEscapeKey() {
|
|
116
|
-
if (this.open() && this.closeOnEscape()) {
|
|
117
|
-
this.close();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
116
|
// ===== ACTIONS =====
|
|
121
117
|
/** Closes the dialog, running any `canClose` guard first; no-ops when `preventClose` is true. */
|
|
122
118
|
async close() {
|
|
@@ -143,12 +139,7 @@ class DialogComponent {
|
|
|
143
139
|
this.openChange.emit(false);
|
|
144
140
|
this.closed.emit();
|
|
145
141
|
}
|
|
146
|
-
|
|
147
|
-
if (this.closeOnBackdrop()) {
|
|
148
|
-
this.close();
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/** Called when the overlay exit animation finishes. */
|
|
142
|
+
/** Called when the panel exit animation finishes. */
|
|
152
143
|
onExitAnimationDone() {
|
|
153
144
|
if (this.animatingOut()) {
|
|
154
145
|
this.animatingOut.set(false);
|
|
@@ -162,13 +153,9 @@ class DialogComponent {
|
|
|
162
153
|
this.beforeOpen.emit();
|
|
163
154
|
this.animatingOut.set(false);
|
|
164
155
|
this.visible.set(true);
|
|
165
|
-
if (this.modal()) {
|
|
166
|
-
this.lockBodyScroll();
|
|
167
|
-
}
|
|
168
156
|
this.opened.emit();
|
|
169
157
|
}
|
|
170
158
|
onDialogClose() {
|
|
171
|
-
this.unlockBodyScroll();
|
|
172
159
|
if (this.visible()) {
|
|
173
160
|
if (this.animation() !== 'none') {
|
|
174
161
|
this.animatingOut.set(true);
|
|
@@ -182,34 +169,18 @@ class DialogComponent {
|
|
|
182
169
|
this.previouslyFocusedElement = null;
|
|
183
170
|
}
|
|
184
171
|
}
|
|
185
|
-
// ===== SCROLL LOCK =====
|
|
186
|
-
lockBodyScroll() {
|
|
187
|
-
if (!this.bodyScrollLocked) {
|
|
188
|
-
this.doc.body.style.overflow = 'hidden';
|
|
189
|
-
this.bodyScrollLocked = true;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
unlockBodyScroll() {
|
|
193
|
-
if (this.bodyScrollLocked) {
|
|
194
|
-
this.doc.body.style.overflow = '';
|
|
195
|
-
this.bodyScrollLocked = false;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
172
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
199
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DialogComponent, isStandalone: true, selector: "fk-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, preventClose: { classPropertyName: "preventClose", publicName: "preventClose", isSignal: true, isRequired: false, transformFunction: null }, canClose: { classPropertyName: "canClose", publicName: "canClose", isSignal: true, isRequired: false, transformFunction: null }, fullscreenMobile: { classPropertyName: "fullscreenMobile", publicName: "fullscreenMobile", isSignal: true, isRequired: false, transformFunction: null }, flexBody: { classPropertyName: "flexBody", publicName: "flexBody", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openChange: "openChange", beforeOpen: "beforeOpen", opened: "opened", beforeClose: "beforeClose", closed: "closed" }, host: { listeners: { "document:keydown.escape": "onEscapeKey()" }, properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, queries: [{ propertyName: "customHeader", first: true, predicate: FkDialogHeaderDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"fk-dialog__overlay\"\n [class.fk-dialog__overlay--modal]=\"modal()\"\n [class.fk-dialog__animate-overlay--in]=\"!animatingOut()\"\n [class.fk-dialog__animate-overlay--out]=\"animatingOut()\"\n [class.fk-dialog__animate-overlay--none]=\"animation() === 'none'\"\n (click)=\"onOverlayClick()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n </div>\n}\n", styles: [":host{display:contents}.fk-dialog__overlay{position:fixed;inset:0;z-index:var(--fk-dialog-overlay-z-index, 1000);display:flex;align-items:center;justify-content:center;padding:var(--fk-dialog-panel-margin, var(--fk-rhythm-4, 1rem))}.fk-dialog__overlay--modal{background:var(--fk-dialog-overlay-bg, rgba(0, 0, 0, .5))}.fk-dialog__overlay.fk-dialog__animate-overlay--in{animation:fk-dialog-overlay-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__overlay.fk-dialog__animate-overlay--out{animation:fk-dialog-overlay-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__overlay.fk-dialog__animate-overlay--none{animation:none}.fk-dialog__panel{display:flex;flex-direction:column;background:var(--fk-dialog-panel-bg, var(--fk-color-surface, #ffffff));border:var(--fk-dialog-panel-border, none);border-radius:var(--fk-dialog-panel-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-dialog-panel-shadow, 0 8px 32px rgba(0, 0, 0, .12));max-height:var(--fk-dialog-panel-max-height, 85vh);width:100%;overflow:clip}.fk-dialog__panel--sm{max-width:var(--fk-dialog-width-sm, 24rem)}.fk-dialog__panel--md{max-width:var(--fk-dialog-width-md, 32rem)}.fk-dialog__panel--lg{max-width:var(--fk-dialog-width-lg, 40rem)}.fk-dialog__panel--xl{max-width:var(--fk-dialog-width-xl, 52rem)}.fk-dialog__panel--fullscreen{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}@media(max-width:47.999em){.fk-dialog__panel--fullscreen-auto{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}}.fk-dialog__panel--top{align-self:flex-start}.fk-dialog__panel.fk-dialog__animate-panel--scale-fade{animation:fk-dialog-scale-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--scale-fade{animation:fk-dialog-scale-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--fade{animation:fk-dialog-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--fade{animation:fk-dialog-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-up{animation:fk-dialog-slide-up-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-up{animation:fk-dialog-slide-up-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-down{animation:fk-dialog-slide-down-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-down{animation:fk-dialog-slide-down-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__header{display:flex;align-items:center;justify-content:center;position:relative;padding:var(--fk-dialog-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem)));flex-shrink:0}.fk-dialog__title{font-family:var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\");font-size:var(--fk-typography-h4-font-size, 1.125rem);font-weight:var(--fk-font-weight-semibold, 600);color:var(--fk-color-text, #1f2d3d);line-height:var(--fk-typography-h4-line-height, 1.25);padding-inline-end:var(--fk-rhythm-7, 2rem)}.fk-dialog__close{position:absolute;right:var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem));display:flex;align-items:center;justify-content:center;width:var(--fk-dialog-close-size, 2rem);height:var(--fk-dialog-close-size, 2rem);padding:0;border:none;border-radius:var(--fk-radius-sm, .25rem);background:transparent;color:var(--fk-dialog-close-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-font-size-xl, 1.25rem);line-height:1;cursor:pointer;transition:color .15s ease,background-color .15s ease}.fk-dialog__close:hover{color:var(--fk-dialog-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-color-surface-muted, #f7f9fb)}.fk-dialog__close:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-dialog__body{flex:1;padding:var(--fk-dialog-body-padding, var(--fk-rhythm-6, 1.5rem));overflow-y:auto;overscroll-behavior:contain;container-type:inline-size}.fk-dialog__body--flex{display:flex;flex-direction:column;overflow:hidden}::ng-deep [libDialogFooter]{display:flex;align-items:center;justify-content:center;gap:var(--fk-dialog-footer-gap, .75rem);padding:var(--fk-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}::ng-deep [libDialogFooter]>*{flex:1 1 0;min-width:0}::ng-deep [fkDialogActions]{display:flex;gap:var(--fk-dialog-actions-gap, var(--fk-rhythm-3, .75rem));margin-top:var(--fk-dialog-actions-margin-top, var(--fk-rhythm-5, 1.25rem))}::ng-deep [fkDialogActions]>*{flex:1 1 0;min-width:0}@container (max-width: 24rem){::ng-deep [fkDialogActions]{flex-direction:column-reverse}::ng-deep [fkDialogActions]>*{flex:none;width:100%}}@keyframes fk-dialog-overlay-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-dialog-overlay-fade-out{0%{opacity:1}to{opacity:0}}@keyframes fk-dialog-scale-fade-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fk-dialog-scale-fade-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes fk-dialog-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-dialog-fade-out{0%{opacity:1}to{opacity:0}}@keyframes fk-dialog-slide-up-in{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-up-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes fk-dialog-slide-down-in{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-down-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-1rem)}}@media(prefers-reduced-motion:reduce){.fk-dialog__animate-overlay--in,.fk-dialog__animate-overlay--out,.fk-dialog__animate-panel--scale-fade,.fk-dialog__animate-panel--fade,.fk-dialog__animate-panel--slide-up,.fk-dialog__animate-panel--slide-down,.fk-dialog__animate-panel-out--scale-fade,.fk-dialog__animate-panel-out--fade,.fk-dialog__animate-panel-out--slide-up,.fk-dialog__animate-panel-out--slide-down{animation:none}}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
173
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DialogComponent, isStandalone: true, selector: "fk-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, preventClose: { classPropertyName: "preventClose", publicName: "preventClose", isSignal: true, isRequired: false, transformFunction: null }, canClose: { classPropertyName: "canClose", publicName: "canClose", isSignal: true, isRequired: false, transformFunction: null }, fullscreenMobile: { classPropertyName: "fullscreenMobile", publicName: "fullscreenMobile", isSignal: true, isRequired: false, transformFunction: null }, flexBody: { classPropertyName: "flexBody", publicName: "flexBody", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openChange: "openChange", beforeOpen: "beforeOpen", opened: "opened", beforeClose: "beforeClose", closed: "closed" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, queries: [{ propertyName: "customHeader", first: true, predicate: FkDialogHeaderDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n", styles: [":host{display:contents}.fk-dialog__panel{display:flex;flex-direction:column;background:var(--fk-dialog-panel-bg, var(--fk-color-surface, #ffffff));border:var(--fk-dialog-panel-border, none);border-radius:var(--fk-dialog-panel-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-dialog-panel-shadow, 0 8px 32px rgba(0, 0, 0, .12));max-height:var(--fk-dialog-panel-max-height, 85vh);width:calc(100vw - 2 * var(--fk-dialog-panel-margin, var(--fk-rhythm-4, 1rem)));overflow:clip}.fk-dialog__panel--sm{max-width:var(--fk-dialog-width-sm, 24rem)}.fk-dialog__panel--md{max-width:var(--fk-dialog-width-md, 32rem)}.fk-dialog__panel--lg{max-width:var(--fk-dialog-width-lg, 40rem)}.fk-dialog__panel--xl{max-width:var(--fk-dialog-width-xl, 52rem)}.fk-dialog__panel--fullscreen{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}@media(max-width:47.999em){.fk-dialog__panel--fullscreen-auto{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}}.fk-dialog__panel--top{align-self:flex-start}.fk-dialog__panel.fk-dialog__animate-panel--scale-fade{animation:fk-dialog-scale-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--scale-fade{animation:fk-dialog-scale-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--fade{animation:fk-dialog-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--fade{animation:fk-dialog-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-up{animation:fk-dialog-slide-up-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-up{animation:fk-dialog-slide-up-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-down{animation:fk-dialog-slide-down-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-down{animation:fk-dialog-slide-down-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__header{display:flex;align-items:center;justify-content:center;position:relative;padding:var(--fk-dialog-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem)));flex-shrink:0}.fk-dialog__title{font-family:var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\");font-size:var(--fk-typography-h4-font-size, 1.125rem);font-weight:var(--fk-font-weight-semibold, 600);color:var(--fk-color-text, #1f2d3d);line-height:var(--fk-typography-h4-line-height, 1.25);padding-inline-end:var(--fk-rhythm-7, 2rem)}.fk-dialog__close{position:absolute;right:var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem));display:flex;align-items:center;justify-content:center;width:var(--fk-dialog-close-size, 2rem);height:var(--fk-dialog-close-size, 2rem);padding:0;border:none;border-radius:var(--fk-radius-sm, .25rem);background:transparent;color:var(--fk-dialog-close-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-font-size-xl, 1.25rem);line-height:1;cursor:pointer;transition:color .15s ease,background-color .15s ease}.fk-dialog__close:hover{color:var(--fk-dialog-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-color-surface-muted, #f7f9fb)}.fk-dialog__close:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-dialog__body{flex:1;padding:var(--fk-dialog-body-padding, var(--fk-rhythm-6, 1.5rem));overflow-y:auto;overscroll-behavior:contain;container-type:inline-size}.fk-dialog__body--flex{display:flex;flex-direction:column;overflow:hidden}::ng-deep [libDialogFooter]{display:flex;align-items:center;justify-content:center;gap:var(--fk-dialog-footer-gap, .75rem);padding:var(--fk-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}::ng-deep [libDialogFooter]>*{flex:1 1 0;min-width:0}::ng-deep [fkDialogActions]{display:flex;gap:var(--fk-dialog-actions-gap, var(--fk-rhythm-3, .75rem));margin-top:var(--fk-dialog-actions-margin-top, var(--fk-rhythm-5, 1.25rem))}::ng-deep [fkDialogActions]>*{flex:1 1 0;min-width:0}@container (max-width: 24rem){::ng-deep [fkDialogActions]{flex-direction:column-reverse}::ng-deep [fkDialogActions]>*{flex:none;width:100%}}@keyframes fk-dialog-scale-fade-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fk-dialog-scale-fade-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes fk-dialog-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-dialog-fade-out{0%{opacity:1}to{opacity:0}}@keyframes fk-dialog-slide-up-in{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-up-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes fk-dialog-slide-down-in{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-down-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-1rem)}}@media(prefers-reduced-motion:reduce){.fk-dialog__animate-panel--scale-fade,.fk-dialog__animate-panel--fade,.fk-dialog__animate-panel--slide-up,.fk-dialog__animate-panel--slide-down,.fk-dialog__animate-panel-out--scale-fade,.fk-dialog__animate-panel-out--fade,.fk-dialog__animate-panel-out--slide-up,.fk-dialog__animate-panel-out--slide-down{animation:none}}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
200
174
|
}
|
|
201
175
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogComponent, decorators: [{
|
|
202
176
|
type: Component,
|
|
203
|
-
args: [{ selector: 'fk-dialog', standalone: true, imports: [A11yModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (visible()) {\n
|
|
204
|
-
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }],
|
|
177
|
+
args: [{ selector: 'fk-dialog', standalone: true, imports: [A11yModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n", styles: [":host{display:contents}.fk-dialog__panel{display:flex;flex-direction:column;background:var(--fk-dialog-panel-bg, var(--fk-color-surface, #ffffff));border:var(--fk-dialog-panel-border, none);border-radius:var(--fk-dialog-panel-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-dialog-panel-shadow, 0 8px 32px rgba(0, 0, 0, .12));max-height:var(--fk-dialog-panel-max-height, 85vh);width:calc(100vw - 2 * var(--fk-dialog-panel-margin, var(--fk-rhythm-4, 1rem)));overflow:clip}.fk-dialog__panel--sm{max-width:var(--fk-dialog-width-sm, 24rem)}.fk-dialog__panel--md{max-width:var(--fk-dialog-width-md, 32rem)}.fk-dialog__panel--lg{max-width:var(--fk-dialog-width-lg, 40rem)}.fk-dialog__panel--xl{max-width:var(--fk-dialog-width-xl, 52rem)}.fk-dialog__panel--fullscreen{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}@media(max-width:47.999em){.fk-dialog__panel--fullscreen-auto{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}}.fk-dialog__panel--top{align-self:flex-start}.fk-dialog__panel.fk-dialog__animate-panel--scale-fade{animation:fk-dialog-scale-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--scale-fade{animation:fk-dialog-scale-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--fade{animation:fk-dialog-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--fade{animation:fk-dialog-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-up{animation:fk-dialog-slide-up-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-up{animation:fk-dialog-slide-up-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-down{animation:fk-dialog-slide-down-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-down{animation:fk-dialog-slide-down-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__header{display:flex;align-items:center;justify-content:center;position:relative;padding:var(--fk-dialog-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem)));flex-shrink:0}.fk-dialog__title{font-family:var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\");font-size:var(--fk-typography-h4-font-size, 1.125rem);font-weight:var(--fk-font-weight-semibold, 600);color:var(--fk-color-text, #1f2d3d);line-height:var(--fk-typography-h4-line-height, 1.25);padding-inline-end:var(--fk-rhythm-7, 2rem)}.fk-dialog__close{position:absolute;right:var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem));display:flex;align-items:center;justify-content:center;width:var(--fk-dialog-close-size, 2rem);height:var(--fk-dialog-close-size, 2rem);padding:0;border:none;border-radius:var(--fk-radius-sm, .25rem);background:transparent;color:var(--fk-dialog-close-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-font-size-xl, 1.25rem);line-height:1;cursor:pointer;transition:color .15s ease,background-color .15s ease}.fk-dialog__close:hover{color:var(--fk-dialog-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-color-surface-muted, #f7f9fb)}.fk-dialog__close:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-dialog__body{flex:1;padding:var(--fk-dialog-body-padding, var(--fk-rhythm-6, 1.5rem));overflow-y:auto;overscroll-behavior:contain;container-type:inline-size}.fk-dialog__body--flex{display:flex;flex-direction:column;overflow:hidden}::ng-deep [libDialogFooter]{display:flex;align-items:center;justify-content:center;gap:var(--fk-dialog-footer-gap, .75rem);padding:var(--fk-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}::ng-deep [libDialogFooter]>*{flex:1 1 0;min-width:0}::ng-deep [fkDialogActions]{display:flex;gap:var(--fk-dialog-actions-gap, var(--fk-rhythm-3, .75rem));margin-top:var(--fk-dialog-actions-margin-top, var(--fk-rhythm-5, 1.25rem))}::ng-deep [fkDialogActions]>*{flex:1 1 0;min-width:0}@container (max-width: 24rem){::ng-deep [fkDialogActions]{flex-direction:column-reverse}::ng-deep [fkDialogActions]>*{flex:none;width:100%}}@keyframes fk-dialog-scale-fade-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fk-dialog-scale-fade-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes fk-dialog-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-dialog-fade-out{0%{opacity:1}to{opacity:0}}@keyframes fk-dialog-slide-up-in{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-up-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes fk-dialog-slide-down-in{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-down-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-1rem)}}@media(prefers-reduced-motion:reduce){.fk-dialog__animate-panel--scale-fade,.fk-dialog__animate-panel--fade,.fk-dialog__animate-panel--slide-up,.fk-dialog__animate-panel--slide-down,.fk-dialog__animate-panel-out--scale-fade,.fk-dialog__animate-panel-out--fade,.fk-dialog__animate-panel-out--slide-up,.fk-dialog__animate-panel-out--slide-down{animation:none}}\n"] }]
|
|
178
|
+
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], restoreFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocus", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], preventClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventClose", required: false }] }], canClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "canClose", required: false }] }], fullscreenMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullscreenMobile", required: false }] }], flexBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "flexBody", required: false }] }], customHeader: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FkDialogHeaderDirective), { isSignal: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], openChange: [{ type: i0.Output, args: ["openChange"] }], beforeOpen: [{ type: i0.Output, args: ["beforeOpen"] }], opened: [{ type: i0.Output, args: ["opened"] }], beforeClose: [{ type: i0.Output, args: ["beforeClose"] }], closed: [{ type: i0.Output, args: ["closed"] }], hostClass: [{
|
|
205
179
|
type: HostBinding,
|
|
206
180
|
args: ['class']
|
|
207
181
|
}], hostId: [{
|
|
208
182
|
type: HostBinding,
|
|
209
183
|
args: ['attr.id']
|
|
210
|
-
}], onEscapeKey: [{
|
|
211
|
-
type: HostListener,
|
|
212
|
-
args: ['document:keydown.escape']
|
|
213
184
|
}] } });
|
|
214
185
|
|
|
215
186
|
const DEFAULT_DIALOG_CONFIG = {
|
|
@@ -296,15 +267,23 @@ class DialogRef {
|
|
|
296
267
|
|
|
297
268
|
const DIALOG_DATA = Symbol('DIALOG_DATA');
|
|
298
269
|
const DIALOG_REF = Symbol('DIALOG_REF');
|
|
299
|
-
|
|
300
|
-
|
|
270
|
+
/**
|
|
271
|
+
* Opens dialogs as CDK overlays.
|
|
272
|
+
*
|
|
273
|
+
* CDK owns the cross-cutting overlay concerns — backdrop, scroll blocking,
|
|
274
|
+
* centered positioning, z-index stacking (overlays layer by open order), and
|
|
275
|
+
* top-of-stack dispatch of Escape / outside clicks. The `DialogComponent` it
|
|
276
|
+
* hosts is just the panel chrome (header / body / footer, sizing, enter
|
|
277
|
+
* animation, focus trap). There is no global "opening X closes lower overlays"
|
|
278
|
+
* rule: a dialog opened over a drawer stacks on top of it, and Escape / an
|
|
279
|
+
* outside press dismisses whichever overlay is on top.
|
|
280
|
+
*/
|
|
301
281
|
class DialogService {
|
|
282
|
+
overlay = inject(Overlay);
|
|
302
283
|
appRef = inject(ApplicationRef);
|
|
303
284
|
injector = inject(EnvironmentInjector);
|
|
304
285
|
doc = inject(DOCUMENT);
|
|
305
|
-
orchestrator = inject(OverlayOrchestrator);
|
|
306
286
|
activeDialogs = [];
|
|
307
|
-
overlayIds = new Map();
|
|
308
287
|
get openCount() {
|
|
309
288
|
return this.activeDialogs.length;
|
|
310
289
|
}
|
|
@@ -314,6 +293,24 @@ class DialogService {
|
|
|
314
293
|
...config,
|
|
315
294
|
};
|
|
316
295
|
const dialogRef = new DialogRef(mergedConfig);
|
|
296
|
+
const positionStrategy = this.overlay
|
|
297
|
+
.position()
|
|
298
|
+
.global()
|
|
299
|
+
.centerHorizontally();
|
|
300
|
+
if (mergedConfig.position === 'top') {
|
|
301
|
+
positionStrategy.top('10vh');
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
positionStrategy.centerVertically();
|
|
305
|
+
}
|
|
306
|
+
const overlayRef = this.overlay.create({
|
|
307
|
+
hasBackdrop: mergedConfig.modal ?? true,
|
|
308
|
+
backdropClass: 'fk-dialog__backdrop',
|
|
309
|
+
panelClass: 'fk-dialog__pane',
|
|
310
|
+
scrollStrategy: this.overlay.scrollStrategies.block(),
|
|
311
|
+
positionStrategy,
|
|
312
|
+
disposeOnNavigation: true,
|
|
313
|
+
});
|
|
317
314
|
const childInjector = Injector.create({
|
|
318
315
|
parent: this.injector,
|
|
319
316
|
providers: [
|
|
@@ -321,32 +318,34 @@ class DialogService {
|
|
|
321
318
|
{ provide: DIALOG_REF, useValue: dialogRef },
|
|
322
319
|
],
|
|
323
320
|
});
|
|
324
|
-
const hostRef =
|
|
325
|
-
environmentInjector: this.injector,
|
|
326
|
-
elementInjector: childInjector,
|
|
327
|
-
});
|
|
321
|
+
const hostRef = overlayRef.attach(new ComponentPortal(DialogComponent, null, childInjector));
|
|
328
322
|
const contentRef = createComponent(content, {
|
|
329
323
|
environmentInjector: this.injector,
|
|
330
324
|
elementInjector: childInjector,
|
|
331
325
|
hostElement: this.doc.createElement('div'),
|
|
332
326
|
});
|
|
333
|
-
this.applyConfig(hostRef, mergedConfig);
|
|
334
|
-
this.appRef.attachView(hostRef.hostView);
|
|
335
327
|
this.appRef.attachView(contentRef.hostView);
|
|
336
|
-
this.doc.body.appendChild(hostRef.location.nativeElement);
|
|
337
328
|
const entry = {
|
|
338
329
|
ref: dialogRef,
|
|
330
|
+
overlayRef,
|
|
339
331
|
hostRef,
|
|
340
332
|
contentRef,
|
|
341
333
|
};
|
|
342
334
|
this.activeDialogs.push(entry);
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
335
|
+
this.applyConfig(hostRef, mergedConfig);
|
|
336
|
+
// CDK dispatches these to the top overlay only, so Escape / an outside
|
|
337
|
+
// press dismisses the topmost dialog. `dialogRef.close()` runs the
|
|
338
|
+
// preventClose + canClose guards.
|
|
339
|
+
overlayRef.keydownEvents().subscribe((event) => {
|
|
340
|
+
if (event.keyCode === ESCAPE && mergedConfig.closeOnEscape) {
|
|
341
|
+
dialogRef.close();
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
overlayRef.backdropClick().subscribe(() => {
|
|
345
|
+
if (mergedConfig.closeOnBackdrop) {
|
|
346
|
+
dialogRef.close();
|
|
347
|
+
}
|
|
348
348
|
});
|
|
349
|
-
this.overlayIds.set(entry, overlayId);
|
|
350
349
|
hostRef.instance.beforeOpen.subscribe(() => {
|
|
351
350
|
dialogRef.markBeforeOpen();
|
|
352
351
|
});
|
|
@@ -361,42 +360,26 @@ class DialogService {
|
|
|
361
360
|
});
|
|
362
361
|
hostRef.setInput('open', true);
|
|
363
362
|
hostRef.changeDetectorRef.detectChanges();
|
|
364
|
-
const panelBody =
|
|
363
|
+
const panelBody = overlayRef.overlayElement.querySelector('.fk-dialog__body');
|
|
365
364
|
if (panelBody) {
|
|
366
365
|
panelBody.appendChild(contentRef.location.nativeElement);
|
|
367
366
|
contentRef.changeDetectorRef.detectChanges();
|
|
368
|
-
// Move [libDialogFooter] elements out of body to the panel root
|
|
369
|
-
//
|
|
370
|
-
const panel = panelBody.
|
|
367
|
+
// Move [libDialogFooter] elements out of the body to the panel root so
|
|
368
|
+
// they render in the pinned footer area (after fk-dialog__body).
|
|
369
|
+
const panel = panelBody.closest('.fk-dialog__panel');
|
|
371
370
|
const footerEls = panelBody.querySelectorAll('[libDialogFooter]');
|
|
372
371
|
footerEls.forEach((el) => {
|
|
373
372
|
panel?.appendChild(el);
|
|
374
373
|
});
|
|
375
374
|
}
|
|
376
|
-
this.applyZIndex(entry);
|
|
377
375
|
return dialogRef;
|
|
378
376
|
}
|
|
379
377
|
closeAll() {
|
|
380
378
|
[...this.activeDialogs].forEach((entry) => entry.ref.close());
|
|
381
379
|
}
|
|
382
|
-
/** Returns true if the given entry is the topmost (last) active dialog. */
|
|
383
|
-
isTopmost(entry) {
|
|
384
|
-
return (this.activeDialogs.length > 0 &&
|
|
385
|
-
this.activeDialogs[this.activeDialogs.length - 1] === entry);
|
|
386
|
-
}
|
|
387
|
-
applyZIndex(entry) {
|
|
388
|
-
const index = this.activeDialogs.indexOf(entry);
|
|
389
|
-
const zIndex = BASE_Z_INDEX + index * Z_INDEX_STEP;
|
|
390
|
-
const overlay = entry.hostRef.location.nativeElement.querySelector('.fk-dialog__overlay');
|
|
391
|
-
if (overlay) {
|
|
392
|
-
overlay.style.zIndex = String(zIndex);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
380
|
applyConfig(hostRef, config) {
|
|
396
381
|
hostRef.setInput('modal', config.modal ?? true);
|
|
397
382
|
hostRef.setInput('closable', config.closable ?? true);
|
|
398
|
-
hostRef.setInput('closeOnEscape', config.closeOnEscape ?? true);
|
|
399
|
-
hostRef.setInput('closeOnBackdrop', config.closeOnBackdrop ?? false);
|
|
400
383
|
hostRef.setInput('size', config.size ?? 'md');
|
|
401
384
|
hostRef.setInput('position', config.position ?? 'center');
|
|
402
385
|
hostRef.setInput('animation', config.animation ?? 'scale-fade');
|
|
@@ -412,21 +395,19 @@ class DialogService {
|
|
|
412
395
|
hostRef.setInput('ariaDescribedBy', config.ariaDescribedBy ?? null);
|
|
413
396
|
}
|
|
414
397
|
destroyDialog(entry) {
|
|
415
|
-
const overlayId = this.overlayIds.get(entry);
|
|
416
|
-
if (overlayId) {
|
|
417
|
-
this.orchestrator.unregister(overlayId);
|
|
418
|
-
this.overlayIds.delete(entry);
|
|
419
|
-
}
|
|
420
398
|
const idx = this.activeDialogs.indexOf(entry);
|
|
421
399
|
if (idx > -1) {
|
|
422
400
|
this.activeDialogs.splice(idx, 1);
|
|
423
401
|
}
|
|
402
|
+
// Let the component restore focus before the overlay (and its hosted
|
|
403
|
+
// component) are torn down.
|
|
424
404
|
entry.hostRef.setInput('open', false);
|
|
425
405
|
entry.hostRef.changeDetectorRef.detectChanges();
|
|
426
406
|
this.appRef.detachView(entry.contentRef.hostView);
|
|
427
|
-
this.appRef.detachView(entry.hostRef.hostView);
|
|
428
407
|
entry.contentRef.destroy();
|
|
429
|
-
|
|
408
|
+
// Disposing the overlay detaches + destroys the hosted DialogComponent,
|
|
409
|
+
// removes the backdrop, and releases the scroll-block strategy.
|
|
410
|
+
entry.overlayRef.dispose();
|
|
430
411
|
}
|
|
431
412
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
432
413
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogService, providedIn: 'root' });
|