// #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 { Property } from '../../../../Decorators/PropertyDecorator';
import { CustomElement } from '../../../Abstracts/CustomElement';
// #endregion
/**
 * Items - An abstract foundation for components that display and manage collections of data items.
 *
 * @description
 * The ItemsElement serves as the base class for components that work with arrays of data objects,
 * providing a reactive source property and change detection mechanisms. This element is designed
 * to be extended by concrete implementations like lists, grids, carousels, data tables, or any
 * component that needs to render and manage collections of items. It handles source data updates,
 * provides lifecycle hooks for reacting to data changes, and establishes a consistent pattern
 * for item-based components throughout the design system. The generic type parameter allows
 * type-safe item handling for different data structures.
 *
 * @name Items
 * @category Selectors
 *
 * @fires changed {PropertyChangedEvent} - Fired when any property changes
 * @fires connected {ConnectedEvent} - Fired when the element is connected to the DOM
 *
 * @example
 * Extending for a custom list component:
 * ```typescript
 * interface IUser {
 *   id: string;
 *   name: string;
 *   email: string;
 * }
 *
 * class UserListElement extends ItemsElement<IUser> {
 *   protected override onSourceChanged(prev: Array<IUser>, next: Array<IUser>): void {
 *     super.onSourceChanged(prev, next);
 *     this.renderUsers(next);
 *   }
 * }
 * ```
 *
 * @example
 * Setting and updating the source data:
 * ```typescript
 * const list = new MyItemsElement<Product>();
 * list.source = [
 *   { id: '1', name: 'Product A', price: 29.99 },
 *   { id: '2', name: 'Product B', price: 39.99 }
 * ];
 * ```
 *
 * @example
 * Reacting to source changes:
 * ```typescript
 * class DataGridElement extends ItemsElement<DataRow> {
 *   protected override onSourceChanged(prev: Array<DataRow>, next: Array<DataRow>): void {
 *     super.onSourceChanged(prev, next);
 *     console.log(`Items changed from ${prev.length} to ${next.length}`);
 *     this.invalidateLayout();
 *   }
 * }
 * ```
 *
 * @example
 * Type-safe item access:
 * ```typescript
 * interface ITask {
 *   id: number;
 *   title: string;
 *   completed: boolean;
 * }
 *
 * const taskList = new TaskListElement<ITask>();
 * taskList.source = tasks;
 * const firstTask = taskList.source[0]; // Fully typed as ITask
 * ```
 *
 * @public
 * @abstract
 */
export class ItemsElement extends CustomElement {
    // #region Fields
    _source;
    // #endregion
    // #region Ctor
    /**
     * @protected
     */
    constructor() {
        super();
        this._source = [];
    }
    // #endregion
    // #region Properties
    /**
     * Gets or sets the `source` property.
     *
     * @public
     */
    get source() {
        return this._source;
    }
    set source(value) {
        this.onSourceChanged(this._source, value);
        this.requestUpdate('source');
    }
    // #endregion
    // #region Methods
    /**
     * This method is invoked when the `source` property is changed.
     *
     * @protected
     * @virtual
     * @param prev - The old value of the `source` property.
     * @param next - The new value of the `source` property.
     */
    onSourceChanged(prev, next) {
        this._source = next;
        this.requestUpdate('source');
    }
}
__decorate([
    Property({ type: Array }),
    __metadata("design:type", Array),
    __metadata("design:paramtypes", [Array])
], ItemsElement.prototype, "source", null);
//# sourceMappingURL=ItemsElement.js.map