import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { _ as __decorate, a as __metadata } from './tslib.es6.js';
import { B as BEM } from './bem.js';
import { r as raf, k as debounceEvent, w as waitForComponent, t as transitionEndAsync } from './helpers.js';
import { L as Logger } from './log.js';
import { d as defineCustomElement$4 } from './bal-button2.js';
import { d as defineCustomElement$3 } from './bal-icon2.js';
import { d as defineCustomElement$2 } from './bal-spinner2.js';
import { L as ListenToConfig } from './config.decorator.js';

const balAccordionCss = ".bal-accordion{display:block;position:relative;width:100%}.bal-accordion--card-v1,.bal-accordion--card-v2{margin-top:var(--bal-space-medium)}@media screen and (min-width: 769px),print{.bal-accordion--card-v1,.bal-accordion--card-v2{margin-top:var(--bal-space-medium-tablet)}}@media screen and (min-width: 1024px){.bal-accordion--card-v1,.bal-accordion--card-v2{margin-top:var(--bal-space-medium-desktop)}}.bal-accordion--card-v2{padding-left:var(--bal-space-medium);padding-right:var(--bal-space-medium);padding-bottom:var(--bal-space-medium)}@media screen and (min-width: 769px),print{.bal-accordion--card-v2{padding-left:var(--bal-space-medium-tablet);padding-right:var(--bal-space-medium-tablet);padding-bottom:var(--bal-space-medium-tablet)}}@media screen and (min-width: 1024px){.bal-accordion--card-v2{padding-left:var(--bal-space-medium-desktop);padding-right:var(--bal-space-medium-desktop);padding-bottom:var(--bal-space-medium-desktop)}}.bal-accordion__wrapper{display:-ms-flexbox;display:flex;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.bal-accordion__trigger--card{margin-left:var(--bal-space-medium);margin-right:var(--bal-space-medium);margin-bottom:var(--bal-space-medium)}@media screen and (min-width: 769px),print{.bal-accordion__trigger--card{margin-left:var(--bal-space-medium-tablet);margin-right:var(--bal-space-medium-tablet);margin-bottom:var(--bal-space-medium-tablet)}}@media screen and (min-width: 1024px){.bal-accordion__trigger--card{margin-left:var(--bal-space-medium-desktop);margin-right:var(--bal-space-medium-desktop);margin-bottom:var(--bal-space-medium-desktop)}}.bal-accordion__content--card{margin-left:var(--bal-space-medium);margin-right:var(--bal-space-medium)}@media screen and (min-width: 769px),print{.bal-accordion__content--card{margin-left:var(--bal-space-medium-tablet);margin-right:var(--bal-space-medium-tablet)}}@media screen and (min-width: 1024px){.bal-accordion__content--card{margin-left:var(--bal-space-medium-desktop);margin-right:var(--bal-space-medium-desktop)}}.bal-accordion--animated{-webkit-transition:all var(--bal-animation-transition-duration) var(--bal-animation-transition-easing);transition:all var(--bal-animation-transition-duration) var(--bal-animation-transition-easing)}.bal-accordion--animated .bal-accordion__content{-webkit-transition:max-height var(--bal-animation-transition-duration) var(--bal-animation-transition-easing);transition:max-height var(--bal-animation-transition-duration) var(--bal-animation-transition-easing)}.bal-accordion__content{will-change:max-height}.bal-accordion__content--overflow-hidden{overflow:hidden;-webkit-clip-path:border-box;clip-path:border-box}.bal-accordion--collapsing .bal-accordion__content{max-height:0 !important}.bal-accordion--collapsed .bal-accordion__content{display:none}.bal-accordion--expanding .bal-accordion__content{max-height:0}@media (prefers-reduced-motion: reduce){.bal-accordion,.bal-accordion__content{-webkit-transition:none !important;transition:none !important}}";

const Accordion = /*@__PURE__*/ proxyCustomElement(class Accordion extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.balChange = createEvent(this, "balChange", 7);
        this.balWillAnimate = createEvent(this, "balWillAnimate", 7);
        this.balDidAnimate = createEvent(this, "balDidAnimate", 7);
        this.componentId = `bal-accordion-${accordionIds++}`;
        this.animationGeneration = 0;
        this.state = 1 /* AccordionState.Collapsed */;
        this.animated = true;
        /**
         * PUBLIC PROPERTY API
         * ------------------------------------------------------
         */
        /**
         * If `true` the accordion is open.
         */
        this.active = false;
        /**
         * Set the amount of time, in milliseconds, to wait to trigger the `balChange` event after each keystroke. This also impacts form bindings such as `ngModel` or `v-model`.
         */
        this.debounce = 0;
        /**
         * Label of the open trigger button
         */
        this.openLabel = '';
        /**
         * BalIcon of the open trigger button
         */
        this.openIcon = 'plus';
        /**
         * Label of the close trigger button
         */
        this.closeLabel = '';
        /**
         * BalIcon of the close trigger button
         */
        this.closeIcon = 'close';
        /**
         * If `true` the accordion is used on the bottom of a card
         */
        this.card = false;
        /**
         * defines the version of the component
         */
        this.version = 2;
        /**
         * PRIVATE METHODS
         * ------------------------------------------------------
         */
        this.updateState = (initialUpdate = false) => {
            if (this.active) {
                this.expand(initialUpdate);
            }
            else {
                this.collapse(initialUpdate);
            }
        };
        this.setState = (state) => {
            this.state = state;
            if (this.version === 2) {
                this.updateTriggerElement();
                this.updateDetailsElement();
                this.updateSummaryElement();
            }
        };
        this.updateDetailsElement = () => {
            const detailsElement = this.detailsElement;
            if (detailsElement) {
                detailsElement.state = this.state;
                detailsElement.active = this.active;
                detailsElement.animated = this.animated;
            }
        };
        this.updateTriggerElement = () => {
            const triggerElement = this.triggerElement;
            if (triggerElement) {
                triggerElement.state = this.state;
                triggerElement.active = this.active;
            }
        };
        this.updateSummaryElement = () => {
            const summaryElement = this.summaryElement;
            if (summaryElement) {
                summaryElement.state = this.state;
                summaryElement.active = this.active;
            }
        };
        this.cancelAnimation = () => {
            if (this.currentRaf !== undefined) {
                cancelAnimationFrame(this.currentRaf);
                this.currentRaf = undefined;
            }
            if (this.currentRafInner !== undefined) {
                cancelAnimationFrame(this.currentRafInner);
                this.currentRafInner = undefined;
            }
            this.animationGeneration++;
        };
        this.expand = (initialUpdate = false) => {
            this.active = true;
            const detailsElement = this.detailsElement;
            const detailsWrapperElement = this.detailsWrapperElement;
            if (initialUpdate || detailsElement === null || detailsWrapperElement === null) {
                this.setState(4 /* AccordionState.Expanded */);
                return this.active;
            }
            if (this.state === 4 /* AccordionState.Expanded */) {
                return this.active;
            }
            this.cancelAnimation();
            const generation = this.animationGeneration;
            if (this.shouldAnimate()) {
                this.currentRaf = raf(() => {
                    if (generation !== this.animationGeneration)
                        return;
                    this.setState(8 /* AccordionState.Expanding */);
                    this.balWillAnimate.emit(this.active);
                    this.currentRafInner = raf(async () => {
                        if (generation !== this.animationGeneration)
                            return;
                        const contentHeight = detailsWrapperElement.offsetHeight;
                        const waitForTransition = transitionEndAsync(detailsElement, 300);
                        detailsElement.style.setProperty('max-height', `${contentHeight}px`);
                        await waitForTransition;
                        if (generation !== this.animationGeneration)
                            return;
                        this.setState(4 /* AccordionState.Expanded */);
                        detailsElement.style.removeProperty('max-height');
                        this.balDidAnimate.emit(this.active);
                    });
                });
            }
            else {
                this.balWillAnimate.emit(this.active);
                this.setState(4 /* AccordionState.Expanded */);
                this.balDidAnimate.emit(this.active);
            }
            return this.active;
        };
        this.collapse = (initialUpdate = false) => {
            this.active = false;
            const detailsElement = this.detailsElement;
            if (initialUpdate || detailsElement === null) {
                this.setState(1 /* AccordionState.Collapsed */);
                return this.active;
            }
            if (this.state === 1 /* AccordionState.Collapsed */) {
                return this.active;
            }
            this.cancelAnimation();
            const generation = this.animationGeneration;
            if (this.shouldAnimate()) {
                this.currentRaf = raf(async () => {
                    if (generation !== this.animationGeneration)
                        return;
                    const contentHeight = detailsElement.offsetHeight;
                    detailsElement.style.setProperty('max-height', `${contentHeight}px`);
                    this.currentRafInner = raf(async () => {
                        if (generation !== this.animationGeneration)
                            return;
                        const waitForTransition = transitionEndAsync(detailsElement, 300);
                        this.setState(2 /* AccordionState.Collapsing */);
                        this.balWillAnimate.emit(this.active);
                        await waitForTransition;
                        if (generation !== this.animationGeneration)
                            return;
                        this.setState(1 /* AccordionState.Collapsed */);
                        detailsElement.style.removeProperty('max-height');
                        this.balDidAnimate.emit(this.active);
                    });
                });
            }
            else {
                this.balWillAnimate.emit(this.active);
                this.setState(1 /* AccordionState.Collapsed */);
                this.balDidAnimate.emit(this.active);
            }
            return this.active;
        };
        this.shouldAnimate = () => {
            if (typeof window === 'undefined') {
                return false;
            }
            return this.animated;
        };
        /**
         * EVENT BINDING
         * ------------------------------------------------------
         */
        this.onTriggerClickV1 = () => {
            this.humanToggle();
        };
    }
    createLogger(log) {
        this.log = log;
    }
    async activeChanged(newActive, oldActive) {
        if (newActive !== oldActive) {
            this.active = newActive;
            this.updateState();
        }
    }
    debounceChanged() {
        this.balChange = debounceEvent(this.balChange, this.debounce);
    }
    /**
     * LIFECYCLE
     * ------------------------------------------------------
     */
    async connectedCallback() {
        this.debounceChanged();
        await waitForComponent(this.el);
        if (this.active) {
            this.activeChanged(this.active, false);
        }
        this.updateState(true);
    }
    /**
     * LISTENERS
     * ------------------------------------------------------
     */
    /**
     * @internal define config for the component
     */
    async configChanged(state) {
        this.animated = state.animated;
    }
    /**
     * PUBLIC METHODS
     * ------------------------------------------------------
     */
    /**
     * Opens the accordion
     */
    async present() {
        return this.expand();
    }
    /**
     * Closes the accordion
     */
    async dismiss() {
        return this.collapse();
    }
    /**
     * Triggers the accordion
     */
    async toggle() {
        if (this.active) {
            return this.collapse();
        }
        else {
            return this.expand();
        }
    }
    /**
     * @internal
     */
    async humanToggle() {
        if (this.active) {
            await this.collapse();
        }
        else {
            await this.expand();
        }
        this.balChange.emit(this.active);
        return this.active;
    }
    /**
     * GETTERS
     * ------------------------------------------------------
     */
    get summaryElement() {
        var _a;
        return ((_a = this.el) === null || _a === void 0 ? void 0 : _a.querySelector(`#${this.componentId}-summary`)) || null;
    }
    get triggerElement() {
        var _a;
        return ((_a = this.el) === null || _a === void 0 ? void 0 : _a.querySelector(`#${this.componentId}-trigger`)) || null;
    }
    get detailsElement() {
        var _a;
        if (this.version === 1) {
            return this.contentEl || null;
        }
        return ((_a = this.el) === null || _a === void 0 ? void 0 : _a.querySelector(`#${this.componentId}-details`)) || null;
    }
    get detailsWrapperElement() {
        var _a;
        if (this.version === 1) {
            return this.contentElWrapper || null;
        }
        return ((_a = this.el) === null || _a === void 0 ? void 0 : _a.querySelector(`#${this.componentId}-details > div`)) || null;
    }
    /**
     * RENDER
     * ------------------------------------------------------
     */
    render() {
        return this.version === 2 ? this.renderVersion2() : this.renderVersion1();
    }
    renderVersion2() {
        const block = BEM.block('accordion');
        return (h(Host, { id: this.componentId, class: Object.assign(Object.assign(Object.assign(Object.assign({}, block.class()), block.modifier('active').class(this.active)), block.modifier('card-v2').class(this.card)), block.modifier('animated').class(this.animated)) }));
    }
    renderVersion1() {
        const label = this.active ? this.closeLabel : this.openLabel;
        const icon = this.active ? this.closeIcon : this.openIcon;
        const block = BEM.block('accordion');
        const expanded = this.state === 4 /* AccordionState.Expanded */ || this.state === 8 /* AccordionState.Expanding */;
        const buttonPart = expanded ? 'button expanded' : 'button';
        const contentPart = expanded ? 'content expanded' : 'content';
        return (h(Host, { id: this.componentId, class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, block.class()), block.modifier('card-v1').class(this.card)), block.modifier('active').class(this.active)), block.modifier('expanding').class(this.state === 8 /* AccordionState.Expanding */)), block.modifier('expanded').class(this.state === 4 /* AccordionState.Expanded */)), block.modifier('collapsing').class(this.state === 2 /* AccordionState.Collapsing */)), block.modifier('collapsed').class(this.state === 1 /* AccordionState.Collapsed */)), block.modifier('animated').class(this.animated)) }, h("div", { class: Object.assign({}, block.element('wrapper').class()) }, h("div", { class: Object.assign(Object.assign({}, block.element('trigger').class()), block.element('trigger').modifier('card').class(this.card)), "data-testid": "bal-accordion-summary" }, h("bal-button", { id: `${this.componentId}-button`, "aria-controls": `${this.componentId}-content`, part: buttonPart, "data-testid": "bal-accordion-trigger", expanded: true, color: 'info', icon: icon, onClick: this.onTriggerClickV1 }, label)), h("div", { id: `${this.componentId}-content`, "aria-labelledby": `${this.componentId}-button`, role: "region", part: contentPart, class: Object.assign(Object.assign(Object.assign({}, block.element('content').class()), block.element('content').modifier('card').class(this.card)), block
                .element('content')
                .modifier('overflow-hidden')
                .class(this.state !== 4 /* AccordionState.Expanded */)), ref: contentEl => (this.contentEl = contentEl) }, h("div", { id: `${this.componentId}-content-wrapper`, "data-testid": "bal-accordion-details", class: Object.assign({}, block.element('content').element('wrapper').class()), ref: contentElWrapper => (this.contentElWrapper = contentElWrapper) }, h("slot", null))))));
    }
    get el() { return this; }
    static get watchers() { return {
        "active": ["activeChanged"],
        "debounce": ["debounceChanged"]
    }; }
    static get style() { return balAccordionCss; }
}, [260, "bal-accordion", {
        "active": [1540],
        "debounce": [2],
        "openLabel": [1, "open-label"],
        "openIcon": [1, "open-icon"],
        "closeLabel": [1, "close-label"],
        "closeIcon": [1, "close-icon"],
        "card": [4],
        "version": [2],
        "state": [32],
        "animated": [32],
        "configChanged": [64],
        "present": [64],
        "dismiss": [64],
        "toggle": [64],
        "humanToggle": [64]
    }, undefined, {
        "active": ["activeChanged"],
        "debounce": ["debounceChanged"]
    }]);
__decorate([
    Logger('bal-accordion'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Function]),
    __metadata("design:returntype", void 0)
], Accordion.prototype, "createLogger", null);
__decorate([
    ListenToConfig(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Accordion.prototype, "configChanged", null);
let accordionIds = 0;
function defineCustomElement$1() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["bal-accordion", "bal-button", "bal-icon", "bal-spinner"];
    components.forEach(tagName => { switch (tagName) {
        case "bal-accordion":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, Accordion);
            }
            break;
        case "bal-button":
            if (!customElements.get(tagName)) {
                defineCustomElement$4();
            }
            break;
        case "bal-icon":
            if (!customElements.get(tagName)) {
                defineCustomElement$3();
            }
            break;
        case "bal-spinner":
            if (!customElements.get(tagName)) {
                defineCustomElement$2();
            }
            break;
    } });
}

const BalAccordion = Accordion;
const defineCustomElement = defineCustomElement$1;

export { BalAccordion, defineCustomElement };
