import { h, Host, } from "@stencil/core";
import { getRel } from "../../util/link-helper";
import { getIconName } from "../icon/get-icon-props";
import { makeEnterClickable, removeEnterClickable, } from "../../util/make-enter-clickable";
import translate from "../../global/translations";
import { BACKSPACE, DELETE } from "../../util/keycodes";
import { isEmpty } from "lodash-es";
/**
 * Chips and buttons are both interactive elements in UI design,
 * but they serve different purposes and are used in different contexts.
 *
 * :::warning
 * Do not use the chip component carelessly, as an alternative for
 * [`limel-button`](#/component/limel-button/) in the UI design!
 *
 * **Buttons:**
 * Buttons are used to trigger actions. They are typically used to
 * submit forms, open dialogs, initiate a process, or perform any action
 * that changes the state of the application.
 * Buttons' labels usually contain action words, in other words, the labels is
 * a _verb in imperative mood_ such as "Submit" or "Delete".
 * Buttons are placed in areas where it's clear they will initiate
 * an action when clicked.
 *
 * **Chips:**
 * Chips however are elements which may look like buttons, but they are
 * representing choices, filters, or tags, in a small block
 * or clearly bundled into a group. Chips are rarely used alone in the
 * user interface.
 * They are often used in a so called "chip-set", or placed together in
 * a section of the UI, where the user can expect more than one chip to be present.
 *
 * For example, a chip may represent a filter in a filter bar, or a tag in a tag list,
 * or an item in a shopping list.
 * Clicking a chip can also trigger an action, for example toggling a filter ON or OFF,
 * or opening a page with all posts tagged with the tag represented by the chip,
 * or navigating to a page with more information about the item in the shopping list.
 * :::
 *
 * @exampleComponent limel-example-chip-button
 * @exampleComponent limel-example-chip-link
 * @exampleComponent limel-example-chip-icon-colors
 * @exampleComponent limel-example-chip-image
 * @exampleComponent limel-example-chip-badge
 * @exampleComponent limel-example-chip-filter
 * @exampleComponent limel-example-chip-removable
 * @exampleComponent limel-example-chip-menu
 * @exampleComponent limel-example-chip-loading
 * @exampleComponent limel-example-chip-progress
 * @exampleComponent limel-example-chip-size
 * @exampleComponent limel-example-chip-readonly-border
 * @exampleComponent limel-example-chip-aria-role
 */
export class Chip {
    constructor() {
        /**
         * Defines the language for translations.
         * Will translate the translatable strings on the components.
         */
        this.language = 'en';
        /**
         * Set to `true` to disable the chip.
         */
        this.disabled = false;
        /**
         * Set to `true` to render the chip as a static UI element.
         * Useful when the parent component has a `readonly` state.
         */
        this.readonly = false;
        /**
         * Set to `true` to visualize the chip in a "selected" state.
         * This is typically used when the chip is used in a chip-set
         * along with other chips.
         */
        this.selected = false;
        /**
         * Set to `true` to visualize the chip in an "invalid" or "error" state.
         */
        this.invalid = false;
        /**
         * Set to `true` to render a remove button on the chip.
         */
        this.removable = false;
        /**
         * Set to `filter` to render the chip with a distinct style
         * suitable for visualizing filters.
         *
         */
        this.type = 'default';
        /**
         * Set to `true` to put the component in the `loading` state,
         * and render an indeterminate progress indicator inside the chip.
         * This does _not_ disable the interactivity of the chip!
         */
        this.loading = false;
        /**
         * Identifier for the chip. Must be unique.
         */
        this.identifier = crypto.randomUUID();
        /**
         * Defines the size of the chip.
         */
        this.size = 'default';
        /**
         * When provided, the chip will render an ellipsis menu with the supplied items.
         * Also, this will hide the "remove button" when `removable={true}`, as
         * the remove button will automatically become the last item in the menu.
         */
        this.menuItems = [];
        this.renderAsButton = () => {
            return [
                h("button", { id: 'chip-' + this.identifier, class: "chip", role: "button", disabled: this.disabled || this.readonly, "aria-busy": this.loading ? 'true' : 'false', "aria-live": "polite", onKeyDown: this.handleDeleteKeyDown }, this.renderSpinner(), this.renderPicture(), this.renderLabel(), this.renderBadge(), this.renderProgressBar()),
                this.renderRemoveButton(),
                this.renderActionsMenu(),
            ];
        };
        this.renderAsLink = () => {
            var _a, _b;
            const rel = getRel((_a = this.link) === null || _a === void 0 ? void 0 : _a.target, (_b = this.link) === null || _b === void 0 ? void 0 : _b.rel);
            return [
                h("a", { id: 'chip-' + this.identifier, class: "chip", href: this.link.href, title: this.link.title, target: this.link.target, rel: rel, "aria-disabled": this.disabled || this.readonly, tabindex: this.disabled || this.readonly ? -1 : 0, onKeyDown: this.handleDeleteKeyDown }, this.renderSpinner(), this.renderPicture(), this.renderLabel(), this.renderBadge(), this.renderProgressBar()),
                this.renderRemoveButton(),
                this.renderActionsMenu(),
            ];
        };
        this.renderLabel = () => {
            return h("span", { class: "text" }, this.text);
        };
        this.filterClickWhenDisabled = (e) => {
            if (this.disabled || this.readonly) {
                e.preventDefault();
            }
        };
        this.handleRemoveClick = (event) => {
            event.stopPropagation();
            this.remove.emit(this.identifier);
        };
        this.handleDeleteKeyDown = (event) => {
            if (!this.removable) {
                return;
            }
            const keys = [DELETE, BACKSPACE];
            if (keys.includes(event.key)) {
                this.handleRemoveClick(event);
            }
        };
        this.removeChipLabel = () => {
            return `${this.getTranslation('remove')} ${this.text}`;
        };
        this.actionMenuLabel = () => {
            return this.getTranslation('file-viewer.more-actions');
        };
        this.getTranslation = (key) => {
            return translate.get(key, this.language);
        };
        this.handleActionMenuSelect = (event) => {
            const menuItem = event.detail;
            if (!menuItem) {
                return;
            }
            if (menuItem.value === '_remove') {
                this.remove.emit(this.identifier);
                return;
            }
            this.menuItemSelected.emit(menuItem);
        };
        this.handleActionMenuCancel = (event) => {
            event.stopPropagation();
        };
    }
    componentWillLoad() {
        makeEnterClickable(this.host);
    }
    disconnectedCallback() {
        removeEnterClickable(this.host);
    }
    render() {
        return (h(Host, { key: 'ff0578a9545aa295b7a5c58dd7c17605e4a8acc2', onClick: this.filterClickWhenDisabled }, this.link ? this.renderAsLink() : this.renderAsButton()));
    }
    renderPicture() {
        var _a, _b;
        const icon = getIconName(this.icon);
        if (!icon && !this.image) {
            return;
        }
        if (!isEmpty(this.image)) {
            return (h("img", { src: this.image.src, alt: this.image.alt, loading: "lazy" }));
        }
        return (h("limel-icon", { badge: true, name: icon, style: {
                color: `${(_a = this.icon) === null || _a === void 0 ? void 0 : _a.color}`,
                'background-color': `${(_b = this.icon) === null || _b === void 0 ? void 0 : _b.backgroundColor}`,
            } }));
    }
    renderBadge() {
        if (!this.badge) {
            return;
        }
        return h("limel-badge", { label: this.badge });
    }
    renderRemoveButton() {
        var _a;
        if (!this.removable ||
            this.readonly ||
            this.disabled ||
            !!((_a = this.menuItems) === null || _a === void 0 ? void 0 : _a.length)) {
            return;
        }
        const svgData = '<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" stroke-width="2" d="m8 8 16 16M24 8 8 24"/></svg>';
        return (h("button", { class: "trailing-button remove-button", tabIndex: -1, "aria-label": this.removeChipLabel(), "aria-controls": 'chip-' + this.identifier, innerHTML: svgData, onClick: this.handleRemoveClick }));
    }
    renderActionsMenu() {
        var _a;
        if (!((_a = this.menuItems) === null || _a === void 0 ? void 0 : _a.length)) {
            return;
        }
        const svgData = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" xml:space="preserve"><circle fill="currentColor" cx="16" cy="16" r="2"/><circle fill="currentColor" cx="16" cy="24" r="2"/><circle fill="currentColor" cx="16" cy="8" r="2"/></svg>';
        const menuItems = this.getMenuItems();
        return (h("limel-menu", { items: menuItems, onSelect: this.handleActionMenuSelect, openDirection: "bottom-end", onCancel: this.handleActionMenuCancel }, h("button", { slot: "trigger", disabled: this.disabled, class: "trailing-button", "aria-label": this.actionMenuLabel(), innerHTML: svgData })));
    }
    getMenuItems() {
        let menuItems = [...this.menuItems];
        if (this.removable) {
            menuItems = [
                ...menuItems,
                { separator: true },
                {
                    text: this.removeChipLabel(),
                    icon: {
                        name: 'delete_sign',
                        color: 'rgb(var(--color-red-default))',
                    },
                    value: '_remove',
                },
            ];
        }
        return menuItems;
    }
    renderSpinner() {
        if (!this.loading) {
            return;
        }
        return h("limel-linear-progress", { indeterminate: true });
    }
    renderProgressBar() {
        if (!this.progress) {
            return;
        }
        const currentPercentage = this.progress + '%';
        return (h("div", { role: "progressbar", "aria-label": "%", "aria-valuemin": "0", "aria-valuemax": "100", "aria-valuenow": this.progress, style: {
                '--limel-chip-progress-percentage': currentPercentage,
            } }));
    }
    static get is() { return "limel-chip"; }
    static get encapsulation() { return "shadow"; }
    static get delegatesFocus() { return true; }
    static get originalStyleUrls() {
        return {
            "$": ["chip.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["chip.css"]
        };
    }
    static get properties() {
        return {
            "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.\nWill translate the translatable strings on the components."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "language",
                "defaultValue": "'en'"
            },
            "text": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Label displayed on the chip"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "text"
            },
            "icon": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string | Icon",
                    "resolved": "Icon | string",
                    "references": {
                        "Icon": {
                            "location": "import",
                            "path": "../../global/shared-types/icon.types",
                            "id": "src/global/shared-types/icon.types.ts::Icon",
                            "referenceLocation": "Icon"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Icon of the chip."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "icon"
            },
            "image": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Image",
                    "resolved": "Image",
                    "references": {
                        "Image": {
                            "location": "import",
                            "path": "../../global/shared-types/image.types",
                            "id": "src/global/shared-types/image.types.ts::Image",
                            "referenceLocation": "Image"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A picture to be displayed instead of the icon on the chip."
                },
                "getter": false,
                "setter": false
            },
            "link": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Omit<Link, 'text'>",
                    "resolved": "\"text\" | Link",
                    "references": {
                        "Omit": {
                            "location": "global",
                            "id": "global::Omit"
                        },
                        "Link": {
                            "location": "import",
                            "path": "../../global/shared-types/link.types",
                            "id": "src/global/shared-types/link.types.ts::Link",
                            "referenceLocation": "Link"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If supplied, the chip will become a clickable link."
                },
                "getter": false,
                "setter": false
            },
            "badge": {
                "type": "any",
                "mutable": false,
                "complexType": {
                    "original": "string | number",
                    "resolved": "number | string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The value of the badge, displayed on the chip."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "badge"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to disable the chip."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "readonly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to render the chip as a static UI element.\nUseful when the parent component has a `readonly` state."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "readonly",
                "defaultValue": "false"
            },
            "selected": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to visualize the chip in a \"selected\" state.\nThis is typically used when the chip is used in a chip-set\nalong with other chips."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "selected",
                "defaultValue": "false"
            },
            "invalid": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to visualize the chip in an \"invalid\" or \"error\" state."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "invalid",
                "defaultValue": "false"
            },
            "removable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to render a remove button on the chip."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "removable",
                "defaultValue": "false"
            },
            "type": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "ChipType",
                    "resolved": "\"default\" | \"filter\"",
                    "references": {
                        "ChipType": {
                            "location": "import",
                            "path": "../chip-set/chip.types",
                            "id": "src/components/chip-set/chip.types.ts::ChipType",
                            "referenceLocation": "ChipType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Set to `filter` to render the chip with a distinct style\nsuitable for visualizing filters."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "type",
                "defaultValue": "'default'"
            },
            "loading": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to put the component in the `loading` state,\nand render an indeterminate progress indicator inside the chip.\nThis does _not_ disable the interactivity of the chip!"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "loading",
                "defaultValue": "false"
            },
            "progress": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Reflects the current value of a progress bar on the chip,\nvisualizing the percentage of an ongoing process.\nMust be a number between `0` and `100`."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "progress"
            },
            "identifier": {
                "type": "any",
                "mutable": false,
                "complexType": {
                    "original": "number | string",
                    "resolved": "number | string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Identifier for the chip. Must be unique."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "identifier",
                "defaultValue": "crypto.randomUUID()"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'small' | 'default'",
                    "resolved": "\"default\" | \"small\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the size of the chip."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "size",
                "defaultValue": "'default'"
            },
            "menuItems": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Array<MenuItem | ListSeparator>",
                    "resolved": "any[]",
                    "references": {
                        "Array": {
                            "location": "global",
                            "id": "global::Array"
                        },
                        "MenuItem": {
                            "location": "global",
                            "id": "global::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": true,
                "docs": {
                    "tags": [],
                    "text": "When provided, the chip will render an ellipsis menu with the supplied items.\nAlso, this will hide the \"remove button\" when `removable={true}`, as\nthe remove button will automatically become the last item in the menu."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            }
        };
    }
    static get events() {
        return [{
                "method": "remove",
                "name": "remove",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Fired when clicking on the remove button of a `removable` chip.\nThe value of `identifier` is emitted as the event detail."
                },
                "complexType": {
                    "original": "number | string",
                    "resolved": "number | string",
                    "references": {}
                }
            }, {
                "method": "menuItemSelected",
                "name": "menuItemSelected",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when a menu item is selected from the actions menu."
                },
                "complexType": {
                    "original": "MenuItem",
                    "resolved": "MenuItem",
                    "references": {
                        "MenuItem": {
                            "location": "global",
                            "id": "global::MenuItem"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "host"; }
}
