import { Host, h, } from "@stencil/core";
import { createPopper } from "@popperjs/core";
import { isSafari, onComponentRequiredPropUndefined, } from "../../utils/helpers";
export class Tooltip {
    constructor() {
        this.delayedHideEvents = ["mouseleave"];
        this.instantHideEvents = ["focusout"];
        this.mouseOverTool = false;
        this.persistTooltip = false;
        this.showEvents = [
            !this.disableHover && "mouseenter",
            !this.disableHover && "focusin",
            !this.disableClick && "click",
        ];
        /**
         * If `true`, the tooltip will not be displayed on click, it will require hover or using the display method.
         */
        this.disableClick = false;
        /**
         * If `true`, the tooltip will not be displayed on hover, it will require a click.
         */
        this.disableHover = false;
        /**
         * Setting to `true` can help in situations where tooltip content is clipped by a parent element.
         */
        this.fixedPositioning = false;
        /**
         * The position of the tooltip in relation to the parent element.
         */
        this.placement = "bottom";
        /**
         * @internal Sets the tooltip to aria-hidden, when used as part of components that are already announced.
         */
        this.silent = false;
        /**
         * Sets the tooltip to the dark or light theme colors. "inherit" will set the color based on the system settings or ic-theme component.
         */
        this.theme = "inherit";
        this.popperProps = {};
        this.show = () => {
            if (this.label) {
                this.toolTip.setAttribute("data-show", "");
                if (this.containerContentArea) {
                    this.el.classList.add("ic-tooltip-in-container");
                }
                this.popperInstance = createPopper(this.el, this.toolTip, Object.assign({ strategy: this.fixedPositioning ? "fixed" : "absolute", placement: this.placement, modifiers: [
                        {
                            name: "offset",
                            options: {
                                offset: [0, 10],
                            },
                        },
                        {
                            name: "arrow",
                            options: {
                                element: this.arrow,
                            },
                        },
                        {
                            name: "eventListeners",
                            options: { scroll: false, resize: false },
                        },
                        ...(this.containerContentArea
                            ? [
                                {
                                    name: "preventOverflow",
                                    options: {
                                        boundary: this.containerContentArea,
                                        padding: 8,
                                    },
                                },
                                {
                                    name: "flip",
                                    options: {
                                        boundary: this.containerContentArea,
                                    },
                                },
                            ]
                            : []),
                    ] }, this.popperProps));
                this.icTooltipShow.emit();
            }
            else {
                console.warn(`Tooltip can't display without prop 'label' set`);
            }
        };
        this.hide = () => {
            if (this.toolTip !== undefined) {
                this.toolTip.removeAttribute("data-show");
                this.persistTooltip = false;
            }
            if (this.popperInstance !== undefined) {
                this.popperInstance.destroy();
            }
        };
        this.checkCloseTooltip = () => {
            setTimeout(() => {
                if (!this.mouseOverTool && !this.persistTooltip) {
                    this.hide();
                }
            }, 100);
        };
        this.mouseEnterTooltip = () => {
            this.mouseOverTool = true;
        };
        this.mouseLeaveTooltip = () => {
            this.mouseOverTool = false;
            this.checkCloseTooltip();
        };
        this.handleKeyDown = (event) => {
            if (event.key === "Escape" && !this.persistTooltip) {
                this.hide();
            }
        };
        this.manageEventListeners = (action) => {
            const method = action === "add" ? "addEventListener" : "removeEventListener";
            this.showEvents.forEach((event) => {
                if (event) {
                    this.el[method](event, this.show);
                    if (this.toolTip !== undefined) {
                        this.toolTip[method](event, this.mouseEnterTooltip);
                    }
                }
            });
            if (!this.persistTooltip) {
                this.instantHideEvents.forEach((event) => {
                    this.el[method](event, this.hide);
                });
            }
            this.delayedHideEvents.forEach((event) => {
                this.el[method](event, this.checkCloseTooltip);
                if (this.toolTip !== undefined) {
                    this.toolTip[method](event, this.mouseLeaveTooltip);
                }
            });
            document[method]("keydown", this.handleKeyDown);
        };
        this.updateTooltipEvents = () => {
            this.manageEventListeners("remove");
            this.showEvents = [
                !this.disableHover && "mouseenter",
                !this.disableHover && "focusin",
                !this.disableClick && "click",
            ];
            this.manageEventListeners("add");
        };
    }
    watchDisableClickHandler() {
        if (this.disableClick) {
            this.hide();
        }
        this.updateTooltipEvents();
    }
    watchDisableHoverHandler() {
        if (this.disableHover) {
            this.hide();
        }
        this.updateTooltipEvents();
    }
    watchLabelHandler() {
        var _a;
        if (((_a = this.toolTip) === null || _a === void 0 ? void 0 : _a.hasAttribute("data-show")) && this.popperInstance) {
            this.popperInstance.update();
        }
    }
    /**
     * @internal This method allows props to be added to the PopperJS createPopper instance outside of tooltip
     * @param props object - createPopper props set externally
     */
    async setExternalPopperProps(props) {
        this.popperProps = props;
    }
    disconnectedCallback() {
        this.manageEventListeners("remove");
        if (this.popperInstance !== undefined) {
            this.popperInstance.destroy();
        }
    }
    componentDidLoad() {
        var _a, _b;
        this.manageEventListeners("add");
        // Display tooltips correctly within drawer and dialog components
        let container;
        if (this.el.getRootNode().host) {
            container = this.el.getRootNode().host.closest("ic-dialog, ic-drawer");
        }
        else {
            container = this.el.closest("ic-dialog, ic-drawer");
        }
        this.containerContentArea =
            (_b = (_a = container === null || container === void 0 ? void 0 : container.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(".content-area")) !== null && _b !== void 0 ? _b : null;
        onComponentRequiredPropUndefined([{ prop: this.label, propName: "label" }], "Tooltip");
    }
    componentDidRender() {
        var _a;
        const typographyEl = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(".ic-tooltip-container > ic-typography");
        this.maxLines &&
            this.maxLines > 0 &&
            (typographyEl === null || typographyEl === void 0 ? void 0 : typographyEl.setAttribute("style", `--truncation-max-lines: ${this.maxLines}`));
    }
    /**
     * Method to programmatically show/hide the tooltip without needing to interact with an anchor element
     * @param show Whether to show or hide the tooltip
     * @param persistTooltip Whether the tooltip should stay on the screen when actions are performed that would previously dismiss the tooltip, such as on hover
     */
    async displayTooltip(show, persistTooltip) {
        this.persistTooltip = !!persistTooltip;
        show ? this.show() : this.hide();
    }
    /**
     * @internal Method to return if tooltip is currently visible.
     */
    async isTooltipVisible() {
        return Promise.resolve(this.toolTip.hasAttribute("data-show"));
    }
    render() {
        const { label, maxLines, silent, theme } = this;
        return (h(Host, { key: '61c01b4710b1fb71a42044c7e4b7675497952575', class: {
                "ic-tooltip": true,
                [`ic-theme-${theme}`]: theme !== "inherit",
            }, "aria-label": isSafari && label }, h("div", { key: '5b7e00e8164b7a95ca17523d11b4bd02bc4eefbb', ref: (el) => (this.toolTip = el), role: "tooltip", class: "ic-tooltip-container", "aria-hidden": `${silent}` }, h("ic-typography", { key: 'a118c99c30c776f39ed25c630a4231cb637fdcd2', maxLines: maxLines, variant: "caption" }, label), h("div", { key: '2ee6065bc691893170591e43aba77973e6387141', ref: (el) => (this.arrow = el), class: "ic-tooltip-arrow" })), h("slot", { key: 'd76275c08c93ee6d4b39b0ab6be9093a8d5e6de1' })));
    }
    static get is() { return "ic-tooltip"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-tooltip.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-tooltip.css"]
        };
    }
    static get properties() {
        return {
            "disableClick": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the tooltip will not be displayed on click, it will require hover or using the display method."
                },
                "getter": false,
                "setter": false,
                "attribute": "disable-click",
                "reflect": false,
                "defaultValue": "false"
            },
            "disableHover": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the tooltip will not be displayed on hover, it will require a click."
                },
                "getter": false,
                "setter": false,
                "attribute": "disable-hover",
                "reflect": false,
                "defaultValue": "false"
            },
            "fixedPositioning": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Setting to `true` can help in situations where tooltip content is clipped by a parent element."
                },
                "getter": false,
                "setter": false,
                "attribute": "fixed-positioning",
                "reflect": false,
                "defaultValue": "false"
            },
            "maxLines": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The number of lines to display before truncating the text."
                },
                "getter": false,
                "setter": false,
                "attribute": "max-lines",
                "reflect": false
            },
            "placement": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcTooltipPlacements",
                    "resolved": "\"bottom\" | \"bottom-end\" | \"bottom-start\" | \"left\" | \"left-end\" | \"left-start\" | \"right\" | \"right-end\" | \"right-start\" | \"top\" | \"top-end\" | \"top-start\" | undefined",
                    "references": {
                        "IcTooltipPlacements": {
                            "location": "import",
                            "path": "./ic-tooltip.types",
                            "id": "src/components/ic-tooltip/ic-tooltip.types.ts::IcTooltipPlacements"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The position of the tooltip in relation to the parent element."
                },
                "getter": false,
                "setter": false,
                "attribute": "placement",
                "reflect": false,
                "defaultValue": "\"bottom\""
            },
            "silent": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Sets the tooltip to aria-hidden, when used as part of components that are already announced."
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "attribute": "silent",
                "reflect": false,
                "defaultValue": "false"
            },
            "target": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The ID of the element the tooltip is describing - for when aria-labelledby or aria-describedby is used."
                },
                "getter": false,
                "setter": false,
                "attribute": "target",
                "reflect": true
            },
            "theme": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcThemeMode",
                    "resolved": "\"dark\" | \"inherit\" | \"light\" | undefined",
                    "references": {
                        "IcThemeMode": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcThemeMode"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Sets the tooltip to the dark or light theme colors. \"inherit\" will set the color based on the system settings or ic-theme component."
                },
                "getter": false,
                "setter": false,
                "attribute": "theme",
                "reflect": false,
                "defaultValue": "\"inherit\""
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The text to display on the tooltip."
                },
                "getter": false,
                "setter": false,
                "attribute": "label",
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "popperProps": {}
        };
    }
    static get events() {
        return [{
                "method": "icTooltipShow",
                "name": "icTooltipShow",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the tooltip becomes visible."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "setExternalPopperProps": {
                "complexType": {
                    "signature": "<T extends Partial<Options>>(props: T) => Promise<void>",
                    "parameters": [{
                            "name": "props",
                            "type": "T",
                            "docs": "object - createPopper props set externally"
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "Partial": {
                            "location": "global",
                            "id": "global::Partial"
                        },
                        "Options": {
                            "location": "import",
                            "path": "@popperjs/core",
                            "id": "node_modules::Options"
                        },
                        "T": {
                            "location": "global",
                            "id": "global::T"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "This method allows props to be added to the PopperJS createPopper instance outside of tooltip"
                        }, {
                            "name": "param",
                            "text": "props object - createPopper props set externally"
                        }]
                }
            },
            "displayTooltip": {
                "complexType": {
                    "signature": "(show: boolean, persistTooltip?: boolean) => Promise<void>",
                    "parameters": [{
                            "name": "show",
                            "type": "boolean",
                            "docs": "Whether to show or hide the tooltip"
                        }, {
                            "name": "persistTooltip",
                            "type": "boolean | undefined",
                            "docs": "Whether the tooltip should stay on the screen when actions are performed that would previously dismiss the tooltip, such as on hover"
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Method to programmatically show/hide the tooltip without needing to interact with an anchor element",
                    "tags": [{
                            "name": "param",
                            "text": "show Whether to show or hide the tooltip"
                        }, {
                            "name": "param",
                            "text": "persistTooltip Whether the tooltip should stay on the screen when actions are performed that would previously dismiss the tooltip, such as on hover"
                        }]
                }
            },
            "isTooltipVisible": {
                "complexType": {
                    "signature": "() => Promise<boolean>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<boolean>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "Method to return if tooltip is currently visible."
                        }]
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "disableClick",
                "methodName": "watchDisableClickHandler"
            }, {
                "propName": "disableHover",
                "methodName": "watchDisableHoverHandler"
            }, {
                "propName": "label",
                "methodName": "watchLabelHandler"
            }];
    }
}
//# sourceMappingURL=ic-tooltip.js.map
