// #region Imports
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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Listen } from '../../../../Events/Decorators/ListenDecorator';
import { Appearanceable } from '../../../Behaviors/Appearanceable';
import { Disableable } from '../../../Behaviors/Disableable';
import { Slottable } from '../../../Behaviors/Slottable';
import { Variantable } from '../../../Behaviors/Variantable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { TabPanelAlignment } from '../../../Types/TabPanelAlignment';
import { TabStripPlacement } from '../../../Types/TabStripPlacement';
import { CustomElement } from '../../Abstracts/CustomElement';
import { InkBarElement } from '../../Primitives/InkBar/InkBarElement';
import { TextElement } from '../../Primitives/Text/TextElement';
import { TabStripElement } from '../TabStrip/TabStripElement';
import { TabStripItemElement } from '../TabStrip/TabStripItemElement';
import { tabElementTemplate } from './TabElementTemplate';
import { TabPanelElement } from './TabPanelElement';
import { tabElementJoyStyle } from './Themes/TabElement.Joy';
import { tabElementRetroStyle } from './Themes/TabElement.Retro';
import { tabElementCosmopolitanStyle } from './Themes/TabElement.Cosmopolitan';
import { Themeable } from '../../../Behaviors/Themeable';
import { TabItemElement } from './TabItemElement';
// #endregion
/**
 * Tab - A navigation element used to switch between different sections of content.
 *
 * @element mosaik-tab
 *
 * @dependency {InkBarElement} mosaik-ink-bar - InkBarElement
 * @dependency {TextElement} mosaik-text - TextElement
 * @dependency {TabPanelElement} mosaik-tab-panel - TabPanelElement
 * @dependency {TabStripElement} mosaik-tab-strip - TabStripElement
 * @dependency {TabStripItemElement} mosaik-tab-strip-item - TabStripItemElement
 *
 * @public
 */
let TabElement = class TabElement extends Themeable(Slottable(Disableable(Variantable(Appearanceable(CustomElement))))) {
    // #region Fields
    _alignment;
    _placement;
    _hasIndicator;
    _enableGestures;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._alignment = TabPanelAlignment.Stretch;
        this._placement = TabStripPlacement.Top;
        this._hasIndicator = true;
        this._enableGestures = false;
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     *
     * @public
     * @static
     * @readonly
    */
    static get is() {
        return 'mosaik-tab';
    }
    /**
     * Gets or sets the `alignment` property.
     *
     * @public
     * @attr
     */
    get alignment() {
        return this._alignment;
    }
    set alignment(value) {
        if (this._alignment !== value) {
            this._alignment = value;
            this.requestUpdate('alignment');
        }
    }
    /**
     * Gets or sets the `placement` property.
     *
     * @public
     * @attr
     */
    get placement() {
        return this._placement;
    }
    set placement(value) {
        if (this._placement !== value) {
            this._placement = value;
            this.requestUpdate('placement');
        }
    }
    /**
     * Gets or sets the `hasIndicator` property.
     *
     * @public
     * @attr
     */
    get hasIndicator() {
        return this._hasIndicator;
    }
    set hasIndicator(value) {
        if (this._hasIndicator !== value) {
            this._hasIndicator = value;
            this.requestUpdate('hasIndicator');
        }
    }
    /**
     * Gets or sets the `enableGestures` property.
     *
     * @public
     * @attr
     */
    get enableGestures() {
        return this._enableGestures;
    }
    set enableGestures(value) {
        if (this._enableGestures !== value) {
            this._enableGestures = value;
            this.requestUpdate('enableGestures');
        }
    }
    /**
     * Returns the items of the tab.
     *
     * @public
     * @readonly
     */
    get items() {
        return this.getSlotAssignmentsOf('', TabItemElement);
    }
    /**
     * Returns the selected tab item.
     *
     * @public
     * @readonly
     */
    get selectedItem() {
        return this.items.find((x) => x.isSelected) ?? null;
    }
    /**
     * Returns the selected index.
     *
     * @public
     * @readonly
     */
    get selectedIndex() {
        return this.items.findIndex((x) => x.isSelected);
    }
    // #endregion
    // #region Methods
    /**
     * Selects the specified tab item.
     *
     * @public
     * @param tabItem - The tab item to select.
     */
    select(tabItem) {
        if (tabItem.disabled) {
            return;
        }
        for (const item of this.items) {
            const isCurrent = item === tabItem;
            item.isSelected = isCurrent;
        }
        this.requestUpdate();
    }
    /**
     * Selects the specified tab item by its index.
     *
     * @public
     * @param index - The index of the tab item to select.
     */
    selectByIndex(index) {
        this.select(this.items[index]);
    }
    /**
     * Selects the specified tab item by its value.
     *
     * @public
     * @param value - The value of the tab item to select.
     */
    selectByValue(value) {
        const item = this.items.find((x) => x.value === value);
        if (item) {
            this.select(item);
        }
    }
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        super.onApplyTemplate();
        // in tabs wh have a special logic. if no tab is selected, we select always the first one.
        const selectedItem = this.items.find((x) => x.isSelected);
        if (!selectedItem && this.items.length > 0) {
            this.select(this.items[0]);
        }
    }
    /**
     * @protected
     */
    onTabItemSelectionChanged(event) {
        if (event.target instanceof TabItemElement) {
            if (event.target.isSelected) {
                // this.alignIndicatorTo(event.target);
                this.select(event.target);
            }
        }
    }
    /**
     * @internal
     * @template
     */
    onTabStripItemSelectionChanged(event, tab) {
        if (event.detail.isSelected) {
            this.select(tab);
        }
    }
};
__decorate([
    Attribute({ type: TabPanelAlignment }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], TabElement.prototype, "alignment", null);
__decorate([
    Attribute({ type: TabStripPlacement }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], TabElement.prototype, "placement", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], TabElement.prototype, "hasIndicator", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], TabElement.prototype, "enableGestures", null);
__decorate([
    Listen('selectionChanged'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [CustomEvent]),
    __metadata("design:returntype", void 0)
], TabElement.prototype, "onTabItemSelectionChanged", null);
TabElement = __decorate([
    Component({
        selector: 'mosaik-tab',
        template: tabElementTemplate,
        themes: {
            joy: tabElementJoyStyle,
            retro: tabElementRetroStyle,
            cosmopolitan: tabElementCosmopolitanStyle
        },
        host: {
            role: 'tablist'
        },
        imports: [
            TabStripElement,
            TabStripItemElement,
            TabPanelElement,
            TextElement,
            InkBarElement
        ]
    }),
    __metadata("design:paramtypes", [])
], TabElement);
export { TabElement };
//# sourceMappingURL=TabElement.js.map