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, m as rIC, t as transitionEndAsync } from './helpers.js';
import { L as Logger } from './log.js';
import { L as ListenToConfig } from './config.decorator.js';

const ListItem = /*@__PURE__*/ proxyCustomElement(class ListItem extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.balNavigate = createEvent(this, "balNavigate", 7);
        this.balGroupStateChanged = createEvent(this, "balGroupStateChanged", 7);
        this.balWillAnimate = createEvent(this, "balWillAnimate", 7);
        this.balDidAnimate = createEvent(this, "balDidAnimate", 7);
        this.accordionOpen = false;
        this.animated = true;
        this.state = 1 /* AccordionState.Collapsed */;
        /**
         * PUBLIC PROPERTY API
         * ------------------------------------------------------
         */
        /**
         * If `true` the list item can be hovered
         */
        this.disabled = false;
        /**
         * If `true` the list item shows that it is clickable
         */
        this.clickable = false;
        /**
         * If `true` the list item has a selected theme
         */
        this.selected = false;
        /**
         * If `true` the list item can be used as a accordion
         */
        this.accordion = false;
        /**
         * If `true` the list item can be used as an accordion inside another accordion
         */
        this.subAccordionItem = false;
        /**
         * Specifies the URL of the page the link goes to
         */
        this.href = '';
        /**
         * Specifies where to open the linked document
         */
        this.target = '_self';
        /**
         * LISTENERS
         * ------------------------------------------------------
         */
        this.accordionChanged = (ev) => {
            const { detail } = ev;
            if (detail !== this.accordionOpen) {
                this.accordionOpen = detail;
                this.updateState();
            }
        };
        /**
         * PRIVATE METHODS
         * ------------------------------------------------------
         */
        this.addEventListenerAccordionChange = () => {
            const accordionHeadEl = this.el.querySelector(ListItem.selectors.accordionHead);
            if (accordionHeadEl) {
                accordionHeadEl.addEventListener('balAccordionChange', this.accordionChanged);
                this.accordionOpen = accordionHeadEl.accordionOpen;
                this.updateState(true);
            }
        };
        this.removeEventListenerAccordionChange = () => {
            const accordionHeadEl = this.el.querySelector(ListItem.selectors.accordionHead);
            if (accordionHeadEl) {
                accordionHeadEl.removeEventListener('balAccordionChange', this.accordionChanged);
            }
        };
        this.updateHead = () => {
            const headEl = this.el.querySelector('bal-list-item-accordion-head');
            if (headEl) {
                headEl.accordionOpen = this.accordionOpen;
            }
        };
        this.updateState = (initialUpdate = false) => {
            if (this.accordionOpen) {
                this.expandAccordion(initialUpdate);
            }
            else {
                this.collapseAccordion(initialUpdate);
            }
        };
        this.expandAccordion = (initialUpdate = false) => {
            const contentEl = this.el.querySelector(ListItem.selectors.accordionBody);
            const contentElWrapper = this.el.querySelector(ListItem.selectors.accordionBodyWrapper);
            if (initialUpdate || contentEl === null || contentElWrapper === null) {
                this.state = 4 /* AccordionState.Expanded */;
                return;
            }
            if (this.state === 4 /* AccordionState.Expanded */) {
                return;
            }
            if (this.currentRaf !== undefined) {
                cancelAnimationFrame(this.currentRaf);
            }
            const parentListEl = this.el.closest('bal-list');
            if (parentListEl && parentListEl.accordionOneLevel) {
                const items = Array.from(parentListEl.querySelectorAll('bal-list-item')).filter(el => el !== this.el);
                items.forEach(item => item.dismiss(true));
            }
            if (this.shouldAnimate()) {
                raf(() => {
                    this.state = 8 /* AccordionState.Expanding */;
                    this.currentRaf = raf(async () => {
                        const contentHeight = contentElWrapper.offsetHeight;
                        const waitForTransition = transitionEndAsync(contentEl, 300);
                        contentEl.style.setProperty('max-height', `${contentHeight}px`);
                        this.balWillAnimate.emit(this.accordionOpen);
                        await waitForTransition;
                        this.state = 4 /* AccordionState.Expanded */;
                        contentEl.style.removeProperty('max-height');
                        this.balDidAnimate.emit(this.accordionOpen);
                    });
                });
            }
            else {
                this.balWillAnimate.emit(this.accordionOpen);
                this.state = 4 /* AccordionState.Expanded */;
                this.balDidAnimate.emit(this.accordionOpen);
            }
        };
        this.collapseAccordion = (initialUpdate = false, ignoreNested = false) => {
            const contentEl = this.el.querySelector(ListItem.selectors.accordionBody);
            if (initialUpdate || contentEl === null) {
                this.state = 1 /* AccordionState.Collapsed */;
                return;
            }
            if (this.state === 1 /* AccordionState.Collapsed */) {
                return;
            }
            if (this.currentRaf !== undefined) {
                cancelAnimationFrame(this.currentRaf);
            }
            if (!ignoreNested) {
                const parentListEl = this.el.closest('bal-list');
                if (parentListEl && parentListEl.accordionOneLevel) {
                    const items = Array.from(this.el.querySelectorAll('bal-list-item')).filter(el => el !== this.el);
                    items.forEach(item => item.dismiss(true));
                }
            }
            if (this.shouldAnimate()) {
                this.currentRaf = raf(async () => {
                    const contentHeight = contentEl.offsetHeight;
                    contentEl.style.setProperty('max-height', `${contentHeight}px`);
                    raf(async () => {
                        const waitForTransition = transitionEndAsync(contentEl, 300);
                        this.state = 2 /* AccordionState.Collapsing */;
                        this.balWillAnimate.emit(this.accordionOpen);
                        await waitForTransition;
                        this.state = 1 /* AccordionState.Collapsed */;
                        contentEl.style.removeProperty('max-height');
                        this.balDidAnimate.emit(this.accordionOpen);
                    });
                });
            }
            else {
                this.balWillAnimate.emit(this.accordionOpen);
                this.state = 1 /* AccordionState.Collapsed */;
                this.balDidAnimate.emit(this.accordionOpen);
            }
        };
        this.shouldAnimate = () => {
            if (typeof window === 'undefined') {
                return false;
            }
            return this.animated;
        };
        /**
         * EVENT BINDING
         * ------------------------------------------------------
         */
        this.onClickTrigger = (ev) => {
            const accordionBodyEl = this.el.querySelector(ListItem.selectors.accordionBody);
            if (accordionBodyEl) {
                if (!accordionBodyEl.contains(ev.target)) {
                    this.balNavigate.emit(ev);
                }
            }
            else {
                this.balNavigate.emit(ev);
            }
        };
    }
    createLogger(log) {
        this.log = log;
    }
    /**
     * LIFECYCLE
     * ------------------------------------------------------
     */
    connectedCallback() {
        if (this.accordion) {
            this.addEventListenerAccordionChange();
        }
    }
    componentDidLoad() {
        if (this.accordion) {
            rIC(() => {
                this.addEventListenerAccordionChange();
            });
        }
    }
    disconnectedCallback() {
        this.removeEventListenerAccordionChange();
    }
    /**
     * @internal define config for the component
     */
    async configChanged(state) {
        this.animated = state.animated;
    }
    /**
     * PUBLIC METHODS
     * ------------------------------------------------------
     */
    /**
     * Opens the accordion
     */
    async present() {
        if (this.accordion && this.accordionOpen === false) {
            this.accordionOpen = true;
            this.updateHead();
            this.expandAccordion();
        }
    }
    /**
     * Closes the accordion
     */
    async dismiss(ignoreNested = false) {
        if (this.accordion && this.accordionOpen === true) {
            this.accordionOpen = false;
            this.updateHead();
            this.collapseAccordion(false, ignoreNested);
        }
    }
    /**
     * Triggers the accordion
     */
    async toggle() {
        if (this.accordion) {
            if (this.accordionOpen) {
                this.dismiss();
            }
            else {
                this.present();
            }
        }
    }
    /**
     * RENDER
     * ------------------------------------------------------
     */
    render() {
        const item = BEM.block('list').element('item');
        const trigger = item.element('trigger');
        const basicClasses = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, item.class()), item.modifier('disabled').class(this.disabled)), item.modifier('selected').class(this.selected)), item.modifier('animated').class(this.animated)), item.modifier('accordion').class(this.accordion)), item.modifier('sub-accordion').class(this.subAccordionItem)), item.modifier('active').class(this.accordionOpen)), item.modifier('expanding').class(this.state === 8 /* AccordionState.Expanding */)), item.modifier('expanded').class(this.state === 4 /* AccordionState.Expanded */)), item.modifier('collapsing').class(this.state === 2 /* AccordionState.Collapsing */)), item.modifier('collapsed').class(this.state === 1 /* AccordionState.Collapsed */)), item.modifier('clickable').class(!this.disabled && (this.clickable || this.href.length > 0 || this.accordion)));
        if (this.href.length > 0 && !this.disabled) {
            return (h(Host, { role: "listitem", class: Object.assign({}, basicClasses) }, h("a", { class: Object.assign({}, trigger.class()), rel: this.rel, href: this.href, target: this.target, download: this.download, onClick: (ev) => this.onClickTrigger(ev) }, h("slot", null))));
        }
        if (this.clickable) {
            return (h(Host, { role: "listitem", class: Object.assign({}, basicClasses) }, h("button", { class: Object.assign({}, trigger.class()), disabled: this.disabled, onClick: (ev) => this.onClickTrigger(ev) }, h("slot", null))));
        }
        if (this.accordion) {
            return (h(Host, { role: "listitem", class: Object.assign({}, basicClasses), onClick: (ev) => this.onClickTrigger(ev) }, h("div", { class: Object.assign({}, trigger.class()) }, h("slot", null))));
        }
        return (h(Host, { role: "listitem", class: Object.assign({}, basicClasses) }, h("div", { class: Object.assign({}, trigger.class()) }, h("slot", null))));
    }
    get el() { return this; }
}, [260, "bal-list-item", {
        "disabled": [4],
        "clickable": [4],
        "selected": [4],
        "accordion": [4],
        "subAccordionItem": [4, "sub-accordion-item"],
        "href": [1],
        "rel": [1],
        "target": [1],
        "download": [1],
        "state": [32],
        "configChanged": [64],
        "present": [64],
        "dismiss": [64],
        "toggle": [64]
    }]);
ListItem.selectors = {
    accordionHead: '.bal-list__item__trigger > bal-list-item-accordion-head',
    accordionBody: '.bal-list__item__trigger > bal-list-item-accordion-body',
    accordionBodyWrapper: '.bal-list__item__trigger > .bal-list__item__accordion-body > .bal-list__item__accordion-body__content',
};
__decorate([
    Logger('bal-list-item'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Function]),
    __metadata("design:returntype", void 0)
], ListItem.prototype, "createLogger", null);
__decorate([
    ListenToConfig(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], ListItem.prototype, "configChanged", null);
function defineCustomElement() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["bal-list-item"];
    components.forEach(tagName => { switch (tagName) {
        case "bal-list-item":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, ListItem);
            }
            break;
    } });
}

export { ListItem as L, defineCustomElement as d };
