var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { html, LitElement, nothing } from 'lit';
import { property, query, queryAssignedElements, state, } from 'lit/decorators.js';
import { createRef, ref } from 'lit/directives/ref.js';
import { addAnimationController } from '../../animations/player.js';
import { growVerIn, growVerOut } from '../../animations/presets/grow/index.js';
import { addThemingController } from '../../theming/theming-controller.js';
import IgcCheckboxComponent from '../checkbox/checkbox.js';
import { watch } from '../common/decorators/watch.js';
import { registerComponent } from '../common/definitions/register.js';
import { partMap } from '../common/part-map.js';
import { addSafeEventListener, findElementFromEventPath, isLTR, } from '../common/util.js';
import IgcIconComponent from '../icon/icon.js';
import IgcCircularProgressComponent from '../progress/circular-progress.js';
import { styles } from './themes/item.base.css.js';
import { all } from './themes/item.js';
import { styles as shared } from './themes/shared/item.common.css.js';
export default class IgcTreeItemComponent extends LitElement {
    static { this.tagName = 'igc-tree-item'; }
    static { this.styles = [styles, shared]; }
    static register() {
        registerComponent(IgcTreeItemComponent, IgcIconComponent, IgcCheckboxComponent, IgcCircularProgressComponent);
    }
    async toggleAnimation(dir) {
        const animation = dir === 'open' ? growVerIn : growVerOut;
        const [_, event] = await Promise.all([
            this.animationPlayer.stopAll(),
            this.animationPlayer.play(animation()),
        ]);
        return event.type === 'finish';
    }
    bothChange() {
        if (this.hasChildren) {
            this.setAttribute('aria-expanded', this.expanded.toString());
        }
        else {
            this.removeAttribute('aria-expanded');
        }
    }
    expandedChange(oldValue) {
        this.navService?.update_visible_cache(this, this.expanded);
        if (!oldValue) {
            return;
        }
        Promise.resolve().then(() => {
            if (this.navService?.focusedItem !== this && !this.isFocused) {
                this.navService?.focusedItem?.wrapper?.scrollIntoView({
                    behavior: 'smooth',
                    block: 'nearest',
                    inline: 'nearest',
                });
            }
        });
    }
    activeChange() {
        if ((this.active && this.navService?.activeItem === this) || !this.active) {
            return;
        }
        if (this.navService) {
            this.navService.setActiveItem(this, false);
        }
        this.tree?.expandToItem(this);
        Promise.resolve().then(() => {
            this.wrapper?.scrollIntoView({
                behavior: 'smooth',
                block: 'nearest',
                inline: 'nearest',
            });
        });
    }
    disabledChange() {
        this.navService?.update_disabled_cache(this);
    }
    selectedChange() {
        if (this.selected && !this.selectionService?.isItemSelected(this)) {
            this.selectionService?.selectItemsWithNoEvent([this]);
        }
        if (!this.selected && this.selectionService?.isItemSelected(this)) {
            this.selectionService?.deselectItemsWithNoEvent([this]);
        }
    }
    constructor() {
        super();
        this.focusedProgrammatically = false;
        this.groupRef = createRef();
        this.animationPlayer = addAnimationController(this, this.groupRef);
        this.parent = null;
        this.init = false;
        this.isFocused = false;
        this.hasChildren = false;
        this.level = 0;
        this.indeterminate = false;
        this.label = '';
        this.expanded = false;
        this.active = false;
        this.disabled = false;
        this.selected = false;
        this.loading = false;
        this.value = undefined;
        addThemingController(this, all);
        addSafeEventListener(this, 'click', this.itemClick);
        addSafeEventListener(this, 'focus', this.onFocus);
        addSafeEventListener(this, 'blur', this.onBlur);
    }
    connectedCallback() {
        super.connectedCallback();
        this.tree = this.closest('igc-tree');
        this.parent = this.parentElement?.closest('igc-tree-item');
        this.level = this.parent ? this.parent.level + 1 : 0;
        this.setAttribute('role', 'treeitem');
        this.activeChange();
        if (this.init) {
            this.selectedChange();
        }
        else {
            this.selectionService?.retriggerItemState(this);
        }
        this.init = false;
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this.selectionService?.ensureStateOnItemDelete(this);
        this.navService?.delete_item(this);
    }
    get selectionService() {
        return this.tree?.selectionService;
    }
    get navService() {
        return this.tree?.navService;
    }
    get parts() {
        return {
            wrapper: true,
            selected: this.selected,
            focused: this.isFocused,
            active: this.active,
        };
    }
    get directChildren() {
        return this.allChildren.filter((x) => (x.parent ?? x.parentElement?.closest('igc-tree-item')) === this);
    }
    get allChildren() {
        return Array.from(this.querySelectorAll('igc-tree-item'));
    }
    get path() {
        return this.parent?.path ? [...this.parent.path, this] : [this];
    }
    itemClick(event) {
        if (this.disabled ||
            this !== findElementFromEventPath(this.tagName, event)) {
            return;
        }
        this.tabIndex = 0;
        if (this.tree?.toggleNodeOnClick && event.button === 0) {
            if (this.expanded) {
                this.collapseWithEvent();
            }
            else {
                this.expandWithEvent();
            }
        }
        this.navService?.setFocusedAndActiveItem(this, true, true);
    }
    expandIndicatorClick() {
        if (this.disabled) {
            return;
        }
        if (this.expanded) {
            this.collapseWithEvent();
        }
        else {
            this.expandWithEvent();
        }
    }
    selectorClick(event) {
        event.preventDefault();
        if (this.tree?.toggleNodeOnClick) {
            event.stopPropagation();
        }
        if (event.shiftKey) {
            this.selectionService?.selectMultipleItems(this);
            return;
        }
        if (this.selected) {
            this.selectionService?.deselectItem(this);
        }
        else {
            this.selectionService?.selectItem(this);
        }
    }
    onFocus() {
        if (this.disabled) {
            return;
        }
        if (this.navService?.focusedItem !== this) {
            this.navService?.focusItem(this, false);
            this.wrapper?.scrollIntoView({
                behavior: 'smooth',
                block: 'nearest',
                inline: 'nearest',
            });
        }
        if (this.tabbableEl?.length) {
            this.tabbableEl.forEach((element) => {
                element.tabIndex = 0;
            });
            this.focusedProgrammatically = true;
            this.tabbableEl[0].focus();
            return;
        }
        this.isFocused = true;
    }
    onBlur() {
        this.isFocused = false;
    }
    onFocusIn(ev) {
        ev?.stopPropagation();
        if (!this.disabled) {
            if (!this.focusedProgrammatically) {
                this.tabbableEl?.forEach((element) => {
                    element.tabIndex = 0;
                });
            }
            this.removeAttribute('tabIndex');
            this.isFocused = true;
            this.focusedProgrammatically = false;
        }
    }
    onFocusOut(ev) {
        ev?.stopPropagation();
        this.isFocused = false;
        this.tabbableEl?.forEach((element) => {
            element.tabIndex = -1;
        });
        if (this.navService?.focusedItem === this) {
            this.setAttribute('tabindex', '0');
        }
    }
    labelChange() {
        const firstElement = this.contentList[0];
        const tabbableSelector = 'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])';
        this.tabbableEl = [
            ...firstElement.querySelectorAll(tabbableSelector),
        ];
        if (firstElement.matches(tabbableSelector)) {
            this.tabbableEl.splice(0, 0, firstElement);
        }
        if (this.tabbableEl?.length) {
            this.setAttribute('role', 'none');
            this.tabbableEl[0].setAttribute('role', 'treeitem');
            this.tabbableEl.forEach((element) => {
                element.tabIndex = -1;
            });
        }
        else {
            this.setAttribute('role', 'treeitem');
        }
    }
    handleChange() {
        this.hasChildren = !!this.directChildren.length;
        this.navService?.update_visible_cache(this, this.expanded, false);
    }
    getChildren(options = { flatten: false }) {
        if (options.flatten) {
            return this.allChildren;
        }
        return this.directChildren;
    }
    async expandWithEvent() {
        if (this.expanded) {
            return;
        }
        const args = {
            detail: this,
            cancelable: true,
        };
        const allowed = this.tree?.emitEvent('igcItemExpanding', args);
        if (!allowed) {
            return;
        }
        if (this.tree?.singleBranchExpand) {
            const pathSet = new Set(this.path.splice(0, this.path.length - 1));
            this.tree.items.forEach((item) => {
                if (!pathSet.has(item)) {
                    item.collapseWithEvent();
                }
            });
        }
        this.expanded = true;
        if (await this.toggleAnimation('open')) {
            this.tree?.emitEvent('igcItemExpanded', { detail: this });
        }
    }
    async collapseWithEvent() {
        if (!this.expanded) {
            return;
        }
        const args = {
            detail: this,
            cancelable: true,
        };
        const allowed = this.tree?.emitEvent('igcItemCollapsing', args);
        if (!allowed) {
            return;
        }
        this.expanded = false;
        if (await this.toggleAnimation('close')) {
            this.tree?.emitEvent('igcItemCollapsed', { detail: this });
        }
    }
    toggle() {
        this.expanded = !this.expanded;
    }
    expand() {
        this.expanded = true;
    }
    collapse() {
        this.expanded = false;
    }
    render() {
        const indicatorParts = {
            indicator: true,
            rtl: !(this.tree ? isLTR(this.tree) : true),
        };
        return html `
      <div id="wrapper" part=${partMap(this.parts)}>
        <div
          style="width: calc(${this.level} * var(--igc-tree-indentation-size))"
          part="indentation"
          aria-hidden="true"
        >
          <slot name="indentation"></slot>
        </div>
        <div part=${partMap(indicatorParts)} aria-hidden="true">
          ${this.loading
            ? html `
                <slot name="loading">
                  <igc-circular-progress indeterminate></igc-circular-progress>
                </slot>
              `
            : html `
                <slot
                  name="indicator"
                  @click=${this.tree?.toggleNodeOnClick
                ? nothing
                : this.expandIndicatorClick}
                >
                  ${this.hasChildren
                ? html `
                        <igc-icon
                          name=${this.expanded
                    ? 'tree_collapse'
                    : 'tree_expand'}
                          collection="default"
                        >
                        </igc-icon>
                      `
                : ''}
                </slot>
              `}
        </div>
        ${this.tree?.selection !== 'none'
            ? html `
              <div part="select" aria-hidden="true">
                <igc-checkbox
                  @click=${this.selectorClick}
                  .checked=${this.selected}
                  .indeterminate=${this.indeterminate}
                  .disabled=${this.disabled}
                  tabindex="-1"
                >
                </igc-checkbox>
              </div>
            `
            : ''}
        <div part="label">
          <slot
            name="label"
            @slotchange=${this.labelChange}
            @focusin=${this.onFocusIn}
            @focusout=${this.onFocusOut}
          >
            <span part="text">${this.label}</span>
          </slot>
        </div>
      </div>
      <div ${ref(this.groupRef)} role="group" aria-hidden=${!this.expanded}>
        <slot @slotchange=${this.handleChange}></slot>
      </div>
    `;
    }
}
__decorate([
    queryAssignedElements({ slot: 'label', flatten: true })
], IgcTreeItemComponent.prototype, "contentList", void 0);
__decorate([
    query('#wrapper')
], IgcTreeItemComponent.prototype, "wrapper", void 0);
__decorate([
    state()
], IgcTreeItemComponent.prototype, "isFocused", void 0);
__decorate([
    state()
], IgcTreeItemComponent.prototype, "hasChildren", void 0);
__decorate([
    state()
], IgcTreeItemComponent.prototype, "level", void 0);
__decorate([
    state()
], IgcTreeItemComponent.prototype, "indeterminate", void 0);
__decorate([
    property()
], IgcTreeItemComponent.prototype, "label", void 0);
__decorate([
    property({ reflect: true, type: Boolean })
], IgcTreeItemComponent.prototype, "expanded", void 0);
__decorate([
    property({ reflect: true, type: Boolean })
], IgcTreeItemComponent.prototype, "active", void 0);
__decorate([
    property({ reflect: true, type: Boolean })
], IgcTreeItemComponent.prototype, "disabled", void 0);
__decorate([
    property({ reflect: true, type: Boolean })
], IgcTreeItemComponent.prototype, "selected", void 0);
__decorate([
    property({ reflect: true, type: Boolean })
], IgcTreeItemComponent.prototype, "loading", void 0);
__decorate([
    property({ attribute: true })
], IgcTreeItemComponent.prototype, "value", void 0);
__decorate([
    watch('expanded', { waitUntilFirstUpdate: true }),
    watch('hasChildren', { waitUntilFirstUpdate: true })
], IgcTreeItemComponent.prototype, "bothChange", null);
__decorate([
    watch('expanded')
], IgcTreeItemComponent.prototype, "expandedChange", null);
__decorate([
    watch('active', { waitUntilFirstUpdate: true })
], IgcTreeItemComponent.prototype, "activeChange", null);
__decorate([
    watch('disabled')
], IgcTreeItemComponent.prototype, "disabledChange", null);
__decorate([
    watch('selected', { waitUntilFirstUpdate: true })
], IgcTreeItemComponent.prototype, "selectedChange", null);
//# sourceMappingURL=tree-item.js.map