// #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 { IntlController } from '../../../../Intl/IntlController';
import { Disableable } from '../../../Behaviors/Disableable';
import { Filterable, contains, getMemberValue } from '../../../Behaviors/Filterable';
import { Insetable } from '../../../Behaviors/Insetable';
import { Orientable } from '../../../Behaviors/Orientable';
import { Themeable } from '../../../Behaviors/Themeable';
import { addInheritanceProviderController } from '../../../Controllers/InheritanceProviderController';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Property } from '../../../Decorators/PropertyDecorator';
import { Watch } from '../../../Decorators/WatchDecorator';
import { Orientation } from '../../../Types/Orientation';
import { SelectionMode } from '../../../Types/SelectionMode';
import { TextBoxElement } from '../../Inputs/TextBox/TextBoxElement';
import { SpacerElement } from '../../Primitives/Spacer/SpacerElement';
import { SelectorElement } from '../Abstracts/Selector/SelectorElement';
import { ListElementIntl } from './ListElementIntl';
import { listElementTemplate } from './ListElementTemplate';
import { LIST_INHERITANCE_CONTEXT } from './ListInheritanceContext';
import { ListItemElement } from './ListItemElement';
import { ListItemGroupElement } from './ListItemGroupElement';
import { listElementCosmopolitanStyle } from './Themes/ListElement.Cosmopolitan';
import { listElementJoyStyle } from './Themes/ListElement.Joy';
import { listElementMemphisStyle } from './Themes/ListElement.Memphis';
// #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 empty - Empty state content when no items are available
 * @slot filter - Filter controls and search functionality area
 * @slot footer - Footer content below the list items
 * @slot header - Header content above the list items
 *
 * @csspart empty - Empty state container
 * @csspart filter - Filter controls container
 * @csspart items - Container for all list items
 *
 * @cssprop {String} --list-background-color - The background color CSS custom property.
 * @cssprop {String} --list-border-color - The border color CSS custom property.
 * @cssprop {String} --list-border-radius - Border radius for list styling
 * @cssprop {String} --list-border-style - The border style CSS custom property.
 * @cssprop {String} --list-border-width - The border width CSS custom property.
 * @cssprop {String} --list-font-family - The font family CSS custom property.
 * @cssprop {String} --list-font-letter-spacing - The font letter spacing CSS custom property.
 * @cssprop {String} --list-font-line-height - The font line height CSS custom property.
 * @cssprop {String} --list-font-size - The font size CSS custom property.
 * @cssprop {String} --list-font-text-decoration - The font text decoration CSS custom property.
 * @cssprop {String} --list-font-text-transform - The font text transform CSS custom property.
 * @cssprop {String} --list-font-weight - The font weight CSS custom property.
 * @cssprop {String} --list-foreground-color - The foreground color CSS custom property.
 * @cssprop {String} --list-gap - The gap CSS custom property.
 * @cssprop {String} --list-padding-bottom - The padding bottom CSS custom property.
 * @cssprop {String} --list-padding-left - The padding left CSS custom property.
 * @cssprop {String} --list-padding-right - The padding right CSS custom property.
 * @cssprop {String} --list-padding-top - The padding top CSS custom property.
 * @cssprop {String} --list-shadow - The shadow CSS custom property.
 * @cssprop {String} --list-shadow-blur - The shadow blur CSS custom property.
 * @cssprop {String} --list-shadow-color - The shadow color CSS custom property.
 * @cssprop {String} --list-shadow-offset-x - The shadow offset x CSS custom property.
 * @cssprop {String} --list-shadow-offset-y - The shadow offset y CSS custom property.
 * @cssprop {String} --list-shadow-spread - The shadow spread CSS custom property.
 * @cssprop {String} --list-transition-duration - The transition duration CSS custom property.
 * @cssprop {String} --list-transition-mode - The transition mode CSS custom property.
 * @cssprop {String} --list-transition-property - The transition property CSS custom property.
 * @cssprop {String} --list-translate - The translate CSS custom property.
 *
 * @dependency mosaik-spacer - The Spacer element.
 * @dependency mosaik-textbox - The Textbox element.
 *
 * @example
 * ```html
 * <!-- Simple navigation list -->
 * <mosaik-list>
 *   <mosaik-list-item value="dashboard">
 *     <mosaik-icon slot="prefix"></mosaik-icon>
 *     Dashboard
 *   </mosaik-list-item>
 *   <mosaik-list-item value="analytics">
 *     <mosaik-icon slot="prefix"></mosaik-icon>
 *     Analytics
 *   </mosaik-list-item>
 *   <mosaik-list-item value="settings">
 *     <mosaik-icon slot="prefix"></mosaik-icon>
 *     Settings
 *   </mosaik-list-item>
 * </mosaik-list>
 *
 * <!-- Multi-select list with filter -->
 * <mosaik-list selection-mode="multiple" show-filter>
 *   <mosaik-list-item-group header="Favorites">
 *     <mosaik-list-item value="john">
 *       John Smith
 *       <mosaik-text slot="suffix">john@example.com</mosaik-text>
 *     </mosaik-list-item>
 *   </mosaik-list-item-group>
 *   <mosaik-list-item-group header="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 suffix descriptions -->
 * <mosaik-list>
 *   <mosaik-list-item value="export">
 *     <mosaik-icon slot="prefix"></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"></mosaik-icon>
 *     Import Data
 *     <mosaik-text slot="suffix" variant="caption">Upload data from file</mosaik-text>
 *   </mosaik-list-item>
 * </mosaik-list>
 * ```
 *
 * @public
 *
 * @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
 */
let ListElement = class ListElement extends Themeable(Disableable(Filterable(Orientable(Insetable(SelectorElement))))) {
    // #region Fields
    _provider = addInheritanceProviderController(this, {
        context: LIST_INHERITANCE_CONTEXT,
        values: () => ({
            disabled: this.disabled
        })
    });
    _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()
        });
        // REMARK: This is a workaround for the issue with the docs generation.
        Object.assign(this, { orientation: Orientation.Vertical });
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     * The `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);
    }
    /**
     * Gets or sets the `intl` property.
     *
     * @public
     */
    get intl() {
        return this._intlController.intl;
    }
    set intl(value) {
        this._intlController.provide(value);
    }
    // #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
     */
    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) {
        //     // deselect 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([
    Property({ type: Object }),
    __metadata("design:type", ListElementIntl),
    __metadata("design:paramtypes", [ListElementIntl])
], ListElement.prototype, "intl", null);
__decorate([
    Watch('selectionMode'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ListElement.prototype, "onSelectionModePropertyChanged", 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,
            memphis: listElementMemphisStyle,
            cosmopolitan: listElementCosmopolitanStyle
        },
        options: {
            mode: 'open',
            delegatesFocus: true
        },
        host: {
            tabIndex: '0',
            role: 'listbox'
        },
        imports: [
            ListItemElement,
            ListItemGroupElement,
            TextBoxElement,
            SpacerElement
        ]
    }),
    __metadata("design:paramtypes", [])
], ListElement);
export { ListElement };
//# sourceMappingURL=ListElement.js.map