'use strict';

var index = require('./index-BUvWX8u2.js');

const pdsModalCss = ".pds-modal__backdrop{-ms-flex-align:start;align-items:flex-start;background-color:rgba(0, 0, 0, 0.4);border:0;display:-ms-flexbox;display:flex;height:100%;inset:0;-ms-flex-pack:center;justify-content:center;margin:0;max-height:100%;max-width:100%;opacity:0;padding:0;position:fixed;-webkit-transition:opacity var(--pine-motion-duration-base) var(--pine-motion-easing-in), visibility var(--pine-motion-duration-base) var(--pine-motion-easing-in);transition:opacity var(--pine-motion-duration-base) var(--pine-motion-easing-in), visibility var(--pine-motion-duration-base) var(--pine-motion-easing-in);visibility:hidden;width:100%;z-index:var(--pine-z-index-modal)}@supports ((-webkit-backdrop-filter: blur(3px)) or (backdrop-filter: blur(3px))){.pds-modal__backdrop{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}}pds-modal .pds-modal__backdrop{z-index:var(--pine-z-index-priority)}.pds-modal__backdrop::-webkit-backdrop{background:transparent}.pds-modal__backdrop::-ms-backdrop{background:transparent}.pds-modal__backdrop::backdrop{background:transparent}.pds-modal__backdrop.open{opacity:1;-webkit-transition-timing-function:var(--pine-motion-easing-out);transition-timing-function:var(--pine-motion-easing-out);visibility:visible}.pds-modal{background:var(--pine-color-background-overlay);border-radius:var(--pine-dimension-sm);-webkit-box-shadow:var(--pine-box-shadow-400);box-shadow:var(--pine-box-shadow-400);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;margin:var(--pine-dimension-md);max-height:none;width:100%}.pds-modal.pds-modal--scrollable{max-height:calc(100vh - (5vh + 96px))}@supports (height: 100dvh){.pds-modal.pds-modal--scrollable{max-height:calc(100dvh - (5dvh + 96px))}}@media (min-width: 992px){.pds-modal{-webkit-margin-before:6vh;margin-block-start:6vh}@supports (height: 100dvh){.pds-modal{-webkit-margin-before:6dvh;margin-block-start:6dvh}}}@media (min-width: 1200px){.pds-modal{-webkit-margin-before:8vh;margin-block-start:8vh}@supports (height: 100dvh){.pds-modal{-webkit-margin-before:8dvh;margin-block-start:8dvh}}}.pds-modal--sm{max-width:520px}.pds-modal--md{max-width:700px}.pds-modal--lg{max-width:900px}.pds-modal--fullscreen{border-radius:0;height:100%;margin:0;max-height:100vh;max-width:100%}@supports (height: 100dvh){.pds-modal--fullscreen{max-height:100dvh}}.pds-modal--fullscreen.pds-modal--scrollable{max-height:100vh}@supports (height: 100dvh){.pds-modal--fullscreen.pds-modal--scrollable{max-height:100dvh}}.pds-modal--fullscreen .pds-modal-content{-ms-flex:1;flex:1}.pds-modal--scrollable pds-modal-content{-webkit-border-after:1px solid transparent;border-block-end:1px solid transparent;-webkit-border-before:1px solid transparent;border-block-start:1px solid transparent;overflow-y:auto}.pds-modal:not(.pds-modal--scrollable) pds-modal-content{overflow-y:visible}";

const PdsModal = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.pdsModalOpen = index.createEvent(this, "pdsModalOpen");
        this.pdsModalClose = index.createEvent(this, "pdsModalClose");
        this.focusableElements = [];
        /**
         * Whether the modal can be dismissed by clicking the backdrop
         * @default true
         */
        this.backdropDismiss = true;
        /**
         * Whether the modal is open
         * @default false
         */
        this.open = false;
        /**
         * The size of the modal
         * @default 'md'
         */
        this.size = 'md';
        /**
         * Whether the modal content should be scrollable
         * @default true
         */
        this.scrollable = true;
        /**
         * Stores the list of focusable elements in the modal
         */
        this.focusableElementsArray = [];
        this.handleBackdropClick = (e) => {
            if (!this.backdropDismiss || !this.open)
                return;
            if (e.target.classList.contains('pds-modal__backdrop')) {
                e.stopPropagation();
                // Only close if this is the innermost modal
                if (this.isInnermostModal()) {
                    this.hideModal();
                }
            }
        };
        this.handleKeyDown = (e) => {
            // If the modal is not open, don't handle any keyboard events
            if (!this.open)
                return;
            // Handle Escape key to close the modal
            if (e.key === 'Escape') {
                // Always prevent native dialog close behavior
                e.preventDefault();
                // Only close if backdropDismiss is enabled and this is the innermost modal
                if (this.backdropDismiss && this.isInnermostModal()) {
                    this.hideModal();
                }
                return;
            }
            // Handle Tab key for focus trapping
            if (e.key === 'Tab') {
                // If there are no focusable elements, do nothing
                if (this.focusableElements.length === 0)
                    return;
                // Get the first and last focusable elements
                const firstFocusableElement = this.focusableElements[0];
                const lastFocusableElement = this.focusableElements[this.focusableElements.length - 1];
                // Get the current active element
                const activeElement = document.activeElement;
                // Check if we need to wrap focus
                const isFirstElement = activeElement === firstFocusableElement ||
                    firstFocusableElement.contains(activeElement);
                const isLastElement = activeElement === lastFocusableElement ||
                    lastFocusableElement.contains(activeElement);
                // If shift + tab is pressed and focus is on the first element, move to the last element
                if (e.shiftKey && isFirstElement) {
                    e.preventDefault();
                    this.focusElement(lastFocusableElement);
                }
                // If tab is pressed and focus is on the last element, move to the first element
                else if (!e.shiftKey && isLastElement) {
                    e.preventDefault();
                    this.focusElement(firstFocusableElement);
                }
            }
        };
    }
    componentDidLoad() {
        this.modalRef = this.el.querySelector('.pds-modal__backdrop');
        // Add keyboard event listener
        document.addEventListener('keydown', this.handleKeyDown);
    }
    disconnectedCallback() {
        // Clean up event listener
        document.removeEventListener('keydown', this.handleKeyDown);
    }
    handleOpenChange(newValue) {
        if (newValue) {
            this.showModal();
        }
        else {
            this.hideModal();
        }
    }
    /**
     * Updates the list of focusable elements in the modal
     */
    updateFocusableElements() {
        if (!this.modalRef)
            return;
        // Get all focusable elements within the modal
        const selector = [
            'a[href]',
            'button:not([disabled])',
            'input:not([disabled])',
            'select:not([disabled])',
            'textarea:not([disabled])',
            '[tabindex]:not([tabindex="-1"])',
            'pds-button:not([disabled])',
            'pds-link:not([disabled])',
            'pds-input:not([disabled])',
            'pds-checkbox:not([disabled])',
            'pds-radio:not([disabled])',
            'pds-switch:not([disabled])',
            'pds-select:not([disabled])',
        ].join(',');
        this.focusableElements = Array.from(this.modalRef.querySelectorAll(selector));
        // Filter out elements with display: none or visibility: hidden
        this.focusableElements = this.focusableElements.filter(el => {
            const style = window.getComputedStyle(el);
            return style.display !== 'none' && style.visibility !== 'hidden';
        });
    }
    /**
     * Sets focus to the first focusable element in the modal
     */
    setInitialFocus() {
        if (this.focusableElements.length === 0)
            return;
        // Focus the first focusable element
        const firstElement = this.focusableElements[0];
        // For web components, we need to ensure they're properly focused
        this.focusElement(firstElement);
    }
    /**
     * Helper method to focus an element, with special handling for web components
     */
    focusElement(element) {
        if (!element)
            return;
        try {
            // Try standard focus first
            element.focus();
            // Check if focus worked
            setTimeout(() => {
                if (document.activeElement !== element) {
                    // For web components, try to find a focusable element inside
                    if (element.shadowRoot) {
                        const focusableInShadow = element.shadowRoot.querySelector('button, [tabindex], input, a[href]');
                        if (focusableInShadow) {
                            focusableInShadow.focus();
                        }
                    }
                }
            }, 0);
        }
        catch (error) {
            console.error('Error focusing element:', error);
        }
    }
    /**
     * Opens the modal
     */
    async showModal() {
        if (this.modalRef) {
            try {
                // Store the currently focused element to restore focus when modal closes
                this.previousActiveElement = document.activeElement;
                // Use native dialog showModal method which makes the rest of the page inert
                this.modalRef.showModal();
                this.open = true;
                // Update focusable elements and set initial focus
                // Using a longer timeout to ensure all components are fully rendered
                setTimeout(() => {
                    this.updateFocusableElements();
                    this.setInitialFocus();
                    this.pdsModalOpen.emit();
                }, 100);
            }
            catch (error) {
                console.error('Failed to show modal:', error);
            }
        }
    }
    /**
     * Closes the modal
     */
    async hideModal() {
        if (this.modalRef) {
            try {
                this.modalRef.close();
                this.open = false;
                // Restore focus to the element that was focused before the modal was opened
                if (this.previousActiveElement && typeof this.previousActiveElement.focus === 'function') {
                    this.previousActiveElement.focus();
                }
                this.pdsModalClose.emit();
            }
            catch (error) {
                console.error('Failed to hide modal:', error);
            }
        }
    }
    /**
     * Gets the z-index of a modal's backdrop element
     */
    getBackdropZIndex(modal) {
        const backdrop = modal.querySelector('.pds-modal__backdrop');
        return backdrop ? parseInt(getComputedStyle(backdrop).zIndex, 10) : -1;
    }
    /**
     * Checks if this modal is the innermost (highest z-index) modal
     */
    isInnermostModal() {
        // Find all open modals
        const openModals = Array.from(document.querySelectorAll('pds-modal')).filter(modal => modal.open);
        if (openModals.length === 0)
            return false;
        // Get this modal's backdrop element
        const thisBackdrop = this.el.querySelector('.pds-modal__backdrop');
        if (!thisBackdrop)
            return false;
        // Get computed z-index of all open modal backdrops
        const modalZIndexes = openModals.map(modal => this.getBackdropZIndex(modal));
        // Get the highest z-index
        const maxZIndex = Math.max(...modalZIndexes);
        // Check if this modal's backdrop has the highest z-index
        const thisZIndex = this.getBackdropZIndex(this.el);
        return thisZIndex === maxZIndex;
    }
    render() {
        return (index.h("dialog", { key: 'cf2710a889d8f0e80a3551088ab38a88dc44ad1e', class: {
                'pds-modal__backdrop': true,
                'open': this.open
            }, "aria-modal": "true", "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick }, index.h("div", { key: 'a06d017153e67ad38bc1ced56ba22aeade977aaf', class: {
                'pds-modal': true,
                [`pds-modal--${this.size}`]: true,
                'pds-modal--scrollable': this.scrollable
            }, part: "modal" }, index.h("slot", { key: 'd995c586809a4940c091912244a86cb4605a961c' }))));
    }
    get el() { return index.getElement(this); }
    static get watchers() { return {
        "open": ["handleOpenChange"]
    }; }
};
PdsModal.style = pdsModalCss;

exports.pds_modal = PdsModal;
//# sourceMappingURL=pds-modal.entry.cjs.js.map
