import { Host, h, Fragment, } from "@stencil/core";
import { IcBrandForegroundEnum, } from "../../utils/types";
import { checkResizeObserver, DEVICE_SIZES, getCurrentDeviceSize, getBrandForegroundAppearance, getSlot, onComponentPropUndefinedChange, onComponentRequiredPropUndefined, isSlotUsed, isEmptyString, isPropDefined, } from "../../utils/helpers";
/**
 * @slot app-icon - Content will be rendered to left of app title. Anything that is slotted here will be hidden from screen readers.
 * @slot app-title - Handle routing by nesting a route in the app title.
 * @slot short-app-title - Handle routing by nesting a route in the short app title (to be displayed in place of app title on small screen sizes).
 * @slot search - Content will be rendered in search area to left of buttons.
 * @slot toggle-icon - Icon to be displayed on the button to toggle search slot content on smaller devices
 * @slot navigation - Content will be rendered in navigation panel.
 * @slot buttons - Content will be rendered to right of search bar.
 */
export class TopNavigation {
    constructor() {
        this.hasAppIcon = false;
        this.hasAppTitleSlot = false;
        this.hasIconButtons = false;
        this.hasNavigation = false;
        this.hasSearchSlotContent = false;
        this.resizeObserver = null;
        this.searchBar = null;
        this.deviceSize = DEVICE_SIZES.XL;
        this.foregroundColor = getBrandForegroundAppearance();
        this.hasFullWidthSearchBar = false;
        this.mobileSearchBarVisible = false;
        this.mobileSearchHiddenOnBlur = false;
        this.navMenuVisible = false;
        this.searchButtonClick = false;
        this.searchValue = "";
        /**
         * The alignment of the top navigation content.
         */
        this.contentAligned = "full-width";
        /**
         * Can set a custom breakpoint for the top navigation to switch to mobile mode.
         * Must be one of our specified breakpoints in px: `0`, `576`, `768`, `992`, `1200`.
         */
        this.customMobileBreakpoint = DEVICE_SIZES.L;
        /**
         *  The URL to navigate to when the app title is clicked.
         */
        this.href = "/";
        /**
         * If `true`, the flyout navigation menu on small devices will be contained by the parent element.
         */
        this.inline = false;
        /**
         * The short title of the app to be displayed at small screen sizes in place of the app title.
         */
        this.shortAppTitle = "";
        /**
         * The status info to be displayed.
         */
        this.status = "";
        /**
         * Sets the theme color to the dark or light theme color. "inherit" will set the color based on the system settings or ic-theme component.
         */
        this.theme = "inherit";
        /**
         * The version info to be displayed.
         */
        this.version = "";
        this.checkSlots = () => {
            this.hasAppIcon = isSlotUsed(this.el, "app-icon");
            this.hasAppTitleSlot = isSlotUsed(this.el, "app-title");
            this.hasNavigation = isSlotUsed(this.el, "navigation");
            this.hasIconButtons = isSlotUsed(this.el, "buttons");
            this.hasSearchSlotContent = isSlotUsed(this.el, "search");
            if (this.hasAppIcon) {
                const slottedAppIcon = this.el.querySelector('[slot="app-icon"]');
                if (slottedAppIcon && slottedAppIcon.tagName === "A")
                    slottedAppIcon.tabIndex = -1;
            }
        };
        this.initialiseSearchBar = () => {
            if (!this.hasSearchSlotContent)
                return;
            const slot = getSlot(this.el, "search");
            if ((slot === null || slot === void 0 ? void 0 : slot.tagName) === "IC-SEARCH-BAR") {
                this.searchBar = slot;
            }
            else if ((slot === null || slot === void 0 ? void 0 : slot.tagName) === "FORM") {
                this.searchBar = slot.querySelector("ic-search-bar");
            }
            if (this.searchBar !== null) {
                this.searchBar.hideLabel = true;
            }
        };
        this.toggleSearchBar = () => {
            var _a;
            this.mobileSearchBarVisible = !this.mobileSearchBarVisible;
            if (!this.searchBar)
                return;
            (_a = this.mobileSearchButtonEl) === null || _a === void 0 ? void 0 : _a.setAttribute("aria-label", `${this.mobileSearchBarVisible ? "Hide" : "Show"} search`);
            this.hasFullWidthSearchBar = this.mobileSearchBarVisible;
            this.searchBar.fullWidth = this.mobileSearchBarVisible;
            if (this.mobileSearchBarVisible) {
                setTimeout(() => {
                    var _a;
                    (_a = this.searchBar) === null || _a === void 0 ? void 0 : _a.focus();
                }, 100);
            }
        };
        this.menuButtonClick = () => {
            this.showNavMenu(true);
        };
        this.showNavMenu = (show) => {
            this.navMenuVisible = show;
            (show ? this.icNavigationMenuOpened : this.icNavigationMenuClosed).emit();
            document.body.style.height = show ? "100%" : "auto";
            document.body.style.overflow = show ? "hidden" : "auto";
        };
        this.searchButtonMouseDownHandler = () => {
            this.searchButtonClick = true;
        };
        this.searchButtonClickHandler = () => {
            this.toggleSearchBar();
            this.searchButtonClick = false;
        };
        this.resizeObserverCallback = (currSize) => {
            if (currSize === this.deviceSize)
                return;
            this.deviceSize = currSize;
            if (currSize > this.customMobileBreakpoint) {
                this.showNavMenu(false);
                if (this.mobileSearchBarVisible) {
                    this.toggleSearchBar();
                }
            }
            this.icTopNavResized.emit({
                size: currSize,
            });
            if (this.searchBar && document.activeElement === this.searchBar) {
                this.searchBar.setAttribute("hidden", "true");
                //remove attribute again as this trigger a redraw & applies css
                this.searchBar.removeAttribute("hidden");
                setTimeout(() => {
                    var _a;
                    (_a = this.searchBar) === null || _a === void 0 ? void 0 : _a.focus();
                }, 100);
            }
        };
        this.runResizeObserver = () => {
            this.resizeObserver = new ResizeObserver(() => {
                this.resizeObserverCallback(getCurrentDeviceSize());
            });
            this.resizeObserver.observe(this.el);
        };
    }
    watchPropHandler(newValue, oldValue) {
        //added for Gatsby rehydration issue where prop is initially undefined but then changes to actual value
        //this watch can be removed once Gatsby hydration issue is resolved
        onComponentPropUndefinedChange(oldValue, newValue, this.initialiseSearchBar);
    }
    disconnectedCallback() {
        var _a;
        (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
    }
    componentWillLoad() {
        this.checkSlots();
        this.deviceSize = getCurrentDeviceSize();
        this.initialiseSearchBar();
    }
    componentDidLoad() {
        checkResizeObserver(this.runResizeObserver);
        if (!this.hasAppTitleSlot) {
            onComponentRequiredPropUndefined([{ prop: this.appTitle, propName: "app-title" }], "Top Navigation");
        }
    }
    componentWillRender() {
        this.checkSlots();
    }
    navBarMenuCloseHandler() {
        var _a;
        this.showNavMenu(false);
        (_a = this.menuButtonEl) === null || _a === void 0 ? void 0 : _a.setFocus();
    }
    searchInputBlurHandler({ detail, }) {
        if (detail !== null) {
            if (this.mobileSearchBarVisible && !this.searchButtonClick) {
                //don't hide if blur was triggered by click on search button - let the click handler toggle the state
                this.toggleSearchBar();
            }
            this.searchValue = detail.value;
        }
    }
    searchValueChangeHandler({ detail }) {
        this.searchValue = detail.value;
    }
    brandChangeHandler({ detail }) {
        this.foregroundColor = detail.mode;
    }
    render() {
        const { appTitle, contentAligned, customMobileBreakpoint, deviceSize, el, foregroundColor, hasAppIcon, hasAppTitleSlot, hasFullWidthSearchBar, hasIconButtons, hasNavigation, hasSearchSlotContent, href, inline, menuButtonClick, mobileSearchBarVisible, navMenuVisible, searchButtonClickHandler, searchButtonMouseDownHandler, shortAppTitle, status, version, theme, } = this;
        const hasStatus = status !== "";
        const hasVersion = version !== "";
        const hasMenuContent = hasNavigation || hasIconButtons || hasStatus || hasVersion;
        const isSmallDeviceSize = deviceSize <= DEVICE_SIZES.S;
        const searchButtonSize = isSmallDeviceSize ? "medium" : "large";
        const hasTitle = appTitle !== "" && isPropDefined(appTitle);
        const overMobileBreakpoint = deviceSize <= customMobileBreakpoint;
        const appTitleVariant = overMobileBreakpoint
            ? isSmallDeviceSize
                ? "subtitle-small"
                : "h4"
            : "h3";
        const mobileSearchButtonTitle = `${mobileSearchBarVisible ? "Hide" : "Show"} search`;
        const menuSize = isSmallDeviceSize ? "small" : "medium";
        const shortAppTitleSlot = isSlotUsed(el, "short-app-title");
        const Component = hasAppTitleSlot ? "div" : "a";
        const attrs = Component == "a" && {
            href: href,
        };
        return (h(Host, { key: 'c0c457a694891bb06ad49c6601fb57d83e6ac6c6', class: {
                "fullwidth-searchbar": hasFullWidthSearchBar,
                "mobile-mode": overMobileBreakpoint,
                [IcBrandForegroundEnum.Dark]: foregroundColor === IcBrandForegroundEnum.Dark,
                [`ic-theme-${theme}`]: theme !== "inherit",
            } }, h("div", { key: 'fd5f04cfce660e81024b45ebee521d73d42a448d', class: "top-navigation" }, h("ic-section-container", { key: '028947110e4a66cccc58659ca164b2938cd7e533', aligned: contentAligned, "full-height": true }, h("header", { key: 'f528842ca7c9fe6a127e53cf7ea0c5af9aeebe79', role: "banner" }, h("div", { key: 'e23371a5539f686060f624053e8b04a2cef1f860', class: "top-panel-container" }, h("div", { key: '25ede4b34cb30ba1d25d3fb06a3f44e48ad4a4c9', class: "app-details-container" }, (hasTitle || hasAppTitleSlot) && (h(Component, Object.assign({ key: '666eddef4b8be110a1796083432cd754cda18152', class: "title-link" }, attrs), hasAppIcon && (h("div", { key: 'cb7c5cdf6ccc28c5dc5d7699e0332770aa5246f9', class: "app-icon-container" }, h("slot", { key: 'cd21e969e6fd23594aeb2b31468e81d1d68de7f7', name: "app-icon" }))), isSmallDeviceSize &&
            (!isEmptyString(shortAppTitle) || shortAppTitleSlot) ? (h("ic-typography", { variant: "subtitle-small", "aria-label": (!hasAppTitleSlot || !shortAppTitleSlot) &&
                `${appTitle} (${shortAppTitle})` }, h("h1", null, shortAppTitleSlot ? (h("slot", { name: "short-app-title" })) : (shortAppTitle)))) : (h("ic-typography", { variant: appTitleVariant }, h("h1", { class: "title-wrap" }, hasAppTitleSlot ? (h("slot", { name: "app-title" })) : (appTitle)))))), hasStatus && (h("div", { key: '938a6e6d13bfd92a87baf43934342fb426802d65', class: "app-status" }, h("ic-typography", { key: 'e3e8e83984ead5be2e4869e67640762af42f5f32', "aria-label": "app tag", variant: "label-uppercase", class: "app-status-text" }, status))), hasVersion && (h("div", { key: '1129e504a1db3af56d2c931e08bd15f992b5721f', class: "app-version" }, h("ic-typography", { key: 'c6f56458fc5f565055fdb0bde408e6078216d51b', variant: "label", class: "app-version-text", "aria-label": "app version" }, version)))), (hasSearchSlotContent || hasMenuContent) && (h("div", { key: '4523603a02eeb22eca466afc1d2cfa44755b8f17', class: "search-menu-container" }, h("div", { key: '77ff191542abaa41c8610418d54922e91268d364', class: "search-actions-container" }, !overMobileBreakpoint ? (h(Fragment, null, h("slot", { name: "search" }), hasIconButtons && (h("div", { class: "icon-buttons-container" }, h("slot", { name: "buttons" }))))) : (h(Fragment, null, hasSearchSlotContent && (h("ic-button", { id: "search-toggle-button", ref: (el) => (this.mobileSearchButtonEl = el), onMouseDown: searchButtonMouseDownHandler, variant: "icon-tertiary", monochrome: true, size: searchButtonSize, "aria-label": mobileSearchButtonTitle, theme: foregroundColor, onClick: searchButtonClickHandler }, h("slot", { name: "toggle-icon" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "#ffffff" }, h("path", { d: "M0 0h24v24H0V0z", fill: "none" }), h("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" }))))), hasMenuContent && (h("div", { class: "menu-button-container" }, h("span", { id: "navigation-landmark-button-text", class: "navigation-landmark-button-text", "aria-hidden": "true" }, "Main navigation button"), h("nav", { "aria-labelledby": "navigation-landmark-button-text", "aria-hidden": `${navMenuVisible}` }, h("ic-button", { id: "menu-button", ref: (el) => (this.menuButtonEl = el), theme: foregroundColor, variant: "secondary", monochrome: true, "aria-expanded": "false", "aria-haspopup": "true", "aria-label": `Open ${hasNavigation ? "navigation" : "app"} menu`, size: menuSize, onClick: menuButtonClick }, "Menu", h("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#ffffff", slot: "left-icon" }, h("path", { d: "M0 0h24v24H0V0z", fill: "none" }), h("path", { d: "M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" })))))))))))), mobileSearchBarVisible && (h("div", { key: 'e18aab12917ebdfead1c16c9d508c7feaf7797cb', class: "search-bar-container" }, h("slot", { key: '4bf9ae342c58629ea76dc7de395128afd695dc8b', name: "search" }))), hasNavigation && !overMobileBreakpoint && (h("div", { key: '30401c56949e21a33b18166da0ba2b07ad91c3f0', class: "navigation-tabs" }, h("span", { key: '72561ee2554f09e0ff33b29fb257e7dde0a99a0f', id: "navigation-landmark-text", class: "navigation-landmark-text", "aria-hidden": "true" }, "Main pages"), h("nav", { key: '411b215af2ef320d415af6e189a60dce1b730cdf', "aria-labelledby": "navigation-landmark-text", class: "nav-panel-container" }, h("ic-horizontal-scroll", { key: 'fac1019061aeaea2ea8197cc0100a23f0cd1a69d',
            // eslint-disable-next-line
            // @ts-ignore
            monochrome: true, appearance: foregroundColor }, h("ul", { key: 'b85234906c34f1fa03b56903656d6f18eb20829d', class: "navigation-item-list", tabindex: "-1" }, h("slot", { key: 'd8ef04882230955d8faba63b13edffeeb969e6e6', name: "navigation" }))))))))), navMenuVisible && (h("ic-navigation-menu", { key: '46b00abe99e079c940d24d4e9693c5445ebcbafa', version: version, status: status, class: {
                inline,
            } }, hasIconButtons && (h("div", { key: '29a9b4e6ba1733b2e96ad9b886bb879ade662d41', class: "menu-buttons-slot", slot: "buttons" }, h("slot", { key: '748b40fd29aedee029a4fa27e999cf9844483613', name: "buttons" }))), h("ul", { key: '20b81216ba0c01470673678a14d873fe8cbcaaae', slot: "navigation" }, h("slot", { key: 'fb9e239a48344888b970e865e103b1ee2f9156ed', name: "navigation" }))))));
    }
    static get is() { return "ic-top-navigation"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-top-navigation.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-top-navigation.css"]
        };
    }
    static get properties() {
        return {
            "contentAligned": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcAlignment",
                    "resolved": "\"center\" | \"full-width\" | \"left\"",
                    "references": {
                        "IcAlignment": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcAlignment"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The alignment of the top navigation content."
                },
                "getter": false,
                "setter": false,
                "attribute": "content-aligned",
                "reflect": false,
                "defaultValue": "\"full-width\""
            },
            "customMobileBreakpoint": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "IcDeviceSizes",
                    "resolved": "0 | 1200 | 576 | 768 | 992",
                    "references": {
                        "IcDeviceSizes": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcDeviceSizes"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Can set a custom breakpoint for the top navigation to switch to mobile mode.\nMust be one of our specified breakpoints in px: `0`, `576`, `768`, `992`, `1200`."
                },
                "getter": false,
                "setter": false,
                "attribute": "custom-mobile-breakpoint",
                "reflect": false,
                "defaultValue": "DEVICE_SIZES.L"
            },
            "href": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The URL to navigate to when the app title is clicked."
                },
                "getter": false,
                "setter": false,
                "attribute": "href",
                "reflect": false,
                "defaultValue": "\"/\""
            },
            "inline": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the flyout navigation menu on small devices will be contained by the parent element."
                },
                "getter": false,
                "setter": false,
                "attribute": "inline",
                "reflect": false,
                "defaultValue": "false"
            },
            "shortAppTitle": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The short title of the app to be displayed at small screen sizes in place of the app title."
                },
                "getter": false,
                "setter": false,
                "attribute": "short-app-title",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "status": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The status info to be displayed."
                },
                "getter": false,
                "setter": false,
                "attribute": "status",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "theme": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcThemeMode",
                    "resolved": "\"dark\" | \"inherit\" | \"light\"",
                    "references": {
                        "IcThemeMode": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcThemeMode"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets the theme color to the dark or light theme color. \"inherit\" will set the color based on the system settings or ic-theme component."
                },
                "getter": false,
                "setter": false,
                "attribute": "theme",
                "reflect": false,
                "defaultValue": "\"inherit\""
            },
            "version": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The version info to be displayed."
                },
                "getter": false,
                "setter": false,
                "attribute": "version",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "appTitle": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The app title to be displayed. This is required, unless a slotted app title link is used."
                },
                "getter": false,
                "setter": false,
                "attribute": "app-title",
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "deviceSize": {},
            "foregroundColor": {},
            "hasFullWidthSearchBar": {},
            "mobileSearchBarVisible": {},
            "mobileSearchHiddenOnBlur": {},
            "navMenuVisible": {},
            "searchButtonClick": {},
            "searchValue": {}
        };
    }
    static get events() {
        return [{
                "method": "icNavigationMenuClosed",
                "name": "icNavigationMenuClosed",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "- Emitted when the menu is closed."
                        }],
                    "text": ""
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "icNavigationMenuOpened",
                "name": "icNavigationMenuOpened",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "- Emitted when the menu is opened."
                        }],
                    "text": ""
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "icTopNavResized",
                "name": "icTopNavResized",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the top navigation is resized."
                },
                "complexType": {
                    "original": "{ size: number }",
                    "resolved": "{ size: number; }",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "appTitle",
                "methodName": "watchPropHandler"
            }];
    }
    static get listeners() {
        return [{
                "name": "icNavigationMenuClose",
                "method": "navBarMenuCloseHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "icSearchBarBlur",
                "method": "searchInputBlurHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "icChange",
                "method": "searchValueChangeHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "brandChange",
                "method": "brandChangeHandler",
                "target": "document",
                "capture": false,
                "passive": false
            }];
    }
}
//# sourceMappingURL=ic-top-navigation.js.map
