/*!
 * Built with Stencil
 * By PostNord.
 */
import { h, Host } from "@stencil/core";
import { chevron_down } from "pn-design-assets/pn-assets/icons.js";
import { reduceMotion, ripple } from "../../../../index";
/**
 * Use this row component inside a `pn-accordion` to create an accordion group.
 *
 * **Note**: you can use the `pn-accordion-row` without the parent accordion.
 * But you will have to style the gap between each row.
 *
 * @slot label - Include your own HTML as the label.
 * ```
 * <h3 slot="label">Custom title</h3>
 * ```
 */
export class PnAccordionRow {
    details;
    summary;
    content;
    animation;
    defaultAnimationDuration = 400;
    animationDuration = this.defaultAnimationDuration;
    hostElement;
    isClosing = false;
    isExpanding = false;
    /** The label/title of the accordion row, you can also pass a slot with the name "label" if you want to put custom HTML content in there. */
    label;
    /** The open/close status of the accordion row. */
    state = false;
    /** Optional unique id for the `summary` element. @category ID */
    buttonid;
    /** Optional unique id for the `div` element containing the content. @category ID */
    contentid;
    /** Optional prop that removes the default white background on the accordion row. @since v7.10.0 */
    transparent = false;
    /** Dispatched every time the row is toggled. Includes the row element and the boolean `state` prop. */
    togglerow;
    /** Internal function for closing rows when using the `single` prop on the `pn-accordion`. */
    handleRowState(event) {
        if (event.detail !== this.state) {
            this.details.style.overflow = 'hidden';
            this.closeAccordion();
        }
    }
    componentWillLoad() {
        const slottedLabel = !!this.hostElement.querySelector('[slot="label"]');
        this.label = slottedLabel ? null : this.label;
    }
    toggleOpen(open) {
        const state = open ?? !this.state;
        if (this.state !== open)
            this.togglerow.emit({ element: this.details, state });
        this.state = state;
    }
    clickHandler(e) {
        e.preventDefault();
        this.details.style.overflow = 'hidden';
        if (this.isClosing || !this.state)
            this.openAccordion();
        else if (this.isClosing || this.state)
            this.closeAccordion();
        const { x, width, y, top } = this.hostElement.getBoundingClientRect();
        const clientCor = e.clientX === 0 && e.clientY === 0 ? { clientX: x + width - 24, clientY: y - top } : e;
        ripple(clientCor, this.hostElement, '.pn-accordion-row-text');
    }
    openAccordion() {
        this.details.style.height = `${this.details.offsetHeight}px`;
        this.toggleOpen(true);
        requestAnimationFrame(() => {
            this.isExpanding = true;
            const startHeight = `${this.details.offsetHeight}px`;
            const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight}px`;
            this.cancelAnimations();
            this.animate(true, startHeight, endHeight);
        });
    }
    closeAccordion() {
        this.isClosing = true;
        const startHeight = `${this.details.offsetHeight}px`;
        const endHeight = `${this.summary.offsetHeight}px`;
        this.cancelAnimations();
        this.animate(false, startHeight, endHeight);
    }
    animate(open, startHeight, endHeight) {
        if (reduceMotion())
            this.animationDuration = 0;
        else
            this.animationDuration = this.defaultAnimationDuration;
        this.animation = this.details.animate({
            height: [startHeight, endHeight],
        }, {
            duration: this.animationDuration,
            easing: 'cubic-bezier(0.6, 0, 0.2, 1)',
        });
        this.animation.onfinish = () => this.animationFinish(open);
        this.animation.oncancel = () => {
            if (open)
                this.isExpanding = false;
            else
                this.isClosing = false;
        };
    }
    animationFinish(open) {
        this.toggleOpen(open);
        this.cancelAnimations();
        this.isClosing = false;
        this.isExpanding = false;
        this.details.style.height = '';
        this.details.style.overflow = '';
    }
    cancelAnimations() {
        if (this.animation)
            this.animation.cancel();
    }
    render() {
        return (h(Host, { key: '2b50f9026275b623128e0a441ec4434c50a54338' }, h("details", { key: 'd60df44b58cd5c27306ec97dd42750bf1f01486c', class: "pn-accordion-row", open: this.state, ref: (el) => (this.details = el) }, h("summary", { key: '448587e8102df440a0d633702ea4af8cfe1d9da3', id: this.buttonid, class: "pn-accordion-row-summary", onClick: e => this.clickHandler(e), ref: el => (this.summary = el) }, h("div", { key: 'bef1fa9595b890919445a6631742c03fd7e18f3f', class: "pn-accordion-row-text", "data-transparent": this.transparent }, this.label ? this.label : '', h("slot", { key: '30742c10f2f557f39f80e97ec3e1c5473400d128', name: "label" }), h("pn-icon", { key: 'cfde3e68aab8348a0773c7aa41e02bb905a47e07', class: "pn-accordion-row-icon", icon: chevron_down }))), h("div", { key: '054aae1bcf9fb3bf9a050c9fdf7cefef38f164d0', id: this.contentid, class: "pn-accordion-row-content", ref: (el) => (this.content = el) }, h("slot", { key: '69378af205ca6c4c159c718f497a2ecf319be959' })))));
    }
    static get is() { return "pn-accordion-row"; }
    static get originalStyleUrls() {
        return {
            "$": ["pn-accordion-row.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["pn-accordion-row.css"]
        };
    }
    static get properties() {
        return {
            "label": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The label/title of the accordion row, you can also pass a slot with the name \"label\" if you want to put custom HTML content in there."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "label"
            },
            "state": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The open/close status of the accordion row."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "state",
                "defaultValue": "false"
            },
            "buttonid": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "category",
                            "text": "ID"
                        }],
                    "text": "Optional unique id for the `summary` element."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "buttonid"
            },
            "contentid": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "category",
                            "text": "ID"
                        }],
                    "text": "Optional unique id for the `div` element containing the content."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "contentid"
            },
            "transparent": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "since",
                            "text": "v7.10.0"
                        }],
                    "text": "Optional prop that removes the default white background on the accordion row."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "transparent",
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "isClosing": {},
            "isExpanding": {}
        };
    }
    static get events() {
        return [{
                "method": "togglerow",
                "name": "togglerow",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Dispatched every time the row is toggled. Includes the row element and the boolean `state` prop."
                },
                "complexType": {
                    "original": "{ element: HTMLElement; state: Boolean }",
                    "resolved": "{ element: HTMLElement; state: Boolean; }",
                    "references": {
                        "HTMLElement": {
                            "location": "global",
                            "id": "global::HTMLElement"
                        },
                        "Boolean": {
                            "location": "global",
                            "id": "global::Boolean"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "hostElement"; }
    static get listeners() {
        return [{
                "name": "rowstate",
                "method": "handleRowState",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
