import * as i0 from '@angular/core';
import { InjectionToken, inject, ChangeDetectorRef, viewChild, EventEmitter, Component, Injector, Injectable, input, Directive } from '@angular/core';
import { Subject, filter, take } from 'rxjs';
import * as i1 from '@angular/cdk/dialog';
import { CdkDialogContainer, DialogModule, Dialog as Dialog$1 } from '@angular/cdk/dialog';
import { filter as filter$1, take as take$1 } from 'rxjs/operators';
import { CdkPortalOutlet } from '@angular/cdk/portal';

class DialogConfig {
    data = null;
    width = '';
    height = '';
    minWidth;
    minHeight;
    maxWidth;
    maxHeight;
    hasBackdrop = true;
    backdropClass = 'ngs-dialog-backdrop';
    panelClass = '';
    disableClose = false;
    autoFocus = 'first-tabbable';
    restoreFocus = true;
    ariaDescribedBy = null;
    ariaLabelledBy = null;
    ariaLabel = null;
    role = 'dialog';
    closeOnNavigation = true;
}
const DIALOG_DATA = new InjectionToken('DialogData');
const DIALOG_DEFAULT_OPTIONS = new InjectionToken('DialogConfig');

class DialogRef {
    _afterClosed = new Subject();
    _afterOpened = new Subject();
    _backdropClick = new Subject();
    _keydownEvents = new Subject();
    componentInstance = null;
    disableClose;
    /** @internal */
    _cdkRef;
    /** @internal */
    _container;
    _isClosing = false;
    close(dialogResult) {
        if (this._isClosing) {
            return;
        }
        this._isClosing = true;
        if (this._container && this._cdkRef) {
            // Start exit animation for the container
            this._container._startExitAnimation();
            // Start exit animation for the backdrop
            const overlayRef = this._cdkRef.overlayRef;
            const backdropElement = overlayRef.backdropElement;
            if (backdropElement) {
                // Remove both classes that could be forcing opacity: 1
                backdropElement.classList.remove('ngs-dialog-backdrop-showing');
                backdropElement.classList.remove('cdk-overlay-backdrop-showing');
            }
            // Wait for the container animation to finish before destroying the overlay
            this._container._animationStateChanged
                .pipe(filter((event) => event.phaseName === 'done' && event.toState === 'exit'), take(1))
                .subscribe(() => {
                this._finishClose(dialogResult);
            });
            // Fallback in case transitionend never fires (e.g. if opacity was already 0 or style didn't apply)
            setTimeout(() => {
                if (this._isClosing && this._cdkRef) {
                    this._finishClose(dialogResult);
                }
            }, 250);
            return;
        }
        this._finishClose(dialogResult);
    }
    _finishClose(dialogResult) {
        if (this._cdkRef) {
            const cdkRef = this._cdkRef;
            this._cdkRef = null;
            cdkRef.close(dialogResult);
        }
        this._afterClosed.next(dialogResult);
        this._afterClosed.complete();
        this._afterOpened.complete();
        this._backdropClick.complete();
        this._keydownEvents.complete();
    }
    afterClosed() {
        return this._afterClosed.asObservable();
    }
    afterOpened() {
        return this._afterOpened.asObservable();
    }
    backdropClick() {
        return this._backdropClick.asObservable();
    }
    keydownEvents() {
        return this._keydownEvents.asObservable();
    }
    __fireAfterOpened() {
        this._afterOpened.next();
    }
    __fireBackdropClick(event) {
        this._backdropClick.next(event);
    }
    __fireKeydownEvent(event) {
        this._keydownEvents.next(event);
    }
}

class DialogContainer extends CdkDialogContainer {
    _cdr = inject(ChangeDetectorRef);
    _portalOutlet = viewChild(CdkPortalOutlet);
    /** State of the dialog animation. */
    _animationState = 'void';
    /** Emits when an animation state changes. */
    _animationStateChanged = new EventEmitter();
    ngOnInit() {
        const config = this._config;
        if (config) {
            const element = this._elementRef.nativeElement;
            if (config.maxWidth) {
                element.style.setProperty('--ngs-dialog-container-max-width', this._formatValue(config.maxWidth));
            }
            if (config.minWidth) {
                element.style.setProperty('--ngs-dialog-container-min-width', this._formatValue(config.minWidth));
            }
            if (config.width) {
                element.style.setProperty('--ngs-dialog-container-max-width', 'none');
            }
        }
    }
    _formatValue(value) {
        return typeof value === 'number' ? `${value}px` : value;
    }
    _onTransitionEnd(event) {
        if (event.propertyName === 'opacity' && event.target === event.currentTarget) {
            this._animationStateChanged.emit({
                fromState: this._animationState === 'enter' ? 'void' : 'enter',
                toState: this._animationState,
                totalTime: 150,
                phaseName: 'done',
            });
        }
    }
    /** Starts the dialog enter animation. */
    _startEnterAnimation() {
        this._animationState = 'enter';
        this._cdr.markForCheck();
    }
    /** Starts the dialog exit animation. */
    _startExitAnimation() {
        this._animationState = 'exit';
        this._cdr.markForCheck();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogContainer, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.4", type: DialogContainer, isStandalone: true, selector: "ngs-dialog-container", host: { listeners: { "transitionend": "_onTransitionEnd($event)" }, properties: { "class.ngs-dialog-container-enter": "_animationState === \"enter\"", "class.ngs-dialog-container-exit": "_animationState === \"exit\"" }, classAttribute: "ngs-dialog-container" }, viewQueries: [{ propertyName: "_portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-template cdkPortalOutlet />\n", styles: [":host{background:var(--ngs-dialog-background, var(--ngs-dialog-bg));color:var(--ngs-dialog-color, var(--ngs-color-on-surface));border-radius:var(--ngs-dialog-border-radius, var(--ngs-dialog-radius));box-shadow:var(--ngs-dialog-box-shadow, var(--ngs-dialog-shadow));max-width:var(--ngs-dialog-container-max-width, 560px);min-width:var(--ngs-dialog-container-min-width, 280px);width:100%;height:100%;max-height:inherit;min-height:inherit;box-sizing:border-box;outline:0;overflow:hidden;margin:auto;opacity:0;transform:scale(.8);position:relative;display:flex;flex-direction:column}:host.ngs-dialog-container-enter{opacity:1;transform:scale(1);transition:opacity linear .15s,transform .2s cubic-bezier(0,0,.2,1)}:host.ngs-dialog-container-exit{opacity:0}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "directive", type: i1.ɵɵCdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogContainer, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-dialog-container', imports: [DialogModule], host: {
                        'class': 'ngs-dialog-container',
                        '[class.ngs-dialog-container-enter]': '_animationState === "enter"',
                        '[class.ngs-dialog-container-exit]': '_animationState === "exit"',
                        '(transitionend)': '_onTransitionEnd($event)',
                    }, template: "<ng-template cdkPortalOutlet />\n", styles: [":host{background:var(--ngs-dialog-background, var(--ngs-dialog-bg));color:var(--ngs-dialog-color, var(--ngs-color-on-surface));border-radius:var(--ngs-dialog-border-radius, var(--ngs-dialog-radius));box-shadow:var(--ngs-dialog-box-shadow, var(--ngs-dialog-shadow));max-width:var(--ngs-dialog-container-max-width, 560px);min-width:var(--ngs-dialog-container-min-width, 280px);width:100%;height:100%;max-height:inherit;min-height:inherit;box-sizing:border-box;outline:0;overflow:hidden;margin:auto;opacity:0;transform:scale(.8);position:relative;display:flex;flex-direction:column}:host.ngs-dialog-container-enter{opacity:1;transform:scale(1);transition:opacity linear .15s,transform .2s cubic-bezier(0,0,.2,1)}:host.ngs-dialog-container-exit{opacity:0}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], propDecorators: { _portalOutlet: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkPortalOutlet), { isSignal: true }] }] } });

class Dialog {
    _cdkDialog = inject(Dialog$1);
    _injector = inject(Injector);
    _defaultOptions = inject(DIALOG_DEFAULT_OPTIONS, { optional: true });
    open(componentOrTemplateRef, config) {
        const dialogRef = new DialogRef();
        const mergedConfig = { ...new DialogConfig(), ...this._defaultOptions, ...config };
        // Set default maxWidth if not specified and no width is set
        if (!mergedConfig.maxWidth && !mergedConfig.width) {
            mergedConfig.maxWidth = 560;
        }
        // Set default minWidth if not specified
        if (!mergedConfig.minWidth) {
            mergedConfig.minWidth = 280;
        }
        let container;
        const cdkConfig = {
            ...mergedConfig,
            container: DialogContainer,
            panelClass: this._buildPanelClass(mergedConfig?.panelClass),
            backdropClass: this._buildBackdropClass(mergedConfig?.backdropClass),
            providers: (ref, config, _container) => {
                container = _container;
                dialogRef._container = _container;
                return [
                    { provide: DialogRef, useValue: dialogRef },
                    { provide: DIALOG_DATA, useValue: config?.data }
                ];
            }
        };
        const cdkRef = this._cdkDialog.open(componentOrTemplateRef, cdkConfig);
        dialogRef.disableClose = mergedConfig?.disableClose;
        dialogRef._cdkRef = cdkRef;
        if (container) {
            container._animationStateChanged
                .pipe(filter$1((event) => event.phaseName === 'done' && event.toState === 'enter'), take$1(1))
                .subscribe(() => {
                dialogRef.__fireAfterOpened();
            });
            // Use double rAF to ensure the browser has rendered the initial state (opacity: 0)
            // before we trigger the transition to opacity: 1.
            requestAnimationFrame(() => {
                requestAnimationFrame(() => {
                    if (container) {
                        container._startEnterAnimation();
                    }
                    const overlayRef = cdkRef.overlayRef;
                    if (overlayRef.backdropElement) {
                        overlayRef.backdropElement.classList.add('ngs-dialog-backdrop-showing');
                    }
                });
            });
        }
        cdkRef.closed.subscribe(result => {
            if (dialogRef._cdkRef) {
                dialogRef._cdkRef = null;
                dialogRef.close(result);
            }
        });
        cdkRef.backdropClick.subscribe(event => {
            dialogRef.__fireBackdropClick(event);
            if (!dialogRef.disableClose) {
                dialogRef.close();
            }
        });
        cdkRef.keydownEvents.subscribe(event => {
            dialogRef.__fireKeydownEvent(event);
            if (event.key === 'Escape' && !dialogRef.disableClose) {
                dialogRef.close();
            }
        });
        return dialogRef;
    }
    close(dialogRef, result) {
        dialogRef.close(result);
    }
    closeAll() {
        this._cdkDialog.closeAll();
    }
    _buildPanelClass(panelClass) {
        const classes = ['ngs-dialog-panel', 'overflow-hidden', 'flex', 'flex-col'];
        if (Array.isArray(panelClass)) {
            classes.push(...panelClass);
        }
        else if (panelClass) {
            classes.push(panelClass);
        }
        return classes;
    }
    _buildBackdropClass(backdropClass) {
        const classes = ['ngs-dialog-backdrop'];
        if (Array.isArray(backdropClass)) {
            classes.push(...backdropClass);
        }
        else if (backdropClass) {
            classes.push(backdropClass);
        }
        return classes;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Dialog, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Dialog, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Dialog, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }] });

let nextUniqueId = 0;
class DialogTitle {
    _dialogRef = inject(DialogRef, { optional: true });
    id = input(`ngs-dialog-title-${nextUniqueId++}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
    ngOnInit() {
        if (this._dialogRef && !this._dialogRef.disableClose) {
            // Logic for ARIA if needed
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogTitle, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: DialogTitle, isStandalone: true, selector: "ngs-dialog-title, [ngs-dialog-title], [ngsDialogTitle]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "id()" }, classAttribute: "ngs-dialog-title" }, exportAs: ["ngsDialogTitle"], ngImport: i0, template: '<ng-content/>', isInline: true, styles: [":host{display:block;font-size:var(--ngs-dialog-title-font-size);font-weight:var(--ngs-dialog-title-font-weight);padding:var(--ngs-dialog-headline-padding, var(--ngs-dialog-header-padding));flex:none}:host:before{display:inline-block;width:0;height:40px;content:\"\";vertical-align:0}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogTitle, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-dialog-title, [ngs-dialog-title], [ngsDialogTitle]', exportAs: 'ngsDialogTitle', template: '<ng-content/>', host: {
                        'class': 'ngs-dialog-title',
                        '[id]': 'id()',
                    }, styles: [":host{display:block;font-size:var(--ngs-dialog-title-font-size);font-weight:var(--ngs-dialog-title-font-weight);padding:var(--ngs-dialog-headline-padding, var(--ngs-dialog-header-padding));flex:none}:host:before{display:inline-block;width:0;height:40px;content:\"\";vertical-align:0}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });

class DialogContent {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: DialogContent, isStandalone: true, selector: "ngs-dialog-content,[ngs-dialog-content],[ngsDialogContent]", host: { classAttribute: "ngs-dialog-content" }, ngImport: i0, template: '<ng-content/>', isInline: true, styles: [":host{display:block;margin:0;padding:var(--ngs-dialog-with-content-padding, calc(var(--spacing, .25rem) * 5) calc(var(--spacing, .25rem) * 6) calc(var(--spacing, .25rem) * 6));overflow:auto;-webkit-overflow-scrolling:touch;flex-grow:1}@media(min-height:640px){:host{max-height:65vh}}:host-context(ngs-dialog-container:has(.ngs-dialog-title)){padding-top:2px}:host-context(ngs-dialog-container:has(.ngs-dialog-actions)){padding-bottom:2px}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogContent, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-dialog-content,[ngs-dialog-content],[ngsDialogContent]', template: '<ng-content/>', host: {
                        'class': 'ngs-dialog-content'
                    }, styles: [":host{display:block;margin:0;padding:var(--ngs-dialog-with-content-padding, calc(var(--spacing, .25rem) * 5) calc(var(--spacing, .25rem) * 6) calc(var(--spacing, .25rem) * 6));overflow:auto;-webkit-overflow-scrolling:touch;flex-grow:1}@media(min-height:640px){:host{max-height:65vh}}:host-context(ngs-dialog-container:has(.ngs-dialog-title)){padding-top:2px}:host-context(ngs-dialog-container:has(.ngs-dialog-actions)){padding-bottom:2px}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }] });

class DialogActions {
    align = input('end', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogActions, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: DialogActions, isStandalone: true, selector: "ngs-dialog-actions, [ngs-dialog-actions], [ngsDialogActions]", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.ngs-dialog-actions-align-center": "align() === \"center\"", "class.ngs-dialog-actions-align-end": "align() === \"end\"" }, classAttribute: "ngs-dialog-actions" }, ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:flex;flex-wrap:wrap;min-height:var(--ngs-control-height-lg);align-items:center;box-sizing:content-box;gap:calc(var(--spacing, .25rem) * 2);padding:var(--ngs-dialog-actions-padding, calc(var(--spacing, .25rem) * 4) calc(var(--spacing, .25rem) * 6));flex:none}:host.ngs-dialog-actions-align-center{justify-content:center}:host.ngs-dialog-actions-align-end{justify-content:flex-end}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogActions, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-dialog-actions, [ngs-dialog-actions], [ngsDialogActions]', template: '<ng-content />', host: {
                        'class': 'ngs-dialog-actions',
                        '[class.ngs-dialog-actions-align-center]': 'align() === "center"',
                        '[class.ngs-dialog-actions-align-end]': 'align() === "end"',
                    }, styles: [":host{display:flex;flex-wrap:wrap;min-height:var(--ngs-control-height-lg);align-items:center;box-sizing:content-box;gap:calc(var(--spacing, .25rem) * 2);padding:var(--ngs-dialog-actions-padding, calc(var(--spacing, .25rem) * 4) calc(var(--spacing, .25rem) * 6));flex:none}:host.ngs-dialog-actions-align-center{justify-content:center}:host.ngs-dialog-actions-align-end{justify-content:flex-end}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], propDecorators: { align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }] } });

class DialogClose {
    dialogResult = input(undefined, { ...(ngDevMode ? { debugName: "dialogResult" } : /* istanbul ignore next */ {}), alias: 'ngs-dialog-close' });
    _dialogResult = input(undefined, { ...(ngDevMode ? { debugName: "_dialogResult" } : /* istanbul ignore next */ {}), alias: 'ngsDialogClose' });
    ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
    type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
    _dialogRef = inject(DialogRef, { optional: true });
    _dialog = inject(Dialog);
    _onClick() {
        if (this._dialogRef) {
            this._dialog.close(this._dialogRef, this.dialogResult() || this._dialogResult());
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogClose, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: DialogClose, isStandalone: true, selector: "[ngs-dialog-close], [ngsDialogClose]", inputs: { dialogResult: { classPropertyName: "dialogResult", publicName: "ngs-dialog-close", isSignal: true, isRequired: false, transformFunction: null }, _dialogResult: { classPropertyName: "_dialogResult", publicName: "ngsDialogClose", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "_onClick()" }, properties: { "attr.aria-label": "ariaLabel() || null", "attr.type": "type()" } }, exportAs: ["ngsDialogClose"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DialogClose, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngs-dialog-close], [ngsDialogClose]',
                    exportAs: 'ngsDialogClose',
                    standalone: true,
                    host: {
                        '[attr.aria-label]': 'ariaLabel() || null',
                        '[attr.type]': 'type()',
                        '(click)': '_onClick()',
                    }
                }]
        }], propDecorators: { dialogResult: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngs-dialog-close", required: false }] }], _dialogResult: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngsDialogClose", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { DIALOG_DATA, DIALOG_DEFAULT_OPTIONS, Dialog, DialogActions, DialogClose, DialogConfig, DialogContainer, DialogContent, DialogRef, DialogTitle };
//# sourceMappingURL=ngstarter-ui-components-dialog.mjs.map
