/**
 * Copyright Aquera Inc 2023
 *
 * This source code is licensed under the BSD-3-Clause license found in the
 * LICENSE file in the root directory of this source tree.
 */
import { __decorate } from "tslib";
import { html } from 'lit';
import { styles } from './nile-accordion.css';
import NileElement from '../internal/nile-element';
import { animateTo, shimKeyframesHeightAuto, stopAnimations } from '../internal/animate';
import { classMap } from 'lit/directives/class-map.js';
import { customElement, property, query } from 'lit/decorators.js';
import { getAnimation, setDefaultAnimation } from '../utilities/animation-registry';
import { waitForEvent } from '../internal/event';
import { watch } from '../internal/watch';
/**
 * Nile detail component.
 *
 * @tag nile-accordion
 *
 */
let NileAccordion = class NileAccordion extends NileElement {
    constructor() {
        /**
         * @summary Accordian show a brief summary and expand to show additional content.
         *
         * @dependency nile-icon
         *
         * @slot - The accordian' main content.
         * @slot summary - The accordian' summary. Alternatively, you can use the `summary` attribute.
         * @slot expand-icon - Optional expand icon to use instead of the default. Works best with `<nile-icon>`.
         * @slot collapse-icon - Optional collapse icon to use instead of the default. Works best with `<nile-icon>`.
         *
         * @event nile-show - Emitted when the accordian opens.
         * @event nile-after-show - Emitted after the accordian opens and all animations are complete.
         * @event nile-hide - Emitted when the accordian closes.
         * @event nile-after-hide - Emitted after the accordian closes and all animations are complete.
         *
         * @csspart base - The component's base wrapper.
         * @csspart header - The header that wraps both the summary and the expand/collapse icon.
         * @csspart summary - The container that wraps the summary.
         * @csspart summary-icon - The container that wraps the expand/collapse icons.
         * @csspart content - The accordian content.
         *
         * @animation accordian.show - The animation to use when showing accordian. You can use `height: auto` with this animation.
         * @animation accordian.hide - The animation to use when hiding accordian. You can use `height: auto` with this animation.
         */
        super(...arguments);
        /**
         * Indicates whether or not the accordian is open. You can toggle this attribute to show and hide the accordian, or you
         * can use the `show()` and `hide()` methods and this attribute will reflect the accordian' open state.
         */
        this.open = false;
        /**
         * Indicates the visual style of the accordian component. Accepted values are `'dark'` or `'light'`.
         * Defaults to `'light'`.
         */
        this.variant = 'light';
        /**
         * Specifies the direction of the arrow indicator. Accepted values are `'left'` or `'right'`.
         * Defaults to `'right'`.
         */
        this.expandIconPlacement = 'right';
        /**
         * Specifies the size of the accordian component. Accepted values are `'sm'`, `'md'`, or `'lg'`.
         * Defaults to `'md'`.
         */
        this.size = 'md';
        /** Disables the accordian so it can't be toggled. */
        this.disabled = false;
    }
    firstUpdated() {
        this.body.hidden = !this.open;
        this.body.style.height = this.open ? 'auto' : '0';
    }
    handleSummaryClick() {
        if (!this.disabled) {
            if (this.open) {
                this.hide();
            }
            else {
                this.show();
            }
            this.header.focus();
        }
    }
    handleSummaryKeyDown(event) {
        if (event.key === 'Enter' || event.key === ' ') {
            event.preventDefault();
            if (this.open) {
                this.hide();
            }
            else {
                this.show();
            }
        }
        if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
            event.preventDefault();
            this.hide();
        }
        if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
            event.preventDefault();
            this.show();
        }
    }
    async handleOpenChange() {
        if (this.open) {
            // Show
            const nileShow = this.emit('nile-show', { cancelable: true });
            if (nileShow.defaultPrevented) {
                this.open = false;
                return;
            }
            await stopAnimations(this.body);
            this.body.hidden = false;
            const { keyframes, options } = getAnimation(this, 'accordian.show', { dir: 'ltr' });
            await animateTo(this.body, shimKeyframesHeightAuto(keyframes, this.body.scrollHeight), options);
            this.body.style.height = 'auto';
            this.emit('nile-after-show');
        }
        else {
            // Hide
            const nileHide = this.emit('nile-hide', { cancelable: true });
            if (nileHide.defaultPrevented) {
                this.open = true;
                return;
            }
            await stopAnimations(this.body);
            const { keyframes, options } = getAnimation(this, 'accordian.hide', { dir: 'ltr' });
            await animateTo(this.body, shimKeyframesHeightAuto(keyframes, this.body.scrollHeight), options);
            this.body.hidden = true;
            this.body.style.height = 'auto';
            this.emit('nile-after-hide');
        }
    }
    /** Shows the accordian. */
    async show() {
        if (this.open || this.disabled) {
            return undefined;
        }
        this.open = true;
        return waitForEvent(this, 'nile-after-show');
    }
    /** Hides the accordian */
    async hide() {
        if (!this.open || this.disabled) {
            return undefined;
        }
        this.open = false;
        return waitForEvent(this, 'nile-after-hide');
    }
    render() {
        const isRtl = true;
        return html `
    <div
      part="base"
      class=${classMap({
            accordian: true,
            'accordian--open': this.open,
            'accordian--disabled': this.disabled,
            'accordian--sm': this.size == 'sm',
            'accordian--md': this.size == 'md',
            'accordian--lg': this.size == 'lg',
        })}
    >
      <div
        part="header"
        id="header"
        class="${classMap({
            'accordian__header': true,
            'accordian__header--dark': this.variant == 'dark',
            'accordian__header--arrow-left': 'left' == this.expandIconPlacement
        })}"
        role="button"
        aria-expanded=${this.open ? 'true' : 'false'}
        aria-controls="content"
        aria-disabled=${this.disabled ? 'true' : 'false'}
        tabindex=${this.disabled ? '-1' : '0'}
        @click=${this.handleSummaryClick}
        @keydown=${this.handleSummaryKeyDown}
      >
        <slot name="summary" part="summary" class="accordian__summary">${this.summary}</slot>

        <span part="summary-icon" class="accordian__summary-icon">
          <slot name="expand-icon">
            <nile-icon name="var(--nile-icon-arrow-right, var(--ng-icon-chevron-right))" method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))" library="system"></nile-icon>
          </slot>
          <slot name="collapse-icon">
            <nile-icon name="var(--nile-icon-arrow-right, var(--ng-icon-chevron-right))" method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))" library="system"></nile-icon>
          </slot>
        </span>
      </div>

      <div class="accordian__body" role="region" aria-labelledby="header">
        <slot part="content" id="content" 
          class="${classMap({
            'accordian__content': true,
            'accordian__content--arrow-left': this.expandIconPlacement == 'left'
        })}"></slot>
      </div>
    </div>
  `;
    }
};
NileAccordion.styles = styles;
__decorate([
    query('.accordian')
], NileAccordion.prototype, "accordian", void 0);
__decorate([
    query('.accordian__header')
], NileAccordion.prototype, "header", void 0);
__decorate([
    query('.accordian__body')
], NileAccordion.prototype, "body", void 0);
__decorate([
    query('.accordian__expand-icon-slot')
], NileAccordion.prototype, "expandIconSlot", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NileAccordion.prototype, "open", void 0);
__decorate([
    property({ reflect: true })
], NileAccordion.prototype, "variant", void 0);
__decorate([
    property({ reflect: true })
], NileAccordion.prototype, "expandIconPlacement", void 0);
__decorate([
    property({ reflect: true })
], NileAccordion.prototype, "size", void 0);
__decorate([
    property()
], NileAccordion.prototype, "summary", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NileAccordion.prototype, "disabled", void 0);
__decorate([
    watch('open', { waitUntilFirstUpdate: true })
], NileAccordion.prototype, "handleOpenChange", null);
NileAccordion = __decorate([
    customElement('nile-accordion')
], NileAccordion);
export { NileAccordion };
setDefaultAnimation('accordian.show', {
    keyframes: [
        { height: '0', opacity: '0' },
        { height: 'auto', opacity: '1' }
    ],
    options: { duration: 250, easing: 'linear' }
});
setDefaultAnimation('accordian.hide', {
    keyframes: [
        { height: 'auto', opacity: '1' },
        { height: '0', opacity: '0' }
    ],
    options: { duration: 250, easing: 'linear' }
});
export default NileAccordion;
//# sourceMappingURL=nile-accordion.js.map