/*!
 * Custom elements for Nanopore-Digital Web applications
 */
import { Host, writeTask, Build, } from "@stencil/core";
import { closestElement } from "../../utils/dom";
import { transformTag, h } from "../../utils/renderer";
import { HasSlotController } from "../../utils/slot";
/**
 *
 * Display navigation items in a collapsible drawer at the side of a UI.
 *
 * @status stable
 * @version 1.0.0
 *
 * @slot foot - nav items to be placed at the bottom of the drawer
 * @slot - default slot for nav items
 */
export class MenuDrawer {
    containerDiv;
    contentDiv;
    globalNav;
    children = [];
    ro;
    slotCtrl = new HasSlotController(this, 'foot');
    el;
    reset = false;
    isLoading = true;
    hide = false;
    secondaryOpen = false;
    /**
     * Set the initial menu drawer open or closed
     */
    open = true;
    /**
     * Global-nav width to hide the menu drawer and move the items into the nano-global-nav
     */
    hideWidth = 576;
    cancelNavItemEvents(ev) {
        if (!ev.detail.secondaryMenu)
            return;
        ev.stopPropagation();
        this.secondaryOpen = ev.type === 'nanoOpen';
    }
    openChange() {
        if (Build.isBrowser) {
            localStorage.setItem('nanoMenuDrawerOpen', this.open.toString());
        }
        if (this.containerDiv) {
            const documentWidth = document.documentElement.clientWidth;
            const scrollbarWidth = Math.abs(window.innerWidth - documentWidth);
            if (this.open) {
                const menuWidth = this.contentDiv.scrollWidth;
                writeTask(() => {
                    this.containerDiv.style.width = menuWidth + 'px';
                    this.containerDiv.style.setProperty('--menu-width', menuWidth + 'px');
                    this.containerDiv.style.setProperty('--scrollbar-width', scrollbarWidth + 'px');
                });
            }
            else {
                writeTask(() => {
                    this.containerDiv.style.width = null;
                    this.containerDiv.style.removeProperty('--menu-width');
                    this.containerDiv.style.setProperty('--scrollbar-width', scrollbarWidth + 'px');
                });
            }
        }
    }
    moveItemsToGlobalNav() {
        // dimensions not cool - move items out of element and into global nav
        const currNavItems = this.el.querySelectorAll(transformTag('nano-nav-item'));
        this.hide = true;
        this.globalNav.triggerResize();
        currNavItems.forEach((element) => {
            this.children.push({
                slot: element.getAttribute('slot'),
                element: element,
            });
            element.setAttribute('slot', 'menu');
            element.classList.add('nano-global-nav-menu');
            this.globalNav.appendChild(element);
        });
    }
    moveItemsToDrawer() {
        if (!this.children || !this.children.length)
            return;
        this.children.forEach((child) => {
            child.element.removeAttribute('slot');
            child.element.classList.remove('nano-global-nav-menu');
            if (child.slot && child.slot.length)
                child.element.setAttribute('slot', child.slot);
            this.el.appendChild(child.element);
        });
        this.children = [];
        this.hide = false;
    }
    onResize = () => {
        if (!this.globalNav || !Build.isBrowser)
            return;
        const { width } = this.globalNav.getBoundingClientRect();
        if (width > this.hideWidth) {
            this.moveItemsToDrawer();
        }
        else {
            this.moveItemsToGlobalNav();
        }
    };
    toggle = (e) => {
        e.preventDefault();
        this.open = !this.open;
    };
    attachRO() {
        if (!Build.isBrowser || this.ro)
            return;
        this.ro = new ResizeObserver(() => {
            this.onResize();
        });
        this.ro.observe(this.globalNav);
    }
    componentWillLoad() {
        this.globalNav = closestElement(transformTag('nano-global-nav'), this.el);
        if (!this.globalNav) {
            console.warn('nano-menu-drawer: no nano-global-nav found in the document. nano-global-nav is required to use nano-menu-drawer.');
        }
        if (Build.isBrowser) {
            const localState = localStorage.getItem('nanoMenuDrawerOpen');
            this.open = localState
                ? localState === 'true'
                    ? true
                    : false
                : this.open;
            this.globalNav.componentOnReady().then(() => {
                this.openChange();
            });
        }
    }
    connectedCallback() {
        this.onResize();
    }
    componentDidLoad() {
        if (Build.isBrowser)
            this.attachRO();
    }
    disconnectedCallback() {
        if (Build.isBrowser) {
            this.ro?.disconnect();
            this.ro = undefined;
        }
    }
    render() {
        return (h(Host, { key: 'bed821db8e5a30f26c3c9bad45b01321bdf4ca77', class: {
                open: this.open,
                'secondary-open': this.secondaryOpen,
                hide: this.hide,
                loading: this.isLoading,
                'has-global-nav': !!this.globalNav,
                'nano-menu-drawer': true,
            }, dir: this.el.ownerDocument.dir === 'rtl' ? 'rtl' : null }, h("div", { key: 'e80fe18a73873359fc1d86ca93a06b8c6d3173c1', ref: (div) => (this.containerDiv = div), class: "container" }, h("div", { key: 'fe83b1858bacd94f3e0540ee3933d1018f7bfb9d', class: `content-wrap ${this.secondaryOpen ? 'secondary-open' : ''}` }, h("nav", { key: 'bed3b6c253cf16f8a796393be71c2c1b9aebd266', ref: (div) => (this.contentDiv = div), class: "content" }, h("div", { key: 'a8ea363c51345c83fcbf8723a32627bd99c5a9cf', class: "head" }, h("button", { key: 'fa9765354704685582e64771ded73c30c88e0374', onClick: this.toggle, class: "collapse-btn" }, h("nano-icon", { key: '0489c46c0c76a72720daf6656e26c2946433bccc', name: "light/arrow-right-to-line" }), h("span", { key: '81b00aaf09a528d6137351df20e23149a5325bf0', class: "visually-hidden" }, "collapse / expand menu"))), h("slot", { key: 'ab5f6ed3b81b2d5f741a1d102a12db5b0f68bae7' }), this.slotCtrl.has('foot') && (h("div", { key: 'dbb8345173ee78b9685cc46c6dcde5c2d617a868', class: "foot" }, h("slot", { key: '93bfeb1493a1d5e9a420803a09e64dced877591b', name: "foot" }))))))));
    }
    static get is() { return "nano-menu-drawer"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["menu-drawer.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["menu-drawer.css"]
        };
    }
    static get properties() {
        return {
            "open": {
                "type": "boolean",
                "attribute": "open",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set the initial menu drawer open or closed"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "true"
            },
            "hideWidth": {
                "type": "number",
                "attribute": "hide-width",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Global-nav width to hide the menu drawer and move the items into the nano-global-nav"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "576"
            }
        };
    }
    static get states() {
        return {
            "reset": {},
            "isLoading": {},
            "hide": {},
            "secondaryOpen": {}
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "open",
                "methodName": "openChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "nanoOpen",
                "method": "cancelNavItemEvents",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "nanoClose",
                "method": "cancelNavItemEvents",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
