/*!
 * Custom elements for Nanopore-Digital Web applications
 */
import { Fragment, forceUpdate, } from "@stencil/core";
import { h } from "../../utils/renderer";
/**
 * Presents an accordion interface for a multi-step process,
 * allowing users to see their progress and navigate back to completed steps.
 *
 * @version 8.4.0
 * @status new
 *
 * @slot - Dynamic slots. Use `slot="step-0"`, `slot="step-1"`, etc. for each step.
 */
export class NanoStepAccordion {
    host;
    nanoDetails;
    gridWorking = true;
    /** The currently active step, zero-based index */
    activeStep = 0;
    handleActiveStepChange(newValue, oldValue) {
        if (!this.steps[newValue]?.enabled)
            this.activeStep = oldValue;
        else {
            const event = this.nanoStepActive.emit({
                index: newValue,
                step: this.steps[newValue],
            });
            if (event.defaultPrevented) {
                this.activeStep = oldValue;
            }
        }
    }
    _steps = [];
    stepProxyHandler = {
        set: (target, prop, value) => {
            target[prop] = value;
            forceUpdate(this.host);
            return true;
        },
    };
    /** An array of steps, each with a title, completion status, and enabled state */
    get steps() {
        return this._steps;
    }
    set steps(value) {
        this._steps = [];
        // improved devX - use a proxy to re-render when step properties change
        value.forEach((step) => {
            const proxyStep = new Proxy(step, this.stepProxyHandler);
            this._steps.push(proxyStep);
        });
    }
    /** Emitted when the active step changes. Prevent default to cancel the change */
    nanoStepActive;
    handleToggle(event) {
        if (event.detail.index === this.activeStep)
            return;
        this.activeStep = event.detail.index;
    }
    // A dirty great hack for Firefox - it doesn't support grid layout in `<details>`
    // so we use this to apply different styles based on whether grid is working or not
    isDetailsGridWorking(detailsEl) {
        // Create a test element with explicit grid placement
        const testEl = document.createElement('div');
        testEl.style.gridColumn = '2';
        testEl.style.height = '1px';
        testEl.style.width = '1px';
        testEl.style.visibility = 'hidden';
        detailsEl.appendChild(testEl);
        const parentX = detailsEl.getBoundingClientRect().x;
        const testX = testEl.getBoundingClientRect().x;
        detailsEl.removeChild(testEl);
        // If testEl moved horizontally, grid is in effect
        return Math.abs(testX - parentX) > 1;
    }
    componentDidLoad() {
        if (!this.nanoDetails)
            return;
        const detailsEl = this.nanoDetails.shadowRoot.querySelector('details');
        if (detailsEl) {
            this.gridWorking = this.isDetailsGridWorking(detailsEl);
        }
    }
    render() {
        return (h("nano-accordion", { key: '1a977444388da596ff3fbf0559ac77a274efce11', alwaysOpen: true, onNanoToggle: (event) => this.handleToggle(event) }, this.steps.map((step, index) => (h("nano-details", { open: index === this.activeStep, disabled: !step.enabled, class: {
                step: true,
                'step--active': index === this.activeStep,
                'step--complete': step.complete,
                'step--grid-working': this.gridWorking,
                'step--grid-not-working': !this.gridWorking,
                'step--disabled': !step.enabled,
            }, ref: (el) => (this.nanoDetails = el) }, h("span", { class: "step-icon", slot: "icon-start" }, index + 1), h("div", { class: "step-header", slot: "label" }, h("span", { class: `step-title ${step.complete ? 'complete' : ''}` }, step.title), step.complete && (h(Fragment, null, h("span", null, " - "), h("span", { class: "step-change" }, "Change")))), h("span", { slot: "icon-end" }), h("div", { class: "step-content" }, h("slot", { name: `step-${index}` })))))));
    }
    static get is() { return "nano-step-accordion"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["step-accordion.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["step-accordion.css"]
        };
    }
    static get properties() {
        return {
            "activeStep": {
                "type": "number",
                "attribute": "active-step",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The currently active step, zero-based index"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "0"
            },
            "steps": {
                "type": "unknown",
                "attribute": "steps",
                "mutable": false,
                "complexType": {
                    "original": "Step[]",
                    "resolved": "Step[]",
                    "references": {
                        "Step": {
                            "location": "global",
                            "id": "global::Step"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "An array of steps, each with a title, completion status, and enabled state"
                },
                "getter": true,
                "setter": true,
                "defaultValue": "[]"
            }
        };
    }
    static get states() {
        return {
            "gridWorking": {}
        };
    }
    static get events() {
        return [{
                "method": "nanoStepActive",
                "name": "nanoStepActive",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the active step changes. Prevent default to cancel the change"
                },
                "complexType": {
                    "original": "{ index: number; step: Step }",
                    "resolved": "{ index: number; step: Step; }",
                    "references": {
                        "Step": {
                            "location": "global",
                            "id": "global::Step"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "activeStep",
                "methodName": "handleActiveStepChange"
            }];
    }
}
