// #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';
// #endregion
/**
 * List - A container for displaying a collection of related items in a vertical or horizontal layout. Lists are often used to present data, navigation options, or other grouped content.
 *
 * @element mosaik-list
 * @category Selector
 *
 * @slot - The default slot.
 * @slot filter - The filter slot.
 * @slot empty - The empty slot.
 *
 * @public
 */
let ListElement = class ListElement extends Themeable(Disableable(Filterable(SelectorElement))) {
    // #region Fields
    _itemsClickSubscriptions;
    _selectionMode;
    _value;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._selectionMode = SelectionMode.Single;
        this._value = null;
        this._itemsClickSubscriptions = new Array();
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `{@link is}` property.
     * The `{@link is}` property represents natural name of this element.
     *
     * @public
     * @static
     * @override
     * @readonly
     */
    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);
    }
    // #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);
        }
    }
    onSelectionModePropertyChanged(prev, next) {
        if (prev !== next) {
            if (next) {
                // request update children changed
                this.items.forEach((x) => x.requestUpdate());
            }
        }
    }
    onDisabledPropertyChanged(_, next) {
        this.items.forEach((x) => x.disabled = next ?? false);
    }
    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
        ]
    }),
    __metadata("design:paramtypes", [])
], ListElement);
export { ListElement };
//# sourceMappingURL=ListElement.js.map