import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
import { a as autoUpdate, c as computePosition, o as offset, f as flip, s as shift } from './floating-ui.dom.js';
import { d as defineCustomElement$2 } from './pds-box2.js';

const pdsDropdownMenuCss = ":host{display:block}.is-hidden{display:none}.pds-dropdown-menu--panel{background-color:var(--pine-color-background-overlay);border-radius:var(--pine-dimension-xs);left:var(--pine-dimension-none);min-width:170px;padding:var(--pine-dimension-xs);position:fixed;z-index:var(--pine-z-index-overlay)}:host-context([data-theme=dark]) .pds-dropdown-menu--panel{border:var(--pine-border)}::slotted(a),::slotted(button){-ms-flex-align:center;align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;border-radius:var(--pine-dimension-xs) !important;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--pine-color-text) !important;cursor:pointer;display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;font:var(--pine-typography-body-medium) !important;gap:var(--pine-dimension-xs);margin:calc(var(--pine-border-width) + 2px) !important;padding:var(--pine-dimension-xs) !important;text-align:start;text-decoration:none !important;width:calc(100% - (var(--pine-border-width) + 2px) * 2)}::slotted(.destructive){color:var(--pine-color-danger) !important}::slotted([aria-disabled=true]),::slotted([disabled]:not([disabled=false])){cursor:not-allowed;opacity:0.5;pointer-events:none}";

const PdsDropdownMenu$1 = /*@__PURE__*/ proxyCustomElement(class PdsDropdownMenu extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.__attachShadow();
        this.isOpen = false;
        this.menuItems = [];
        this.cleanupAutoUpdate = null;
        this.currentFocusIndex = -1;
        /**
         * The placement of the dropdown panel relative to the trigger.
         */
        this.placement = 'bottom-start';
        this.handleTriggerSlotChange = (event) => {
            this.slotEl = event.target;
            // Get all elements assigned to this slot
            const assignedElements = this.slotEl.assignedElements();
            this.triggerEl = assignedElements[0];
            this.triggerEl.onclick = this.handleClick;
            // Add accessibility attributes to trigger
            this.triggerEl.setAttribute('aria-haspopup', 'menu');
            this.triggerEl.setAttribute('aria-expanded', 'false');
        };
        this.handleSlotChange = (event) => {
            this.slotEl = event.target;
            // Get all elements assigned to this slot
            const assignedElements = this.slotEl.assignedElements();
            // Allowed elements: pds-dropdown-menu-item, pds-dropdown-menu-separator, <a>, <button>
            // Raw <a> and <button> elements are allowed for edge cases requiring native browser/framework
            // behavior (e.g., Rails UJS, Turbo) that cannot work through Shadow DOM.
            const allowedTags = ['pds-dropdown-menu-item', 'pds-dropdown-menu-separator', 'a', 'button'];
            const invalidElements = assignedElements.filter(el => !allowedTags.includes(el.tagName.toLowerCase()));
            if (invalidElements.length > 0) {
                const invalidTags = invalidElements.map(el => el.tagName.toLowerCase()).join(', ');
                console.warn(`pds-dropdown-menu: Unexpected element(s) found: ${invalidTags}. ` +
                    `Expected: ${allowedTags.join(', ')}`);
            }
            // Store all focusable items for keyboard navigation
            // This includes pds-dropdown-menu-item components and raw <a>/<button> elements
            this.menuItems = assignedElements.filter(el => {
                const tag = el.tagName.toLowerCase();
                return tag === 'pds-dropdown-menu-item' || tag === 'a' || tag === 'button';
            });
        };
        // Toggle dropdown open/closed
        this.toggleDropdown = () => {
            this.isOpen = !this.isOpen;
            if (this.isOpen) {
                this.openDropdown();
            }
            else {
                this.closeDropdown();
            }
        };
        // Open the dropdown and position it
        this.openDropdown = () => {
            var _a;
            const updatePosition = () => {
                computePosition(this.triggerEl, this.panelEl, {
                    placement: this.placement,
                    strategy: 'fixed',
                    middleware: [offset(6), flip(), shift({ padding: 5 })],
                }).then(({ x, y }) => {
                    Object.assign(this.panelEl.style, {
                        left: `${x}px`,
                        top: `${y}px`,
                    });
                });
            };
            // Initial position
            updatePosition();
            // Set up auto-update for window resize and scroll
            this.cleanupAutoUpdate = autoUpdate(this.triggerEl, this.panelEl, updatePosition);
            (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('pds-box').classList.remove('is-hidden');
            this.isOpen = true;
            // Update ARIA attributes
            this.triggerEl.setAttribute('aria-expanded', 'true');
        };
        // Close the dropdown
        this.closeDropdown = () => {
            var _a;
            (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('pds-box').classList.add('is-hidden');
            this.isOpen = false;
            // Clean up auto-update
            if (this.cleanupAutoUpdate) {
                this.cleanupAutoUpdate();
                this.cleanupAutoUpdate = null;
            }
            // Update ARIA attributes
            this.triggerEl.setAttribute('aria-expanded', 'false');
            // Reset focus index
            this.currentFocusIndex = -1;
            // Return focus to trigger
            this.triggerEl.focus();
        };
        // Handle click on the trigger element
        this.handleClick = () => {
            this.toggleDropdown();
        };
    }
    componentDidRender() {
        var _a;
        this.panelEl = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('pds-box');
    }
    disconnectedCallback() {
        // Clean up auto-update when component is removed from DOM
        if (this.cleanupAutoUpdate) {
            this.cleanupAutoUpdate();
            this.cleanupAutoUpdate = null;
        }
    }
    // Check if a menu item is disabled (handles both component and raw elements)
    isItemDisabled(item) {
        const tagName = item.tagName.toLowerCase();
        if (tagName === 'pds-dropdown-menu-item') {
            return item.disabled;
        }
        else if (tagName === 'button') {
            return item.disabled;
        }
        else if (tagName === 'a') {
            return item.getAttribute('aria-disabled') === 'true';
        }
        return false;
    }
    // Get the index of the currently focused menu item
    getFocusedItemIndex() {
        const activeElement = document.activeElement;
        if (!activeElement)
            return -1;
        // For raw elements, check direct match
        // For pds-dropdown-menu-item, also check if the active element is inside the shadow root
        return this.menuItems.findIndex(item => {
            if (item === activeElement)
                return true;
            // Check if activeElement is inside the item's shadow root (for pds-dropdown-menu-item)
            if (item.tagName.toLowerCase() === 'pds-dropdown-menu-item') {
                const shadowRoot = item.shadowRoot;
                if (shadowRoot === null || shadowRoot === void 0 ? void 0 : shadowRoot.contains(activeElement))
                    return true;
            }
            return false;
        });
    }
    // Focus a specific menu item by index
    focusItemByIndex(index) {
        var _a, _b, _c, _d, _e;
        if (index >= 0 && index < this.menuItems.length) {
            this.currentFocusIndex = index;
            const item = this.menuItems[index];
            const tagName = item.tagName.toLowerCase();
            if (tagName === 'pds-dropdown-menu-item') {
                // For pds-dropdown-menu-item, focus the inner element
                const menuItem = item;
                const innerButton = (_a = menuItem.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('button');
                const innerLink = ((_d = (_c = (_b = menuItem.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('pds-link')) === null || _c === void 0 ? void 0 : _c.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('a'))
                    || ((_e = menuItem.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('a'));
                if (innerButton) {
                    innerButton.focus();
                }
                else if (innerLink) {
                    innerLink.focus();
                }
                else {
                    // Fallback to focusing the host
                    menuItem.focus();
                }
            }
            else {
                // For raw <a> or <button> elements, focus directly
                item.focus();
            }
        }
    }
    // Focus the next menu item
    focusNextItem() {
        let nextIndex = (this.currentFocusIndex + 1) % this.menuItems.length;
        // Skip disabled items
        let attempts = 0;
        const maxAttempts = this.menuItems.length;
        while (attempts < maxAttempts && this.isItemDisabled(this.menuItems[nextIndex])) {
            nextIndex = (nextIndex + 1) % this.menuItems.length;
            attempts++;
        }
        // Only focus if we found a non-disabled item
        if (attempts < maxAttempts) {
            this.focusItemByIndex(nextIndex);
        }
    }
    // Focus the previous menu item
    focusPreviousItem() {
        let prevIndex = this.currentFocusIndex <= 0
            ? this.menuItems.length - 1
            : this.currentFocusIndex - 1;
        // Skip disabled items
        let attempts = 0;
        const maxAttempts = this.menuItems.length;
        while (attempts < maxAttempts && this.isItemDisabled(this.menuItems[prevIndex])) {
            prevIndex = prevIndex <= 0 ? this.menuItems.length - 1 : prevIndex - 1;
            attempts++;
        }
        // Only focus if we found a non-disabled item
        if (attempts < maxAttempts) {
            this.focusItemByIndex(prevIndex);
        }
    }
    // Handle keyboard events for the dropdown
    handleKeyDown(event) {
        if (!this.isOpen)
            return;
        switch (event.key) {
            case 'Escape':
                event.preventDefault();
                this.closeDropdown();
                break;
            case 'ArrowDown':
                event.preventDefault();
                this.focusNextItem();
                break;
            case 'ArrowUp':
                event.preventDefault();
                this.focusPreviousItem();
                break;
            case 'Home':
                event.preventDefault();
                if (this.menuItems.length > 0) {
                    // Find first non-disabled item
                    let firstIndex = 0;
                    while (firstIndex < this.menuItems.length && this.isItemDisabled(this.menuItems[firstIndex])) {
                        firstIndex++;
                    }
                    if (firstIndex < this.menuItems.length) {
                        this.focusItemByIndex(firstIndex);
                    }
                }
                break;
            case 'End':
                event.preventDefault();
                if (this.menuItems.length > 0) {
                    // Find last non-disabled item
                    let lastIndex = this.menuItems.length - 1;
                    while (lastIndex >= 0 && this.isItemDisabled(this.menuItems[lastIndex])) {
                        lastIndex--;
                    }
                    if (lastIndex >= 0) {
                        this.focusItemByIndex(lastIndex);
                    }
                }
                break;
            case 'Tab':
                if (event.shiftKey) {
                    // Let Shift+Tab navigate naturally from first item to trigger
                    // For all other items, move to previous item
                    const currentIndex = this.getFocusedItemIndex();
                    if (currentIndex > 0) {
                        // If not on first item, prevent default and go to previous item
                        event.preventDefault();
                        this.focusPreviousItem(); // Use our method that skips disabled items
                    }
                    // If on first item or no item, let natural tab order move back to trigger
                }
                else {
                    // Forward Tab navigation
                    const activeElement = document.activeElement;
                    const isTriggerFocused = activeElement === this.triggerEl;
                    const currentIndex = this.getFocusedItemIndex();
                    if (isTriggerFocused && this.menuItems.length > 0) {
                        // If trigger is focused, move to first non-disabled menu item
                        event.preventDefault();
                        // Find the first non-disabled item
                        let firstFocusableIndex = 0;
                        while (firstFocusableIndex < this.menuItems.length && this.isItemDisabled(this.menuItems[firstFocusableIndex])) {
                            firstFocusableIndex++;
                        }
                        if (firstFocusableIndex < this.menuItems.length) {
                            this.focusItemByIndex(firstFocusableIndex);
                        }
                    }
                    else if (currentIndex === -1 && this.menuItems.length > 0) {
                        // If no menu item is focused, focus the first non-disabled one
                        event.preventDefault();
                        // Find the first non-disabled item
                        let firstFocusableIndex = 0;
                        while (firstFocusableIndex < this.menuItems.length && this.isItemDisabled(this.menuItems[firstFocusableIndex])) {
                            firstFocusableIndex++;
                        }
                        if (firstFocusableIndex < this.menuItems.length) {
                            this.focusItemByIndex(firstFocusableIndex);
                        }
                    }
                    else if (currentIndex !== -1) {
                        // Use our method that skips disabled items
                        event.preventDefault();
                        this.focusNextItem();
                    }
                }
                break;
        }
    }
    // Handle clicks outside the dropdown to close it
    handleWindowClick(event) {
        if (this.isOpen && !this.host.contains(event.target) && event.target !== this.triggerEl) {
            this.closeDropdown();
        }
    }
    render() {
        return (h(Host, { key: '467662b4b14612153ba10a4d3a6f578edec52d89', id: this.componentId }, h("slot", { key: 'ba1b44fe9276b96fd123694742a34bd7c8717a3d', name: "trigger", onSlotchange: this.handleTriggerSlotChange }), h("pds-box", { key: '8287d0cc6fea80eeb73ca355eb247883d6257c19', "border-radius": "sm", display: "flex", direction: "column", class: "pds-dropdown-menu--panel is-hidden", shadow: "100", role: "menu", "aria-orientation": "vertical", part: "menu-panel" }, h("slot", { key: '5d5aa3cc226fabaadb4572bfa38f9189dbcb55c7', onSlotchange: this.handleSlotChange }))));
    }
    get host() { return this; }
    static get style() { return pdsDropdownMenuCss; }
}, [257, "pds-dropdown-menu", {
        "componentId": [1, "component-id"],
        "placement": [1],
        "currentFocusIndex": [32]
    }, [[8, "keydown", "handleKeyDown"], [8, "click", "handleWindowClick"]]]);
function defineCustomElement$1() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["pds-dropdown-menu", "pds-box"];
    components.forEach(tagName => { switch (tagName) {
        case "pds-dropdown-menu":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, PdsDropdownMenu$1);
            }
            break;
        case "pds-box":
            if (!customElements.get(tagName)) {
                defineCustomElement$2();
            }
            break;
    } });
}

const PdsDropdownMenu = PdsDropdownMenu$1;
const defineCustomElement = defineCustomElement$1;

export { PdsDropdownMenu, defineCustomElement };
//# sourceMappingURL=pds-dropdown-menu.js.map

//# sourceMappingURL=pds-dropdown-menu.js.map