import { h } from "@stencil/core";
import { createRandomString } from "../../util/random-string";
import { getOwnerElement } from "./get-owner-element";
import { TooltipTimer } from "./tooltip-timer";
const DEFAULT_MAX_LENGTH = 50;
/**
 * A tooltip can be used to display a descriptive text for any element.
 * The displayed content must be a brief and supplemental string of text,
 * identifying the element or describing its function for the user,
 * helping them better understand unfamiliar objects that aren't described
 * directly in the UI.
 *
 * ## Interaction
 * The tooltip appears after a slight delay, when the element is hovered;
 * and disappears as soon as the cursor leaves the element.
 * Therefore, users cannot interact with the tip, but if the trigger element
 * itself is interactive, it will remain interactible even with a tooltip bound
 * to it.
 *
 * :::note
 * In order to display the tooltip, the tooltip element and its trigger element
 * must be within the same document or document fragment (the same shadowRoot).
 * Often, it's easiest to just place them next to each other like in the example
 * below, but if you need to, you can place them differently.
 *
 * ```html
 * <limel-button icon="search" id="tooltip-example" />
 * <limel-tooltip label="Search" elementId="tooltip-example" />
 * ```
 * :::
 *
 * ## Usage
 * - Keep in mind that tooltips can be distracting, and can be perceived as an interruption.
 * Use them only when they add significant value.
 * - A good tip is concise, helpful, and informative.
 * Don't explain the obvious or simply repeat what is already on the screen.
 * When used correctly, supplemental info of a tooltip helps to [declutter the UI](#/DesignGuidelines/decluttering.md/).
 * - If the tip is essential to the primary tasks that the user is performing,
 * such as warnings or important notes, include the information directly in the
 * interface instead.
 * - When a component offers a helper text (e.g. [Input field](#/component/limel-input-field/)),
 * use that, not a tooltip.
 * - Make sure to use the tooltip on an element that users naturally and
 * effortlessly recognize can be hovered.
 *
 * @exampleComponent limel-example-tooltip-basic
 * @exampleComponent limel-example-tooltip-max-character
 * @exampleComponent limel-example-tooltip-composite
 */
export class Tooltip {
    constructor() {
        /**
         * The maximum amount of characters before rendering 'label' and
         * 'helperLabel' in two rows.
         */
        this.maxlength = DEFAULT_MAX_LENGTH;
        /**
         * Decides the tooltip's location in relation to its trigger.
         */
        this.openDirection = 'top';
        this.showTooltip = () => {
            this.tooltipTimer.showAfterDelay();
        };
        this.hideTooltip = () => {
            this.tooltipTimer.hide();
        };
        this.portalId = createRandomString();
        this.tooltipId = createRandomString();
        this.tooltipTimer = new TooltipTimer(() => (this.open = true), () => (this.open = false));
    }
    connectedCallback() {
        this.ownerElement = getOwnerElement(this.elementId, this.host);
        this.setOwnerAriaLabel();
        this.addListeners();
    }
    disconnectedCallback() {
        this.removeListeners();
    }
    render() {
        const tooltipZIndex = getComputedStyle(this.host).getPropertyValue('--tooltip-z-index');
        return (h("div", { key: '41e07fbdde2814c108805286e919ac0da916c0f3', class: "trigger-anchor" }, h("limel-portal", { key: '4bb06a6307a3ccb934cc30c76ebde152fb784beb', openDirection: this.openDirection, visible: this.open, containerId: this.portalId, containerStyle: {
                'z-index': tooltipZIndex,
                'pointer-events': 'none',
            }, anchor: this.ownerElement }, h("limel-tooltip-content", { key: 'eb24b1a7df99ef054b4d0108275480568c22eede', label: this.label, helperLabel: this.helperLabel, maxlength: this.maxlength, role: "tooltip", "aria-hidden": !this.open, id: this.tooltipId }))));
    }
    setOwnerAriaLabel() {
        var _a;
        (_a = this.ownerElement) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-describedby', this.tooltipId);
    }
    addListeners() {
        var _a, _b, _c, _d;
        (_a = this.ownerElement) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseover', this.showTooltip);
        (_b = this.ownerElement) === null || _b === void 0 ? void 0 : _b.addEventListener('mouseout', this.hideTooltip);
        (_c = this.ownerElement) === null || _c === void 0 ? void 0 : _c.addEventListener('focus', this.showTooltip);
        (_d = this.ownerElement) === null || _d === void 0 ? void 0 : _d.addEventListener('blur', this.hideTooltip);
    }
    removeListeners() {
        var _a, _b, _c, _d;
        (_a = this.ownerElement) === null || _a === void 0 ? void 0 : _a.removeEventListener('mouseover', this.showTooltip);
        (_b = this.ownerElement) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseout', this.hideTooltip);
        (_c = this.ownerElement) === null || _c === void 0 ? void 0 : _c.removeEventListener('focus', this.showTooltip);
        (_d = this.ownerElement) === null || _d === void 0 ? void 0 : _d.removeEventListener('blur', this.hideTooltip);
    }
    static get is() { return "limel-tooltip"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["tooltip.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["tooltip.css"]
        };
    }
    static get properties() {
        return {
            "elementId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "ID of the owner element that the tooltip should describe.\nMust be a child within the same document fragment as the tooltip element\nitself."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "element-id"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Short descriptive text of the owner element."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "label"
            },
            "helperLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Additional helper text for the element.\nExample usage can be a keyboard shortcut to activate the function of the\nowner element."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "helper-label"
            },
            "maxlength": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The maximum amount of characters before rendering 'label' and\n'helperLabel' in two rows."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "maxlength",
                "defaultValue": "DEFAULT_MAX_LENGTH"
            },
            "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": "Decides the tooltip's location in relation to its trigger."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "open-direction",
                "defaultValue": "'top'"
            }
        };
    }
    static get states() {
        return {
            "open": {}
        };
    }
    static get elementRef() { return "host"; }
}
