@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.
@@ -1 +1 @@
1
- {"version":3,"file":"frame-kit-ui-ng-ui-dialog.mjs","sources":["../../../../packages/ui-ng/ui/dialog/dialog-header.directive.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.html","../../../../packages/ui-ng/ui/dialog/dialog.config.ts","../../../../packages/ui-ng/ui/dialog/dialog-ref.ts","../../../../packages/ui-ng/ui/dialog/dialog.service.ts","../../../../packages/ui-ng/ui/dialog/dialog-actions.directive.ts","../../../../packages/ui-ng/ui/dialog/frame-kit-ui-ng-ui-dialog.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogHeader]',\n standalone: true,\n})\nexport class FkDialogHeaderDirective {}\n","import { A11yModule } from '@angular/cdk/a11y';\nimport { DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n DestroyRef,\n effect,\n HostBinding,\n HostListener,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\nimport { FkDialogHeaderDirective } from './dialog-header.directive';\n\nlet nextDialogId = 0;\n\n@Component({\n selector: 'fk-dialog',\n standalone: true,\n imports: [A11yModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './dialog.component.html',\n styleUrl: './dialog.component.scss',\n})\nexport class DialogComponent {\n // ===== INPUTS =====\n /** Controls whether the dialog is open. */\n readonly open = input(false);\n /** When true, renders a backdrop overlay behind the dialog. */\n readonly modal = input(true);\n /** When true, shows the close button in the dialog header. */\n readonly closable = input(true);\n /** When true, pressing Escape closes the dialog. */\n readonly closeOnEscape = input(true);\n /** When true, clicking the backdrop overlay closes the dialog. */\n readonly closeOnBackdrop = input(false);\n /** Size variant that controls the dialog's max-width. */\n readonly size = input<DialogSize>('md');\n /** Where the dialog is anchored on screen. */\n readonly position = input<DialogPosition>('center');\n /** Optional title text rendered in the dialog header and used for `aria-labelledby`. */\n readonly header = input<string | null>(null);\n /** When true, focus returns to the previously focused element when the dialog closes. */\n readonly restoreFocus = input(true);\n /** When true, CDK auto-focus is applied when the dialog opens. */\n readonly autoFocus = input(true);\n /** Entry/exit animation applied to the dialog panel. */\n readonly animation = input<DialogAnimation>('scale-fade');\n /** When true, all close mechanisms (Escape, backdrop, button) are blocked. */\n readonly preventClose = input(false);\n /** Async guard function called before closing; return false to cancel the close. */\n readonly canClose = input<CanCloseFn | null>(null);\n /** When true, the dialog expands to full-screen on mobile viewports. */\n readonly fullscreenMobile = input(false);\n /** When true, the dialog body uses a flex column layout. */\n readonly flexBody = input(false);\n\n // ===== CONTENT CHILDREN =====\n readonly customHeader = contentChild(FkDialogHeaderDirective);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n readonly ariaDescribedBy = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires when the dialog's open state should change, emitting the new boolean. */\n readonly openChange = output<boolean>();\n /** Fires immediately before the dialog begins its open animation. */\n readonly beforeOpen = output<void>();\n /** Fires after the dialog is fully open and visible. */\n readonly opened = output<void>();\n /** Fires immediately before the dialog begins its close animation. */\n readonly beforeClose = output<void>();\n /** Fires after the dialog is fully closed. */\n readonly closed = output<void>();\n\n // ===== INTERNAL STATE =====\n private readonly doc = inject(DOCUMENT);\n private readonly destroyRef = inject(DestroyRef);\n readonly titleId = `fk-dialog-title-${nextDialogId++}`;\n private previouslyFocusedElement: HTMLElement | null = null;\n private bodyScrollLocked = false;\n private closeGuardRunning = false;\n\n /** Whether the dialog DOM is rendered (stays true during exit animation). */\n readonly visible = signal(false);\n\n /** Whether the dialog is animating out. */\n readonly animatingOut = signal(false);\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return ['fk-dialog', this.className()].filter(Boolean).join(' ');\n });\n\n readonly ariaLabelledBy = computed(() => {\n if (this.ariaLabel()) {\n return null;\n }\n\n return this.header() ? this.titleId : null;\n });\n\n constructor() {\n effect(() => {\n const isOpen = this.open();\n\n if (isOpen) {\n this.onDialogOpen();\n } else {\n this.onDialogClose();\n }\n });\n\n this.destroyRef.onDestroy(() => {\n this.unlockBodyScroll();\n });\n }\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.id')\n get hostId() {\n return this.id();\n }\n\n // ===== KEYBOARD =====\n @HostListener('document:keydown.escape')\n onEscapeKey() {\n if (this.open() && this.closeOnEscape()) {\n this.close();\n }\n }\n\n // ===== ACTIONS =====\n /** Closes the dialog, running any `canClose` guard first; no-ops when `preventClose` is true. */\n async close() {\n if (this.closeGuardRunning) {\n return;\n }\n\n if (this.preventClose()) {\n return;\n }\n\n const guard = this.canClose();\n\n if (guard) {\n this.closeGuardRunning = true;\n\n try {\n const allowed = await Promise.resolve(guard());\n\n if (!allowed) {\n return;\n }\n } finally {\n this.closeGuardRunning = false;\n }\n }\n\n this.beforeClose.emit();\n this.openChange.emit(false);\n this.closed.emit();\n }\n\n onOverlayClick() {\n if (this.closeOnBackdrop()) {\n this.close();\n }\n }\n\n /** Called when the overlay exit animation finishes. */\n onExitAnimationDone() {\n if (this.animatingOut()) {\n this.animatingOut.set(false);\n this.visible.set(false);\n }\n }\n\n // ===== LIFECYCLE =====\n private onDialogOpen() {\n this.previouslyFocusedElement =\n (this.doc.activeElement as HTMLElement) ?? null;\n\n this.beforeOpen.emit();\n this.animatingOut.set(false);\n this.visible.set(true);\n\n if (this.modal()) {\n this.lockBodyScroll();\n }\n\n this.opened.emit();\n }\n\n private onDialogClose() {\n this.unlockBodyScroll();\n\n if (this.visible()) {\n if (this.animation() !== 'none') {\n this.animatingOut.set(true);\n } else {\n this.visible.set(false);\n }\n }\n\n if (this.restoreFocus() && this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n }\n\n // ===== SCROLL LOCK =====\n private lockBodyScroll() {\n if (!this.bodyScrollLocked) {\n this.doc.body.style.overflow = 'hidden';\n this.bodyScrollLocked = true;\n }\n }\n\n private unlockBodyScroll() {\n if (this.bodyScrollLocked) {\n this.doc.body.style.overflow = '';\n this.bodyScrollLocked = false;\n }\n }\n}\n","@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 &times;\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","import type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\n\nexport interface DialogConfig<TData = unknown> {\n modal?: boolean;\n closable?: boolean;\n closeOnEscape?: boolean;\n closeOnBackdrop?: boolean;\n size?: DialogSize;\n position?: DialogPosition;\n animation?: DialogAnimation;\n header?: string | null;\n restoreFocus?: boolean;\n autoFocus?: boolean;\n preventClose?: boolean;\n canClose?: CanCloseFn;\n fullscreenMobile?: boolean;\n flexBody?: boolean;\n className?: string;\n ariaLabel?: string | null;\n ariaDescribedBy?: string | null;\n data?: TData;\n}\n\nexport const DEFAULT_DIALOG_CONFIG: DialogConfig = {\n modal: true,\n closable: true,\n closeOnEscape: true,\n closeOnBackdrop: false,\n size: 'md',\n position: 'center',\n animation: 'scale-fade',\n header: null,\n restoreFocus: true,\n autoFocus: true,\n preventClose: false,\n fullscreenMobile: false,\n flexBody: false,\n className: '',\n ariaLabel: null,\n ariaDescribedBy: null,\n};\n","import { Observable, Subject } from 'rxjs';\nimport { take } from 'rxjs/operators';\n\nimport type { DialogConfig } from './dialog.config';\nimport type { CanCloseFn } from './dialog.types';\n\nexport class DialogRef<TResult = unknown, TData = unknown> {\n private readonly beforeOpenSubject = new Subject<void>();\n private readonly afterOpenedSubject = new Subject<void>();\n private readonly beforeCloseSubject = new Subject<void>();\n private readonly afterClosedSubject = new Subject<TResult | undefined>();\n private closed = false;\n private closeGuard: CanCloseFn | null = null;\n\n readonly config: DialogConfig<TData>;\n\n constructor(config: DialogConfig<TData> = {} as DialogConfig<TData>) {\n this.config = config;\n\n if (config.canClose) {\n this.closeGuard = config.canClose;\n }\n }\n\n get data(): TData | undefined {\n return this.config.data;\n }\n\n setCanClose(guard: CanCloseFn | null) {\n this.closeGuard = guard;\n }\n\n async close(result?: TResult) {\n if (this.closed) {\n return;\n }\n\n if (this.config.preventClose) {\n return;\n }\n\n if (this.closeGuard) {\n const allowed = await Promise.resolve(this.closeGuard());\n\n if (!allowed) {\n return;\n }\n }\n\n this.beforeCloseSubject.next();\n this.beforeCloseSubject.complete();\n\n this.closed = true;\n this.afterClosedSubject.next(result);\n this.afterClosedSubject.complete();\n }\n\n beforeOpen(): Observable<void> {\n return this.beforeOpenSubject.asObservable().pipe(take(1));\n }\n\n afterOpened(): Observable<void> {\n return this.afterOpenedSubject.asObservable().pipe(take(1));\n }\n\n beforeClose(): Observable<void> {\n return this.beforeCloseSubject.asObservable().pipe(take(1));\n }\n\n afterClosed(): Observable<TResult | undefined> {\n return this.afterClosedSubject.asObservable().pipe(take(1));\n }\n\n /** @internal */\n markBeforeOpen() {\n this.beforeOpenSubject.next();\n this.beforeOpenSubject.complete();\n }\n\n /** @internal */\n markOpened() {\n this.afterOpenedSubject.next();\n this.afterOpenedSubject.complete();\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport {\n ApplicationRef,\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n inject,\n Injectable,\n Injector,\n Type,\n} from '@angular/core';\n\nimport { OverlayOrchestrator } from '@frame-kit/ui-ng/services/overlay-orchestrator';\nimport { OVERLAY_PRIORITY } from '@frame-kit/ui-ng/services/overlay-orchestrator';\nimport { DialogComponent } from './dialog.component';\nimport { DEFAULT_DIALOG_CONFIG, DialogConfig } from './dialog.config';\nimport { DialogRef } from './dialog-ref';\n\nexport const DIALOG_DATA = Symbol('DIALOG_DATA');\nexport const DIALOG_REF = Symbol('DIALOG_REF');\n\nconst BASE_Z_INDEX = 1000;\nconst Z_INDEX_STEP = 10;\n\ninterface DialogEntry {\n ref: DialogRef;\n hostRef: ComponentRef<DialogComponent>;\n contentRef: ComponentRef<unknown>;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class DialogService {\n private readonly appRef = inject(ApplicationRef);\n private readonly injector = inject(EnvironmentInjector);\n private readonly doc = inject(DOCUMENT);\n private readonly orchestrator = inject(OverlayOrchestrator);\n\n private activeDialogs: DialogEntry[] = [];\n private overlayIds = new Map<DialogEntry, string>();\n\n get openCount(): number {\n return this.activeDialogs.length;\n }\n\n open<TResult = unknown, TData = unknown>(\n content: Type<unknown>,\n config?: DialogConfig<TData>,\n ): DialogRef<TResult, TData> {\n const mergedConfig = {\n ...DEFAULT_DIALOG_CONFIG,\n ...config,\n } as DialogConfig<TData>;\n const dialogRef = new DialogRef<TResult, TData>(mergedConfig);\n\n const childInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: DIALOG_DATA as never, useValue: mergedConfig.data },\n { provide: DIALOG_REF as never, useValue: dialogRef },\n ],\n });\n\n const hostRef = createComponent(DialogComponent, {\n environmentInjector: this.injector,\n elementInjector: childInjector,\n });\n\n const contentRef = createComponent(content, {\n environmentInjector: this.injector,\n elementInjector: childInjector,\n hostElement: this.doc.createElement('div'),\n });\n\n this.applyConfig(hostRef, mergedConfig);\n this.appRef.attachView(hostRef.hostView);\n this.appRef.attachView(contentRef.hostView);\n\n this.doc.body.appendChild(hostRef.location.nativeElement);\n\n const entry: DialogEntry = {\n ref: dialogRef as DialogRef<unknown, unknown>,\n hostRef,\n contentRef,\n };\n\n this.activeDialogs.push(entry);\n\n // Register with orchestrator — closes lower-priority overlays\n const overlayId = this.orchestrator.register({\n priority: OVERLAY_PRIORITY.DIALOG,\n type: 'dialog',\n close: () => dialogRef.close(),\n });\n\n this.overlayIds.set(entry, overlayId);\n\n hostRef.instance.beforeOpen.subscribe(() => {\n dialogRef.markBeforeOpen();\n });\n\n hostRef.instance.opened.subscribe(() => {\n dialogRef.markOpened();\n });\n\n hostRef.instance.closed.subscribe(() => {\n dialogRef.close();\n });\n\n dialogRef.afterClosed().subscribe(() => {\n this.destroyDialog(entry);\n });\n\n hostRef.setInput('open', true);\n hostRef.changeDetectorRef.detectChanges();\n\n const panelBody =\n hostRef.location.nativeElement.querySelector('.fk-dialog__body');\n\n if (panelBody) {\n panelBody.appendChild(contentRef.location.nativeElement);\n contentRef.changeDetectorRef.detectChanges();\n\n // Move [libDialogFooter] elements out of body to the panel root\n // so they render in the pinned footer area (after fk-dialog__body)\n const panel = panelBody.parentElement;\n const footerEls = panelBody.querySelectorAll('[libDialogFooter]');\n\n footerEls.forEach((el: Element) => {\n panel?.appendChild(el);\n });\n }\n\n this.applyZIndex(entry);\n\n return dialogRef;\n }\n\n closeAll() {\n [...this.activeDialogs].forEach((entry) => entry.ref.close());\n }\n\n /** Returns true if the given entry is the topmost (last) active dialog. */\n isTopmost(entry: DialogEntry): boolean {\n return (\n this.activeDialogs.length > 0 &&\n this.activeDialogs[this.activeDialogs.length - 1] === entry\n );\n }\n\n private applyZIndex(entry: DialogEntry) {\n const index = this.activeDialogs.indexOf(entry);\n const zIndex = BASE_Z_INDEX + index * Z_INDEX_STEP;\n const overlay = entry.hostRef.location.nativeElement.querySelector(\n '.fk-dialog__overlay',\n );\n\n if (overlay) {\n overlay.style.zIndex = String(zIndex);\n }\n }\n\n private applyConfig(\n hostRef: ComponentRef<DialogComponent>,\n config: DialogConfig,\n ) {\n hostRef.setInput('modal', config.modal ?? true);\n hostRef.setInput('closable', config.closable ?? true);\n hostRef.setInput('closeOnEscape', config.closeOnEscape ?? true);\n hostRef.setInput('closeOnBackdrop', config.closeOnBackdrop ?? false);\n hostRef.setInput('size', config.size ?? 'md');\n hostRef.setInput('position', config.position ?? 'center');\n hostRef.setInput('animation', config.animation ?? 'scale-fade');\n hostRef.setInput('header', config.header ?? null);\n hostRef.setInput('restoreFocus', config.restoreFocus ?? true);\n hostRef.setInput('autoFocus', config.autoFocus ?? true);\n hostRef.setInput('className', config.className ?? '');\n hostRef.setInput('preventClose', config.preventClose ?? false);\n hostRef.setInput('canClose', config.canClose ?? null);\n hostRef.setInput('fullscreenMobile', config.fullscreenMobile ?? false);\n hostRef.setInput('flexBody', config.flexBody ?? false);\n hostRef.setInput('ariaLabel', config.ariaLabel ?? null);\n hostRef.setInput('ariaDescribedBy', config.ariaDescribedBy ?? null);\n }\n\n private destroyDialog(entry: DialogEntry) {\n const overlayId = this.overlayIds.get(entry);\n\n if (overlayId) {\n this.orchestrator.unregister(overlayId);\n this.overlayIds.delete(entry);\n }\n\n const idx = this.activeDialogs.indexOf(entry);\n\n if (idx > -1) {\n this.activeDialogs.splice(idx, 1);\n }\n\n entry.hostRef.setInput('open', false);\n entry.hostRef.changeDetectorRef.detectChanges();\n\n this.appRef.detachView(entry.contentRef.hostView);\n this.appRef.detachView(entry.hostRef.hostView);\n\n entry.contentRef.destroy();\n entry.hostRef.destroy();\n }\n}\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogActions]',\n standalone: true,\n})\nexport class FkDialogActionsDirective {}\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-ui-dialog.mjs","sources":["../../../../packages/ui-ng/ui/dialog/dialog-header.directive.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.html","../../../../packages/ui-ng/ui/dialog/dialog.config.ts","../../../../packages/ui-ng/ui/dialog/dialog-ref.ts","../../../../packages/ui-ng/ui/dialog/dialog.service.ts","../../../../packages/ui-ng/ui/dialog/dialog-actions.directive.ts","../../../../packages/ui-ng/ui/dialog/frame-kit-ui-ng-ui-dialog.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogHeader]',\n standalone: true,\n})\nexport class FkDialogHeaderDirective {}\n","import { A11yModule } from '@angular/cdk/a11y';\nimport { DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n HostBinding,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\nimport { FkDialogHeaderDirective } from './dialog-header.directive';\n\nlet nextDialogId = 0;\n\n/**\n * Dialog panel chrome.\n *\n * Hosted inside a CDK overlay by `DialogService`, so the overlay layer owns\n * the backdrop, scroll blocking, positioning, stacking, and Escape / outside\n * dispatch. This component renders the panel itself: header / body / footer\n * projection, sizing, the enter animation, focus trapping, and the close\n * guard.\n */\n@Component({\n selector: 'fk-dialog',\n standalone: true,\n imports: [A11yModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './dialog.component.html',\n styleUrl: './dialog.component.scss',\n})\nexport class DialogComponent {\n // ===== INPUTS =====\n /** Controls whether the dialog is open. */\n readonly open = input(false);\n /** When true, marks the panel `aria-modal` and traps focus. */\n readonly modal = input(true);\n /** When true, shows the close button in the dialog header. */\n readonly closable = input(true);\n /** Size variant that controls the dialog's max-width. */\n readonly size = input<DialogSize>('md');\n /** Where the dialog is anchored on screen. */\n readonly position = input<DialogPosition>('center');\n /** Optional title text rendered in the dialog header and used for `aria-labelledby`. */\n readonly header = input<string | null>(null);\n /** When true, focus returns to the previously focused element when the dialog closes. */\n readonly restoreFocus = input(true);\n /** When true, CDK auto-focus is applied when the dialog opens. */\n readonly autoFocus = input(true);\n /** Entry/exit animation applied to the dialog panel. */\n readonly animation = input<DialogAnimation>('scale-fade');\n /** When true, all close mechanisms (Escape, backdrop, button) are blocked. */\n readonly preventClose = input(false);\n /** Async guard function called before closing; return false to cancel the close. */\n readonly canClose = input<CanCloseFn | null>(null);\n /** When true, the dialog expands to full-screen on mobile viewports. */\n readonly fullscreenMobile = input(false);\n /** When true, the dialog body uses a flex column layout. */\n readonly flexBody = input(false);\n\n // ===== CONTENT CHILDREN =====\n readonly customHeader = contentChild(FkDialogHeaderDirective);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n readonly ariaDescribedBy = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires when the dialog's open state should change, emitting the new boolean. */\n readonly openChange = output<boolean>();\n /** Fires immediately before the dialog begins its open animation. */\n readonly beforeOpen = output<void>();\n /** Fires after the dialog is fully open and visible. */\n readonly opened = output<void>();\n /** Fires immediately before the dialog begins its close animation. */\n readonly beforeClose = output<void>();\n /** Fires after the dialog is fully closed. */\n readonly closed = output<void>();\n\n // ===== INTERNAL STATE =====\n private readonly doc = inject(DOCUMENT);\n readonly titleId = `fk-dialog-title-${nextDialogId++}`;\n private previouslyFocusedElement: HTMLElement | null = null;\n private closeGuardRunning = false;\n\n /** Whether the dialog DOM is rendered (stays true during exit animation). */\n readonly visible = signal(false);\n\n /** Whether the dialog is animating out. */\n readonly animatingOut = signal(false);\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return ['fk-dialog', this.className()].filter(Boolean).join(' ');\n });\n\n readonly ariaLabelledBy = computed(() => {\n if (this.ariaLabel()) {\n return null;\n }\n\n return this.header() ? this.titleId : null;\n });\n\n constructor() {\n effect(() => {\n const isOpen = this.open();\n\n if (isOpen) {\n this.onDialogOpen();\n } else {\n this.onDialogClose();\n }\n });\n }\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.id')\n get hostId() {\n return this.id();\n }\n\n // ===== ACTIONS =====\n /** Closes the dialog, running any `canClose` guard first; no-ops when `preventClose` is true. */\n async close() {\n if (this.closeGuardRunning) {\n return;\n }\n\n if (this.preventClose()) {\n return;\n }\n\n const guard = this.canClose();\n\n if (guard) {\n this.closeGuardRunning = true;\n\n try {\n const allowed = await Promise.resolve(guard());\n\n if (!allowed) {\n return;\n }\n } finally {\n this.closeGuardRunning = false;\n }\n }\n\n this.beforeClose.emit();\n this.openChange.emit(false);\n this.closed.emit();\n }\n\n /** Called when the panel exit animation finishes. */\n onExitAnimationDone() {\n if (this.animatingOut()) {\n this.animatingOut.set(false);\n this.visible.set(false);\n }\n }\n\n // ===== LIFECYCLE =====\n private onDialogOpen() {\n this.previouslyFocusedElement =\n (this.doc.activeElement as HTMLElement) ?? null;\n\n this.beforeOpen.emit();\n this.animatingOut.set(false);\n this.visible.set(true);\n this.opened.emit();\n }\n\n private onDialogClose() {\n if (this.visible()) {\n if (this.animation() !== 'none') {\n this.animatingOut.set(true);\n } else {\n this.visible.set(false);\n }\n }\n\n if (this.restoreFocus() && this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n }\n}\n","@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 &times;\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","import type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\n\nexport interface DialogConfig<TData = unknown> {\n modal?: boolean;\n closable?: boolean;\n closeOnEscape?: boolean;\n closeOnBackdrop?: boolean;\n size?: DialogSize;\n position?: DialogPosition;\n animation?: DialogAnimation;\n header?: string | null;\n restoreFocus?: boolean;\n autoFocus?: boolean;\n preventClose?: boolean;\n canClose?: CanCloseFn;\n fullscreenMobile?: boolean;\n flexBody?: boolean;\n className?: string;\n ariaLabel?: string | null;\n ariaDescribedBy?: string | null;\n data?: TData;\n}\n\nexport const DEFAULT_DIALOG_CONFIG: DialogConfig = {\n modal: true,\n closable: true,\n closeOnEscape: true,\n closeOnBackdrop: false,\n size: 'md',\n position: 'center',\n animation: 'scale-fade',\n header: null,\n restoreFocus: true,\n autoFocus: true,\n preventClose: false,\n fullscreenMobile: false,\n flexBody: false,\n className: '',\n ariaLabel: null,\n ariaDescribedBy: null,\n};\n","import { Observable, Subject } from 'rxjs';\nimport { take } from 'rxjs/operators';\n\nimport type { DialogConfig } from './dialog.config';\nimport type { CanCloseFn } from './dialog.types';\n\nexport class DialogRef<TResult = unknown, TData = unknown> {\n private readonly beforeOpenSubject = new Subject<void>();\n private readonly afterOpenedSubject = new Subject<void>();\n private readonly beforeCloseSubject = new Subject<void>();\n private readonly afterClosedSubject = new Subject<TResult | undefined>();\n private closed = false;\n private closeGuard: CanCloseFn | null = null;\n\n readonly config: DialogConfig<TData>;\n\n constructor(config: DialogConfig<TData> = {} as DialogConfig<TData>) {\n this.config = config;\n\n if (config.canClose) {\n this.closeGuard = config.canClose;\n }\n }\n\n get data(): TData | undefined {\n return this.config.data;\n }\n\n setCanClose(guard: CanCloseFn | null) {\n this.closeGuard = guard;\n }\n\n async close(result?: TResult) {\n if (this.closed) {\n return;\n }\n\n if (this.config.preventClose) {\n return;\n }\n\n if (this.closeGuard) {\n const allowed = await Promise.resolve(this.closeGuard());\n\n if (!allowed) {\n return;\n }\n }\n\n this.beforeCloseSubject.next();\n this.beforeCloseSubject.complete();\n\n this.closed = true;\n this.afterClosedSubject.next(result);\n this.afterClosedSubject.complete();\n }\n\n beforeOpen(): Observable<void> {\n return this.beforeOpenSubject.asObservable().pipe(take(1));\n }\n\n afterOpened(): Observable<void> {\n return this.afterOpenedSubject.asObservable().pipe(take(1));\n }\n\n beforeClose(): Observable<void> {\n return this.beforeCloseSubject.asObservable().pipe(take(1));\n }\n\n afterClosed(): Observable<TResult | undefined> {\n return this.afterClosedSubject.asObservable().pipe(take(1));\n }\n\n /** @internal */\n markBeforeOpen() {\n this.beforeOpenSubject.next();\n this.beforeOpenSubject.complete();\n }\n\n /** @internal */\n markOpened() {\n this.afterOpenedSubject.next();\n this.afterOpenedSubject.complete();\n }\n}\n","import { ESCAPE } from '@angular/cdk/keycodes';\nimport { Overlay, OverlayRef } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { DOCUMENT } from '@angular/common';\nimport {\n ApplicationRef,\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n inject,\n Injectable,\n Injector,\n Type,\n} from '@angular/core';\n\nimport { DialogComponent } from './dialog.component';\nimport { DEFAULT_DIALOG_CONFIG, DialogConfig } from './dialog.config';\nimport { DialogRef } from './dialog-ref';\n\nexport const DIALOG_DATA = Symbol('DIALOG_DATA');\nexport const DIALOG_REF = Symbol('DIALOG_REF');\n\ninterface DialogEntry {\n ref: DialogRef;\n overlayRef: OverlayRef;\n hostRef: ComponentRef<DialogComponent>;\n contentRef: ComponentRef<unknown>;\n}\n\n/**\n * Opens dialogs as CDK overlays.\n *\n * CDK owns the cross-cutting overlay concerns — backdrop, scroll blocking,\n * centered positioning, z-index stacking (overlays layer by open order), and\n * top-of-stack dispatch of Escape / outside clicks. The `DialogComponent` it\n * hosts is just the panel chrome (header / body / footer, sizing, enter\n * animation, focus trap). There is no global \"opening X closes lower overlays\"\n * rule: a dialog opened over a drawer stacks on top of it, and Escape / an\n * outside press dismisses whichever overlay is on top.\n */\n@Injectable({ providedIn: 'root' })\nexport class DialogService {\n private readonly overlay = inject(Overlay);\n private readonly appRef = inject(ApplicationRef);\n private readonly injector = inject(EnvironmentInjector);\n private readonly doc = inject(DOCUMENT);\n\n private activeDialogs: DialogEntry[] = [];\n\n get openCount(): number {\n return this.activeDialogs.length;\n }\n\n open<TResult = unknown, TData = unknown>(\n content: Type<unknown>,\n config?: DialogConfig<TData>,\n ): DialogRef<TResult, TData> {\n const mergedConfig = {\n ...DEFAULT_DIALOG_CONFIG,\n ...config,\n } as DialogConfig<TData>;\n const dialogRef = new DialogRef<TResult, TData>(mergedConfig);\n\n const positionStrategy = this.overlay\n .position()\n .global()\n .centerHorizontally();\n\n if (mergedConfig.position === 'top') {\n positionStrategy.top('10vh');\n } else {\n positionStrategy.centerVertically();\n }\n\n const overlayRef = this.overlay.create({\n hasBackdrop: mergedConfig.modal ?? true,\n backdropClass: 'fk-dialog__backdrop',\n panelClass: 'fk-dialog__pane',\n scrollStrategy: this.overlay.scrollStrategies.block(),\n positionStrategy,\n disposeOnNavigation: true,\n });\n\n const childInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: DIALOG_DATA as never, useValue: mergedConfig.data },\n { provide: DIALOG_REF as never, useValue: dialogRef },\n ],\n });\n\n const hostRef = overlayRef.attach(\n new ComponentPortal(DialogComponent, null, childInjector),\n );\n\n const contentRef = createComponent(content, {\n environmentInjector: this.injector,\n elementInjector: childInjector,\n hostElement: this.doc.createElement('div'),\n });\n\n this.appRef.attachView(contentRef.hostView);\n\n const entry: DialogEntry = {\n ref: dialogRef as DialogRef<unknown, unknown>,\n overlayRef,\n hostRef,\n contentRef,\n };\n\n this.activeDialogs.push(entry);\n\n this.applyConfig(hostRef, mergedConfig);\n\n // CDK dispatches these to the top overlay only, so Escape / an outside\n // press dismisses the topmost dialog. `dialogRef.close()` runs the\n // preventClose + canClose guards.\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.keyCode === ESCAPE && mergedConfig.closeOnEscape) {\n dialogRef.close();\n }\n });\n\n overlayRef.backdropClick().subscribe(() => {\n if (mergedConfig.closeOnBackdrop) {\n dialogRef.close();\n }\n });\n\n hostRef.instance.beforeOpen.subscribe(() => {\n dialogRef.markBeforeOpen();\n });\n\n hostRef.instance.opened.subscribe(() => {\n dialogRef.markOpened();\n });\n\n hostRef.instance.closed.subscribe(() => {\n dialogRef.close();\n });\n\n dialogRef.afterClosed().subscribe(() => {\n this.destroyDialog(entry);\n });\n\n hostRef.setInput('open', true);\n hostRef.changeDetectorRef.detectChanges();\n\n const panelBody =\n overlayRef.overlayElement.querySelector('.fk-dialog__body');\n\n if (panelBody) {\n panelBody.appendChild(contentRef.location.nativeElement);\n contentRef.changeDetectorRef.detectChanges();\n\n // Move [libDialogFooter] elements out of the body to the panel root so\n // they render in the pinned footer area (after fk-dialog__body).\n const panel = panelBody.closest('.fk-dialog__panel');\n const footerEls = panelBody.querySelectorAll('[libDialogFooter]');\n\n footerEls.forEach((el: Element) => {\n panel?.appendChild(el);\n });\n }\n\n return dialogRef;\n }\n\n closeAll() {\n [...this.activeDialogs].forEach((entry) => entry.ref.close());\n }\n\n private applyConfig(\n hostRef: ComponentRef<DialogComponent>,\n config: DialogConfig,\n ) {\n hostRef.setInput('modal', config.modal ?? true);\n hostRef.setInput('closable', config.closable ?? true);\n hostRef.setInput('size', config.size ?? 'md');\n hostRef.setInput('position', config.position ?? 'center');\n hostRef.setInput('animation', config.animation ?? 'scale-fade');\n hostRef.setInput('header', config.header ?? null);\n hostRef.setInput('restoreFocus', config.restoreFocus ?? true);\n hostRef.setInput('autoFocus', config.autoFocus ?? true);\n hostRef.setInput('className', config.className ?? '');\n hostRef.setInput('preventClose', config.preventClose ?? false);\n hostRef.setInput('canClose', config.canClose ?? null);\n hostRef.setInput('fullscreenMobile', config.fullscreenMobile ?? false);\n hostRef.setInput('flexBody', config.flexBody ?? false);\n hostRef.setInput('ariaLabel', config.ariaLabel ?? null);\n hostRef.setInput('ariaDescribedBy', config.ariaDescribedBy ?? null);\n }\n\n private destroyDialog(entry: DialogEntry) {\n const idx = this.activeDialogs.indexOf(entry);\n\n if (idx > -1) {\n this.activeDialogs.splice(idx, 1);\n }\n\n // Let the component restore focus before the overlay (and its hosted\n // component) are torn down.\n entry.hostRef.setInput('open', false);\n entry.hostRef.changeDetectorRef.detectChanges();\n\n this.appRef.detachView(entry.contentRef.hostView);\n entry.contentRef.destroy();\n\n // Disposing the overlay detaches + destroys the hosted DialogComponent,\n // removes the backdrop, and releases the scroll-block strategy.\n entry.overlayRef.dispose();\n }\n}\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogActions]',\n standalone: true,\n})\nexport class FkDialogActionsDirective {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -2,22 +2,28 @@ 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 { input, output, inject, DestroyRef, signal, computed, effect, HostListener, HostBinding, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, Injector, createComponent, Injectable } from '@angular/core';
6
- import { OverlayOrchestrator, OVERLAY_PRIORITY } from '@frame-kit/ui-ng/services/overlay-orchestrator';
5
+ import { input, 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
 
10
12
  let nextDrawerId = 0;
13
+ /**
14
+ * Drawer panel chrome.
15
+ *
16
+ * Hosted inside a CDK overlay by `DrawerService`, which owns the backdrop,
17
+ * scroll blocking, positioning, stacking, and Escape / outside dispatch. This
18
+ * component renders the sliding panel: header / body / footer projection,
19
+ * width sizing, the slide animation, focus trapping, and the close guard.
20
+ */
11
21
  class DrawerComponent {
12
22
  // ===== INPUTS =====
13
23
  /** Controls whether the drawer is open. */
14
24
  open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
15
25
  /** When true, shows the close button in the drawer header. */
16
26
  closable = input(true, ...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
17
- /** When true, pressing Escape closes the drawer. */
18
- closeOnEscape = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscape" }] : /* istanbul ignore next */ []));
19
- /** When true, clicking the backdrop overlay closes the drawer. */
20
- closeOnBackdrop = input(true, ...(ngDevMode ? [{ debugName: "closeOnBackdrop" }] : /* istanbul ignore next */ []));
21
27
  /** Width variant of the drawer panel. */
22
28
  width = input('md', ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
23
29
  /** Optional title text rendered in the drawer header. */
@@ -49,7 +55,6 @@ class DrawerComponent {
49
55
  closed = output();
50
56
  // ===== INTERNAL STATE =====
51
57
  doc = inject(DOCUMENT);
52
- destroyRef = inject(DestroyRef);
53
58
  titleId = `fk-drawer-title-${nextDrawerId++}`;
54
59
  previouslyFocusedElement = null;
55
60
  closeGuardRunning = false;
@@ -75,9 +80,6 @@ class DrawerComponent {
75
80
  this.onDrawerClose();
76
81
  }
77
82
  });
78
- this.destroyRef.onDestroy(() => {
79
- // Placeholder for future cleanup (e.g., nested drawer teardown)
80
- });
81
83
  }
82
84
  get hostClass() {
83
85
  return this.classes();
@@ -85,12 +87,6 @@ class DrawerComponent {
85
87
  get hostId() {
86
88
  return this.id();
87
89
  }
88
- // ===== KEYBOARD =====
89
- onEscapeKey() {
90
- if (this.open() && this.closeOnEscape()) {
91
- this.close();
92
- }
93
- }
94
90
  // ===== ACTIONS =====
95
91
  /** Closes the drawer, running any `canClose` guard first; no-ops when `preventClose` is true. */
96
92
  async close() {
@@ -117,11 +113,7 @@ class DrawerComponent {
117
113
  this.openChange.emit(false);
118
114
  this.closed.emit();
119
115
  }
120
- onOverlayClick() {
121
- if (this.closeOnBackdrop()) {
122
- this.close();
123
- }
124
- }
116
+ /** Called when the panel exit animation finishes. */
125
117
  onExitAnimationDone() {
126
118
  if (this.animatingOut()) {
127
119
  this.animatingOut.set(false);
@@ -152,20 +144,17 @@ class DrawerComponent {
152
144
  }
153
145
  }
154
146
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
155
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DrawerComponent, isStandalone: true, selector: "fk-drawer", inputs: { open: { classPropertyName: "open", publicName: "open", 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 }, width: { classPropertyName: "width", publicName: "width", 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 }, 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 } }, 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" } }, 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-drawer__overlay\"\n [class.fk-drawer__animate-overlay--in]=\"!animatingOut()\"\n [class.fk-drawer__animate-overlay--out]=\"animatingOut()\"\n [class.fk-drawer__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-drawer__panel\"\n [class.fk-drawer__panel--sm]=\"width() === 'sm'\"\n [class.fk-drawer__panel--md]=\"width() === 'md'\"\n [class.fk-drawer__panel--lg]=\"width() === 'lg'\"\n [class.fk-drawer__panel--xl]=\"width() === 'xl'\"\n [class.fk-drawer__animate-panel--slide-right]=\"\n animation() === 'slide-right' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--slide-right]=\"\n animation() === 'slide-right' && animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [cdkTrapFocus]=\"true\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (header() || closable()) {\n <div class=\"fk-drawer__header\">\n @if (header()) {\n <span class=\"fk-drawer__title\" [id]=\"titleId\">\n {{ header() }}\n </span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-drawer__close\"\n type=\"button\"\n aria-label=\"Close drawer\"\n (click)=\"close()\"\n >\n &times;\n </button>\n }\n </div>\n }\n\n <div class=\"fk-drawer__body\">\n <ng-content />\n </div>\n\n <div class=\"fk-drawer__footer\">\n <ng-content select=\"[fkDrawerFooter]\" />\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.fk-drawer__overlay{position:fixed;top:var(--fk-drawer-bounds-top, 0);right:var(--fk-drawer-bounds-right, 0);bottom:var(--fk-drawer-bounds-bottom, 0);left:var(--fk-drawer-bounds-left, 0);z-index:var(--fk-drawer-overlay-z-index, 1050);display:flex;justify-content:flex-end;background-color:var(--fk-drawer-overlay-bg, var(--fk-overlay-bg, rgba(0, 0, 0, .4)))}.fk-drawer__panel{position:relative;display:flex;flex-direction:column;align-self:stretch;margin:var(--fk-drawer-margin-block, .375rem) 0;background-color:var(--fk-drawer-bg, var(--fk-color-surface, #ffffff));border-left:var(--fk-drawer-border-left, 1px solid var(--fk-drawer-border-color, var(--fk-color-border, #d9e2ee)));border-radius:var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem)) 0 0 var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-drawer-shadow, none);overflow:hidden}.fk-drawer__panel--sm{width:var(--fk-drawer-width-sm, 20rem)}.fk-drawer__panel--md{width:var(--fk-drawer-width-md, 26.25rem)}.fk-drawer__panel--lg{width:var(--fk-drawer-width-lg, 34rem)}.fk-drawer__panel--xl{width:var(--fk-drawer-width-xl, 44rem)}@media(max-width:47.999em){.fk-drawer__panel{margin:0;border-radius:0;width:100%}}.fk-drawer__header{display:flex;align-items:center;justify-content:space-between;gap:var(--fk-rhythm-3, .75rem);padding:var(--fk-drawer-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-bottom:1px solid var(--fk-drawer-header-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__title{font-family:var(--fk-drawer-title-font-family, var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui));font-size:var(--fk-drawer-title-font-size, var(--fk-typography-h4-font-size, 1.125rem));font-weight:var(--fk-drawer-title-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-drawer-title-color, var(--fk-color-text-strong, #0b1420))}.fk-drawer__close{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-drawer-close-size, 2rem);height:var(--fk-drawer-close-size, 2rem);padding:0;font-size:var(--fk-drawer-close-font-size, 1.25rem);line-height:1;color:var(--fk-drawer-close-color, var(--fk-color-muted, #8a98a8));background:none;border:none;border-radius:var(--fk-drawer-close-radius, var(--fk-radius-md, .375rem));cursor:pointer;transition:background-color .15s ease,color .15s ease}.fk-drawer__close:hover{color:var(--fk-drawer-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-drawer-close-bg-hover, var(--fk-color-surface-hover, #f5f7fa))}.fk-drawer__close:focus-visible{outline:none;box-shadow:var(--fk-drawer-close-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-drawer__body{flex:1;overflow-y:auto;padding:var(--fk-drawer-body-padding, var(--fk-rhythm-5, 1.25rem))}.fk-drawer__footer{flex-shrink:0;padding:var(--fk-drawer-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-top:1px solid var(--fk-drawer-footer-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__footer:empty{display:none}.fk-drawer__animate-overlay--in{animation:fk-drawer-overlay-in .2s ease-out forwards}.fk-drawer__animate-overlay--out{animation:fk-drawer-overlay-out .2s ease-in forwards}.fk-drawer__animate-overlay--none{animation:none}@keyframes fk-drawer-overlay-in{0%{opacity:0}to{opacity:1}}@keyframes fk-drawer-overlay-out{0%{opacity:1}to{opacity:0}}.fk-drawer__animate-panel--slide-right{animation:fk-drawer-slide-in .25s cubic-bezier(.4,0,.2,1) forwards}.fk-drawer__animate-panel-out--slide-right{animation:fk-drawer-slide-out .25s cubic-bezier(.4,0,.2,1) forwards}@keyframes fk-drawer-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes fk-drawer-slide-out{0%{transform:translate(0)}to{transform:translate(100%)}}.fk-drawer__animate-panel--fade{animation:fk-drawer-panel-fade-in .2s ease-out forwards}.fk-drawer__animate-panel-out--fade{animation:fk-drawer-panel-fade-out .2s ease-in forwards}@keyframes fk-drawer-panel-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-drawer-panel-fade-out{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.fk-drawer__animate-overlay--in,.fk-drawer__animate-overlay--out,.fk-drawer__animate-panel--slide-right,.fk-drawer__animate-panel-out--slide-right,.fk-drawer__animate-panel--fade,.fk-drawer__animate-panel-out--fade{animation:none}}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
147
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DrawerComponent, isStandalone: true, selector: "fk-drawer", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", 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 }, 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 } }, outputs: { openChange: "openChange", beforeOpen: "beforeOpen", opened: "opened", beforeClose: "beforeClose", closed: "closed" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, ngImport: i0, template: "@if (visible()) {\n <div\n class=\"fk-drawer__panel\"\n [class.fk-drawer__panel--sm]=\"width() === 'sm'\"\n [class.fk-drawer__panel--md]=\"width() === 'md'\"\n [class.fk-drawer__panel--lg]=\"width() === 'lg'\"\n [class.fk-drawer__panel--xl]=\"width() === 'xl'\"\n [class.fk-drawer__animate-panel--slide-right]=\"\n animation() === 'slide-right' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--slide-right]=\"\n animation() === 'slide-right' && animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [cdkTrapFocus]=\"true\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (header() || closable()) {\n <div class=\"fk-drawer__header\">\n @if (header()) {\n <span class=\"fk-drawer__title\" [id]=\"titleId\">\n {{ header() }}\n </span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-drawer__close\"\n type=\"button\"\n aria-label=\"Close drawer\"\n (click)=\"close()\"\n >\n &times;\n </button>\n }\n </div>\n }\n\n <div class=\"fk-drawer__body\">\n <ng-content />\n </div>\n\n <div class=\"fk-drawer__footer\">\n <ng-content select=\"[fkDrawerFooter]\" />\n </div>\n </div>\n}\n", styles: [":host{display:contents}.fk-drawer__panel{position:relative;display:flex;flex-direction:column;height:100%;background-color:var(--fk-drawer-bg, var(--fk-color-surface, #ffffff));border-left:var(--fk-drawer-border-left, 1px solid var(--fk-drawer-border-color, var(--fk-color-border, #d9e2ee)));border-radius:var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem)) 0 0 var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-drawer-shadow, none);overflow:hidden}.fk-drawer__panel--sm{width:var(--fk-drawer-width-sm, 20rem)}.fk-drawer__panel--md{width:var(--fk-drawer-width-md, 26.25rem)}.fk-drawer__panel--lg{width:var(--fk-drawer-width-lg, 34rem)}.fk-drawer__panel--xl{width:var(--fk-drawer-width-xl, 44rem)}@media(max-width:47.999em){.fk-drawer__panel{margin:0;border-radius:0;width:100%}}.fk-drawer__header{display:flex;align-items:center;justify-content:space-between;gap:var(--fk-rhythm-3, .75rem);padding:var(--fk-drawer-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-bottom:1px solid var(--fk-drawer-header-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__title{font-family:var(--fk-drawer-title-font-family, var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui));font-size:var(--fk-drawer-title-font-size, var(--fk-typography-h4-font-size, 1.125rem));font-weight:var(--fk-drawer-title-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-drawer-title-color, var(--fk-color-text-strong, #0b1420))}.fk-drawer__close{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-drawer-close-size, 2rem);height:var(--fk-drawer-close-size, 2rem);padding:0;font-size:var(--fk-drawer-close-font-size, 1.25rem);line-height:1;color:var(--fk-drawer-close-color, var(--fk-color-muted, #8a98a8));background:none;border:none;border-radius:var(--fk-drawer-close-radius, var(--fk-radius-md, .375rem));cursor:pointer;transition:background-color .15s ease,color .15s ease}.fk-drawer__close:hover{color:var(--fk-drawer-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-drawer-close-bg-hover, var(--fk-color-surface-hover, #f5f7fa))}.fk-drawer__close:focus-visible{outline:none;box-shadow:var(--fk-drawer-close-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-drawer__body{flex:1;overflow-y:auto;padding:var(--fk-drawer-body-padding, var(--fk-rhythm-5, 1.25rem))}.fk-drawer__footer{flex-shrink:0;padding:var(--fk-drawer-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-top:1px solid var(--fk-drawer-footer-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__footer:empty{display:none}.fk-drawer__animate-panel--slide-right{animation:fk-drawer-slide-in .25s cubic-bezier(.4,0,.2,1) forwards}.fk-drawer__animate-panel-out--slide-right{animation:fk-drawer-slide-out .25s cubic-bezier(.4,0,.2,1) forwards}@keyframes fk-drawer-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes fk-drawer-slide-out{0%{transform:translate(0)}to{transform:translate(100%)}}.fk-drawer__animate-panel--fade{animation:fk-drawer-panel-fade-in .2s ease-out forwards}.fk-drawer__animate-panel-out--fade{animation:fk-drawer-panel-fade-out .2s ease-in forwards}@keyframes fk-drawer-panel-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-drawer-panel-fade-out{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.fk-drawer__animate-panel--slide-right,.fk-drawer__animate-panel-out--slide-right,.fk-drawer__animate-panel--fade,.fk-drawer__animate-panel-out--fade{animation:none}}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
156
148
  }
157
149
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DrawerComponent, decorators: [{
158
150
  type: Component,
159
- args: [{ selector: 'fk-drawer', standalone: true, imports: [A11yModule], changeDetection: ChangeDetectionStrategy.OnPush, 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-drawer__overlay\"\n [class.fk-drawer__animate-overlay--in]=\"!animatingOut()\"\n [class.fk-drawer__animate-overlay--out]=\"animatingOut()\"\n [class.fk-drawer__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-drawer__panel\"\n [class.fk-drawer__panel--sm]=\"width() === 'sm'\"\n [class.fk-drawer__panel--md]=\"width() === 'md'\"\n [class.fk-drawer__panel--lg]=\"width() === 'lg'\"\n [class.fk-drawer__panel--xl]=\"width() === 'xl'\"\n [class.fk-drawer__animate-panel--slide-right]=\"\n animation() === 'slide-right' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--slide-right]=\"\n animation() === 'slide-right' && animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [cdkTrapFocus]=\"true\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (header() || closable()) {\n <div class=\"fk-drawer__header\">\n @if (header()) {\n <span class=\"fk-drawer__title\" [id]=\"titleId\">\n {{ header() }}\n </span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-drawer__close\"\n type=\"button\"\n aria-label=\"Close drawer\"\n (click)=\"close()\"\n >\n &times;\n </button>\n }\n </div>\n }\n\n <div class=\"fk-drawer__body\">\n <ng-content />\n </div>\n\n <div class=\"fk-drawer__footer\">\n <ng-content select=\"[fkDrawerFooter]\" />\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.fk-drawer__overlay{position:fixed;top:var(--fk-drawer-bounds-top, 0);right:var(--fk-drawer-bounds-right, 0);bottom:var(--fk-drawer-bounds-bottom, 0);left:var(--fk-drawer-bounds-left, 0);z-index:var(--fk-drawer-overlay-z-index, 1050);display:flex;justify-content:flex-end;background-color:var(--fk-drawer-overlay-bg, var(--fk-overlay-bg, rgba(0, 0, 0, .4)))}.fk-drawer__panel{position:relative;display:flex;flex-direction:column;align-self:stretch;margin:var(--fk-drawer-margin-block, .375rem) 0;background-color:var(--fk-drawer-bg, var(--fk-color-surface, #ffffff));border-left:var(--fk-drawer-border-left, 1px solid var(--fk-drawer-border-color, var(--fk-color-border, #d9e2ee)));border-radius:var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem)) 0 0 var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-drawer-shadow, none);overflow:hidden}.fk-drawer__panel--sm{width:var(--fk-drawer-width-sm, 20rem)}.fk-drawer__panel--md{width:var(--fk-drawer-width-md, 26.25rem)}.fk-drawer__panel--lg{width:var(--fk-drawer-width-lg, 34rem)}.fk-drawer__panel--xl{width:var(--fk-drawer-width-xl, 44rem)}@media(max-width:47.999em){.fk-drawer__panel{margin:0;border-radius:0;width:100%}}.fk-drawer__header{display:flex;align-items:center;justify-content:space-between;gap:var(--fk-rhythm-3, .75rem);padding:var(--fk-drawer-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-bottom:1px solid var(--fk-drawer-header-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__title{font-family:var(--fk-drawer-title-font-family, var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui));font-size:var(--fk-drawer-title-font-size, var(--fk-typography-h4-font-size, 1.125rem));font-weight:var(--fk-drawer-title-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-drawer-title-color, var(--fk-color-text-strong, #0b1420))}.fk-drawer__close{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-drawer-close-size, 2rem);height:var(--fk-drawer-close-size, 2rem);padding:0;font-size:var(--fk-drawer-close-font-size, 1.25rem);line-height:1;color:var(--fk-drawer-close-color, var(--fk-color-muted, #8a98a8));background:none;border:none;border-radius:var(--fk-drawer-close-radius, var(--fk-radius-md, .375rem));cursor:pointer;transition:background-color .15s ease,color .15s ease}.fk-drawer__close:hover{color:var(--fk-drawer-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-drawer-close-bg-hover, var(--fk-color-surface-hover, #f5f7fa))}.fk-drawer__close:focus-visible{outline:none;box-shadow:var(--fk-drawer-close-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-drawer__body{flex:1;overflow-y:auto;padding:var(--fk-drawer-body-padding, var(--fk-rhythm-5, 1.25rem))}.fk-drawer__footer{flex-shrink:0;padding:var(--fk-drawer-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-top:1px solid var(--fk-drawer-footer-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__footer:empty{display:none}.fk-drawer__animate-overlay--in{animation:fk-drawer-overlay-in .2s ease-out forwards}.fk-drawer__animate-overlay--out{animation:fk-drawer-overlay-out .2s ease-in forwards}.fk-drawer__animate-overlay--none{animation:none}@keyframes fk-drawer-overlay-in{0%{opacity:0}to{opacity:1}}@keyframes fk-drawer-overlay-out{0%{opacity:1}to{opacity:0}}.fk-drawer__animate-panel--slide-right{animation:fk-drawer-slide-in .25s cubic-bezier(.4,0,.2,1) forwards}.fk-drawer__animate-panel-out--slide-right{animation:fk-drawer-slide-out .25s cubic-bezier(.4,0,.2,1) forwards}@keyframes fk-drawer-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes fk-drawer-slide-out{0%{transform:translate(0)}to{transform:translate(100%)}}.fk-drawer__animate-panel--fade{animation:fk-drawer-panel-fade-in .2s ease-out forwards}.fk-drawer__animate-panel-out--fade{animation:fk-drawer-panel-fade-out .2s ease-in forwards}@keyframes fk-drawer-panel-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-drawer-panel-fade-out{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.fk-drawer__animate-overlay--in,.fk-drawer__animate-overlay--out,.fk-drawer__animate-panel--slide-right,.fk-drawer__animate-panel-out--slide-right,.fk-drawer__animate-panel--fade,.fk-drawer__animate-panel-out--fade{animation:none}}\n"] }]
160
- }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeOnBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdrop", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", 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 }] }], 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 }] }], 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: [{
151
+ args: [{ selector: 'fk-drawer', standalone: true, imports: [A11yModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (visible()) {\n <div\n class=\"fk-drawer__panel\"\n [class.fk-drawer__panel--sm]=\"width() === 'sm'\"\n [class.fk-drawer__panel--md]=\"width() === 'md'\"\n [class.fk-drawer__panel--lg]=\"width() === 'lg'\"\n [class.fk-drawer__panel--xl]=\"width() === 'xl'\"\n [class.fk-drawer__animate-panel--slide-right]=\"\n animation() === 'slide-right' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--slide-right]=\"\n animation() === 'slide-right' && animatingOut()\n \"\n [class.fk-drawer__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [cdkTrapFocus]=\"true\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (header() || closable()) {\n <div class=\"fk-drawer__header\">\n @if (header()) {\n <span class=\"fk-drawer__title\" [id]=\"titleId\">\n {{ header() }}\n </span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-drawer__close\"\n type=\"button\"\n aria-label=\"Close drawer\"\n (click)=\"close()\"\n >\n &times;\n </button>\n }\n </div>\n }\n\n <div class=\"fk-drawer__body\">\n <ng-content />\n </div>\n\n <div class=\"fk-drawer__footer\">\n <ng-content select=\"[fkDrawerFooter]\" />\n </div>\n </div>\n}\n", styles: [":host{display:contents}.fk-drawer__panel{position:relative;display:flex;flex-direction:column;height:100%;background-color:var(--fk-drawer-bg, var(--fk-color-surface, #ffffff));border-left:var(--fk-drawer-border-left, 1px solid var(--fk-drawer-border-color, var(--fk-color-border, #d9e2ee)));border-radius:var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem)) 0 0 var(--fk-drawer-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-drawer-shadow, none);overflow:hidden}.fk-drawer__panel--sm{width:var(--fk-drawer-width-sm, 20rem)}.fk-drawer__panel--md{width:var(--fk-drawer-width-md, 26.25rem)}.fk-drawer__panel--lg{width:var(--fk-drawer-width-lg, 34rem)}.fk-drawer__panel--xl{width:var(--fk-drawer-width-xl, 44rem)}@media(max-width:47.999em){.fk-drawer__panel{margin:0;border-radius:0;width:100%}}.fk-drawer__header{display:flex;align-items:center;justify-content:space-between;gap:var(--fk-rhythm-3, .75rem);padding:var(--fk-drawer-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-bottom:1px solid var(--fk-drawer-header-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__title{font-family:var(--fk-drawer-title-font-family, var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui));font-size:var(--fk-drawer-title-font-size, var(--fk-typography-h4-font-size, 1.125rem));font-weight:var(--fk-drawer-title-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-drawer-title-color, var(--fk-color-text-strong, #0b1420))}.fk-drawer__close{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-drawer-close-size, 2rem);height:var(--fk-drawer-close-size, 2rem);padding:0;font-size:var(--fk-drawer-close-font-size, 1.25rem);line-height:1;color:var(--fk-drawer-close-color, var(--fk-color-muted, #8a98a8));background:none;border:none;border-radius:var(--fk-drawer-close-radius, var(--fk-radius-md, .375rem));cursor:pointer;transition:background-color .15s ease,color .15s ease}.fk-drawer__close:hover{color:var(--fk-drawer-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-drawer-close-bg-hover, var(--fk-color-surface-hover, #f5f7fa))}.fk-drawer__close:focus-visible{outline:none;box-shadow:var(--fk-drawer-close-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-drawer__body{flex:1;overflow-y:auto;padding:var(--fk-drawer-body-padding, var(--fk-rhythm-5, 1.25rem))}.fk-drawer__footer{flex-shrink:0;padding:var(--fk-drawer-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-5, 1.25rem));border-top:1px solid var(--fk-drawer-footer-border-color, var(--fk-color-border, #d9e2ee))}.fk-drawer__footer:empty{display:none}.fk-drawer__animate-panel--slide-right{animation:fk-drawer-slide-in .25s cubic-bezier(.4,0,.2,1) forwards}.fk-drawer__animate-panel-out--slide-right{animation:fk-drawer-slide-out .25s cubic-bezier(.4,0,.2,1) forwards}@keyframes fk-drawer-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes fk-drawer-slide-out{0%{transform:translate(0)}to{transform:translate(100%)}}.fk-drawer__animate-panel--fade{animation:fk-drawer-panel-fade-in .2s ease-out forwards}.fk-drawer__animate-panel-out--fade{animation:fk-drawer-panel-fade-out .2s ease-in forwards}@keyframes fk-drawer-panel-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-drawer-panel-fade-out{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.fk-drawer__animate-panel--slide-right,.fk-drawer__animate-panel-out--slide-right,.fk-drawer__animate-panel--fade,.fk-drawer__animate-panel-out--fade{animation:none}}\n"] }]
152
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", 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 }] }], 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 }] }], 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: [{
161
153
  type: HostBinding,
162
154
  args: ['class']
163
155
  }], hostId: [{
164
156
  type: HostBinding,
165
157
  args: ['attr.id']
166
- }], onEscapeKey: [{
167
- type: HostListener,
168
- args: ['document:keydown.escape']
169
158
  }] } });
170
159
 
171
160
  const DEFAULT_DRAWER_CONFIG = {
@@ -247,15 +236,21 @@ class DrawerRef {
247
236
 
248
237
  const DRAWER_DATA = Symbol('DRAWER_DATA');
249
238
  const DRAWER_REF = Symbol('DRAWER_REF');
250
- const BASE_Z_INDEX = 1100;
251
- const Z_INDEX_STEP = 10;
239
+ /**
240
+ * Opens drawers as CDK overlays pinned to the right edge.
241
+ *
242
+ * CDK owns the backdrop, scroll blocking, positioning, z-index stacking, and
243
+ * top-of-stack Escape / outside dispatch. The hosted `DrawerComponent` is the
244
+ * panel chrome (header / body / footer, the slide animation, focus trap). A
245
+ * drawer and a dialog opened over it coexist — the dialog stacks on top by
246
+ * open order, and the drawer is no longer evicted.
247
+ */
252
248
  class DrawerService {
249
+ overlay = inject(Overlay);
253
250
  appRef = inject(ApplicationRef);
254
251
  injector = inject(EnvironmentInjector);
255
252
  doc = inject(DOCUMENT);
256
- orchestrator = inject(OverlayOrchestrator);
257
253
  activeDrawers = [];
258
- overlayIds = new Map();
259
254
  get openCount() {
260
255
  return this.activeDrawers.length;
261
256
  }
@@ -265,6 +260,15 @@ class DrawerService {
265
260
  ...config,
266
261
  };
267
262
  const drawerRef = new DrawerRef(mergedConfig);
263
+ const overlayRef = this.overlay.create({
264
+ hasBackdrop: true,
265
+ backdropClass: 'fk-drawer__backdrop',
266
+ panelClass: 'fk-drawer__pane',
267
+ scrollStrategy: this.overlay.scrollStrategies.block(),
268
+ positionStrategy: this.overlay.position().global().right('0').top('0'),
269
+ height: '100%',
270
+ disposeOnNavigation: true,
271
+ });
268
272
  const childInjector = Injector.create({
269
273
  parent: this.injector,
270
274
  providers: [
@@ -272,31 +276,31 @@ class DrawerService {
272
276
  { provide: DRAWER_REF, useValue: drawerRef },
273
277
  ],
274
278
  });
275
- const hostRef = createComponent(DrawerComponent, {
276
- environmentInjector: this.injector,
277
- elementInjector: childInjector,
278
- });
279
+ const hostRef = overlayRef.attach(new ComponentPortal(DrawerComponent, null, childInjector));
279
280
  const contentRef = createComponent(content, {
280
281
  environmentInjector: this.injector,
281
282
  elementInjector: childInjector,
282
283
  hostElement: this.doc.createElement('div'),
283
284
  });
284
- this.applyConfig(hostRef, mergedConfig);
285
- this.appRef.attachView(hostRef.hostView);
286
285
  this.appRef.attachView(contentRef.hostView);
287
- this.doc.body.appendChild(hostRef.location.nativeElement);
288
286
  const entry = {
289
287
  ref: drawerRef,
288
+ overlayRef,
290
289
  hostRef,
291
290
  contentRef,
292
291
  };
293
292
  this.activeDrawers.push(entry);
294
- const overlayId = this.orchestrator.register({
295
- priority: OVERLAY_PRIORITY.DRAWER,
296
- type: 'drawer',
297
- close: () => drawerRef.close(),
293
+ this.applyConfig(hostRef, mergedConfig);
294
+ overlayRef.keydownEvents().subscribe((event) => {
295
+ if (event.keyCode === ESCAPE && mergedConfig.closeOnEscape) {
296
+ drawerRef.close();
297
+ }
298
+ });
299
+ overlayRef.backdropClick().subscribe(() => {
300
+ if (mergedConfig.closeOnBackdrop) {
301
+ drawerRef.close();
302
+ }
298
303
  });
299
- this.overlayIds.set(entry, overlayId);
300
304
  hostRef.instance.beforeOpen.subscribe(() => {
301
305
  drawerRef.markBeforeOpen();
302
306
  });
@@ -311,50 +315,26 @@ class DrawerService {
311
315
  });
312
316
  hostRef.setInput('open', true);
313
317
  hostRef.changeDetectorRef.detectChanges();
314
- const panelBody = hostRef.location.nativeElement.querySelector('.fk-drawer__body');
318
+ const panelBody = overlayRef.overlayElement.querySelector('.fk-drawer__body');
315
319
  if (panelBody) {
316
320
  panelBody.appendChild(contentRef.location.nativeElement);
317
- }
318
- // Move [fkDrawerFooter] elements from the body into the footer wrapper
319
- const footerWrapper = hostRef.location.nativeElement.querySelector('.fk-drawer__footer');
320
- if (footerWrapper && panelBody) {
321
+ contentRef.changeDetectorRef.detectChanges();
322
+ // Move [fkDrawerFooter] elements from the body into the footer wrapper.
323
+ const footerWrapper = overlayRef.overlayElement.querySelector('.fk-drawer__footer');
321
324
  const footerElements = panelBody.querySelectorAll('[fkDrawerFooter]');
322
- for (const el of footerElements) {
323
- footerWrapper.appendChild(el);
325
+ if (footerWrapper) {
326
+ footerElements.forEach((el) => {
327
+ footerWrapper.appendChild(el);
328
+ });
324
329
  }
325
330
  }
326
- // Position the overlay to match the container's bounds
327
- if (mergedConfig.container) {
328
- this.applyContainerBounds(entry, mergedConfig.container);
329
- }
330
- this.applyZIndex(entry);
331
331
  return drawerRef;
332
332
  }
333
333
  closeAll() {
334
334
  [...this.activeDrawers].forEach((entry) => entry.ref.close());
335
335
  }
336
- applyContainerBounds(entry, container) {
337
- const rect = container.getBoundingClientRect();
338
- const overlay = entry.hostRef.location.nativeElement.querySelector('.fk-drawer__overlay');
339
- if (overlay) {
340
- overlay.style.setProperty('--fk-drawer-bounds-top', `${rect.top}px`);
341
- overlay.style.setProperty('--fk-drawer-bounds-right', `${window.innerWidth - rect.right}px`);
342
- overlay.style.setProperty('--fk-drawer-bounds-bottom', `${window.innerHeight - rect.bottom}px`);
343
- overlay.style.setProperty('--fk-drawer-bounds-left', `${rect.left}px`);
344
- }
345
- }
346
- applyZIndex(entry) {
347
- const index = this.activeDrawers.indexOf(entry);
348
- const zIndex = BASE_Z_INDEX + index * Z_INDEX_STEP;
349
- const overlay = entry.hostRef.location.nativeElement.querySelector('.fk-drawer__overlay');
350
- if (overlay) {
351
- overlay.style.zIndex = String(zIndex);
352
- }
353
- }
354
336
  applyConfig(hostRef, config) {
355
337
  hostRef.setInput('closable', config.closable ?? true);
356
- hostRef.setInput('closeOnEscape', config.closeOnEscape ?? true);
357
- hostRef.setInput('closeOnBackdrop', config.closeOnBackdrop ?? true);
358
338
  hostRef.setInput('width', config.width ?? 'md');
359
339
  hostRef.setInput('animation', config.animation ?? 'slide-right');
360
340
  hostRef.setInput('header', config.header ?? null);
@@ -366,11 +346,6 @@ class DrawerService {
366
346
  hostRef.setInput('ariaLabel', config.ariaLabel ?? null);
367
347
  }
368
348
  destroyDrawer(entry) {
369
- const overlayId = this.overlayIds.get(entry);
370
- if (overlayId) {
371
- this.orchestrator.unregister(overlayId);
372
- this.overlayIds.delete(entry);
373
- }
374
349
  const idx = this.activeDrawers.indexOf(entry);
375
350
  if (idx > -1) {
376
351
  this.activeDrawers.splice(idx, 1);
@@ -378,9 +353,8 @@ class DrawerService {
378
353
  entry.hostRef.setInput('open', false);
379
354
  entry.hostRef.changeDetectorRef.detectChanges();
380
355
  this.appRef.detachView(entry.contentRef.hostView);
381
- this.appRef.detachView(entry.hostRef.hostView);
382
356
  entry.contentRef.destroy();
383
- entry.hostRef.destroy();
357
+ entry.overlayRef.dispose();
384
358
  }
385
359
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DrawerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
386
360
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DrawerService, providedIn: 'root' });