@acorex/components 20.2.0-next.16 → 20.2.0-next.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,386 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, EventEmitter, signal, computed, model, effect, ViewChild, Output, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import { FormsModule } from '@angular/forms';
6
+ import * as i2 from '@angular/cdk/scrolling';
7
+ import { ScrollingModule, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
8
+ import { MXValueComponent, AXListDataSource } from '@acorex/cdk/common';
9
+ import { AXTooltipDirective } from '@acorex/components/tooltip';
10
+ import { AXCheckBoxComponent } from '@acorex/components/check-box';
11
+
12
+ class AXDataListComponent extends MXValueComponent {
13
+ constructor() {
14
+ super();
15
+ // Inputs
16
+ this.dataSource = input.required(...(ngDevMode ? [{ debugName: "dataSource" }] : []));
17
+ this.config = input({}, ...(ngDevMode ? [{ debugName: "config" }] : []));
18
+ this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
19
+ this.showCheckbox = input(true, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
20
+ this.itemHeight = input(40, ...(ngDevMode ? [{ debugName: "itemHeight" }] : []));
21
+ this.isItemTruncated = input(true, ...(ngDevMode ? [{ debugName: "isItemTruncated" }] : []));
22
+ this.showItemTooltip = input(true, ...(ngDevMode ? [{ debugName: "showItemTooltip" }] : []));
23
+ this.disabledField = input('disabled', ...(ngDevMode ? [{ debugName: "disabledField" }] : []));
24
+ this.tooltipField = input('tooltip', ...(ngDevMode ? [{ debugName: "tooltipField" }] : []));
25
+ this.textField = input('text', ...(ngDevMode ? [{ debugName: "textField" }] : []));
26
+ this.descriptionField = input('description', ...(ngDevMode ? [{ debugName: "descriptionField" }] : []));
27
+ this.levelField = input('level', ...(ngDevMode ? [{ debugName: "levelField" }] : []));
28
+ this.childrenField = input('children', ...(ngDevMode ? [{ debugName: "childrenField" }] : []));
29
+ this.expandedField = input('expanded', ...(ngDevMode ? [{ debugName: "expandedField" }] : []));
30
+ // Templates
31
+ this.itemTemplate = input(...(ngDevMode ? [undefined, { debugName: "itemTemplate" }] : []));
32
+ this.emptyTemplate = input(...(ngDevMode ? [undefined, { debugName: "emptyTemplate" }] : []));
33
+ this.loadingTemplate = input(...(ngDevMode ? [undefined, { debugName: "loadingTemplate" }] : []));
34
+ // Outputs
35
+ this.selectionChange = new EventEmitter();
36
+ this.itemClick = new EventEmitter();
37
+ this.itemDoubleClick = new EventEmitter();
38
+ this.expandChange = new EventEmitter();
39
+ // Internal signals
40
+ this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
41
+ this.totalItems = signal(0, ...(ngDevMode ? [{ debugName: "totalItems" }] : []));
42
+ this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
43
+ this.selectedKeys = signal([], ...(ngDevMode ? [{ debugName: "selectedKeys" }] : []));
44
+ this.focusedIndex = signal(-1, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : []));
45
+ this.expandedItems = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedItems" }] : []));
46
+ // List data source for virtual scrolling
47
+ this.listDataSource = null;
48
+ // Computed values
49
+ this.hasItems = computed(() => {
50
+ const dataSourceItems = this.listDataSource?.source?.cachedItems?.length > 0;
51
+ return dataSourceItems;
52
+ }, ...(ngDevMode ? [{ debugName: "hasItems" }] : []));
53
+ this.isEmpty = computed(() => {
54
+ const notLoading = !this.loading();
55
+ const noDataSourceItems = !this.listDataSource?.source?.cachedItems?.length;
56
+ return notLoading && noDataSourceItems;
57
+ }, ...(ngDevMode ? [{ debugName: "isEmpty" }] : []));
58
+ this.isMultipleSelection = computed(() => this.multiple(), ...(ngDevMode ? [{ debugName: "isMultipleSelection" }] : []));
59
+ this.showCheckboxes = computed(() => this.showCheckbox(), ...(ngDevMode ? [{ debugName: "showCheckboxes" }] : []));
60
+ // Selection model
61
+ this.selectionModel = model(...(ngDevMode ? [undefined, { debugName: "selectionModel" }] : []));
62
+ // Track by function for virtual scrolling
63
+ this.trackByFn = (index, item) => {
64
+ if (!item) {
65
+ return `loading-${index}`;
66
+ }
67
+ return this.getItemKey(item);
68
+ };
69
+ // Effect to sync selection model with internal state
70
+ effect(() => {
71
+ const selection = this.selectionModel();
72
+ if (selection) {
73
+ if (Array.isArray(selection)) {
74
+ this.selectedKeys.set(selection);
75
+ }
76
+ else {
77
+ this.selectedKeys.set([selection]);
78
+ }
79
+ this.updateSelectedItems();
80
+ }
81
+ });
82
+ // Effect to emit selection changes
83
+ effect(() => {
84
+ const selectedItems = this.selectedItems();
85
+ const selectedKeys = this.selectedKeys();
86
+ const isMultiple = this.isMultipleSelection();
87
+ if (selectedItems.length > 0 || selectedKeys.length > 0) {
88
+ this.selectionChange.emit({
89
+ selectedItems,
90
+ selectedKeys,
91
+ isMultiple,
92
+ });
93
+ }
94
+ });
95
+ // Effect to watch for dataSource changes and create listDataSource
96
+ effect(() => {
97
+ const dataSource = this.dataSource();
98
+ if (dataSource) {
99
+ console.log('Data source changed, creating AXListDataSource...');
100
+ this.listDataSource = new AXListDataSource({
101
+ source: dataSource,
102
+ debounceTime: 100, // Add debounce to prevent too many page requests
103
+ });
104
+ console.log('Created AXListDataSource:', this.listDataSource);
105
+ // Set up subscriptions
106
+ this.setupDataSourceSubscription();
107
+ }
108
+ });
109
+ }
110
+ ngOnInit() {
111
+ super.ngOnInit();
112
+ // Data loading is now handled by the effect watching dataSource changes
113
+ }
114
+ setupDataSourceSubscription() {
115
+ if (!this.dataSource() || !this.listDataSource)
116
+ return;
117
+ console.log('Setting up data source subscription for:', this.dataSource());
118
+ // Subscribe to data source changes
119
+ this.dataSource().onChanged.subscribe((data) => {
120
+ console.log('Data source changed:', data);
121
+ if (data && data.cachedItems) {
122
+ this.totalItems.set(data.totalCount || data.cachedItems.length);
123
+ }
124
+ });
125
+ this.dataSource().onLoadingChanged.subscribe((loading) => {
126
+ console.log('Loading changed:', loading);
127
+ this.loading.set(loading);
128
+ });
129
+ // Load initial data - just trigger the first page load
130
+ // The AXListDataSource will handle subsequent pages automatically
131
+ this.dataSource().setPage(0);
132
+ }
133
+ // Selection management
134
+ selectItem(item, event) {
135
+ if (event && typeof event.stopPropagation === 'function') {
136
+ event.stopPropagation();
137
+ }
138
+ if (this.isItemDisabled(item))
139
+ return;
140
+ if (this.isMultipleSelection()) {
141
+ this.toggleMultipleSelection(item);
142
+ }
143
+ else {
144
+ this.setSingleSelection(item);
145
+ }
146
+ }
147
+ toggleMultipleSelection(item) {
148
+ const currentKeys = this.selectedKeys();
149
+ const itemKey = this.getItemKey(item);
150
+ if (currentKeys.includes(itemKey)) {
151
+ this.selectedKeys.set(currentKeys.filter(key => key !== itemKey));
152
+ }
153
+ else {
154
+ this.selectedKeys.set([...currentKeys, itemKey]);
155
+ }
156
+ this.updateSelectedItems();
157
+ }
158
+ setSingleSelection(item) {
159
+ const itemKey = this.getItemKey(item);
160
+ this.selectedKeys.set([itemKey]);
161
+ this.updateSelectedItems();
162
+ }
163
+ deselectItem(item) {
164
+ const currentKeys = this.selectedKeys();
165
+ const itemKey = this.getItemKey(item);
166
+ const newKeys = currentKeys.filter(key => key !== itemKey);
167
+ this.selectedKeys.set(newKeys);
168
+ this.updateSelectedItems();
169
+ }
170
+ updateSelectedItems() {
171
+ const keys = this.selectedKeys();
172
+ const dataSource = this.listDataSource?.source;
173
+ if (!dataSource)
174
+ return;
175
+ const selected = dataSource.cachedItems.filter(item => keys.includes(this.getItemKey(item)));
176
+ this.selectedItems.set(selected);
177
+ // Update selection model
178
+ if (this.isMultipleSelection()) {
179
+ this.selectionModel.set(keys);
180
+ }
181
+ else {
182
+ this.selectionModel.set(keys[0] || '');
183
+ }
184
+ }
185
+ isItemSelected(item) {
186
+ return this.selectedKeys().includes(this.getItemKey(item));
187
+ }
188
+ isItemDisabled(item) {
189
+ const disabledField = this.disabledField();
190
+ if (!disabledField)
191
+ return false;
192
+ const disabled = item[disabledField];
193
+ return Boolean(disabled);
194
+ }
195
+ getItemKey(item) {
196
+ if (item.id !== undefined && item.id !== null) {
197
+ return String(item.id);
198
+ }
199
+ // Fallback to other potential key fields
200
+ if (item['key'] !== undefined && item['key'] !== null) {
201
+ return String(item['key']);
202
+ }
203
+ if (item['value'] !== undefined && item['value'] !== null) {
204
+ return String(item['value']);
205
+ }
206
+ // Last resort: use the item itself as a string
207
+ return String(item);
208
+ }
209
+ // Tree grouping
210
+ toggleExpanded(item, event) {
211
+ if (event && typeof event.stopPropagation === 'function') {
212
+ event.stopPropagation();
213
+ }
214
+ if (!this.hasChildren(item))
215
+ return;
216
+ const currentExpanded = this.expandedItems();
217
+ const itemKey = this.getItemKey(item);
218
+ if (currentExpanded.has(itemKey)) {
219
+ currentExpanded.delete(itemKey);
220
+ }
221
+ else {
222
+ currentExpanded.add(itemKey);
223
+ }
224
+ this.expandedItems.set(new Set(currentExpanded));
225
+ this.expandChange.emit({ item, expanded: currentExpanded.has(itemKey) });
226
+ }
227
+ hasChildren(item) {
228
+ const childrenField = this.childrenField();
229
+ if (!childrenField)
230
+ return false;
231
+ const children = item[childrenField];
232
+ return Array.isArray(children) && children.length > 0;
233
+ }
234
+ isExpanded(item) {
235
+ const expandedField = this.expandedField();
236
+ if (expandedField) {
237
+ const expanded = item[expandedField];
238
+ if (expanded !== undefined && expanded !== null) {
239
+ return Boolean(expanded);
240
+ }
241
+ }
242
+ return this.expandedItems().has(this.getItemKey(item));
243
+ }
244
+ getItemLevel(item) {
245
+ const levelField = this.levelField();
246
+ if (!levelField)
247
+ return 0;
248
+ const level = item[levelField];
249
+ return level !== undefined && level !== null ? Number(level) : 0;
250
+ }
251
+ // Keyboard navigation
252
+ onKeyDown(event, item, index) {
253
+ switch (event.key) {
254
+ case 'ArrowDown':
255
+ event.preventDefault();
256
+ this.focusNextItem(index);
257
+ break;
258
+ case 'ArrowUp':
259
+ event.preventDefault();
260
+ this.focusPreviousItem(index);
261
+ break;
262
+ case 'Enter':
263
+ case ' ':
264
+ event.preventDefault();
265
+ this.selectItem(item);
266
+ break;
267
+ case 'Escape':
268
+ this.focusedIndex.set(-1);
269
+ break;
270
+ }
271
+ }
272
+ focusNextItem(currentIndex) {
273
+ const dataSource = this.listDataSource?.source;
274
+ if (!dataSource || dataSource.cachedItems.length === 0)
275
+ return;
276
+ const nextIndex = Math.min(currentIndex + 1, dataSource.cachedItems.length - 1);
277
+ this.focusedIndex.set(nextIndex);
278
+ this.scrollToIndex(nextIndex);
279
+ }
280
+ focusPreviousItem(currentIndex) {
281
+ const dataSource = this.listDataSource?.source;
282
+ if (!dataSource || dataSource.cachedItems.length === 0)
283
+ return;
284
+ const prevIndex = Math.max(currentIndex - 1, 0);
285
+ this.focusedIndex.set(prevIndex);
286
+ this.scrollToIndex(prevIndex);
287
+ }
288
+ scrollToIndex(index) {
289
+ if (this.viewport && typeof index === 'number' && index >= 0) {
290
+ this.viewport.scrollToIndex(index);
291
+ }
292
+ }
293
+ // Item interaction
294
+ onItemClick(item, event) {
295
+ if (this.isItemDisabled(item))
296
+ return;
297
+ this.itemClick.emit(item);
298
+ this.selectItem(item, event);
299
+ }
300
+ onCheckboxChange(item, checked) {
301
+ if (this.isItemDisabled(item))
302
+ return;
303
+ if (checked) {
304
+ this.selectItem(item);
305
+ }
306
+ else {
307
+ this.deselectItem(item);
308
+ }
309
+ }
310
+ onCheckboxClick(event) {
311
+ if (typeof event.stopPropagation === 'function') {
312
+ event.stopPropagation();
313
+ }
314
+ }
315
+ onItemDoubleClick(item) {
316
+ if (this.isItemDisabled(item))
317
+ return;
318
+ this.itemDoubleClick.emit(item);
319
+ }
320
+ // Utility methods
321
+ getItemText(item) {
322
+ const textField = this.textField();
323
+ if (textField) {
324
+ const text = item[textField];
325
+ if (text !== undefined && text !== null) {
326
+ return String(text);
327
+ }
328
+ }
329
+ return item.text || '';
330
+ }
331
+ getItemDescription(item) {
332
+ const descriptionField = this.descriptionField();
333
+ if (descriptionField) {
334
+ const description = item[descriptionField];
335
+ if (description !== undefined && description !== null) {
336
+ return String(description);
337
+ }
338
+ }
339
+ return item.description || '';
340
+ }
341
+ getItemTooltip(item) {
342
+ const tooltipField = this.tooltipField();
343
+ if (tooltipField) {
344
+ const tooltip = item[tooltipField];
345
+ if (tooltip !== undefined && tooltip !== null) {
346
+ return String(tooltip);
347
+ }
348
+ }
349
+ return item.tooltip || '';
350
+ }
351
+ shouldShowTooltip(item) {
352
+ return this.showItemTooltip() && !!this.getItemTooltip(item);
353
+ }
354
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXDataListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
355
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXDataListComponent, isStandalone: true, selector: "ax-data-list", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, showCheckbox: { classPropertyName: "showCheckbox", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, isItemTruncated: { classPropertyName: "isItemTruncated", publicName: "isItemTruncated", isSignal: true, isRequired: false, transformFunction: null }, showItemTooltip: { classPropertyName: "showItemTooltip", publicName: "showItemTooltip", isSignal: true, isRequired: false, transformFunction: null }, disabledField: { classPropertyName: "disabledField", publicName: "disabledField", isSignal: true, isRequired: false, transformFunction: null }, tooltipField: { classPropertyName: "tooltipField", publicName: "tooltipField", isSignal: true, isRequired: false, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, descriptionField: { classPropertyName: "descriptionField", publicName: "descriptionField", isSignal: true, isRequired: false, transformFunction: null }, levelField: { classPropertyName: "levelField", publicName: "levelField", isSignal: true, isRequired: false, transformFunction: null }, childrenField: { classPropertyName: "childrenField", publicName: "childrenField", isSignal: true, isRequired: false, transformFunction: null }, expandedField: { classPropertyName: "expandedField", publicName: "expandedField", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null }, emptyTemplate: { classPropertyName: "emptyTemplate", publicName: "emptyTemplate", isSignal: true, isRequired: false, transformFunction: null }, loadingTemplate: { classPropertyName: "loadingTemplate", publicName: "loadingTemplate", isSignal: true, isRequired: false, transformFunction: null }, selectionModel: { classPropertyName: "selectionModel", publicName: "selectionModel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", itemClick: "itemClick", itemDoubleClick: "itemDoubleClick", expandChange: "expandChange", selectionModel: "selectionModelChange" }, viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-data-list\" [class.ax-data-list--loading]=\"loading()\">\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"ax-data-list__loading\">\n <ng-container *ngTemplateOutlet=\"loadingTemplate() || defaultLoadingTemplate\"></ng-container>\n </div>\n }\n\n <!-- Empty State -->\n @if (isEmpty()) {\n <div class=\"ax-data-list__empty\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate() || defaultEmptyTemplate\"></ng-container>\n </div>\n }\n\n <!-- List Content -->\n @if (hasItems() && listDataSource !== null) {\n <div class=\"ax-data-list__content\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"itemHeight()\"\n class=\"ax-data-list__viewport\"\n [class.ax-data-list__viewport--truncated]=\"isItemTruncated()\"\n >\n <ng-container *cdkVirtualFor=\"let item of listDataSource; let i = index; trackBy: trackByFn\">\n @if (item) {\n <div\n class=\"ax-data-list__item\"\n [class.ax-data-list__item--selected]=\"isItemSelected(item)\"\n [class.ax-data-list__item--disabled]=\"isItemDisabled(item)\"\n [class.ax-data-list__item--focused]=\"focusedIndex() === i\"\n [class]=\"'ax-data-list__item--level-' + getItemLevel(item)\"\n [style.height.px]=\"itemHeight()\"\n (click)=\"onItemClick(item, $event)\"\n (dblclick)=\"onItemDoubleClick(item)\"\n (keydown)=\"onKeyDown($event, item, i)\"\n tabindex=\"0\"\n role=\"listitem\"\n [attr.aria-selected]=\"isItemSelected(item)\"\n [attr.aria-disabled]=\"isItemDisabled(item)\"\n [attr.aria-level]=\"getItemLevel(item) + 1\"\n >\n <!-- Checkbox -->\n @if (showCheckboxes()) {\n <div class=\"ax-data-list__checkbox\" (click)=\"onCheckboxClick($event)\">\n <ax-check-box\n [value]=\"isItemSelected(item)\"\n [disabled]=\"isItemDisabled(item)\"\n (valueChange)=\"onCheckboxChange(item, $event)\"\n >\n </ax-check-box>\n </div>\n }\n\n <!-- Expand/Collapse Button for Tree Items -->\n @if (hasChildren(item)) {\n <div\n class=\"ax-data-list__expand-button\"\n [class.ax-data-list__expand-button--expanded]=\"isExpanded(item)\"\n (click)=\"toggleExpanded(item, $event)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"isExpanded(item)\"\n >\n <svg class=\"ax-data-list__expand-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M7 10l5 5 5-5z\" />\n </svg>\n </div>\n }\n\n <!-- Item Content -->\n <div class=\"ax-data-list__content-wrapper\">\n <!-- Custom Item Template -->\n @if (itemTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate();\n context: {\n $implicit: item,\n index: i,\n selected: isItemSelected(item),\n disabled: isItemDisabled(item),\n }\n \"\n ></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"defaultItemTemplate\"></ng-container>\n }\n\n <!-- Default Item Template -->\n <ng-template #defaultItemTemplate>\n <div\n class=\"ax-data-list__text\"\n [class.ax-data-list__text--truncated]=\"isItemTruncated()\"\n [axTooltip]=\"shouldShowTooltip(item) ? getItemTooltip(item) : null\"\n [axTooltipDisabled]=\"!shouldShowTooltip(item)\"\n >\n {{ getItemText(item) }}\n </div>\n\n @if (getItemDescription(item)) {\n <div\n class=\"ax-data-list__description\"\n [class.ax-data-list__description--truncated]=\"isItemTruncated()\"\n >\n {{ getItemDescription(item) }}\n </div>\n }\n </ng-template>\n </div>\n </div>\n } @else {\n <!-- Loading skeleton for null items -->\n <div class=\"ax-data-list__item ax-data-list__item--loading\" [style.height.px]=\"itemHeight()\">\n <div class=\"ax-data-list__loading-skeleton\">\n <div class=\"ax-data-list__skeleton-checkbox\"></div>\n <div class=\"ax-data-list__skeleton-content\">\n <div class=\"ax-data-list__skeleton-text\"></div>\n <div class=\"ax-data-list__skeleton-description\"></div>\n </div>\n </div>\n </div>\n }\n </ng-container>\n </cdk-virtual-scroll-viewport>\n </div>\n }\n</div>\n\n<!-- Default Loading Template -->\n<ng-template #defaultLoadingTemplate>\n <div class=\"ax-data-list__loading-default\">\n <div class=\"ax-data-list__loading-spinner\"></div>\n <span>Loading...</span>\n </div>\n</ng-template>\n\n<!-- Default Empty Template -->\n<ng-template #defaultEmptyTemplate>\n <div class=\"ax-data-list__empty-default\">\n <svg class=\"ax-data-list__empty-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z\"\n />\n </svg>\n <span>No items to display</span>\n </div>\n</ng-template>\n", styles: [".ax-data-list{display:flex;flex-direction:column;width:100%;height:100%;background:var(--ax-color-background, #ffffff);border:1px solid var(--ax-color-border, #e5e7eb);border-radius:var(--ax-border-radius, .375rem);overflow:hidden}.ax-data-list--loading .ax-data-list__content{opacity:.6;pointer-events:none}.ax-data-list__loading{display:flex;align-items:center;justify-content:center;padding:2rem;min-height:200px}.ax-data-list__loading-default{display:flex;flex-direction:column;align-items:center;gap:1rem;color:var(--ax-color-text-secondary, #6b7280)}.ax-data-list__loading-spinner{width:2rem;height:2rem;border:2px solid var(--ax-color-border, #e5e7eb);border-top:2px solid var(--ax-color-primary, #3b82f6);border-radius:50%;animation:spin 1s linear infinite}.ax-data-list__empty{display:flex;align-items:center;justify-content:center;padding:2rem;min-height:200px}.ax-data-list__empty-default{display:flex;flex-direction:column;align-items:center;gap:1rem;color:var(--ax-color-text-secondary, #6b7280);text-align:center}.ax-data-list__empty-icon{width:3rem;height:3rem;opacity:.5}.ax-data-list__content{flex:1;overflow:hidden}.ax-data-list__viewport{height:100%;width:100%}.ax-data-list__viewport--truncated .ax-data-list__text,.ax-data-list__viewport--truncated .ax-data-list__description{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ax-data-list__item{display:flex;align-items:center;padding:.5rem 1rem;cursor:pointer;transition:all .15s ease-in-out;border-bottom:1px solid var(--ax-color-border-light, #f3f4f6);position:relative}.ax-data-list__item:hover:not(.ax-data-list__item--disabled){background-color:var(--ax-color-hover, #f9fafb)}.ax-data-list__item:focus{outline:2px solid var(--ax-color-primary, #3b82f6);outline-offset:-2px}.ax-data-list__item--selected{background-color:var(--ax-color-primary-light, #dbeafe);color:var(--ax-color-primary, #3b82f6);border-color:var(--ax-color-primary, #3b82f6)}.ax-data-list__item--selected:hover{background-color:var(--ax-color-primary-light-hover, #bfdbfe)}.ax-data-list__item--disabled{cursor:not-allowed;opacity:.6;background-color:var(--ax-color-disabled, #f9fafb);color:var(--ax-color-text-disabled, #9ca3af)}.ax-data-list__item--disabled:hover{background-color:var(--ax-color-disabled, #f9fafb)}.ax-data-list__item--focused{background-color:var(--ax-color-focus, #eff6ff);outline:2px solid var(--ax-color-primary, #3b82f6);outline-offset:-2px}.ax-data-list__item--loading{cursor:default;pointer-events:none;background-color:var(--ax-color-background, #ffffff)}.ax-data-list__item--loading:hover{background-color:var(--ax-color-background, #ffffff)}.ax-data-list__item--level-0{padding-left:1rem}.ax-data-list__item--level-1{padding-left:2.5rem}.ax-data-list__item--level-2{padding-left:4rem}.ax-data-list__item--level-3{padding-left:5.5rem}.ax-data-list__item--level-4{padding-left:7rem}.ax-data-list__item--level-5{padding-left:8.5rem}.ax-data-list__checkbox{margin-right:.75rem;flex-shrink:0}.ax-data-list__expand-button{display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin-right:.5rem;cursor:pointer;border-radius:.25rem;transition:all .15s ease-in-out;flex-shrink:0}.ax-data-list__expand-button:hover{background-color:var(--ax-color-hover, #f3f4f6)}.ax-data-list__expand-button:focus{outline:2px solid var(--ax-color-primary, #3b82f6);outline-offset:2px}.ax-data-list__expand-button--expanded .ax-data-list__expand-icon{transform:rotate(90deg)}.ax-data-list__expand-icon{width:1rem;height:1rem;transition:transform .15s ease-in-out;color:var(--ax-color-text-secondary, #6b7280)}.ax-data-list__content-wrapper{flex:1;min-width:0;display:flex;flex-direction:column;gap:.25rem}.ax-data-list__text{font-weight:500;color:var(--ax-color-text, #111827);line-height:1.25}.ax-data-list__text--truncated{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ax-data-list__description{font-size:.875rem;color:var(--ax-color-text-secondary, #6b7280);line-height:1.25}.ax-data-list__description--truncated{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (max-width: 768px){.ax-data-list__item{padding:.75rem 1rem}.ax-data-list__item--level-1{padding-left:2rem}.ax-data-list__item--level-2{padding-left:3rem}.ax-data-list__item--level-3{padding-left:4rem}.ax-data-list__item--level-4{padding-left:5rem}.ax-data-list__item--level-5{padding-left:6rem}.ax-data-list__checkbox{margin-right:.5rem}.ax-data-list__expand-button{margin-right:.25rem}}@media (prefers-contrast: high){.ax-data-list{border-width:2px}.ax-data-list__item{border-bottom-width:2px}.ax-data-list__item:focus{outline-width:3px}.ax-data-list__item--selected{border-width:2px}.ax-data-list__expand-button:focus{outline-width:3px}}@media (prefers-reduced-motion: reduce){.ax-data-list__item,.ax-data-list__expand-icon{transition:none}.ax-data-list__loading-spinner{animation:none}}.ax-data-list__loading-skeleton{display:flex;align-items:center;width:100%;gap:.75rem}.ax-data-list__skeleton-checkbox{width:1rem;height:1rem;background:linear-gradient(90deg,#f3f4f6 25%,#e5e7eb,#f3f4f6 75%);background-size:200% 100%;border-radius:.25rem;animation:shimmer 1.5s infinite;flex-shrink:0}.ax-data-list__skeleton-content{flex:1;display:flex;flex-direction:column;gap:.5rem}.ax-data-list__skeleton-text{height:1rem;background:linear-gradient(90deg,#f3f4f6 25%,#e5e7eb,#f3f4f6 75%);background-size:200% 100%;border-radius:.25rem;animation:shimmer 1.5s infinite;width:80%}.ax-data-list__skeleton-description{height:.75rem;background:linear-gradient(90deg,#f3f4f6 25%,#e5e7eb,#f3f4f6 75%);background-size:200% 100%;border-radius:.25rem;animation:shimmer 1.5s infinite;width:60%}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "component", type: AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
356
+ }
357
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXDataListComponent, decorators: [{
358
+ type: Component,
359
+ args: [{ selector: 'ax-data-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, imports: [
360
+ CommonModule,
361
+ FormsModule,
362
+ ScrollingModule,
363
+ AXTooltipDirective,
364
+ AXCheckBoxComponent,
365
+ ], template: "<div class=\"ax-data-list\" [class.ax-data-list--loading]=\"loading()\">\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"ax-data-list__loading\">\n <ng-container *ngTemplateOutlet=\"loadingTemplate() || defaultLoadingTemplate\"></ng-container>\n </div>\n }\n\n <!-- Empty State -->\n @if (isEmpty()) {\n <div class=\"ax-data-list__empty\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate() || defaultEmptyTemplate\"></ng-container>\n </div>\n }\n\n <!-- List Content -->\n @if (hasItems() && listDataSource !== null) {\n <div class=\"ax-data-list__content\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"itemHeight()\"\n class=\"ax-data-list__viewport\"\n [class.ax-data-list__viewport--truncated]=\"isItemTruncated()\"\n >\n <ng-container *cdkVirtualFor=\"let item of listDataSource; let i = index; trackBy: trackByFn\">\n @if (item) {\n <div\n class=\"ax-data-list__item\"\n [class.ax-data-list__item--selected]=\"isItemSelected(item)\"\n [class.ax-data-list__item--disabled]=\"isItemDisabled(item)\"\n [class.ax-data-list__item--focused]=\"focusedIndex() === i\"\n [class]=\"'ax-data-list__item--level-' + getItemLevel(item)\"\n [style.height.px]=\"itemHeight()\"\n (click)=\"onItemClick(item, $event)\"\n (dblclick)=\"onItemDoubleClick(item)\"\n (keydown)=\"onKeyDown($event, item, i)\"\n tabindex=\"0\"\n role=\"listitem\"\n [attr.aria-selected]=\"isItemSelected(item)\"\n [attr.aria-disabled]=\"isItemDisabled(item)\"\n [attr.aria-level]=\"getItemLevel(item) + 1\"\n >\n <!-- Checkbox -->\n @if (showCheckboxes()) {\n <div class=\"ax-data-list__checkbox\" (click)=\"onCheckboxClick($event)\">\n <ax-check-box\n [value]=\"isItemSelected(item)\"\n [disabled]=\"isItemDisabled(item)\"\n (valueChange)=\"onCheckboxChange(item, $event)\"\n >\n </ax-check-box>\n </div>\n }\n\n <!-- Expand/Collapse Button for Tree Items -->\n @if (hasChildren(item)) {\n <div\n class=\"ax-data-list__expand-button\"\n [class.ax-data-list__expand-button--expanded]=\"isExpanded(item)\"\n (click)=\"toggleExpanded(item, $event)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"isExpanded(item)\"\n >\n <svg class=\"ax-data-list__expand-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M7 10l5 5 5-5z\" />\n </svg>\n </div>\n }\n\n <!-- Item Content -->\n <div class=\"ax-data-list__content-wrapper\">\n <!-- Custom Item Template -->\n @if (itemTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate();\n context: {\n $implicit: item,\n index: i,\n selected: isItemSelected(item),\n disabled: isItemDisabled(item),\n }\n \"\n ></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"defaultItemTemplate\"></ng-container>\n }\n\n <!-- Default Item Template -->\n <ng-template #defaultItemTemplate>\n <div\n class=\"ax-data-list__text\"\n [class.ax-data-list__text--truncated]=\"isItemTruncated()\"\n [axTooltip]=\"shouldShowTooltip(item) ? getItemTooltip(item) : null\"\n [axTooltipDisabled]=\"!shouldShowTooltip(item)\"\n >\n {{ getItemText(item) }}\n </div>\n\n @if (getItemDescription(item)) {\n <div\n class=\"ax-data-list__description\"\n [class.ax-data-list__description--truncated]=\"isItemTruncated()\"\n >\n {{ getItemDescription(item) }}\n </div>\n }\n </ng-template>\n </div>\n </div>\n } @else {\n <!-- Loading skeleton for null items -->\n <div class=\"ax-data-list__item ax-data-list__item--loading\" [style.height.px]=\"itemHeight()\">\n <div class=\"ax-data-list__loading-skeleton\">\n <div class=\"ax-data-list__skeleton-checkbox\"></div>\n <div class=\"ax-data-list__skeleton-content\">\n <div class=\"ax-data-list__skeleton-text\"></div>\n <div class=\"ax-data-list__skeleton-description\"></div>\n </div>\n </div>\n </div>\n }\n </ng-container>\n </cdk-virtual-scroll-viewport>\n </div>\n }\n</div>\n\n<!-- Default Loading Template -->\n<ng-template #defaultLoadingTemplate>\n <div class=\"ax-data-list__loading-default\">\n <div class=\"ax-data-list__loading-spinner\"></div>\n <span>Loading...</span>\n </div>\n</ng-template>\n\n<!-- Default Empty Template -->\n<ng-template #defaultEmptyTemplate>\n <div class=\"ax-data-list__empty-default\">\n <svg class=\"ax-data-list__empty-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z\"\n />\n </svg>\n <span>No items to display</span>\n </div>\n</ng-template>\n", styles: [".ax-data-list{display:flex;flex-direction:column;width:100%;height:100%;background:var(--ax-color-background, #ffffff);border:1px solid var(--ax-color-border, #e5e7eb);border-radius:var(--ax-border-radius, .375rem);overflow:hidden}.ax-data-list--loading .ax-data-list__content{opacity:.6;pointer-events:none}.ax-data-list__loading{display:flex;align-items:center;justify-content:center;padding:2rem;min-height:200px}.ax-data-list__loading-default{display:flex;flex-direction:column;align-items:center;gap:1rem;color:var(--ax-color-text-secondary, #6b7280)}.ax-data-list__loading-spinner{width:2rem;height:2rem;border:2px solid var(--ax-color-border, #e5e7eb);border-top:2px solid var(--ax-color-primary, #3b82f6);border-radius:50%;animation:spin 1s linear infinite}.ax-data-list__empty{display:flex;align-items:center;justify-content:center;padding:2rem;min-height:200px}.ax-data-list__empty-default{display:flex;flex-direction:column;align-items:center;gap:1rem;color:var(--ax-color-text-secondary, #6b7280);text-align:center}.ax-data-list__empty-icon{width:3rem;height:3rem;opacity:.5}.ax-data-list__content{flex:1;overflow:hidden}.ax-data-list__viewport{height:100%;width:100%}.ax-data-list__viewport--truncated .ax-data-list__text,.ax-data-list__viewport--truncated .ax-data-list__description{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ax-data-list__item{display:flex;align-items:center;padding:.5rem 1rem;cursor:pointer;transition:all .15s ease-in-out;border-bottom:1px solid var(--ax-color-border-light, #f3f4f6);position:relative}.ax-data-list__item:hover:not(.ax-data-list__item--disabled){background-color:var(--ax-color-hover, #f9fafb)}.ax-data-list__item:focus{outline:2px solid var(--ax-color-primary, #3b82f6);outline-offset:-2px}.ax-data-list__item--selected{background-color:var(--ax-color-primary-light, #dbeafe);color:var(--ax-color-primary, #3b82f6);border-color:var(--ax-color-primary, #3b82f6)}.ax-data-list__item--selected:hover{background-color:var(--ax-color-primary-light-hover, #bfdbfe)}.ax-data-list__item--disabled{cursor:not-allowed;opacity:.6;background-color:var(--ax-color-disabled, #f9fafb);color:var(--ax-color-text-disabled, #9ca3af)}.ax-data-list__item--disabled:hover{background-color:var(--ax-color-disabled, #f9fafb)}.ax-data-list__item--focused{background-color:var(--ax-color-focus, #eff6ff);outline:2px solid var(--ax-color-primary, #3b82f6);outline-offset:-2px}.ax-data-list__item--loading{cursor:default;pointer-events:none;background-color:var(--ax-color-background, #ffffff)}.ax-data-list__item--loading:hover{background-color:var(--ax-color-background, #ffffff)}.ax-data-list__item--level-0{padding-left:1rem}.ax-data-list__item--level-1{padding-left:2.5rem}.ax-data-list__item--level-2{padding-left:4rem}.ax-data-list__item--level-3{padding-left:5.5rem}.ax-data-list__item--level-4{padding-left:7rem}.ax-data-list__item--level-5{padding-left:8.5rem}.ax-data-list__checkbox{margin-right:.75rem;flex-shrink:0}.ax-data-list__expand-button{display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin-right:.5rem;cursor:pointer;border-radius:.25rem;transition:all .15s ease-in-out;flex-shrink:0}.ax-data-list__expand-button:hover{background-color:var(--ax-color-hover, #f3f4f6)}.ax-data-list__expand-button:focus{outline:2px solid var(--ax-color-primary, #3b82f6);outline-offset:2px}.ax-data-list__expand-button--expanded .ax-data-list__expand-icon{transform:rotate(90deg)}.ax-data-list__expand-icon{width:1rem;height:1rem;transition:transform .15s ease-in-out;color:var(--ax-color-text-secondary, #6b7280)}.ax-data-list__content-wrapper{flex:1;min-width:0;display:flex;flex-direction:column;gap:.25rem}.ax-data-list__text{font-weight:500;color:var(--ax-color-text, #111827);line-height:1.25}.ax-data-list__text--truncated{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ax-data-list__description{font-size:.875rem;color:var(--ax-color-text-secondary, #6b7280);line-height:1.25}.ax-data-list__description--truncated{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (max-width: 768px){.ax-data-list__item{padding:.75rem 1rem}.ax-data-list__item--level-1{padding-left:2rem}.ax-data-list__item--level-2{padding-left:3rem}.ax-data-list__item--level-3{padding-left:4rem}.ax-data-list__item--level-4{padding-left:5rem}.ax-data-list__item--level-5{padding-left:6rem}.ax-data-list__checkbox{margin-right:.5rem}.ax-data-list__expand-button{margin-right:.25rem}}@media (prefers-contrast: high){.ax-data-list{border-width:2px}.ax-data-list__item{border-bottom-width:2px}.ax-data-list__item:focus{outline-width:3px}.ax-data-list__item--selected{border-width:2px}.ax-data-list__expand-button:focus{outline-width:3px}}@media (prefers-reduced-motion: reduce){.ax-data-list__item,.ax-data-list__expand-icon{transition:none}.ax-data-list__loading-spinner{animation:none}}.ax-data-list__loading-skeleton{display:flex;align-items:center;width:100%;gap:.75rem}.ax-data-list__skeleton-checkbox{width:1rem;height:1rem;background:linear-gradient(90deg,#f3f4f6 25%,#e5e7eb,#f3f4f6 75%);background-size:200% 100%;border-radius:.25rem;animation:shimmer 1.5s infinite;flex-shrink:0}.ax-data-list__skeleton-content{flex:1;display:flex;flex-direction:column;gap:.5rem}.ax-data-list__skeleton-text{height:1rem;background:linear-gradient(90deg,#f3f4f6 25%,#e5e7eb,#f3f4f6 75%);background-size:200% 100%;border-radius:.25rem;animation:shimmer 1.5s infinite;width:80%}.ax-data-list__skeleton-description{height:.75rem;background:linear-gradient(90deg,#f3f4f6 25%,#e5e7eb,#f3f4f6 75%);background-size:200% 100%;border-radius:.25rem;animation:shimmer 1.5s infinite;width:60%}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}\n"] }]
366
+ }], ctorParameters: () => [], propDecorators: { selectionChange: [{
367
+ type: Output
368
+ }], itemClick: [{
369
+ type: Output
370
+ }], itemDoubleClick: [{
371
+ type: Output
372
+ }], expandChange: [{
373
+ type: Output
374
+ }], viewport: [{
375
+ type: ViewChild,
376
+ args: [CdkVirtualScrollViewport]
377
+ }] } });
378
+
379
+ // Secondary entry point for @acorex/components/data-list
380
+
381
+ /**
382
+ * Generated bundle index. Do not edit.
383
+ */
384
+
385
+ export { AXDataListComponent };
386
+ //# sourceMappingURL=acorex-components-data-list.mjs.map