mtrl-addons 0.2.2 → 0.2.3

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.
Files changed (128) hide show
  1. package/{src/components/index.ts → dist/components/index.d.ts} +0 -2
  2. package/dist/components/vlist/config.d.ts +86 -0
  3. package/{src/components/vlist/constants.ts → dist/components/vlist/constants.d.ts} +10 -11
  4. package/dist/components/vlist/features/api.d.ts +7 -0
  5. package/{src/components/vlist/features/index.ts → dist/components/vlist/features/index.d.ts} +0 -2
  6. package/dist/components/vlist/features/selection.d.ts +6 -0
  7. package/dist/components/vlist/features/viewport.d.ts +9 -0
  8. package/dist/components/vlist/features.d.ts +31 -0
  9. package/{src/components/vlist/index.ts → dist/components/vlist/index.d.ts} +1 -10
  10. package/dist/components/vlist/types.d.ts +596 -0
  11. package/dist/components/vlist/vlist.d.ts +29 -0
  12. package/dist/core/compose/features/gestures/index.d.ts +86 -0
  13. package/dist/core/compose/features/gestures/longpress.d.ts +85 -0
  14. package/dist/core/compose/features/gestures/pan.d.ts +108 -0
  15. package/dist/core/compose/features/gestures/pinch.d.ts +111 -0
  16. package/dist/core/compose/features/gestures/rotate.d.ts +111 -0
  17. package/dist/core/compose/features/gestures/swipe.d.ts +149 -0
  18. package/dist/core/compose/features/gestures/tap.d.ts +79 -0
  19. package/{src/core/compose/features/index.ts → dist/core/compose/features/index.d.ts} +1 -2
  20. package/{src/core/compose/index.ts → dist/core/compose/index.d.ts} +2 -11
  21. package/{src/core/gestures/index.ts → dist/core/gestures/index.d.ts} +1 -20
  22. package/dist/core/gestures/longpress.d.ts +23 -0
  23. package/dist/core/gestures/manager.d.ts +14 -0
  24. package/dist/core/gestures/pan.d.ts +12 -0
  25. package/dist/core/gestures/pinch.d.ts +14 -0
  26. package/dist/core/gestures/rotate.d.ts +14 -0
  27. package/dist/core/gestures/swipe.d.ts +20 -0
  28. package/dist/core/gestures/tap.d.ts +12 -0
  29. package/dist/core/gestures/types.d.ts +320 -0
  30. package/dist/core/gestures/utils.d.ts +57 -0
  31. package/dist/core/index.d.ts +13 -0
  32. package/dist/core/layout/config.d.ts +33 -0
  33. package/dist/core/layout/index.d.ts +51 -0
  34. package/dist/core/layout/jsx.d.ts +65 -0
  35. package/dist/core/layout/schema.d.ts +112 -0
  36. package/dist/core/layout/types.d.ts +69 -0
  37. package/dist/core/viewport/constants.d.ts +105 -0
  38. package/dist/core/viewport/features/base.d.ts +14 -0
  39. package/dist/core/viewport/features/collection.d.ts +41 -0
  40. package/dist/core/viewport/features/events.d.ts +13 -0
  41. package/{src/core/viewport/features/index.ts → dist/core/viewport/features/index.d.ts} +0 -7
  42. package/dist/core/viewport/features/item-size.d.ts +30 -0
  43. package/dist/core/viewport/features/loading.d.ts +34 -0
  44. package/dist/core/viewport/features/momentum.d.ts +17 -0
  45. package/dist/core/viewport/features/performance.d.ts +53 -0
  46. package/dist/core/viewport/features/placeholders.d.ts +38 -0
  47. package/dist/core/viewport/features/rendering.d.ts +16 -0
  48. package/dist/core/viewport/features/scrollbar.d.ts +26 -0
  49. package/dist/core/viewport/features/scrolling.d.ts +16 -0
  50. package/dist/core/viewport/features/utils.d.ts +43 -0
  51. package/dist/core/viewport/features/virtual.d.ts +18 -0
  52. package/{src/core/viewport/index.ts → dist/core/viewport/index.d.ts} +1 -17
  53. package/dist/core/viewport/types.d.ts +96 -0
  54. package/dist/core/viewport/utils/speed-tracker.d.ts +22 -0
  55. package/dist/core/viewport/viewport.d.ts +11 -0
  56. package/{src/index.ts → dist/index.d.ts} +0 -4
  57. package/dist/index.js +5143 -0
  58. package/dist/index.mjs +5111 -0
  59. package/dist/styles.css +254 -0
  60. package/dist/styles.css.map +1 -0
  61. package/package.json +5 -1
  62. package/.cursorrules +0 -117
  63. package/AI.md +0 -39
  64. package/CLAUDE.md +0 -882
  65. package/build.js +0 -377
  66. package/scripts/analyze-orphaned-functions.ts +0 -387
  67. package/scripts/debug/vlist-selection.ts +0 -121
  68. package/src/components/vlist/config.ts +0 -323
  69. package/src/components/vlist/features/api.ts +0 -626
  70. package/src/components/vlist/features/selection.ts +0 -436
  71. package/src/components/vlist/features/viewport.ts +0 -59
  72. package/src/components/vlist/features.ts +0 -112
  73. package/src/components/vlist/types.ts +0 -723
  74. package/src/components/vlist/vlist.ts +0 -92
  75. package/src/core/compose/features/gestures/index.ts +0 -227
  76. package/src/core/compose/features/gestures/longpress.ts +0 -383
  77. package/src/core/compose/features/gestures/pan.ts +0 -424
  78. package/src/core/compose/features/gestures/pinch.ts +0 -475
  79. package/src/core/compose/features/gestures/rotate.ts +0 -485
  80. package/src/core/compose/features/gestures/swipe.ts +0 -492
  81. package/src/core/compose/features/gestures/tap.ts +0 -334
  82. package/src/core/gestures/longpress.ts +0 -68
  83. package/src/core/gestures/manager.ts +0 -418
  84. package/src/core/gestures/pan.ts +0 -48
  85. package/src/core/gestures/pinch.ts +0 -58
  86. package/src/core/gestures/rotate.ts +0 -58
  87. package/src/core/gestures/swipe.ts +0 -66
  88. package/src/core/gestures/tap.ts +0 -45
  89. package/src/core/gestures/types.ts +0 -387
  90. package/src/core/gestures/utils.ts +0 -128
  91. package/src/core/index.ts +0 -43
  92. package/src/core/layout/config.ts +0 -102
  93. package/src/core/layout/index.ts +0 -168
  94. package/src/core/layout/jsx.ts +0 -174
  95. package/src/core/layout/schema.ts +0 -1044
  96. package/src/core/layout/types.ts +0 -95
  97. package/src/core/viewport/constants.ts +0 -145
  98. package/src/core/viewport/features/base.ts +0 -73
  99. package/src/core/viewport/features/collection.ts +0 -1182
  100. package/src/core/viewport/features/events.ts +0 -130
  101. package/src/core/viewport/features/item-size.ts +0 -271
  102. package/src/core/viewport/features/loading.ts +0 -263
  103. package/src/core/viewport/features/momentum.ts +0 -269
  104. package/src/core/viewport/features/performance.ts +0 -161
  105. package/src/core/viewport/features/placeholders.ts +0 -335
  106. package/src/core/viewport/features/rendering.ts +0 -962
  107. package/src/core/viewport/features/scrollbar.ts +0 -434
  108. package/src/core/viewport/features/scrolling.ts +0 -634
  109. package/src/core/viewport/features/utils.ts +0 -94
  110. package/src/core/viewport/features/virtual.ts +0 -525
  111. package/src/core/viewport/types.ts +0 -133
  112. package/src/core/viewport/utils/speed-tracker.ts +0 -79
  113. package/src/core/viewport/viewport.ts +0 -265
  114. package/test/benchmarks/layout/advanced.test.ts +0 -656
  115. package/test/benchmarks/layout/comparison.test.ts +0 -519
  116. package/test/benchmarks/layout/performance-comparison.test.ts +0 -274
  117. package/test/benchmarks/layout/real-components.test.ts +0 -733
  118. package/test/benchmarks/layout/simple.test.ts +0 -321
  119. package/test/benchmarks/layout/stress.test.ts +0 -990
  120. package/test/collection/basic.test.ts +0 -304
  121. package/test/components/vlist-selection.test.ts +0 -240
  122. package/test/components/vlist.test.ts +0 -63
  123. package/test/core/collection/adapter.test.ts +0 -161
  124. package/test/core/collection/collection.test.ts +0 -394
  125. package/test/core/layout/layout.test.ts +0 -201
  126. package/test/utils/dom-helpers.ts +0 -275
  127. package/test/utils/performance-helpers.ts +0 -392
  128. package/tsconfig.json +0 -20
@@ -1,436 +0,0 @@
1
- // src/components/vlist/features/selection.ts
2
-
3
- import type { VListConfig, VListComponent, VListItem } from "../types";
4
- import { VLIST_CLASSES } from "../constants";
5
- import { PREFIX, addClass, removeClass } from "mtrl";
6
-
7
- /**
8
- * Selection state interface
9
- */
10
- interface SelectionState {
11
- selectedIds: Set<string | number>;
12
- mode: "none" | "single" | "multiple";
13
- lastSelectedIndex?: number;
14
- }
15
-
16
- /**
17
- * Get item ID from element or item data
18
- */
19
- const getItemId = (item: any): string | number | undefined => {
20
- if (item?.id !== undefined) return item.id;
21
- if (item?._id !== undefined) return item._id;
22
- if (typeof item === "string" || typeof item === "number") return item;
23
- return undefined;
24
- };
25
-
26
- /**
27
- * Adds selection management capabilities to VList component
28
- */
29
- export const withSelection = <T extends VListItem = VListItem>(
30
- config: VListConfig<T>,
31
- ) => {
32
- return (component: VListComponent<T>): VListComponent<T> => {
33
- if (!config.selection?.enabled || config.selection?.mode === "none") {
34
- return component;
35
- }
36
-
37
- const state: SelectionState = {
38
- selectedIds: new Set(),
39
- mode: config.selection?.mode || "single",
40
- lastSelectedIndex: undefined,
41
- };
42
-
43
- const requireModifiers = config.selection?.requireModifiers ?? false;
44
-
45
- /**
46
- * Apply selection class to rendered elements matching selected IDs
47
- */
48
- const applySelectionToElements = () => {
49
- const container = component.element?.querySelector(
50
- `.${PREFIX}-viewport-items`,
51
- );
52
- if (!container) return;
53
-
54
- const items = container.querySelectorAll(
55
- `.${PREFIX}-viewport-item[data-id]`,
56
- );
57
-
58
- items.forEach((el) => {
59
- const element = el as HTMLElement;
60
- const id = element.dataset.id;
61
- if (id !== undefined) {
62
- // Check both string and number versions of the ID
63
- const isSelected =
64
- state.selectedIds.has(id) || state.selectedIds.has(Number(id));
65
- if (isSelected) {
66
- addClass(element, VLIST_CLASSES.SELECTED);
67
- } else {
68
- removeClass(element, VLIST_CLASSES.SELECTED);
69
- }
70
- }
71
- });
72
- };
73
-
74
- /**
75
- * Handle item click for selection
76
- */
77
- const handleItemClick = (e: MouseEvent) => {
78
- const viewportItem = (e.target as HTMLElement).closest(
79
- `.${PREFIX}-viewport-item[data-index]`,
80
- ) as HTMLElement;
81
- if (!viewportItem) return;
82
-
83
- const index = parseInt(viewportItem.dataset.index || "-1");
84
- if (index < 0) return;
85
-
86
- const enhancedComponent = component as any;
87
- const items = enhancedComponent.getItems?.();
88
- const item = items?.[index];
89
- if (!item) return;
90
-
91
- const itemId = getItemId(item);
92
- if (itemId === undefined) return;
93
-
94
- const wasSelected = state.selectedIds.has(itemId);
95
-
96
- if (state.mode === "single") {
97
- state.selectedIds.clear();
98
- if (!wasSelected) {
99
- state.selectedIds.add(itemId);
100
- state.lastSelectedIndex = index;
101
- } else {
102
- state.lastSelectedIndex = undefined;
103
- }
104
- } else if (state.mode === "multiple") {
105
- if (e.shiftKey && state.lastSelectedIndex !== undefined) {
106
- const start = Math.min(state.lastSelectedIndex, index);
107
- const end = Math.max(state.lastSelectedIndex, index);
108
-
109
- if (!e.ctrlKey && !e.metaKey) {
110
- state.selectedIds.clear();
111
- }
112
-
113
- for (let i = start; i <= end; i++) {
114
- const rangeItem = items?.[i];
115
- const rangeItemId = getItemId(rangeItem);
116
- if (rangeItemId !== undefined) {
117
- state.selectedIds.add(rangeItemId);
118
- }
119
- }
120
- } else if (e.ctrlKey || e.metaKey) {
121
- if (wasSelected) {
122
- state.selectedIds.delete(itemId);
123
- } else {
124
- state.selectedIds.add(itemId);
125
- }
126
- state.lastSelectedIndex = index;
127
- } else {
128
- if (requireModifiers) {
129
- state.selectedIds.clear();
130
- state.selectedIds.add(itemId);
131
- } else {
132
- if (wasSelected) {
133
- state.selectedIds.delete(itemId);
134
- } else {
135
- state.selectedIds.add(itemId);
136
- }
137
- }
138
- state.lastSelectedIndex = index;
139
- }
140
- }
141
-
142
- applySelectionToElements();
143
- emitSelectionChange();
144
- };
145
-
146
- /**
147
- * Emit selection change event
148
- */
149
- const emitSelectionChange = () => {
150
- const enhancedComponent = component as any;
151
- const items = enhancedComponent.getItems?.() || [];
152
-
153
- const selectedItems = items.filter((item: any) => {
154
- const id = getItemId(item);
155
- return id !== undefined && state.selectedIds.has(id);
156
- });
157
-
158
- const selectedIndices = items.reduce(
159
- (acc: number[], item: any, idx: number) => {
160
- const id = getItemId(item);
161
- if (id !== undefined && state.selectedIds.has(id)) {
162
- acc.push(idx);
163
- }
164
- return acc;
165
- },
166
- [] as number[],
167
- );
168
-
169
- component.emit?.("selection:change", { selectedItems, selectedIndices });
170
-
171
- if (config.selection?.onSelectionChange) {
172
- config.selection.onSelectionChange(selectedItems, selectedIndices);
173
- }
174
- };
175
-
176
- // Setup: listen for renders and clicks
177
- const setup = () => {
178
- // Add mode class to container
179
- if (component.element) {
180
- addClass(component.element, "vlist--selection");
181
- addClass(component.element, `vlist--selection-${state.mode}`);
182
- component.element.addEventListener("click", handleItemClick, true);
183
- }
184
-
185
- // Apply selection after each render
186
- (component as any).on?.(
187
- "viewport:items-rendered",
188
- applySelectionToElements,
189
- );
190
- (component as any).on?.("viewport:rendered", applySelectionToElements);
191
-
192
- // Clean up selection when item is removed
193
- (component as any).on?.(
194
- "item:removed",
195
- (data: { item: any; index: number }) => {
196
- const itemId = getItemId(data.item);
197
- if (itemId !== undefined && state.selectedIds.has(itemId)) {
198
- state.selectedIds.delete(itemId);
199
- // If the removed item was the last selected index, clear it
200
- if (state.lastSelectedIndex === data.index) {
201
- state.lastSelectedIndex = undefined;
202
- } else if (
203
- state.lastSelectedIndex !== undefined &&
204
- state.lastSelectedIndex > data.index
205
- ) {
206
- // Adjust lastSelectedIndex since items shifted down
207
- state.lastSelectedIndex--;
208
- }
209
- emitSelectionChange();
210
- }
211
- },
212
- );
213
- };
214
-
215
- // Initialize after component is ready
216
- setTimeout(setup, 0);
217
-
218
- // Listen for initial load complete to auto-select item
219
- // This must be in withSelection because selectById is defined here
220
- (component as any).on?.(
221
- "collection:initial-load-complete",
222
- (data: { selectId: string | number }) => {
223
- if (data?.selectId !== undefined) {
224
- // Use requestAnimationFrame to ensure rendering is complete
225
- requestAnimationFrame(() => {
226
- if (state.mode === "single") {
227
- state.selectedIds.clear();
228
- }
229
- state.selectedIds.add(data.selectId);
230
- applySelectionToElements();
231
- emitSelectionChange();
232
- });
233
- }
234
- },
235
- );
236
-
237
- // Cleanup on destroy
238
- const originalDestroy = component.destroy;
239
- component.destroy = () => {
240
- component.element?.removeEventListener("click", handleItemClick, true);
241
- originalDestroy?.();
242
- };
243
-
244
- // Enhanced component with selection API
245
- return {
246
- ...component,
247
-
248
- selectItems(indices: number[]) {
249
- const items = (this as any).getItems?.();
250
- if (!items) return;
251
-
252
- if (state.mode === "single") {
253
- // In single mode, clear previous selection before adding new one
254
- state.selectedIds.clear();
255
- if (indices.length > 1) {
256
- indices = [indices[0]];
257
- }
258
- }
259
-
260
- indices.forEach((index) => {
261
- const itemId = getItemId(items[index]);
262
- if (itemId !== undefined) {
263
- state.selectedIds.add(itemId);
264
- }
265
- });
266
-
267
- if (indices.length > 0) {
268
- state.lastSelectedIndex = indices[indices.length - 1];
269
- }
270
-
271
- applySelectionToElements();
272
- emitSelectionChange();
273
- },
274
-
275
- deselectItems(indices: number[]) {
276
- const items = (this as any).getItems?.();
277
- if (!items) return;
278
-
279
- indices.forEach((index) => {
280
- const itemId = getItemId(items[index]);
281
- if (itemId !== undefined) {
282
- state.selectedIds.delete(itemId);
283
- }
284
- });
285
-
286
- applySelectionToElements();
287
- emitSelectionChange();
288
- },
289
-
290
- clearSelection() {
291
- state.selectedIds.clear();
292
- state.lastSelectedIndex = undefined;
293
- applySelectionToElements();
294
- emitSelectionChange();
295
- },
296
-
297
- getSelectedItems(): T[] {
298
- const items = (this as any).getItems?.() || [];
299
- return items.filter((item: any) => {
300
- const id = getItemId(item);
301
- return id !== undefined && state.selectedIds.has(id);
302
- });
303
- },
304
-
305
- getSelectedIndices(): number[] {
306
- const items = (this as any).getItems?.() || [];
307
- return items.reduce((acc: number[], item: any, index: number) => {
308
- const id = getItemId(item);
309
- if (id !== undefined && state.selectedIds.has(id)) {
310
- acc.push(index);
311
- }
312
- return acc;
313
- }, [] as number[]);
314
- },
315
-
316
- isSelected(index: number): boolean {
317
- const items = (this as any).getItems?.();
318
- const itemId = getItemId(items?.[index]);
319
- return itemId !== undefined && state.selectedIds.has(itemId);
320
- },
321
-
322
- selectById(id: string | number, silent: boolean = false): boolean {
323
- if (id === undefined || id === null) return false;
324
-
325
- if (state.mode === "single") {
326
- state.selectedIds.clear();
327
- }
328
-
329
- state.selectedIds.add(id);
330
- applySelectionToElements();
331
- if (!silent) {
332
- emitSelectionChange();
333
- }
334
- return true;
335
- },
336
-
337
- /**
338
- * Select item at index, scrolling and waiting for data if needed
339
- * Handles virtual scrolling by loading data before selecting
340
- */
341
- async selectAtIndex(index: number): Promise<boolean> {
342
- const enhancedComponent = component as any;
343
- const totalItems = enhancedComponent.getItemCount?.() || 0;
344
-
345
- if (index < 0 || index >= totalItems) {
346
- return false;
347
- }
348
-
349
- // First scroll to the index (triggers data loading if needed)
350
- if (enhancedComponent.viewport?.scrollToIndex) {
351
- enhancedComponent.viewport.scrollToIndex(index);
352
- }
353
-
354
- // Try to select immediately - works if item is already loaded
355
- const items = enhancedComponent.getItems?.() || [];
356
- if (items[index]) {
357
- this.selectItems([index]);
358
- return true;
359
- }
360
-
361
- // Item not loaded yet - wait for data to load then select
362
- return new Promise<boolean>((resolve) => {
363
- let resolved = false;
364
-
365
- const onRangeLoaded = () => {
366
- if (resolved) return;
367
- resolved = true;
368
- component.off?.("viewport:range-loaded", onRangeLoaded);
369
- requestAnimationFrame(() => {
370
- this.selectItems([index]);
371
- resolve(true);
372
- });
373
- };
374
-
375
- component.on?.("viewport:range-loaded", onRangeLoaded);
376
-
377
- // Fallback timeout in case event doesn't fire (data already loaded)
378
- setTimeout(() => {
379
- if (resolved) return;
380
- resolved = true;
381
- component.off?.("viewport:range-loaded", onRangeLoaded);
382
- this.selectItems([index]);
383
- resolve(true);
384
- }, 300);
385
- });
386
- },
387
-
388
- /**
389
- * Select next item relative to current selection
390
- * Handles virtual scrolling by loading data before selecting
391
- */
392
- async selectNext(): Promise<boolean> {
393
- const enhancedComponent = component as any;
394
- const selectedIndices = this.getSelectedIndices();
395
-
396
- if (selectedIndices.length === 0) {
397
- // Select first item
398
- return this.selectAtIndex(0);
399
- }
400
-
401
- const currentIndex = selectedIndices[0];
402
- const nextIndex = currentIndex + 1;
403
- const totalItems = enhancedComponent.getItemCount?.() || 0;
404
-
405
- if (nextIndex < totalItems) {
406
- return this.selectAtIndex(nextIndex);
407
- }
408
-
409
- return false;
410
- },
411
-
412
- /**
413
- * Select previous item relative to current selection
414
- * Handles virtual scrolling by loading data before selecting
415
- */
416
- async selectPrevious(): Promise<boolean> {
417
- const selectedIndices = this.getSelectedIndices();
418
-
419
- if (selectedIndices.length === 0) {
420
- return false;
421
- }
422
-
423
- const currentIndex = selectedIndices[0];
424
- const prevIndex = currentIndex - 1;
425
-
426
- if (prevIndex >= 0) {
427
- return this.selectAtIndex(prevIndex);
428
- }
429
-
430
- return false;
431
- },
432
- };
433
- };
434
- };
435
-
436
- export default withSelection;
@@ -1,59 +0,0 @@
1
- // src/components/vlist/features/viewport.ts
2
-
3
- /**
4
- * Viewport feature for VList
5
- * Integrates the core viewport functionality with VList component
6
- */
7
-
8
- import type { VListConfig, VListItem } from "../types";
9
- import { createViewport } from "../../../core/viewport";
10
-
11
- /**
12
- * Adds viewport functionality to VList
13
- */
14
- export const withViewport = <T extends VListItem = VListItem>(
15
- config: VListConfig<T>,
16
- ) => {
17
- return (component: any) => {
18
- // Set initial items if provided
19
- if (config.items) {
20
- component.items = config.items;
21
- component.totalItems = config.items.length;
22
- }
23
-
24
- // Set template if provided
25
- if (config.template) {
26
- component.template = config.template;
27
- }
28
-
29
- // Ensure the element has both vlist and viewport classes
30
- const viewportConfig = {
31
- ...config,
32
- className: "mtrl-viewport", // This will be added by viewport base feature
33
- };
34
-
35
- // Pass VList config directly to viewport
36
- const viewportEnhanced = createViewport(viewportConfig as any)(component);
37
-
38
- // Handle parent element if provided
39
- if (config.parent || config.container) {
40
- const container = config.parent || config.container;
41
- const element =
42
- typeof container === "string"
43
- ? document.querySelector(container)
44
- : container;
45
-
46
- if (element && viewportEnhanced.element) {
47
- element.appendChild(viewportEnhanced.element);
48
-
49
- // Ensure viewport is initialized after DOM attachment
50
- if (viewportEnhanced.viewport && viewportEnhanced.viewport.initialize) {
51
- // console.log("📋 [VList] Initializing viewport after DOM attachment");
52
- viewportEnhanced.viewport.initialize();
53
- }
54
- }
55
- }
56
-
57
- return viewportEnhanced;
58
- };
59
- };
@@ -1,112 +0,0 @@
1
- /**
2
- * List component features
3
- *
4
- * Modular features that can be composed with the list component.
5
- * Following mtrl's functional composition pattern.
6
- */
7
-
8
- import type { ListComponent, ListConfig, ListItem } from "./types";
9
-
10
- /**
11
- * Virtual scrolling feature (future implementation)
12
- * This will provide window-based virtual scrolling for massive datasets
13
- */
14
- export function withVirtualScroll<T extends ListItem = ListItem>(
15
- config: any = {}
16
- ) {
17
- return (list: ListComponent<T>): ListComponent<T> => {
18
- console.log(
19
- "🔄 [MTRL-ADDONS-LIST] Virtual scrolling feature (future implementation)"
20
- );
21
-
22
- // TODO: Implement virtual scrolling
23
- // - Window-based strategy
24
- // - Dynamic height calculation
25
- // - GPU-accelerated positioning
26
-
27
- return list;
28
- };
29
- }
30
-
31
- /**
32
- * Enhanced list selection feature (future implementation)
33
- * This will provide advanced selection patterns
34
- */
35
- export function withListSelection<T extends ListItem = ListItem>(
36
- config: any = {}
37
- ) {
38
- return (list: ListComponent<T>): ListComponent<T> => {
39
- console.log(
40
- "✅ [MTRL-ADDONS-LIST] Enhanced selection feature (future implementation)"
41
- );
42
-
43
- // TODO: Implement advanced selection
44
- // - Keyboard navigation
45
- // - Range selection (Shift+Click)
46
- // - Checkbox selection modes
47
- // - Selection persistence
48
-
49
- return list;
50
- };
51
- }
52
-
53
- /**
54
- * Advanced list styling feature (future implementation)
55
- * This will provide theme integration and advanced styling
56
- */
57
- export function withListStyling<T extends ListItem = ListItem>(
58
- config: any = {}
59
- ) {
60
- return (list: ListComponent<T>): ListComponent<T> => {
61
- console.log(
62
- "�� [MTRL-ADDONS-LIST] Advanced styling feature (future implementation)"
63
- );
64
-
65
- // TODO: Implement advanced styling
66
- // - Theme integration
67
- // - Dynamic styling
68
- // - CSS custom properties
69
- // - Responsive layouts
70
-
71
- return list;
72
- };
73
- }
74
-
75
- /**
76
- * Performance optimization feature (future implementation)
77
- * This will provide advanced performance monitoring and optimization
78
- */
79
- export function withListPerformance<T extends ListItem = ListItem>(
80
- config: any = {}
81
- ) {
82
- return (list: ListComponent<T>): ListComponent<T> => {
83
- console.log(
84
- "⚡ [MTRL-ADDONS-LIST] Advanced performance feature (future implementation)"
85
- );
86
-
87
- // TODO: Implement performance optimizations
88
- // - Memory usage tracking
89
- // - Render time optimization
90
- // - Batch updates
91
- // - Performance budgets
92
-
93
- return list;
94
- };
95
- }
96
-
97
- /**
98
- * Re-export the internal composition functions for advanced usage
99
- * These are the actual working implementations used in createList
100
- */
101
- // export {
102
- // // These would be imported from the main list.ts file
103
- // // withListBase,
104
- // // withListStyling as withListStylingInternal,
105
- // // withListSelection as withListSelectionInternal,
106
- // // withListPerformance as withListPerformanceInternal,
107
- // // withListAPI
108
- // } from './list';
109
-
110
- // Note: The above imports are commented out because they would create circular imports
111
- // In a real implementation, we'd restructure to have the composition functions
112
- // in separate files to avoid this issue