'use strict';

var index = require('./index-pX0sBY0-.js');
var domUtils = require('./dom-utils-BdvOgC2b.js');
var tracking = require('./tracking-BPjaTlNR.js');
var popper = require('./popper-Dmp8OTYh.js');

const dropdownCss = () => `:host{display:inline-block}`;

const Dropdown = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.ifxOpen = index.createEvent(this, "ifxOpen", 7);
        this.ifxClose = index.createEvent(this, "ifxClose", 7);
        this.ifxDropdown = index.createEvent(this, "ifxDropdown", 7);
    }
    /** Where the dropdown menu is positioned relative to the trigger. */
    placement = "bottom-start";
    /** Wether the dropdown should be open initially. */
    defaultOpen = false;
    internalIsOpen = false;
    /** If true, the menu is not appended to <body> (stays in place). */
    noAppendToBody = false;
    /** Fired when dropdown open. */
    ifxOpen;
    /** Fired when dropdown closed. */
    ifxClose;
    /** General dropdown event. */
    ifxDropdown;
    /** If true, dropdown is disabled and cannot be opened. */
    disabled;
    /** If true, clicking outside will not close the dropdown. */
    noCloseOnOutsideClick = false;
    /** Id true, clicking inside the menu will not close the dropdown. */
    noCloseOnMenuClick = false;
    get el() { return index.getElement(this); }
    trigger;
    menu;
    // Popper instance for positioning
    popperInstance;
    handleOutsideClick(event) {
        const target = event.target;
        if (!this.noCloseOnOutsideClick &&
            !this.el.contains(target) &&
            !this.menu.contains(target)) {
            this.closeDropdown();
        }
    }
    handleFocusOutside(event) {
        const target = event.target;
        if (this.internalIsOpen &&
            !this.el.contains(target) &&
            !this.menu.contains(target)) {
            this.closeDropdown();
        }
    }
    handleTriggerClick = () => {
        if (!this.internalIsOpen)
            this.openDropdown();
        else
            this.closeDropdown();
    };
    handleTriggerKeyDown = (e) => {
        const key = e.key;
        if (key === "Tab" && this.internalIsOpen && !e.shiftKey) {
            e.preventDefault();
            this.focusFirstItem();
        }
    };
    handleMenuClick = () => {
        if (!this.noCloseOnMenuClick)
            this.closeDropdown();
    };
    getItemFocusables() {
        if (!this.menu)
            return [];
        const hosts = Array.from(this.menu.querySelectorAll("ifx-dropdown-item"));
        return hosts
            .filter((h) => !(h.getAttribute("hide") === "true" || h.classList.contains("hide")))
            .map((h) => h.shadowRoot?.querySelector("a"))
            .filter((el) => !!el);
    }
    handleMenuKeyDown = (e) => {
        const items = this.getItemFocusables();
        if (!items.length)
            return;
        const i = items.indexOf(document.activeElement);
        switch (e.key) {
            case "ArrowDown":
                e.preventDefault();
                items[(i + 1) % items.length].focus();
                break;
            case "ArrowUp":
                e.preventDefault();
                items[(i - 1 + items.length) % items.length].focus();
                break;
            case "Home":
                e.preventDefault();
                items[0].focus();
                break;
            case "End":
                e.preventDefault();
                items[items.length - 1].focus();
                break;
            case "Enter":
            case " ":
            case "Spacebar":
                e.preventDefault();
                document.activeElement?.click();
                break;
            case "Escape":
                e.preventDefault();
                this.closeDropdown();
                this.trigger?.focus();
                break;
            case "Tab":
                if (e.shiftKey && i === 0) {
                    e.preventDefault();
                    this.closeDropdown();
                    this.trigger?.focus();
                }
                break;
        }
    };
    componentWillLoad() {
        //maybe not needed
        this.updateSlotContent();
        this.watchHandlerIsOpen(this.defaultOpen, this.internalIsOpen);
    }
    async componentDidLoad() {
        if (!domUtils.isNestedInIfxComponent(this.el)) {
            const framework = tracking.detectFramework();
            tracking.trackComponent("ifx-dropdown", await framework);
        }
    }
    watchHandlerIsOpen(newValue, oldValue) {
        if (newValue !== oldValue && newValue !== this.internalIsOpen) {
            if (newValue) {
                this.openDropdown();
            }
            else {
                this.closeDropdown();
            }
        }
    }
    watchHandlerDisabled(newValue) {
        if (this.trigger) {
            this.trigger.disabled = newValue;
        }
    }
    watchHandlerSlot() {
        this.updateSlotContent();
    }
    focusFirstItem() {
        const [first] = this.getItemFocusables();
        first?.focus();
    }
    updateSlotContent() {
        const newTrigger = this.el.querySelector("ifx-dropdown-trigger-button, ifx-dropdown-trigger");
        if (newTrigger !== this.trigger) {
            if (this.trigger) {
                this.trigger.removeEventListener("click", this.handleTriggerClick);
                this.trigger.removeEventListener("keydown", this.handleTriggerKeyDown);
            }
            this.trigger = newTrigger;
            if (this.trigger) {
                this.trigger.disabled = this.disabled;
                this.trigger.addEventListener("click", this.handleTriggerClick);
                this.trigger.addEventListener("keydown", this.handleTriggerKeyDown);
            }
        }
        const newMenu = this.el.querySelector("ifx-dropdown-menu");
        if (!this.noAppendToBody) {
            if (this.menu && this.menu !== newMenu) {
                this.menu.removeEventListener("click", this.handleMenuClick);
                this.menu.removeEventListener("keydown", this.handleMenuKeyDown);
                this.menu.remove();
            }
            this.menu = newMenu;
            if (this.menu && !document.body.contains(this.menu)) {
                document.body.append(this.menu);
            }
        }
        else {
            this.menu = newMenu;
        }
        if (this.menu) {
            this.menu.removeEventListener("click", this.handleMenuClick);
            this.menu.removeEventListener("keydown", this.handleMenuKeyDown);
            this.menu.addEventListener("click", this.handleMenuClick);
            this.menu.addEventListener("keydown", this.handleMenuKeyDown);
        }
    }
    disconnectedCallback() {
        if (this.popperInstance) {
            this.popperInstance.destroy();
            this.popperInstance = null;
        }
        if (this.menu) {
            this.menu.remove();
        }
    }
    /** Returns wether the dropdown is currently open. */
    async isOpen() {
        return this.internalIsOpen;
    }
    /** Closes the dropdown and cleans up the popper instance. */
    async closeDropdown() {
        if (this.internalIsOpen) {
            this.internalIsOpen = false;
            this.trigger.isOpen = false;
            this.menu.isOpen = false;
            this.ifxClose.emit();
        }
        if (this.popperInstance) {
            this.popperInstance.destroy();
            this.popperInstance = null;
        }
    }
    /** Opens the dropdown and sets up the popper positioning. */
    async openDropdown() {
        if (!this.internalIsOpen && !this.disabled) {
            this.internalIsOpen = true;
            this.trigger.isOpen = true;
            this.menu.isOpen = true;
            this.popperInstance = popper.createPopper(this.el, this.menu, {
                placement: this.placement,
                strategy: "fixed"
            });
            this.ifxOpen.emit();
        }
    }
    render() {
        return (index.h("div", { key: '4835afaecc8b4ea2095ab573c6cb9b2ade14417f', "aria-label": "dropdown menu", class: "dropdown" }, index.h("slot", { key: '3f7d76fc61ed684e62c6d2cce0931f9b6233edae' })));
    }
    static get watchers() { return {
        "defaultOpen": [{
                "watchHandlerIsOpen": 0
            }],
        "disabled": [{
                "watchHandlerDisabled": 0
            }]
    }; }
};
Dropdown.style = dropdownCss();

exports.ifx_dropdown = Dropdown;
