import { h } from "@stencil/core";
import { isFocusable } from '../../utils/a11y';
import Tunnel from '../locale/i18n.provider';
var Translations;
(function (Translations) {
    Translations["DROPDOWN_TOGGLE"] = "Dropdown toggle";
})(Translations || (Translations = {}));
export class Dropdown {
    constructor() {
        this.expanded = false;
        this.toggleClickListener = () => this.onToggle();
        this.overlayListener = () => this.close();
        this.itemListener = ({ detail }) => this.onItemSelected(detail);
        /**
         * Should the dropdown render the arrow.
         * Defaults to true.
         */
        this.arrow = true;
        /**
         * How to align the overlay when it opens.
         * Supports all popper placements.
         */
        this.placement = 'bottom-start';
    }
    injectedPropWatcher() {
        this.setToggleLabel();
    }
    connectedCallback() {
        this.bindToggle();
    }
    componentDidRender() {
        if (!this.toggle) {
            this.bindToggle();
        }
    }
    disconnectedCallback() {
        if (this.toggle) {
            this.toggle.removeEventListener('click', this.toggleClickListener);
        }
        this.unbindOverlay();
    }
    async close(refocusToggle = false) {
        this.anjDropdownWillClose.emit();
        if (!isFocusable(document.activeElement) || refocusToggle) {
            this.toggle.focus();
        }
        await this.overlay.close();
        this.expanded = false;
        this.setToggleExpanded();
        this.unbindOverlay();
    }
    async open() {
        if (this.expanded)
            return;
        this.overlay = this.bindOverlay();
        this.anjDropdownWillOpen.emit();
        this.expanded = true;
        this.setToggleExpanded();
        return this.overlay.open(this.toggle);
    }
    async onToggle() {
        return this.expanded ? this.close() : this.open();
    }
    async onItemSelected(payload) {
        // Close first THEN emit just in case the selection causes an unload https://git.zias.io/ui-foundation/anjuna/issues/948
        await this.close(true);
        this.anjDropdownSelect.emit(payload);
    }
    setToggleExpanded() {
        this.toggle.parentElement.active = this.expanded;
        this.toggle.setAttribute('aria-expanded', `${this.expanded}`);
    }
    bindToggle() {
        const buttons = Array.from(this.element.querySelectorAll(`.anj-dropdown-toggle button`)).filter(noCloseButtons);
        this.toggle = buttons[buttons.length - 1];
        if (this.toggle) {
            // Eat the mouse down event so that it doesn't trigger the overlay close
            this.toggle.addEventListener('click', this.toggleClickListener);
            this.toggle.setAttribute('aria-haspopup', 'true');
            this.setToggleLabel();
            this.setToggleExpanded();
        }
    }
    bindOverlay() {
        const el = this.element.querySelector('anj-overlay');
        el.addEventListener('anjWillDismiss', this.overlayListener);
        el.addEventListener('anjDropdownItemSelect', this.itemListener);
        return el;
    }
    unbindOverlay() {
        if (this.overlay) {
            this.overlay.removeEventListener('anjWillDismiss', this.overlayListener);
            this.overlay.removeEventListener('anjDropdownItemSelect', this.itemListener);
            this.overlay = undefined;
        }
    }
    setToggleLabel() {
        if (this.toggle) {
            this.toggle.setAttribute('aria-label', this.toggle.textContent
                ? this.toggle.textContent : this.translator(Translations.DROPDOWN_TOGGLE));
        }
    }
    render() {
        return [
            h("span", { class: "anj-dropdown-toggle" },
                h("slot", { name: "dropdown-toggle" })),
            h("anj-overlay", { class: "anj-dropdown-menu", placement: this.placement, offset: this.arrow ? '0, 15' : '0, 0', trapFocus: true },
                this.arrow ? h("anj-arrow", null) : undefined,
                h("slot", null))
        ];
    }
    static get is() { return "anj-dropdown"; }
    static get originalStyleUrls() { return {
        "$": ["dropdown.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["dropdown.css"]
    }; }
    static get properties() { return {
        "arrow": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Should the dropdown render the arrow.\nDefaults to true."
            },
            "attribute": "arrow",
            "reflect": false,
            "defaultValue": "true"
        },
        "placement": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "OverlayPlacement",
                "resolved": "\"auto\" | \"auto-end\" | \"auto-start\" | \"bottom\" | \"bottom-end\" | \"bottom-start\" | \"left\" | \"left-end\" | \"left-start\" | \"right\" | \"right-end\" | \"right-start\" | \"top\" | \"top-end\" | \"top-start\"",
                "references": {
                    "OverlayPlacement": {
                        "location": "import",
                        "path": "../../types/types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "How to align the overlay when it opens.\nSupports all popper placements."
            },
            "attribute": "placement",
            "reflect": false,
            "defaultValue": "'bottom-start'"
        },
        "translator": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "IntlFormatFn",
                "resolved": "(value: any, variables?: any) => string",
                "references": {
                    "IntlFormatFn": {
                        "location": "import",
                        "path": "../locale/i18n.provider"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [{
                        "text": undefined,
                        "name": "internal"
                    }],
                "text": ""
            }
        }
    }; }
    static get events() { return [{
            "method": "anjDropdownWillOpen",
            "name": "anjDropdownWillOpen",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the dropdown will open"
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }, {
            "method": "anjDropdownWillClose",
            "name": "anjDropdownWillClose",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the dropdown will close"
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }, {
            "method": "anjDropdownSelect",
            "name": "anjDropdownSelect",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the user has selected a dropdown item"
            },
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            }
        }]; }
    static get methods() { return {
        "close": {
            "complexType": {
                "signature": "(refocusToggle?: boolean) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        },
        "open": {
            "complexType": {
                "signature": "() => Promise<void>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "element"; }
    static get watchers() { return [{
            "propName": "translator",
            "methodName": "injectedPropWatcher"
        }]; }
}
Tunnel.injectProps(Dropdown, ['translator']);
// Fixes https://git.zias.io/ui-foundation/anjuna/issues/867 by not binding to clear/close buttons as dropdown toggles
const noCloseButtons = (el) => {
    return !el.closest('anj-button-close');
};
