import { h } from "@stencil/core";
/** @experimental */
export class ContextMenu {
    constructor() {
        this.menuListener = (event) => this.open(event);
        this.overlayClickListener = (e) => this.onClick(e);
        /**
         * Where to attach the overlay when opened
         * Options are `"parent"` or `"target"` which is the default.
         */
        this.attach = 'parent';
        /**
         * Loader to get the menu options. The default is to grab whatever is slotted.
         */
        this.loader = () => this.getSlottedOptions();
    }
    connectedCallback() {
        this.bodyEl = this.element.ownerDocument.body;
        this.parentEl = this.element.parentElement;
        if (typeof this.attach !== 'string') {
            this.attach.addEventListener('contextmenu', this.menuListener);
        }
        else {
            this.parentEl.addEventListener('contextmenu', this.menuListener);
        }
    }
    disconnectedCallback() {
        if (this.overlay) {
            this.overlay.remove();
        }
        if (typeof this.attach !== 'string') {
            this.attach.removeEventListener('contextmenu', this.menuListener);
        }
        else {
            this.parentEl.removeEventListener('contextmenu', this.menuListener);
        }
        this.unbindOverlay();
    }
    unbindOverlay() {
        if (this.overlay) {
            this.overlay.removeEventListener('click', this.overlayClickListener);
            this.overlay.innerHTML = '';
            this.overlay = null;
        }
    }
    async onElsewhereOpen({ target }) {
        if (this.overlay && target !== this.overlay) {
            return this.close();
        }
    }
    /**
     * open the date picker
     */
    async open(event) {
        event.preventDefault();
        this.bindOverlay(this.element.querySelector('anj-overlay'));
        const popper = await this.overlay.popper();
        if (popper)
            return;
        this.options = await this.loader(event);
        if (!this.options)
            return;
        this.insertOptions();
        this.bodyEl.appendChild(this.overlay);
        await this.overlay.open(this.attach === 'parent' ? this.parentEl : event.target);
    }
    /**
     * close the date picker
     */
    async close() {
        await this.overlay.close();
        this.unbindOverlay();
    }
    async onClick(event) {
        event.preventDefault();
        event.stopPropagation();
        const item = event.target;
        this.anjContextSelect.emit(item.action);
        return this.close();
    }
    bindOverlay(ref) {
        if (ref && !this.overlay) {
            this.overlay = ref;
            this.overlay.addEventListener('click', this.overlayClickListener);
        }
    }
    insertOptions() {
        this.options.forEach(o => this.overlay.appendChild(o));
    }
    async getSlottedOptions() {
        return Array.from(this.overlay.querySelectorAll('anj-context-menu-item'))
            .map(i => i.cloneNode(true));
    }
    render() {
        return (h("anj-overlay", { class: "anj-dropdown-menu anj-context-menu", placement: "bottom-start", dismiss: "auto" }));
    }
    static get is() { return "anj-context-menu"; }
    static get originalStyleUrls() { return {
        "$": ["context-menu.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["context-menu.css"]
    }; }
    static get properties() { return {
        "attach": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "'parent' | 'target' | HTMLElement",
                "resolved": "\"parent\" | \"target\" | HTMLElement",
                "references": {
                    "HTMLElement": {
                        "location": "global"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Where to attach the overlay when opened\nOptions are `\"parent\"` or `\"target\"` which is the default."
            },
            "attribute": "attach",
            "reflect": false,
            "defaultValue": "'parent'"
        },
        "loader": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "ContextMenuLoader",
                "resolved": "(event: MouseEvent) => Promise<HTMLAnjContextMenuItemElement[]>",
                "references": {
                    "ContextMenuLoader": {
                        "location": "import",
                        "path": "../../types/types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Loader to get the menu options. The default is to grab whatever is slotted."
            },
            "defaultValue": "() => this.getSlottedOptions()"
        }
    }; }
    static get states() { return {
        "options": {}
    }; }
    static get events() { return [{
            "method": "anjContextSelect",
            "name": "anjContextSelect",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when a selection is made"
            },
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            }
        }]; }
    static get methods() { return {
        "open": {
            "complexType": {
                "signature": "(event: MouseEvent) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "MouseEvent": {
                        "location": "global"
                    },
                    "HTMLElement": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "open the date picker",
                "tags": []
            }
        },
        "close": {
            "complexType": {
                "signature": "() => Promise<void>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "close the date picker",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "element"; }
    static get listeners() { return [{
            "name": "anjDidDismiss",
            "method": "unbindOverlay",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjWillOpen",
            "method": "onElsewhereOpen",
            "target": "body",
            "capture": false,
            "passive": false
        }]; }
}
