// #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 { on } from '@breadstone/mosaik-elements';
import { Disableable } from '../../../Behaviors/Disableable';
import { Filterable, contains, getMemberValue } from '../../../Behaviors/Filterable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Watch } from '../../../Decorators/WatchDecorator';
import { SelectionMode } from '../../../Types/SelectionMode';
import { TextBoxElement } from '../../Inputs/TextBox/TextBoxElement';
import { SelectorElement } from '../Abstracts/Selector/SelectorElement';
import { listElementTemplate } from './ListElementTemplate';
import { ListItemElement } from './ListItemElement';
import { ListItemGroupElement } from './ListItemGroupElement';
import { listElementJoyStyle } from './Themes/ListElement.Joy';
import { listElementRetroStyle } from './Themes/ListElement.Retro';
import { listElementCosmopolitanStyle } from './Themes/ListElement.Cosmopolitan';
import { Themeable } from '../../../Behaviors/Themeable';
import { ListElementIntl } from './ListElementIntl';
import { IntlController } from '../../../../Intl/IntlController';
import { SpacerElement } from '../../Primitives/Spacer/SpacerElement';
// #endregion
/**
 * List - A versatile container component for displaying collections of interactive items in organized layouts.
 *
 * Presents ordered or unordered collections of related content items with support for selection,
 * filtering, grouping, and navigation. Optimized for accessibility and keyboard interaction
 * with flexible styling options for various content types.
 *
 * @name ListElement
 * @element mosaik-list
 * @category Selectors
 *
 * @slot - Default content area for list items and groups
 * @slot filter - Filter controls and search functionality area
 * @slot empty - Empty state content when no items are available
 * @slot header - Header content above the list items
 * @slot footer - Footer content below the list items
 *
 * @csspart container - Main list container element
 * @csspart items - Container for all list items
 * @csspart filter - Filter controls container
 * @csspart empty-state - Empty state container
 * @csspart scrollable - Scrollable content area
 *
 * @cssprop --list-padding - Internal padding for the list container
 * @cssprop --list-item-spacing - Vertical spacing between list items
 * @cssprop --list-background - Background color for the list
 * @cssprop --list-border-radius - Border radius for list styling
 * @cssprop --list-max-height - Maximum height before scrolling activates
 * @cssprop --list-scrollbar-width - Width of the scrollbar
 *
 * @keyhandle ArrowUp - Navigates to the previous item
 * @keyhandle ArrowDown - Navigates to the next item
 * @keyhandle Home - Navigates to the first item
 * @keyhandle End - Navigates to the last item
 * @keyhandle Space - Toggles selection of the focused item
 * @keyhandle Enter - Activates the focused item
 *
 * @dependency ListItemElement - For individual selectable items within the list
 * @dependency ListItemGroupElement - For organizing items into logical groups
 * @dependency TextBoxElement - For search and filter functionality
 * @dependency SpacerElement - For layout spacing between groups
 *
 * @example
 * ```html
 * <!-- Simple navigation list -->
 * <mosaik-list>
 *   <mosaik-list-item value="dashboard">
 *     <mosaik-icon slot="prefix" data="home"></mosaik-icon>
 *     Dashboard
 *   </mosaik-list-item>
 *   <mosaik-list-item value="analytics">
 *     <mosaik-icon slot="prefix" data="chart-bar"></mosaik-icon>
 *     Analytics
 *   </mosaik-list-item>
 *   <mosaik-list-item value="settings">
 *     <mosaik-icon slot="prefix" data="cog"></mosaik-icon>
 *     Settings
 *   </mosaik-list-item>
 * </mosaik-list>
 *
 * <!-- Multi-select list with filtering -->
 * <mosaik-list selection-mode="multiple" filterable="true">
 *   <mosaik-text-box slot="filter" placeholder="Search contacts..." />
 *   <mosaik-list-item-group label="Favorites">
 *     <mosaik-list-item value="john">
 *       <mosaik-avatar slot="prefix" src="john.jpg"></mosaik-avatar>
 *       John Smith
 *       <mosaik-text slot="suffix">john@example.com</mosaik-text>
 *     </mosaik-list-item>
 *   </mosaik-list-item-group>
 *   <mosaik-list-item-group label="Colleagues">
 *     <mosaik-list-item value="jane">Jane Doe</mosaik-list-item>
 *     <mosaik-list-item value="mike">Mike Johnson</mosaik-list-item>
 *   </mosaik-list-item-group>
 * </mosaik-list>
 *
 * <!-- Action list with descriptions -->
 * <mosaik-list>
 *   <mosaik-list-item value="export">
 *     <mosaik-icon slot="prefix" data="download"></mosaik-icon>
 *     Export Data
 *     <mosaik-text slot="suffix" variant="caption">Download your data as CSV</mosaik-text>
 *   </mosaik-list-item>
 *   <mosaik-list-item value="import">
 *     <mosaik-icon slot="prefix" data="upload"></mosaik-icon>
 *     Import Data
 *     <mosaik-text slot="suffix" variant="caption">Upload data from file</mosaik-text>
 *   </mosaik-list-item>
 * </mosaik-list>
 *
 * <!-- List with empty state -->
 * <mosaik-list>
 *   <mosaik-empty-state slot="empty">
 *     <mosaik-icon slot="icon" data="inbox"></mosaik-icon>
 *     <mosaik-text slot="header">No items found</mosaik-text>
 *     <mosaik-text slot="content">Add some items to get started</mosaik-text>
 *   </mosaik-empty-state>
 * </mosaik-list>
 * ```
 *
 * @public
 */
let ListElement = class ListElement extends Themeable(Disableable(Filterable(SelectorElement))) {
    // #region Fields
    _itemsClickSubscriptions;
    _intlController;
    _selectionMode;
    _value;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._selectionMode = SelectionMode.Single;
        this._value = null;
        this._itemsClickSubscriptions = new Array();
        this._intlController = new IntlController(this, {
            factory: () => new ListElementIntl()
        });
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `{@link is}` property.
     * The `{@link is}` property represents natural name of this element.
     *
     * @public
     * @static
     * @override
     * @readonly
     */
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    static get is() {
        return 'mosaik-list';
    }
    /**
     * Gets or sets the `selectionMode` property.
     *
     * @public
     * @attr
     */
    get selectionMode() {
        return this._selectionMode;
    }
    set selectionMode(value) {
        if (this._selectionMode !== value) {
            this._selectionMode = value;
            this.requestUpdate('selectionMode');
        }
    }
    /**
     * Gets or sets the `value` property.
     *
     * @public
     * @attr
     */
    get value() {
        return this._value;
    }
    set value(value) {
        if (this._value !== value) {
            this._value = value;
            this.requestUpdate('value');
        }
    }
    /**
     * Gets all the list items in the list.
     *
     * @public
     * @override
     */
    get items() {
        return super.items
            .flatMap((x) => x instanceof ListItemGroupElement ? x.items : x)
            .filter((x) => x instanceof ListItemElement);
    }
    /**
     * Returns the `intl` property.
     *
     * @public
     * @readonly
     */
    get intl() {
        return this._intlController.intl;
    }
    // #endregion
    // #region Methods
    /**
     * @protected
     * @override
     */
    onItemsChanged() {
        super.onItemsChanged();
        // reset all click handler if items are changed.
        this._itemsClickSubscriptions.forEach((x) => x.dispose());
        this.items.forEach((x) => {
            this._itemsClickSubscriptions.push(on(x, 'click', () => {
                if (x.disabled) {
                    return;
                }
                this.onSelectItem(x);
            }, false));
        });
        const current = this.items.find((x) => x.value === this.value);
        if (current) {
            this.onSelectItem(current);
        }
    }
    /**
     * @protected
     */
    onSelectionModePropertyChanged(prev, next) {
        if (prev !== next) {
            if (next) {
                // request update children changed
                this.items.forEach((x) => x.requestUpdate());
            }
        }
    }
    /**
     * @protected
     */
    onDisabledPropertyChanged(_, next) {
        this.items.forEach((x) => x.disabled = next ?? false);
    }
    /**
     * @protected
     */
    onFilterPropertyChanged(_, next) {
        if (next) {
            this.items.forEach((x) => {
                const text = this.filterMemberPath
                    ? this.filterMemberPath
                        ? String(getMemberValue(x, this.filterMemberPath))
                        : ''
                    : x.displayText;
                const hasText = contains(text, next, true);
                x.hidden = !hasText;
            });
        }
        else {
            this.items.forEach((x) => {
                x.hidden = false;
            });
        }
    }
    /**
     * @private
     */
    onSelectItem(item) {
        // if (!item.isActive) {
        //     // unselect siblings
        //     this.items.forEach(y => y.isActive = false);
        //     item.isActive = true;
        //     this.value = String(item.value ?? item.label);
        //     this.select(item);
        //     this.requestUpdate();
        //     this.close();
        // }
    }
};
__decorate([
    Attribute({ type: SelectionMode }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ListElement.prototype, "selectionMode", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], ListElement.prototype, "value", null);
__decorate([
    Watch('selectionMode'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ListElement.prototype, "onSelectionModePropertyChanged", null);
__decorate([
    Watch('disabled'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Boolean, Boolean]),
    __metadata("design:returntype", void 0)
], ListElement.prototype, "onDisabledPropertyChanged", null);
__decorate([
    Watch('filter'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ListElement.prototype, "onFilterPropertyChanged", null);
ListElement = __decorate([
    Component({
        selector: 'mosaik-list',
        template: listElementTemplate,
        themes: {
            joy: listElementJoyStyle,
            retro: listElementRetroStyle,
            cosmopolitan: listElementCosmopolitanStyle
        },
        host: {
            tabIndex: '0',
            role: 'listbox'
        },
        imports: [
            ListItemElement,
            ListItemGroupElement,
            TextBoxElement,
            SpacerElement
        ]
    }),
    __metadata("design:paramtypes", [])
], ListElement);
export { ListElement };
//# sourceMappingURL=ListElement.js.map