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 { eventOptions, property, queryAssignedElements, state, } from 'lit/decorators.js';
import { cache } from 'lit/directives/cache.js';
import { createRef, ref } from 'lit/directives/ref.js';
import { styleMap } from 'lit/directives/style-map.js';
import { addThemingController } from '../../theming/theming-controller.js';
import IgcIconButtonComponent from '../button/icon-button.js';
import { addKeybindings, arrowLeft, arrowRight, endKey, homeKey, } from '../common/controllers/key-bindings.js';
import { createMutationController, } from '../common/controllers/mutation-observer.js';
import { createResizeObserverController } from '../common/controllers/resize-observer.js';
import { watch } from '../common/decorators/watch.js';
import { registerComponent } from '../common/definitions/register.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { partMap } from '../common/part-map.js';
import { findElementFromEventPath, first, getRoot, isEmpty, isLTR, isString, last, scrollIntoView, wrap, } from '../common/util.js';
import IgcTabComponent from './tab.js';
import { createTabHelpers, getTabHeader } from './tab-dom.js';
import { styles as shared } from './themes/shared/tabs/tabs.common.css.js';
import { styles } from './themes/tabs.base.css.js';
import { all } from './themes/tabs-themes.js';
class IgcTabsComponent extends EventEmitterMixin(LitElement) {
    static register() {
        registerComponent(IgcTabsComponent, IgcTabComponent, IgcIconButtonComponent);
    }
    get _enabledTabs() {
        return this._tabs.filter((tab) => !tab.disabled);
    }
    get tabs() {
        return this._tabs;
    }
    get selected() {
        if (this._activeTab) {
            return this._activeTab.label || this._activeTab.id;
        }
        return '';
    }
    _alignmentChanged() {
        this._domHelpers.setIndicator(this._activeTab);
    }
    constructor() {
        super();
        this._resizeController = createResizeObserverController(this, {
            callback: this._resizeCallback,
            options: { box: 'border-box' },
            target: null,
        });
        this._headerRef = createRef();
        this._indicatorRef = createRef();
        this._domHelpers = createTabHelpers(this, this._headerRef, this._indicatorRef);
        this.alignment = 'start';
        this.activation = 'auto';
        addThemingController(this, all);
        addKeybindings(this, {
            ref: this._headerRef,
            skip: this._skipKeyboard,
        })
            .set(arrowLeft, () => this._handleArrowKeys(isLTR(this) ? -1 : 1))
            .set(arrowRight, () => this._handleArrowKeys(isLTR(this) ? 1 : -1))
            .set(homeKey, this._handleHomeKey)
            .set(endKey, this._handleEndKey)
            .setActivateHandler(this._handleActivationKeys, {
            preventDefault: false,
        });
        createMutationController(this, {
            callback: this._mutationCallback,
            config: {
                attributeFilter: ['selected'],
                childList: true,
                subtree: true,
            },
            filter: [IgcTabComponent.tagName],
        });
    }
    async firstUpdated() {
        await this.updateComplete;
        const selectedTab = this._tabs.findLast((tab) => tab.selected) ?? first(this._enabledTabs);
        this._domHelpers.setStyleProperties();
        this._domHelpers.setScrollButtonState();
        this._setSelectedTab(selectedTab, false);
        this._resizeController.observe(this._headerRef.value);
    }
    connectedCallback() {
        super.connectedCallback();
        this.role = 'tablist';
    }
    updated() {
        if (this._domHelpers.isLeftToRightChanged) {
            this._domHelpers.setIndicator(this._activeTab);
        }
    }
    _resizeCallback() {
        this._domHelpers.setStyleProperties();
        this._domHelpers.setScrollButtonState();
        this._domHelpers.setIndicator(this._activeTab);
    }
    _mutationCallback(parameters) {
        this._selectedAttributeChanged(parameters);
        this._handleTabsRemoved(parameters);
        this._handleTabsAdded(parameters);
        this._domHelpers.setStyleProperties();
        this._domHelpers.setScrollButtonState();
        this._domHelpers.setIndicator(this._activeTab);
    }
    _selectedAttributeChanged({ changes, }) {
        const selected = changes.attributes.find(({ node: tab }) => this._tabs.includes(tab) && tab.selected)?.node;
        this._setSelectedTab(selected, false);
    }
    _handleTabsAdded({ changes, }) {
        if (!isEmpty(changes.added)) {
            const lastAdded = changes.added.findLast((change) => change.target.closest(this.tagName) === this && change.node.selected)?.node;
            this._setSelectedTab(lastAdded, false);
        }
    }
    _handleTabsRemoved({ changes, }) {
        if (!isEmpty(changes.removed)) {
            let nextSelectedTab = null;
            const removed = changes.removed.filter((change) => change.target.closest(this.tagName) === this);
            for (const each of removed) {
                if (each.node.selected && each.node === this._activeTab) {
                    nextSelectedTab = first(this._enabledTabs);
                    break;
                }
            }
            if (nextSelectedTab) {
                this._setSelectedTab(nextSelectedTab, false);
            }
        }
    }
    _getClosestActiveTabIndex() {
        const active = getRoot(this).activeElement;
        const tab = active ? active.closest(IgcTabComponent.tagName) : null;
        return tab ? this._enabledTabs.indexOf(tab) : -1;
    }
    _setSelectedTab(tab, shouldEmit = true) {
        if (!tab || tab === this._activeTab) {
            return;
        }
        if (this._activeTab) {
            this._activeTab.selected = false;
        }
        tab.selected = true;
        this._activeTab = tab;
        scrollIntoView(getTabHeader(tab));
        this._domHelpers.setIndicator(this._activeTab);
        if (shouldEmit) {
            this.emitEvent('igcChange', { detail: this._activeTab });
        }
    }
    _keyboardActivateTab(tab) {
        const header = getTabHeader(tab);
        this._domHelpers.setScrollSnap();
        scrollIntoView(header);
        header.focus({ preventScroll: true });
        if (this.activation === 'auto') {
            this._setSelectedTab(tab);
        }
    }
    _skipKeyboard(node, event) {
        return !(this._isEventFromTabHeader(event) &&
            this._tabs.includes(node.closest(IgcTabComponent.tagName)));
    }
    _isEventFromTabHeader(event) {
        return findElementFromEventPath('[part~="tab-header"]', event);
    }
    _handleArrowKeys(delta) {
        const tabs = this._enabledTabs;
        this._keyboardActivateTab(tabs[wrap(0, tabs.length - 1, this._getClosestActiveTabIndex() + delta)]);
    }
    _handleHomeKey() {
        this._keyboardActivateTab(first(this._enabledTabs));
    }
    _handleEndKey() {
        this._keyboardActivateTab(last(this._enabledTabs));
    }
    _handleActivationKeys() {
        const tabs = this._enabledTabs;
        const index = this._getClosestActiveTabIndex();
        if (index > -1) {
            this._setSelectedTab(tabs[index], false);
            this._keyboardActivateTab(tabs[index]);
        }
    }
    _handleClick(event) {
        if (!this._isEventFromTabHeader(event)) {
            return;
        }
        const tab = findElementFromEventPath(IgcTabComponent.tagName, event);
        if (!(tab && this._tabs.includes(tab)) || tab?.disabled) {
            return;
        }
        this._domHelpers.setScrollSnap();
        getTabHeader(tab).focus();
        this._setSelectedTab(tab);
    }
    _handleScroll() {
        this._domHelpers.setScrollButtonState();
    }
    select(ref) {
        const tab = isString(ref) ? this._tabs.find((t) => t.id === ref) : ref;
        if (tab) {
            this._setSelectedTab(tab, false);
        }
    }
    _renderScrollButton(direction) {
        const isStart = direction === 'start';
        const { start, end } = this._domHelpers.scrollButtonsDisabled;
        return html `${cache(this._domHelpers.hasScrollButtons
            ? html `
            <igc-icon-button
              tabindex="-1"
              variant="flat"
              collection="default"
              part="${direction}-scroll-button"
              exportparts="icon"
              name=${isStart ? 'prev' : 'next'}
              ?disabled=${isStart ? start : end}
              @click=${() => this._domHelpers.scrollTabs(direction)}
            >
            </igc-icon-button>
          `
            : nothing)}`;
    }
    render() {
        return html `
      <div
        ${ref(this._headerRef)}
        part="tabs"
        style=${styleMap(this._domHelpers.styleProperties)}
        @scroll=${this._handleScroll}
      >
        <div
          part=${partMap({
            inner: true,
            scrollable: this._domHelpers.hasScrollButtons,
        })}
        >
          ${this._renderScrollButton('start')}
          <slot @click=${this._handleClick}></slot>
          ${this._renderScrollButton('end')}
          <div part="selected-indicator">
            <span ${ref(this._indicatorRef)}></span>
          </div>
        </div>
      </div>
    `;
    }
}
IgcTabsComponent.tagName = 'igc-tabs';
IgcTabsComponent.styles = [styles, shared];
export default IgcTabsComponent;
__decorate([
    queryAssignedElements({ selector: IgcTabComponent.tagName })
], IgcTabsComponent.prototype, "_tabs", void 0);
__decorate([
    state()
], IgcTabsComponent.prototype, "_activeTab", void 0);
__decorate([
    property({ reflect: true })
], IgcTabsComponent.prototype, "alignment", void 0);
__decorate([
    property()
], IgcTabsComponent.prototype, "activation", void 0);
__decorate([
    watch('alignment', { waitUntilFirstUpdate: true })
], IgcTabsComponent.prototype, "_alignmentChanged", null);
__decorate([
    eventOptions({ passive: true })
], IgcTabsComponent.prototype, "_handleScroll", null);
//# sourceMappingURL=tabs.js.map