// #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 { Themeable } from '../../../Behaviors/Themeable';
import { Variantable } from '../../../Behaviors/Variantable';
import { addInheritanceProviderController } from '../../../Controllers/InheritanceProviderController';
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 { TAB_INHERITANCE_CONTEXT } from './TabInheritanceContext';
import { TabItemElement } from './TabItemElement';
import { TabPanelElement } from './TabPanelElement';
import { tabElementCosmopolitanStyle } from './Themes/TabElement.Cosmopolitan';
import { tabElementJoyStyle } from './Themes/TabElement.Joy';
import { tabElementMemphisStyle } from './Themes/TabElement.Memphis';
// #endregion
/**
 * Tab - A navigation component for switching between different content panels within the same context.
 *
 * @description
 * The Tab component provides a tabbed interface for organizing and switching between multiple content
 * panels. It displays tab strip items as navigation headers and manages the visibility of associated
 * content panels. Tabs support multiple placements (top, bottom, left, right), customizable alignment,
 * visual indicators, and optional swipe gestures. The component is ideal for organizing related content
 * into separate views without navigating to different pages, commonly used in settings panels, product
 * details, dashboards, and multi-section forms.
 *
 * @name Tab
 * @element mosaik-tab
 * @category Selectors
 *
 * @slot - The default slot for tab items (mosaik-tab-item elements)
 * @slot end - Content displayed after the tab strip (e.g., action buttons)
 * @slot start - Content displayed before the tab strip (e.g., toolbar buttons)
 *
 * @csspart content - The main content area for active tab panel
 * @csspart header - The header container with tab strip
 * @csspart root - The root container element
 * @csspart tabPanel - The tab panel wrapper element
 * @csspart tabStrip - The tab strip container
 * @csspart tabStripItem - Individual tab strip item elements
 *
 * @cssprop {String} --tab-background-color - The background fill color
 * @cssprop {String} --tab-border-color - The border color
 * @cssprop {String} --tab-border-radius - The corner rounding radius
 * @cssprop {String} --tab-border-style - The border line style
 * @cssprop {String} --tab-border-width - The border thickness
 * @cssprop {String} --tab-divider-height - The height of divider lines
 * @cssprop {String} --tab-font-family - The font family for tab text
 * @cssprop {String} --tab-font-letter-spacing - The letter spacing for tab text
 * @cssprop {String} --tab-font-line-height - The line height for tab text
 * @cssprop {String} --tab-font-size - The font size for tab text
 * @cssprop {String} --tab-font-text-decoration - The text decoration style
 * @cssprop {String} --tab-font-text-transform - The text transformation style
 * @cssprop {String} --tab-font-weight - The font weight for tab text
 * @cssprop {String} --tab-foreground-color - The text and icon color
 * @cssprop {String} --tab-gap - The spacing between elements
 * @cssprop {String} --tab-indicator-height - The height of the selection indicator
 * @cssprop {String} --tab-padding-bottom - The bottom padding inside the tab container
 * @cssprop {String} --tab-padding-left - The left padding inside the tab container
 * @cssprop {String} --tab-padding-right - The right padding inside the tab container
 * @cssprop {String} --tab-padding-top - The top padding inside the tab container
 * @cssprop {String} --tab-panel-background-color - The background color of the panel
 * @cssprop {String} --tab-shadow - The shadow CSS custom property.
 * @cssprop {String} --tab-shadow-blur - The shadow blur CSS custom property.
 * @cssprop {String} --tab-shadow-color - The shadow color CSS custom property.
 * @cssprop {String} --tab-shadow-offset-x - The shadow offset x CSS custom property.
 * @cssprop {String} --tab-shadow-offset-y - The shadow offset y CSS custom property.
 * @cssprop {String} --tab-shadow-spread - The shadow spread CSS custom property.
 * @cssprop {String} --tab-strip-background-color - The background color of the strip
 * @cssprop {String} --tab-strip-padding-bottom - The bottom padding inside the strip
 * @cssprop {String} --tab-strip-padding-left - The left padding inside the strip
 * @cssprop {String} --tab-strip-padding-right - The right padding inside the strip
 * @cssprop {String} --tab-strip-padding-top - The top padding inside the strip
 * @cssprop {String} --tab-transition-duration - The duration of transitions
 * @cssprop {String} --tab-transition-mode - The timing function for transitions
 * @cssprop {String} --tab-transition-property - The CSS properties to transition
 * @cssprop {String} --tab-translate - The translate CSS custom property.
 *
 * @fires connected {ConnectedEvent} - Fired when connected to the DOM
 * @fires changed {PropertyChangedEvent} - Fired when properties change
 *
 * @dependency mosaik-tab-panel - The Tab Panel element.
 * @dependency mosaik-tab-strip - The Tab Strip element.
 * @dependency mosaik-tab-strip-item - The Tab Strip Item element.
 *
 * @example
 * Basic tabs with three panels:
 * ```html
 * <mosaik-tab>
 *   <mosaik-tab-item is-selected>
 *     <p>Overview content goes here.</p>
 *   </mosaik-tab-item>
 *   <mosaik-tab-item>
 *     <p>Details content goes here.</p>
 *   </mosaik-tab-item>
 *   <mosaik-tab-item>
 *     <p>Settings content goes here.</p>
 *   </mosaik-tab-item>
 * </mosaik-tab>
 * ```
 *
 * @example
 * Tabs with bottom placement and primary variant:
 * ```html
 * <mosaik-tab placement="bottom" variant="primary">
 *   <mosaik-tab-item is-selected>
 *     <p>Home content</p>
 *   </mosaik-tab-item>
 *   <mosaik-tab-item>
 *     <p>Search content</p>
 *   </mosaik-tab-item>
 *   <mosaik-tab-item>
 *     <p>Profile content</p>
 *   </mosaik-tab-item>
 * </mosaik-tab>
 * ```
 *
 * @example
 * Tabs with center alignment and gestures:
 * ```html
 * <mosaik-tab alignment="center" enable-gestures>
 *   <mosaik-tab-item>Content 1</mosaik-tab-item>
 *   <mosaik-tab-item>Content 2</mosaik-tab-item>
 *   <mosaik-tab-item>Content 3</mosaik-tab-item>
 * </mosaik-tab>
 * ```
 *
 * @public
 */
let TabElement = class TabElement extends Themeable(Slottable(Disableable(Variantable(Appearanceable(CustomElement))))) {
    // #region Fields
    _provider = addInheritanceProviderController(this, {
        context: TAB_INHERITANCE_CONTEXT,
        values: () => ({
            disabled: this.disabled
        })
    });
    _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,
            memphis: tabElementMemphisStyle,
            cosmopolitan: tabElementCosmopolitanStyle
        },
        host: {
            role: 'tablist'
        },
        imports: [
            TabStripElement,
            TabStripItemElement,
            TabPanelElement,
            TextElement,
            InkBarElement
        ]
    }),
    __metadata("design:paramtypes", [])
], TabElement);
export { TabElement };
//# sourceMappingURL=TabElement.js.map