import { h, Host, } from "@stencil/core";
import translate from "./../../global/translations";
import { isItem } from "./is-item";
/**
 * An action bar is a user interface element commonly found in software applications and websites.
 * It typically appears at the top of the screen or within a specific section
 * and serves as a centralized hub for accessing various actions and commands
 * relevant to the current context or page.
 *
 * The action bar often contains a set of clickable icons or buttons (icons + labels)
 * that represent specific actions, such as saving, deleting, editing, sharing,
 * or bulk operations for selected items.
 *
 * The purpose of an action bar is to provide quick and convenient access to
 * frequently used functionalities, enabling users to perform common tasks efficiently.
 * It enhances usability by organizing important actions in a visually prominent and easily accessible location.
 *
 * The action bar's design and layout can vary based on the platform or application,
 * but its primary goal remains consistent—to
 * empower users to interact with the software and perform desired actions effortlessly.
 *
 * @exampleComponent limel-example-action-bar-basic
 * @exampleComponent limel-example-action-bar-overflow-menu
 * @exampleComponent limel-example-action-bar-selected-item
 * @exampleComponent limel-example-action-bar-colors
 * @exampleComponent limel-example-action-bar-floating
 * @exampleComponent limel-example-action-bar-floating-expand
 * @exampleComponent limel-example-action-bar-styling
 * @exampleComponent limel-example-action-bar-as-primary-component
 * @exampleComponent limel-example-action-bar-icon-title
 */
export class ActionBar {
    constructor() {
        /**
         * Items that are placed in the action bar.
         * These represent primary actions.
         */
        this.actions = [];
        /**
         * Defines the language for translations.
         */
        this.language = document.documentElement.lang;
        /**
         * When set to `true`, the action bar will be collapsible.
         */
        this.collapsible = false;
        this.overflowCutoff = this.actions.length;
        /**
         * Indicates whether the action bar is currently in a collapsed state.
         */
        this.actionBarIsShrunk = false;
        this.hasRendered = false;
        this.isFirstIntersectionCheck = true;
        this.actionBarItems = [];
        this.renderActionBarItem = (item, index) => {
            return (h("limel-action-bar-item", { item: item, onSelect: this.handleSelect, isVisible: this.isVisible(index), role: "gridcell" }));
        };
        this.renderOverflowMenu = (items) => {
            if (!(this.actions.length - this.overflowCutoff)) {
                return;
            }
            const shrunkOverFlowIcon = {
                name: 'more',
                color: 'rgb(var(--contrast-1000))',
                title: this.getTranslation('action-bar.actions'),
            };
            return (h("limel-action-bar-overflow-menu", { openDirection: this.openDirection, items: items, onSelect: this.handleSelect, role: "gridcell", overFlowIcon: this.actionBarIsShrunk ? shrunkOverFlowIcon : undefined }));
        };
        this.handleCollapseExpandClick = () => {
            this.actionBarIsShrunk = !this.actionBarIsShrunk;
        };
        this.handleSelect = (event) => {
            event.stopPropagation();
            if (isItem(event.detail)) {
                this.itemSelected.emit(event.detail);
            }
        };
        this.getTranslation = (key) => {
            return translate.get(key, this.language);
        };
        this.handleIntersection = (entries) => {
            const intersectingItems = entries.filter((entry) => entry.isIntersecting);
            const notIntersectingItems = entries.filter((entry) => !entry.isIntersecting);
            if (this.isFirstIntersectionCheck) {
                this.overflowCutoff = intersectingItems.length;
            }
            else {
                this.overflowCutoff =
                    this.overflowCutoff +
                        intersectingItems.length -
                        notIntersectingItems.length;
            }
            this.isFirstIntersectionCheck = false;
        };
    }
    connectedCallback() {
        if (this.hasRendered) {
            this.createIntersectionObserver();
        }
    }
    componentDidRender() {
        var _a;
        if (this.haveItemsChanged()) {
            (_a = this.intersectionObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
            this.createIntersectionObserver();
        }
    }
    disconnectedCallback() {
        var _a;
        (_a = this.intersectionObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
        this.intersectionObserver = undefined;
        this.actionBarItems = [];
    }
    render() {
        this.hasRendered = true;
        let overflowActions = [];
        if (this.actions.length > 0) {
            overflowActions = this.actions.slice(this.overflowCutoff);
        }
        return (h(Host, { key: 'f81d3acb912e7191889f7b8e4462c6e1a1db692b', "aria-label": this.accessibleLabel, class: {
                'is-full-width': this.layout === 'fullWidth',
                'is-floating': this.layout === 'floating',
                'is-shrunk': this.actionBarIsShrunk && this.collapsible,
                'can-be-shrunk': !!this.collapsible,
            }, role: "grid" }, h("div", { key: 'd6d96d43a7dd278f1f65033b070213cd1c6b963e', class: "items", role: "rowgroup" }, this.actions.map(this.renderActionBarItem)), this.renderOverflowMenu(overflowActions), this.renderCollapseExpandButton()));
    }
    renderCollapseExpandButton() {
        if (!this.collapsible || this.actions.length <= 1) {
            return;
        }
        return (h("button", { class: {
                'expand-shrink': true,
            }, "aria-label": this.tooltipLabel, type: "button", onClick: this.handleCollapseExpandClick }, h("limel-icon", { name: "double_left", id: "tooltip-expand-shrink-button" }), h("limel-tooltip", { label: this.tooltipLabel, elementId: "tooltip-expand-shrink-button" })));
    }
    isVisible(index) {
        return index < this.overflowCutoff;
    }
    get tooltipLabel() {
        let key = 'action-bar.collapse';
        if (this.actionBarIsShrunk) {
            key = 'action-bar.expand';
        }
        return this.getTranslation(key);
    }
    createIntersectionObserver() {
        const options = {
            root: this.host.shadowRoot.querySelector('.items'),
            rootMargin: '0px',
            threshold: 1,
        };
        this.overflowCutoff = this.actions.length;
        this.isFirstIntersectionCheck = true;
        this.actionBarItems = [];
        this.intersectionObserver = new IntersectionObserver(this.handleIntersection, options);
        for (const actionBarItem of this.host.shadowRoot.querySelectorAll('limel-action-bar-item')) {
            this.observe(actionBarItem);
        }
    }
    observe(actionBarItem) {
        this.intersectionObserver.observe(actionBarItem);
        this.actionBarItems.push(actionBarItem);
    }
    haveItemsChanged() {
        const someItemRemoved = this.actionBarItems.some((actionBarItem) => !this.host.shadowRoot.contains(actionBarItem));
        const someItemAdded = [
            ...this.host.shadowRoot.querySelectorAll('limel-action-bar-item'),
        ].some((actionBarItem) => !this.actionBarItems.includes(actionBarItem));
        return someItemRemoved || someItemAdded;
    }
    static get is() { return "limel-action-bar"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["action-bar.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["action-bar.css"]
        };
    }
    static get properties() {
        return {
            "actions": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Array<ActionBarItem | ListSeparator>",
                    "resolved": "(ListSeparator | ActionBarItem)[]",
                    "references": {
                        "Array": {
                            "location": "global",
                            "id": "global::Array"
                        },
                        "ActionBarItem": {
                            "location": "import",
                            "path": "./action-bar.types",
                            "id": "src/components/action-bar/action-bar.types.ts::ActionBarItem",
                            "referenceLocation": "ActionBarItem"
                        },
                        "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": "Items that are placed in the action bar.\nThese represent primary actions."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "language": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "Languages",
                    "resolved": "\"da\" | \"de\" | \"en\" | \"fi\" | \"fr\" | \"nb\" | \"nl\" | \"no\" | \"sv\"",
                    "references": {
                        "Languages": {
                            "location": "import",
                            "path": "./../date-picker/date.types",
                            "id": "src/components/date-picker/date.types.ts::Languages",
                            "referenceLocation": "Languages"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the language for translations."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "language",
                "defaultValue": "document.documentElement.lang as Languages"
            },
            "accessibleLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A label used to describe the purpose of the element to users\nof assistive technologies, like screen readers.\nExample value: \"toolbar\""
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "accessible-label"
            },
            "layout": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'fullWidth' | 'floating'",
                    "resolved": "\"floating\" | \"fullWidth\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "- When set to `fullWidth`, the component will take the\nentire width of its container.\n- When set to `floating`, the component will get basic stylings\nto visualize the floating state.\n:::note\nYou should still properly position the component\naccording to the structure of your user interface.\nFor example, use an `absolute` or `fixed` position.\n:::"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "layout"
            },
            "collapsible": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "When set to `true`, the action bar will be collapsible."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "collapsible",
                "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/menu.types",
                            "id": "src/components/menu/menu.types.ts::OpenDirection",
                            "referenceLocation": "OpenDirection"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the location that the content of the overflow menu\nappears, in relation to its trigger."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "open-direction"
            }
        };
    }
    static get states() {
        return {
            "overflowCutoff": {},
            "actionBarIsShrunk": {}
        };
    }
    static get events() {
        return [{
                "method": "itemSelected",
                "name": "itemSelected",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "public",
                            "text": undefined
                        }],
                    "text": "Fired when a action bar item has been clicked."
                },
                "complexType": {
                    "original": "ActionBarItem",
                    "resolved": "ActionBarItemOnlyIcon<any> | ActionBarItemWithLabel<any>",
                    "references": {
                        "ActionBarItem": {
                            "location": "import",
                            "path": "./action-bar.types",
                            "id": "src/components/action-bar/action-bar.types.ts::ActionBarItem",
                            "referenceLocation": "ActionBarItem"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "host"; }
}
