import { h, } from "@stencil/core";
import { createRandomString } from "../../util/random-string";
import { zipObject, isFunction } from "lodash-es";
import { ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, TAB, } from "../../util/keycodes";
import { focusTriggerElement } from "../../util/focus-trigger-element";
const DEFAULT_ROOT_BREADCRUMBS_ITEM = {
    text: '',
    icon: {
        name: 'home',
    },
    type: 'icon-only',
};
/**
 * @slot trigger - Element to use as a trigger for the menu.
 * @exampleComponent limel-example-menu-basic
 * @exampleComponent limel-example-menu-disabled
 * @exampleComponent limel-example-menu-open-direction
 * @exampleComponent limel-example-menu-surface-width
 * @exampleComponent limel-example-menu-separators
 * @exampleComponent limel-example-menu-icons
 * @exampleComponent limel-example-menu-badge-icons
 * @exampleComponent limel-example-menu-grid
 * @exampleComponent limel-example-menu-hotkeys
 * @exampleComponent limel-example-menu-secondary-text
 * @exampleComponent limel-example-menu-notification
 * @exampleComponent limel-example-menu-sub-menus
 * @exampleComponent limel-example-menu-sub-menu-lazy-loading
 * @exampleComponent limel-example-menu-sub-menu-lazy-loading-infinite
 * @exampleComponent limel-example-menu-searchable
 * @exampleComponent limel-example-menu-composite
 */
export class Menu {
    constructor() {
        /**
         * A list of items and separators to show in the menu.
         */
        this.items = [];
        /**
         * Sets the disabled state of the menu.
         */
        this.disabled = false;
        /**
         * Decides the menu's location in relation to its trigger
         */
        this.openDirection = 'bottom-start';
        /**
         * Decides the width of menu's dropdown
         */
        this.surfaceWidth = 'inherit-from-items';
        /**
         * Sets the open state of the menu.
         */
        this.open = false;
        /**
         * Defines whether the menu should show badges.
         */
        this.badgeIcons = false;
        /**
         * Renders list items in a grid layout, rather than a vertical list
         */
        this.gridLayout = false;
        /**
         * :::warning Internal Use Only
         * This property is for internal use only. We need it for now, but want to
         * find a better implementation of the functionality it currently enables.
         * If and when we do so, this property will be removed without prior
         * notice. If you use it, your code _will_ break in the future.
         * :::
         *
         * @internal
         */
        this.loading = false;
        /**
         * A root breadcrumb item to show above the menu items.
         * Clicking it navigates back from a sub-menu to the root menu.
         */
        this.rootItem = DEFAULT_ROOT_BREADCRUMBS_ITEM;
        this.renderLoader = () => {
            if (!this.loadingSubItems && !this.loading) {
                return;
            }
            const cssProperties = this.getCssProperties();
            return (h("div", { style: {
                    width: cssProperties['--menu-surface-width'],
                    display: 'flex',
                    'align-items': 'center',
                    'justify-content': 'center',
                    padding: '0.5rem 0',
                } }, h("limel-spinner", { size: "mini", limeBranded: false })));
        };
        this.renderBreadcrumb = () => {
            const breadcrumbsItems = this.getBreadcrumbsItems();
            if (breadcrumbsItems.length === 0) {
                return;
            }
            return (h("limel-breadcrumbs", { ref: this.setBreadcrumbsElement, style: {
                    'border-bottom': 'solid 1px rgb(var(--contrast-500))',
                    'flex-shrink': '0',
                }, onSelect: this.handleBreadcrumbsSelect, onKeyDown: this.handleBreadcrumbsKeyDown, items: breadcrumbsItems }));
        };
        this.handleBreadcrumbsSelect = (event) => {
            if (!event.detail.menuItem) {
                this.currentSubMenu = null;
                this.clearSearch();
                this.navigateMenu.emit(null);
                this.setFocus();
                return;
            }
            this.handleSelect(event.detail.menuItem);
        };
        this.renderSearchField = () => {
            if (!this.searcher) {
                return;
            }
            return (h("limel-input-field", { tabindex: "0", ref: this.setSearchElement, placeholder: this.searchPlaceholder, type: "search", leadingIcon: "search", style: {
                    padding: '0.25rem',
                    'box-sizing': 'border-box',
                }, value: this.searchValue, onChange: this.handleTextInput, onKeyDown: this.handleInputKeyDown }));
        };
        this.renderEmptyMessage = () => {
            var _a;
            if (this.loading ||
                this.loadingSubItems ||
                !this.emptyResultMessage ||
                !Array.isArray(this.searchResults) ||
                ((_a = this.searchResults) === null || _a === void 0 ? void 0 : _a.length)) {
                return null;
            }
            return (h("p", { style: {
                    padding: '0 1rem',
                    'text-align': 'center',
                } }, this.emptyResultMessage));
        };
        this.renderMenuList = () => {
            let items = this.visibleItems;
            if (this.loadingSubItems || this.loading) {
                items = [];
            }
            return (h("limel-menu-list", { style: {
                    'overflow-y': 'auto',
                    'flex-grow': '1',
                }, class: {
                    'has-grid-layout has-interactive-items': this.gridLayout,
                }, items: items, badgeIcons: this.badgeIcons, onSelect: this.onSelect, ref: this.setListElement, onKeyDown: this.handleMenuKeyDown }));
        };
        this.handleTextInput = async (event) => {
            event.stopPropagation();
            const query = event.detail;
            this.searchValue = query;
            if (query === '') {
                this.searchResults = null;
                this.loadingSubItems = false;
                return;
            }
            this.loadingSubItems = true;
            const result = await this.searcher(query);
            if (this.searchValue !== query) {
                return;
            }
            this.searchResults = result;
            this.loadingSubItems = false;
        };
        // Key handler for the input search field
        // Will change focus to breadcrumbs (if present) or the first/last item
        // in the dropdown list to enable selection with the keyboard
        this.handleInputKeyDown = (event) => {
            const isForwardTab = event.key === TAB &&
                !event.altKey &&
                !event.metaKey &&
                !event.shiftKey;
            const isUp = event.key === ARROW_UP;
            const isDown = event.key === ARROW_DOWN;
            if (!isForwardTab && !isUp && !isDown) {
                return;
            }
            event.stopPropagation();
            event.preventDefault();
            if (isForwardTab || isDown) {
                if (this.focusBreadcrumbs()) {
                    return;
                }
                this.focusFirstListItem();
                return;
            }
            if (isUp) {
                // Focus the last list item (wrapping behavior)
                this.focusLastListItem();
            }
        };
        // Key handler for the menu list (capture phase)
        // Handles Up arrow on first item and Down arrow on last item
        // Must run in capture phase to intercept before MDC Menu wraps focus
        // Only intercepts when there's a search input or breadcrumbs to navigate to
        this.handleListKeyDownCapture = (event) => {
            const isUp = event.key === ARROW_UP;
            const isDown = event.key === ARROW_DOWN;
            if (!isUp && !isDown) {
                return;
            }
            // Up on first item: go to breadcrumbs or search input (if they exist)
            if (isUp && this.isFirstListItemFocused()) {
                // Try to focus breadcrumbs first
                if (this.focusBreadcrumbs()) {
                    event.stopPropagation();
                    event.preventDefault();
                    return;
                }
                // Then try search input
                if (this.searchInput) {
                    event.stopPropagation();
                    event.preventDefault();
                    this.searchInput.focus();
                }
                // If neither exists, let MDC Menu handle wrap-around
                return;
            }
            // Down on last item: go to search input (if it exists)
            if (isDown && this.isLastListItemFocused() && this.searchInput) {
                event.stopPropagation();
                event.preventDefault();
                this.searchInput.focus();
            }
            // If no search input, let MDC Menu handle wrap-around
        };
        // Key handler for the menu list (bubble phase)
        // Will change focus to the search field if using shift+tab
        // And can go forward/back with right/left arrow keys
        this.handleMenuKeyDown = (event) => {
            var _a;
            const isBackwardTab = event.key === TAB &&
                !event.altKey &&
                !event.metaKey &&
                event.shiftKey;
            const isLeft = event.key === ARROW_LEFT;
            const isRight = event.key === ARROW_RIGHT;
            if (!isBackwardTab && !isLeft && !isRight) {
                return;
            }
            if (isBackwardTab) {
                event.stopPropagation();
                event.preventDefault();
                (_a = this.searchInput) === null || _a === void 0 ? void 0 : _a.focus();
                return;
            }
            if (!this.gridLayout && (isLeft || isRight)) {
                const currentItem = this.getCurrentItem();
                event.stopPropagation();
                event.preventDefault();
                if (isRight) {
                    this.goForward(currentItem);
                }
                else if (isLeft) {
                    this.goBack();
                }
            }
        };
        // Key handler for breadcrumbs
        // Up arrow: focus search input
        // Down arrow: focus first list item
        this.handleBreadcrumbsKeyDown = (event) => {
            var _a;
            const isUp = event.key === ARROW_UP;
            const isDown = event.key === ARROW_DOWN;
            if (!isUp && !isDown) {
                return;
            }
            event.stopPropagation();
            event.preventDefault();
            if (isUp) {
                (_a = this.searchInput) === null || _a === void 0 ? void 0 : _a.focus();
                return;
            }
            if (isDown) {
                this.focusFirstListItem();
            }
        };
        this.clearSearch = () => {
            this.searchValue = '';
            this.searchResults = null;
            this.loadingSubItems = false;
        };
        this.getCurrentItem = () => {
            var _a, _b, _c, _d, _e, _f;
            let menuElement = (_c = (_b = (_a = this.list) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.activeElement) !== null && _c !== void 0 ? _c : null;
            if (menuElement && menuElement.getAttribute('role') !== 'menuitem') {
                menuElement = menuElement.closest('[role="menuitem"]');
            }
            if (!menuElement) {
                menuElement = (_e = (_d = this.list) === null || _d === void 0 ? void 0 : _d.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('[role="menuitem"][tabindex="0"]');
            }
            const dataIndex = Number.parseInt((_f = menuElement === null || menuElement === void 0 ? void 0 : menuElement.dataset.index) !== null && _f !== void 0 ? _f : '0', 10);
            const item = this.visibleItems[dataIndex];
            return (item !== null && item !== void 0 ? item : this.visibleItems[0]);
        };
        this.goForward = (currentItem) => {
            this.handleSelect(currentItem, false);
        };
        this.goBack = () => {
            if (!this.currentSubMenu) {
                // Already in the root of the menu
                return;
            }
            const parent = this.currentSubMenu.parentItem;
            if (!parent) {
                // If only one step down, go to the root of the menu.
                // No need to load a sub-menu.
                this.currentSubMenu = null;
                this.clearSearch();
                this.navigateMenu.emit(null);
                this.setFocus();
                return;
            }
            this.handleSelect(parent);
        };
        this.setTriggerAttributes = (element) => {
            const attributes = {
                'aria-haspopup': true,
                'aria-expanded': this.open,
                'aria-controls': this.portalId,
                disabled: this.disabled,
                role: 'button',
            };
            for (const [key, value] of Object.entries(attributes)) {
                if (value) {
                    element.setAttribute(key, String(value));
                }
                else {
                    element.removeAttribute(key);
                }
            }
        };
        this.onClose = () => {
            this.cancel.emit();
            this.open = false;
            this.currentSubMenu = null;
            setTimeout(this.focusTrigger, 0);
        };
        this.onTriggerClick = (event) => {
            event.stopPropagation();
            if (this.disabled) {
                return;
            }
            this.open = !this.open;
        };
        this.handleSelect = async (menuItem, selectOnEmptyChildren = true) => {
            if (Array.isArray(menuItem === null || menuItem === void 0 ? void 0 : menuItem.items) && menuItem.items.length > 0) {
                this.selectedMenuItem = menuItem;
                this.clearSearch();
                this.currentSubMenu = menuItem;
                this.navigateMenu.emit(menuItem);
                this.setFocus();
                return;
            }
            else if (isFunction(menuItem === null || menuItem === void 0 ? void 0 : menuItem.items)) {
                const menuLoader = menuItem.items;
                this.selectedMenuItem = menuItem;
                this.loadingSubItems = true;
                const subItems = await menuLoader(menuItem);
                if (this.selectedMenuItem !== menuItem) {
                    return;
                }
                menuItem.items = subItems;
                this.loadingSubItems = false;
                if (subItems === null || subItems === void 0 ? void 0 : subItems.length) {
                    this.currentSubMenu = menuItem;
                    this.clearSearch();
                    this.navigateMenu.emit(menuItem);
                    this.setFocus();
                    return;
                }
            }
            if (!selectOnEmptyChildren) {
                return;
            }
            this.selectedMenuItem = menuItem;
            this.loadingSubItems = false;
            this.select.emit(menuItem);
            this.open = false;
            this.currentSubMenu = null;
            setTimeout(this.focusTrigger, 0);
        };
        this.onSelect = (event) => {
            event.stopPropagation();
            this.handleSelect(event.detail);
        };
        this.setListElement = (element) => {
            if (this.list) {
                this.list.removeEventListener('keydown', this.handleListKeyDownCapture, true);
            }
            this.list = element;
            if (this.list) {
                this.list.addEventListener('keydown', this.handleListKeyDownCapture, true);
            }
        };
        this.setFocus = () => {
            setTimeout(() => {
                if (!this.open) {
                    return;
                }
                if (this.searchInput && this.searcher) {
                    const observer = new IntersectionObserver(() => {
                        observer.unobserve(this.searchInput);
                        if (this.searchInput === window.document.activeElement) {
                            return;
                        }
                        this.searchInput.focus();
                    });
                    observer.observe(this.searchInput);
                }
                else if (this.list) {
                    const observer = new IntersectionObserver(() => {
                        observer.unobserve(this.list);
                        this.focusMenuItem();
                    });
                    observer.observe(this.list);
                }
            }, 0);
        };
        this.focusTrigger = () => {
            var _a, _b;
            const trigger = (_b = (_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.assignedElements()) === null || _b === void 0 ? void 0 : _b[0];
            focusTriggerElement(trigger);
        };
        this.setSearchElement = (element) => {
            this.searchInput = element;
        };
        this.setBreadcrumbsElement = (element) => {
            this.breadcrumbs = element;
        };
        /**
         * Focuses the first focusable element inside breadcrumbs.
         * Returns true if breadcrumbs exist and were focused,
         * false otherwise.
         */
        this.focusBreadcrumbs = () => {
            var _a;
            if (!this.breadcrumbs) {
                return false;
            }
            const focusableElement = (_a = this.breadcrumbs.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('button, a');
            if (focusableElement) {
                focusableElement.focus();
                return true;
            }
            return false;
        };
        this.focusFirstListItem = () => {
            const listItems = this.getListItems();
            const firstItem = listItems === null || listItems === void 0 ? void 0 : listItems[0];
            firstItem === null || firstItem === void 0 ? void 0 : firstItem.focus();
        };
        this.focusLastListItem = () => {
            const listItems = this.getListItems();
            const lastItem = listItems === null || listItems === void 0 ? void 0 : listItems.at(-1);
            lastItem === null || lastItem === void 0 ? void 0 : lastItem.focus();
        };
        this.isFirstListItemFocused = () => {
            var _a;
            const listItems = this.getListItems();
            if (!listItems) {
                return false;
            }
            const firstItem = listItems[0];
            const activeElement = (_a = this.list.shadowRoot) === null || _a === void 0 ? void 0 : _a.activeElement;
            return firstItem === activeElement;
        };
        this.isLastListItemFocused = () => {
            var _a;
            const listItems = this.getListItems();
            if (!listItems) {
                return false;
            }
            const lastItem = listItems.at(-1);
            const activeElement = (_a = this.list.shadowRoot) === null || _a === void 0 ? void 0 : _a.activeElement;
            return lastItem === activeElement;
        };
        this.getListItems = () => {
            var _a;
            if (!this.list) {
                return null;
            }
            const items = (_a = this.list.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.mdc-deprecated-list-item');
            if (!(items === null || items === void 0 ? void 0 : items.length)) {
                return null;
            }
            return [...items];
        };
        this.focusMenuItem = () => {
            var _a;
            if (!this.list) {
                return;
            }
            const activeElement = this.list.shadowRoot.activeElement;
            activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur();
            const menuItems = this.visibleItems.filter(this.isMenuItem);
            const selectedIndex = Math.max(menuItems.findIndex((item) => item.selected), 0);
            const menuElements = [
                ...this.list.shadowRoot.querySelectorAll('[role="menuitem"]'),
            ];
            (_a = menuElements[selectedIndex]) === null || _a === void 0 ? void 0 : _a.focus();
        };
        this.renderNotificationBadge = () => {
            if (this.items.some(this.hasNotificationBadge)) {
                return h("limel-badge", null);
            }
        };
        this.hasNotificationBadge = (item) => this.isMenuItem(item) && item.badge !== undefined;
        this.setTriggerRef = (elm) => {
            this.triggerElement = elm;
        };
        this.portalId = createRandomString();
    }
    componentDidRender() {
        const slotElement = this.host.shadowRoot.querySelector('slot');
        // eslint-disable-next-line unicorn/no-array-for-each
        slotElement.assignedElements().forEach(this.setTriggerAttributes);
    }
    render() {
        const cssProperties = this.getCssProperties();
        const dropdownZIndex = getComputedStyle(this.host).getPropertyValue('--dropdown-z-index');
        const menuSurfaceWidth = this.getMenuSurfaceWidth(cssProperties['--menu-surface-width']);
        return (h("div", { key: 'adec7fedfe610207eed79b9587438d17111ffe82', class: "mdc-menu-surface--anchor", onClick: this.onTriggerClick }, h("slot", { key: '5dbc488a563ea2dcc315c35b7751fe829298e46d', ref: this.setTriggerRef, name: "trigger" }), this.renderNotificationBadge(), h("limel-portal", { key: '98b47d2d25f40b5294f6bbfca40371917ce438b2', visible: this.open, containerId: this.portalId, openDirection: this.openDirection, position: "absolute", containerStyle: { 'z-index': dropdownZIndex } }, h("limel-menu-surface", { key: '1a616b513b25383c6534d76c66a088c1e264f4b1', open: this.open, onDismiss: this.onClose, style: Object.assign(Object.assign({}, cssProperties), { '--menu-surface-width': menuSurfaceWidth, '--limel-menu-surface-display': 'flex', '--limel-menu-surface-flex-direction': 'column' }), class: {
                'has-grid-layout': this.gridLayout,
            } }, this.renderSearchField(), this.renderBreadcrumb(), this.renderLoader(), this.renderEmptyMessage(), this.renderMenuList()))));
    }
    itemsWatcher() {
        this.clearSearch();
        this.setFocus();
    }
    openWatcher(newValue) {
        const opened = newValue;
        if (opened) {
            this.setFocus();
        }
        else {
            this.clearSearch();
        }
    }
    getBreadcrumbsItems() {
        const breadCrumbItems = [];
        let currentItem = this.currentSubMenu;
        while (currentItem) {
            breadCrumbItems.push({
                text: currentItem.text,
                icon: currentItem.icon,
                menuItem: currentItem,
            });
            currentItem = currentItem.parentItem;
        }
        if (breadCrumbItems.length > 0 ||
            this.rootItem !== DEFAULT_ROOT_BREADCRUMBS_ITEM) {
            breadCrumbItems.push(this.rootItem);
        }
        return breadCrumbItems.reverse();
    }
    getCssProperties() {
        const propertyNames = [
            '--menu-surface-width',
            '--list-grid-item-max-width',
            '--list-grid-item-min-width',
            '--list-grid-gap',
            '--notification-badge-background-color',
            '--notification-badge-text-color',
        ];
        const style = getComputedStyle(this.host);
        const values = propertyNames.map((property) => {
            return style.getPropertyValue(property);
        });
        return zipObject(propertyNames, values);
    }
    isMenuItem(item) {
        return !('separator' in item);
    }
    getMenuSurfaceWidth(customWidth) {
        var _a, _b, _c, _d;
        if (customWidth) {
            return customWidth;
        }
        if (this.surfaceWidth === 'inherit-from-trigger') {
            const assignedTriggers = (_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.assignedElements();
            if (!(assignedTriggers === null || assignedTriggers === void 0 ? void 0 : assignedTriggers.length) ||
                !((_b = assignedTriggers[0]) === null || _b === void 0 ? void 0 : _b.clientWidth)) {
                return '';
            }
            return `${assignedTriggers[0].clientWidth}px`;
        }
        else if (this.surfaceWidth === 'inherit-from-menu') {
            if (!((_c = this.host) === null || _c === void 0 ? void 0 : _c.clientWidth)) {
                return '';
            }
            return `${(_d = this.host) === null || _d === void 0 ? void 0 : _d.clientWidth}px`;
        }
        return '';
    }
    get visibleItems() {
        var _a;
        if (Array.isArray(this.searchResults) && this.searchValue) {
            return this.searchResults;
        }
        else if (Array.isArray((_a = this.currentSubMenu) === null || _a === void 0 ? void 0 : _a.items)) {
            return this.currentSubMenu.items.map((item) => (Object.assign(Object.assign({}, item), { parentItem: this.currentSubMenu })));
        }
        return this.items;
    }
    static get is() { return "limel-menu"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["menu.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["menu.css"]
        };
    }
    static get properties() {
        return {
            "items": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Array<MenuItem | ListSeparator>",
                    "resolved": "(ListSeparator | MenuItem<any>)[]",
                    "references": {
                        "Array": {
                            "location": "global",
                            "id": "global::Array"
                        },
                        "MenuItem": {
                            "location": "import",
                            "path": "./menu.types",
                            "id": "src/components/menu/menu.types.ts::MenuItem",
                            "referenceLocation": "MenuItem"
                        },
                        "ListSeparator": {
                            "location": "import",
                            "path": "../list-item/list-item.types",
                            "id": "src/components/list-item/list-item.types.ts::ListSeparator",
                            "referenceLocation": "ListSeparator"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A list of items and separators to show in the menu."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets the disabled state of the menu."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "openDirection": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "OpenDirection",
                    "resolved": "\"bottom\" | \"bottom-end\" | \"bottom-start\" | \"left\" | \"left-end\" | \"left-start\" | \"right\" | \"right-end\" | \"right-start\" | \"top\" | \"top-end\" | \"top-start\"",
                    "references": {
                        "OpenDirection": {
                            "location": "import",
                            "path": "./menu.types",
                            "id": "src/components/menu/menu.types.ts::OpenDirection",
                            "referenceLocation": "OpenDirection"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Decides the menu's location in relation to its trigger"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "open-direction",
                "defaultValue": "'bottom-start'"
            },
            "surfaceWidth": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "SurfaceWidth",
                    "resolved": "\"inherit-from-items\" | \"inherit-from-menu\" | \"inherit-from-trigger\"",
                    "references": {
                        "SurfaceWidth": {
                            "location": "import",
                            "path": "./menu.types",
                            "id": "src/components/menu/menu.types.ts::SurfaceWidth",
                            "referenceLocation": "SurfaceWidth"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Decides the width of menu's dropdown"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "surface-width",
                "defaultValue": "'inherit-from-items'"
            },
            "open": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets the open state of the menu."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "open",
                "defaultValue": "false"
            },
            "badgeIcons": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines whether the menu should show badges."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "badge-icons",
                "defaultValue": "false"
            },
            "gridLayout": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Renders list items in a grid layout, rather than a vertical list"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "grid-layout",
                "defaultValue": "false"
            },
            "loading": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ":::warning Internal Use Only\nThis property is for internal use only. We need it for now, but want to\nfind a better implementation of the functionality it currently enables.\nIf and when we do so, this property will be removed without prior\nnotice. If you use it, your code _will_ break in the future.\n:::"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "loading",
                "defaultValue": "false"
            },
            "currentSubMenu": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "MenuItem",
                    "resolved": "MenuItem<any>",
                    "references": {
                        "MenuItem": {
                            "location": "import",
                            "path": "./menu.types",
                            "id": "src/components/menu/menu.types.ts::MenuItem",
                            "referenceLocation": "MenuItem"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ":::warning Internal Use Only\nThis property is for internal use only. We need it for now, but want to\nfind a better implementation of the functionality it currently enables.\nIf and when we do so, this property will be removed without prior\nnotice. If you use it, your code _will_ break in the future.\n:::"
                },
                "getter": false,
                "setter": false
            },
            "rootItem": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "BreadcrumbsItem",
                    "resolved": "BreadcrumbsItem",
                    "references": {
                        "BreadcrumbsItem": {
                            "location": "import",
                            "path": "../breadcrumbs/breadcrumbs.types",
                            "id": "src/components/breadcrumbs/breadcrumbs.types.ts::BreadcrumbsItem",
                            "referenceLocation": "BreadcrumbsItem"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A root breadcrumb item to show above the menu items.\nClicking it navigates back from a sub-menu to the root menu."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "DEFAULT_ROOT_BREADCRUMBS_ITEM"
            },
            "searcher": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "MenuSearcher",
                    "resolved": "(query: string) => Promise<(ListSeparator | MenuItem<any>)[]>",
                    "references": {
                        "MenuSearcher": {
                            "location": "import",
                            "path": "./menu.types",
                            "id": "src/components/menu/menu.types.ts::MenuSearcher",
                            "referenceLocation": "MenuSearcher"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A search function that takes a search-string as an argument,\nand returns a promise that will eventually be resolved with\nan array of `MenuItem`:s.\n\nSee the docs for the type `MenuSearcher` for type information on\nthe searcher function itself."
                },
                "getter": false,
                "setter": false
            },
            "searchPlaceholder": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Placeholder text for the search input field."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "search-placeholder"
            },
            "emptyResultMessage": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Message to display when search returns 0 results."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "empty-result-message"
            }
        };
    }
    static get states() {
        return {
            "loadingSubItems": {},
            "searchValue": {},
            "searchResults": {}
        };
    }
    static get events() {
        return [{
                "method": "cancel",
                "name": "cancel",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Is emitted when the menu is cancelled."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "select",
                "name": "select",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Is emitted when a menu item is selected."
                },
                "complexType": {
                    "original": "MenuItem",
                    "resolved": "MenuItem<any>",
                    "references": {
                        "MenuItem": {
                            "location": "import",
                            "path": "./menu.types",
                            "id": "src/components/menu/menu.types.ts::MenuItem",
                            "referenceLocation": "MenuItem"
                        }
                    }
                }
            }, {
                "method": "navigateMenu",
                "name": "navigateMenu",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Is emitted when a menu item with a sub-menu is selected."
                },
                "complexType": {
                    "original": "MenuItem | null",
                    "resolved": "MenuItem<any>",
                    "references": {
                        "MenuItem": {
                            "location": "import",
                            "path": "./menu.types",
                            "id": "src/components/menu/menu.types.ts::MenuItem",
                            "referenceLocation": "MenuItem"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "items",
                "methodName": "itemsWatcher"
            }, {
                "propName": "open",
                "methodName": "openWatcher"
            }];
    }
}
