import { h, Host, } from "@stencil/core";
import { checkResizeObserver, isElInAGGrid } from "../../utils/helpers";
export class Typography {
    constructor() {
        this.focusBtnFromKeyboard = true;
        this.inAGGrid = false;
        this.lastMarkerTop = 0;
        this.lastWidth = 0;
        this.resizeObserver = null;
        this.truncatedHeight = 0;
        this.truncated = false;
        this.truncButtonFocussed = false;
        /**
         * If `true`, appropriate top and bottom margins will be applied to the typography.
         */
        this.applyVerticalMargins = false;
        /**
         * If `true`, the typography will have a bold font weight.
         * Note: This will have no impact on variants that already use an equivalent or higher font weight (h1, h2, and subtitle-large).
         */
        this.bold = false;
        /**
         * If `true`, the typography will have an italic font style.
         */
        this.italic = false;
        /**
         * If `true`, the typography will have a line through it.
         */
        this.strikethrough = false;
        /**
         * Sets the text 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";
        /**
         * If `true`, the typography will have a line under it.
         */
        this.underline = false;
        /**
         * The ICDS typography style to use.
         */
        this.variant = "body";
        this.expanded = false;
        this.toggleExpanded = (ev) => {
            ev.stopPropagation();
            this.expanded = !this.expanded;
            this.typographyTruncationExpandToggle.emit({
                expanded: this.expanded,
                typographyEl: this.el,
            });
        };
        this.checkMarkerPosition = (elTop, markerTop) => {
            if (markerTop - elTop < this.truncatedHeight) {
                this.truncated = false;
                this.expanded = false;
            }
            else {
                this.truncated = true;
            }
        };
        this.getElementTop = (el) => {
            return el.getClientRects && el.getClientRects()[0]
                ? el.getClientRects()[0].top
                : 0;
        };
        this.runResizeObserver = () => {
            if (this.truncWrapperEl) {
                this.resizeObserver = new ResizeObserver(() => {
                    clearTimeout(this.resizeInterval);
                    this.resizeInterval = window.setTimeout(this.resizeObserverCallback, 50);
                });
                this.resizeObserver.observe(this.truncWrapperEl);
            }
        };
        this.resizeObserverCallback = () => {
            if (this.lastWidth === this.el.clientWidth) {
                return;
            }
            if (this.truncatedHeight === 0) {
                this.checkMaxLines(this.el.clientHeight);
                return;
            }
            const markerTop = this.getElementTop(this.marker);
            if (markerTop === this.lastMarkerTop) {
                return;
            }
            this.checkMarkerPosition(this.getElementTop(this.el), markerTop);
            this.lastMarkerTop = markerTop;
            this.lastWidth = this.el.clientWidth;
        };
        this.truncButtonFocus = () => {
            if (this.focusBtnFromKeyboard) {
                this.truncButtonFocussed = true;
            }
        };
        this.truncButtonBlur = () => {
            this.focusBtnFromKeyboard = true;
            this.truncButtonFocussed = false;
        };
        this.truncButtonFocusFromMouse = () => {
            this.focusBtnFromKeyboard = false;
        };
    }
    watchExpandedHandler() {
        this.el.setAttribute("style", `--truncation-max-lines: ${this.expanded ? "initial" : this.maxLines}`);
    }
    disconnectedCallback() {
        if (this.resizeObserver !== null) {
            this.resizeObserver.disconnect();
        }
    }
    /**
     * @internal This is used by data table to remove all truncation in certain events
     */
    async resetTruncation() {
        if (this.truncated) {
            this.truncated = false;
            this.maxLines = 0;
            this.el.removeAttribute("max-lines");
            this.expanded = false;
            this.el.removeAttribute("style");
        }
    }
    componentDidLoad() {
        var _a, _b;
        if ((this.variant === "body" ||
            ((_b = (_a = this.el.getRootNode()) === null || _a === void 0 ? void 0 : _a.host) === null || _b === void 0 ? void 0 : _b.tagName) ===
                "IC-TOOLTIP") &&
            this.maxLines &&
            this.maxLines > 0) {
            const marker = document.createElement("span");
            marker.style.visibility = "hidden";
            this.el.appendChild(marker);
            this.marker = marker;
            this.lastWidth = this.el.clientWidth;
            this.checkMaxLines(this.el.clientHeight);
            checkResizeObserver(this.runResizeObserver);
        }
    }
    componentWillRender() {
        if (isElInAGGrid(this.el)) {
            this.inAGGrid = true;
        }
    }
    /**
     * @internal This checks if the number of lines of text exceeds the maxLines prop. If so, set the line clamp CSS to the max lines
     * @param height - text container height
     */
    async checkMaxLines(height) {
        //24 is the height of a single line
        const numLines = Math.floor(height / 24);
        if (this.maxLines && numLines > this.maxLines) {
            this.el.setAttribute("style", `--truncation-max-lines: ${this.maxLines}`);
            this.truncatedHeight = this.el.clientHeight;
            this.truncated = true;
        }
    }
    /**
     * @internal This method makes it possible to set the expanded status of truncated text outside of ic-typography component
     */
    async setShowHideExpanded(expanded) {
        this.expanded = expanded;
    }
    render() {
        var _a, _b;
        const { variant, applyVerticalMargins, maxLines, truncated, expanded, strikethrough, underline, italic, bold, theme, } = this;
        return (h(Host, { key: 'd386fa51fb7834aad97904a5b757551c388af06b', class: {
                [`ic-typography-${variant}`]: true,
                [`ic-typography-vertical-margins-${variant}`]: !!applyVerticalMargins,
                ["ic-typography-bold"]: !!bold,
                ["ic-typography-italic"]: !!italic,
                ["ic-typography-strikethrough"]: !!strikethrough,
                ["ic-typography-underline"]: !!underline,
                ["in-ag-grid"]: this.inAGGrid,
                [`ic-theme-${theme}`]: theme !== "inherit",
            } }, (variant === "body" ||
            ((_b = (_a = this.el.getRootNode()) === null || _a === void 0 ? void 0 : _a.host) === null || _b === void 0 ? void 0 : _b.tagName) ===
                "IC-TOOLTIP") &&
            maxLines &&
            maxLines > 0 ? (h("div", { class: "trunc-wrapper", ref: (el) => (this.truncWrapperEl = el) }, h("slot", null))) : (h("slot", null)), variant === "body" && maxLines && maxLines > 0 && truncated && (h("button", { key: '10df0863dfe83f7195a631012461f438fb41a04c', class: { "trunc-btn": true, focus: this.truncButtonFocussed }, onFocus: this.truncButtonFocus, onBlur: this.truncButtonBlur, onMouseDown: this.truncButtonFocusFromMouse, onClick: this.toggleExpanded }, expanded ? "See less" : "See more"))));
    }
    static get is() { return "ic-typography"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-typography.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-typography.css"]
        };
    }
    static get properties() {
        return {
            "applyVerticalMargins": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, appropriate top and bottom margins will be applied to the typography."
                },
                "getter": false,
                "setter": false,
                "attribute": "apply-vertical-margins",
                "reflect": false,
                "defaultValue": "false"
            },
            "bold": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the typography will have a bold font weight.\nNote: This will have no impact on variants that already use an equivalent or higher font weight (h1, h2, and subtitle-large)."
                },
                "getter": false,
                "setter": false,
                "attribute": "bold",
                "reflect": false,
                "defaultValue": "false"
            },
            "italic": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the typography will have an italic font style."
                },
                "getter": false,
                "setter": false,
                "attribute": "italic",
                "reflect": false,
                "defaultValue": "false"
            },
            "maxLines": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The number of lines to display before truncating the text, only used for the 'body' variant."
                },
                "getter": false,
                "setter": false,
                "attribute": "max-lines",
                "reflect": false
            },
            "strikethrough": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the typography will have a line through it."
                },
                "getter": false,
                "setter": false,
                "attribute": "strikethrough",
                "reflect": false,
                "defaultValue": "false"
            },
            "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 text 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\""
            },
            "underline": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the typography will have a line under it."
                },
                "getter": false,
                "setter": false,
                "attribute": "underline",
                "reflect": false,
                "defaultValue": "false"
            },
            "variant": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcTypographyVariants",
                    "resolved": "\"badge\" | \"badge-small\" | \"body\" | \"caption\" | \"caption-uppercase\" | \"code-extra-small\" | \"code-large\" | \"code-small\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"label\" | \"label-uppercase\" | \"subtitle-large\" | \"subtitle-small\" | undefined",
                    "references": {
                        "IcTypographyVariants": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcTypographyVariants"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The ICDS typography style to use."
                },
                "getter": false,
                "setter": false,
                "attribute": "variant",
                "reflect": false,
                "defaultValue": "\"body\""
            }
        };
    }
    static get states() {
        return {
            "truncated": {},
            "truncButtonFocussed": {},
            "expanded": {}
        };
    }
    static get events() {
        return [{
                "method": "typographyTruncationExpandToggle",
                "name": "typographyTruncationExpandToggle",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Emits and event when the typography truncation button has been clicked."
                        }],
                    "text": ""
                },
                "complexType": {
                    "original": "{\n    expanded: boolean;\n    typographyEl: HTMLIcTypographyElement;\n  }",
                    "resolved": "{ expanded: boolean; typographyEl: HTMLIcTypographyElement; }",
                    "references": {
                        "HTMLIcTypographyElement": {
                            "location": "global",
                            "id": "global::HTMLIcTypographyElement"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "resetTruncation": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "This is used by data table to remove all truncation in certain events"
                        }]
                }
            },
            "checkMaxLines": {
                "complexType": {
                    "signature": "(height: number) => Promise<void>",
                    "parameters": [{
                            "name": "height",
                            "type": "number",
                            "docs": "- text container height"
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "This checks if the number of lines of text exceeds the maxLines prop. If so, set the line clamp CSS to the max lines"
                        }, {
                            "name": "param",
                            "text": "height - text container height"
                        }]
                }
            },
            "setShowHideExpanded": {
                "complexType": {
                    "signature": "(expanded: boolean) => Promise<void>",
                    "parameters": [{
                            "name": "expanded",
                            "type": "boolean",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "This method makes it possible to set the expanded status of truncated text outside of ic-typography component"
                        }]
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "expanded",
                "methodName": "watchExpandedHandler"
            }];
    }
}
//# sourceMappingURL=ic-typography.js.map
