mtrl-addons 0.1.2 → 0.2.2

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 (117) hide show
  1. package/AI.md +28 -230
  2. package/CLAUDE.md +882 -0
  3. package/build.js +253 -24
  4. package/package.json +14 -4
  5. package/scripts/debug/vlist-selection.ts +121 -0
  6. package/src/components/index.ts +5 -41
  7. package/src/components/{list → vlist}/config.ts +66 -95
  8. package/src/components/vlist/constants.ts +23 -0
  9. package/src/components/vlist/features/api.ts +626 -0
  10. package/src/components/vlist/features/index.ts +10 -0
  11. package/src/components/vlist/features/selection.ts +436 -0
  12. package/src/components/vlist/features/viewport.ts +59 -0
  13. package/src/components/vlist/index.ts +17 -0
  14. package/src/components/{list → vlist}/types.ts +242 -32
  15. package/src/components/vlist/vlist.ts +92 -0
  16. package/src/core/compose/features/gestures/index.ts +227 -0
  17. package/src/core/compose/features/gestures/longpress.ts +383 -0
  18. package/src/core/compose/features/gestures/pan.ts +424 -0
  19. package/src/core/compose/features/gestures/pinch.ts +475 -0
  20. package/src/core/compose/features/gestures/rotate.ts +485 -0
  21. package/src/core/compose/features/gestures/swipe.ts +492 -0
  22. package/src/core/compose/features/gestures/tap.ts +334 -0
  23. package/src/core/compose/features/index.ts +2 -38
  24. package/src/core/compose/index.ts +13 -29
  25. package/src/core/gestures/index.ts +31 -0
  26. package/src/core/gestures/longpress.ts +68 -0
  27. package/src/core/gestures/manager.ts +418 -0
  28. package/src/core/gestures/pan.ts +48 -0
  29. package/src/core/gestures/pinch.ts +58 -0
  30. package/src/core/gestures/rotate.ts +58 -0
  31. package/src/core/gestures/swipe.ts +66 -0
  32. package/src/core/gestures/tap.ts +45 -0
  33. package/src/core/gestures/types.ts +387 -0
  34. package/src/core/gestures/utils.ts +128 -0
  35. package/src/core/index.ts +27 -151
  36. package/src/core/layout/schema.ts +153 -72
  37. package/src/core/layout/types.ts +5 -2
  38. package/src/core/viewport/constants.ts +145 -0
  39. package/src/core/viewport/features/base.ts +73 -0
  40. package/src/core/viewport/features/collection.ts +1182 -0
  41. package/src/core/viewport/features/events.ts +130 -0
  42. package/src/core/viewport/features/index.ts +20 -0
  43. package/src/core/{list-manager/features/viewport → viewport/features}/item-size.ts +31 -34
  44. package/src/core/{list-manager/features/viewport → viewport/features}/loading.ts +4 -4
  45. package/src/core/viewport/features/momentum.ts +269 -0
  46. package/src/core/viewport/features/placeholders.ts +335 -0
  47. package/src/core/viewport/features/rendering.ts +962 -0
  48. package/src/core/viewport/features/scrollbar.ts +434 -0
  49. package/src/core/viewport/features/scrolling.ts +634 -0
  50. package/src/core/viewport/features/utils.ts +94 -0
  51. package/src/core/viewport/features/virtual.ts +525 -0
  52. package/src/core/viewport/index.ts +31 -0
  53. package/src/core/viewport/types.ts +133 -0
  54. package/src/core/viewport/utils/speed-tracker.ts +79 -0
  55. package/src/core/viewport/viewport.ts +265 -0
  56. package/src/index.ts +0 -7
  57. package/src/styles/components/_vlist.scss +352 -0
  58. package/src/styles/index.scss +1 -1
  59. package/test/components/vlist-selection.test.ts +240 -0
  60. package/test/components/vlist.test.ts +63 -0
  61. package/test/core/collection/adapter.test.ts +161 -0
  62. package/bun.lock +0 -792
  63. package/src/components/list/api.ts +0 -314
  64. package/src/components/list/constants.ts +0 -56
  65. package/src/components/list/features/api.ts +0 -428
  66. package/src/components/list/features/index.ts +0 -31
  67. package/src/components/list/features/list-manager.ts +0 -502
  68. package/src/components/list/index.ts +0 -39
  69. package/src/components/list/list.ts +0 -234
  70. package/src/core/collection/base-collection.ts +0 -100
  71. package/src/core/collection/collection-composer.ts +0 -178
  72. package/src/core/collection/collection.ts +0 -745
  73. package/src/core/collection/constants.ts +0 -172
  74. package/src/core/collection/events.ts +0 -428
  75. package/src/core/collection/features/api/loading.ts +0 -279
  76. package/src/core/collection/features/operations/data-operations.ts +0 -147
  77. package/src/core/collection/index.ts +0 -104
  78. package/src/core/collection/state.ts +0 -497
  79. package/src/core/collection/types.ts +0 -404
  80. package/src/core/compose/features/collection.ts +0 -119
  81. package/src/core/compose/features/selection.ts +0 -213
  82. package/src/core/compose/features/styling.ts +0 -108
  83. package/src/core/list-manager/api.ts +0 -599
  84. package/src/core/list-manager/config.ts +0 -593
  85. package/src/core/list-manager/constants.ts +0 -268
  86. package/src/core/list-manager/features/api.ts +0 -58
  87. package/src/core/list-manager/features/collection/collection.ts +0 -705
  88. package/src/core/list-manager/features/collection/index.ts +0 -17
  89. package/src/core/list-manager/features/viewport/constants.ts +0 -42
  90. package/src/core/list-manager/features/viewport/index.ts +0 -16
  91. package/src/core/list-manager/features/viewport/placeholders.ts +0 -281
  92. package/src/core/list-manager/features/viewport/rendering.ts +0 -575
  93. package/src/core/list-manager/features/viewport/scrollbar.ts +0 -495
  94. package/src/core/list-manager/features/viewport/scrolling.ts +0 -795
  95. package/src/core/list-manager/features/viewport/template.ts +0 -220
  96. package/src/core/list-manager/features/viewport/viewport.ts +0 -654
  97. package/src/core/list-manager/features/viewport/virtual.ts +0 -309
  98. package/src/core/list-manager/index.ts +0 -279
  99. package/src/core/list-manager/list-manager.ts +0 -206
  100. package/src/core/list-manager/types.ts +0 -439
  101. package/src/core/list-manager/utils/calculations.ts +0 -290
  102. package/src/core/list-manager/utils/range-calculator.ts +0 -349
  103. package/src/core/list-manager/utils/speed-tracker.ts +0 -273
  104. package/src/styles/components/_list.scss +0 -244
  105. package/src/types/mtrl.d.ts +0 -6
  106. package/test/components/list.test.ts +0 -256
  107. package/test/core/collection/failed-ranges.test.ts +0 -270
  108. package/test/core/compose/features.test.ts +0 -183
  109. package/test/core/list-manager/features/collection.test.ts +0 -704
  110. package/test/core/list-manager/features/viewport.test.ts +0 -698
  111. package/test/core/list-manager/list-manager.test.ts +0 -593
  112. package/test/core/list-manager/utils/calculations.test.ts +0 -433
  113. package/test/core/list-manager/utils/range-calculator.test.ts +0 -569
  114. package/test/core/list-manager/utils/speed-tracker.test.ts +0 -530
  115. package/tsconfig.build.json +0 -23
  116. /package/src/components/{list → vlist}/features.ts +0 -0
  117. /package/src/core/{compose → viewport}/features/performance.ts +0 -0
@@ -1,428 +0,0 @@
1
- /**
2
- * mtrl-addons List Component API Feature
3
- *
4
- * API enhancement feature for the list component.
5
- * Follows mtrl patterns for component API composition.
6
- */
7
-
8
- import type { ListItem } from "../types";
9
-
10
- /**
11
- * API configuration options for List component
12
- */
13
- interface ApiOptions<T extends ListItem = ListItem> {
14
- // Data operations
15
- data: {
16
- add: (items: T | T[]) => Promise<void>;
17
- update: (id: string, updates: Partial<T>) => Promise<void>;
18
- remove: (id: string) => Promise<void>;
19
- clear: () => Promise<void>;
20
- refresh: () => Promise<void>;
21
- getItems: () => T[];
22
- getItem: (id: string) => T | undefined;
23
- query: (filter: (item: T) => boolean) => T[];
24
- sort: (compareFn?: (a: T, b: T) => number) => Promise<void>;
25
- getSize: () => number;
26
- isEmpty: () => boolean;
27
- isLoading: () => boolean;
28
- getError: () => string | null;
29
- };
30
-
31
- // Selection operations (optional)
32
- selection?: {
33
- selectItem: (id: string) => any;
34
- deselectItem: (id: string) => any;
35
- selectAll: () => any;
36
- deselectAll: () => any;
37
- getSelectedItems: () => T[];
38
- getSelectedIds: () => string[];
39
- };
40
-
41
- // Scrolling operations
42
- scrolling: {
43
- scrollToItem: (id: string, position?: "start" | "center" | "end") => any;
44
- scrollToIndex: (
45
- index: number,
46
- position?: "start" | "center" | "end"
47
- ) => any;
48
- scrollToPage: (
49
- page: number,
50
- position?: "start" | "center" | "end"
51
- ) => Promise<any>;
52
- };
53
-
54
- // Performance operations
55
- performance: {
56
- getMetrics: () => any;
57
- resetMetrics: () => any;
58
- };
59
-
60
- // Template operations
61
- template: {
62
- setTemplate: (template: any) => void;
63
- getTemplate: () => any;
64
- };
65
-
66
- // Events system
67
- events: {
68
- on: (event: string, handler: Function) => any;
69
- off: (event: string, handler: Function) => any;
70
- emit: (event: string, data: any) => void;
71
- subscribe: (observer: Function) => Function;
72
- };
73
-
74
- // Lifecycle operations
75
- lifecycle: {
76
- destroy: () => void;
77
- };
78
-
79
- // Configuration access
80
- config: {
81
- selection?: any;
82
- listStyle?: any;
83
- performance?: any;
84
- virtualScroll?: any;
85
- };
86
- }
87
-
88
- /**
89
- * Component with required elements and methods for API enhancement
90
- */
91
- interface ComponentWithElements {
92
- element: HTMLElement;
93
- on?: (event: string, handler: Function) => any;
94
- off?: (event: string, handler: Function) => any;
95
- emit?: (event: string, data: any) => void;
96
- }
97
-
98
- /**
99
- * Enhances a List component with public API methods
100
- * Following mtrl patterns for API composition
101
- *
102
- * @param {ApiOptions} options - API configuration options
103
- * @returns {Function} Higher-order function that adds API methods to component
104
- *
105
- * @example
106
- * ```typescript
107
- * const component = pipe(
108
- * createBase,
109
- * withElement(),
110
- * withCollection(),
111
- * withApi(getApiConfig(component, config))
112
- * )(config);
113
- * ```
114
- */
115
- export const withApi =
116
- <T extends ListItem = ListItem>(options: ApiOptions<T>) =>
117
- (component: ComponentWithElements) => {
118
- console.log("🔗 [MTRL-ADDONS-LIST] Adding list API methods");
119
-
120
- return {
121
- ...component,
122
- element: component.element,
123
-
124
- // Data operations
125
- /**
126
- * Adds one or more items to the list
127
- * @param {T | T[]} items - Item(s) to add
128
- * @returns {Promise<void>} Promise that resolves when items are added
129
- */
130
- add: async (items: T | T[]) => {
131
- await options.data.add(items);
132
- return component;
133
- },
134
-
135
- /**
136
- * Updates an item in the list
137
- * @param {string} id - Item ID to update
138
- * @param {Partial<T>} updates - Updates to apply
139
- * @returns {Promise<void>} Promise that resolves when item is updated
140
- */
141
- update: async (id: string, updates: Partial<T>) => {
142
- await options.data.update(id, updates);
143
- return component;
144
- },
145
-
146
- /**
147
- * Removes an item from the list
148
- * @param {string} id - Item ID to remove
149
- * @returns {Promise<void>} Promise that resolves when item is removed
150
- */
151
- remove: async (id: string) => {
152
- await options.data.remove(id);
153
- return component;
154
- },
155
-
156
- /**
157
- * Clears all items from the list
158
- * @returns {Promise<void>} Promise that resolves when list is cleared
159
- */
160
- clear: async () => {
161
- await options.data.clear();
162
- return component;
163
- },
164
-
165
- /**
166
- * Refreshes the list with the latest data
167
- * @returns {Promise<void>} Promise that resolves when refresh is complete
168
- */
169
- refresh: async () => {
170
- await options.data.refresh();
171
- return component;
172
- },
173
-
174
- /**
175
- * Gets all items in the list
176
- * @returns {T[]} Array of all items
177
- */
178
- getItems: (): T[] => options.data.getItems(),
179
-
180
- /**
181
- * Gets a specific item by ID
182
- * @param {string} id - Item ID to retrieve
183
- * @returns {T | undefined} Item if found, undefined otherwise
184
- */
185
- getItem: (id: string): T | undefined => options.data.getItem(id),
186
-
187
- /**
188
- * Queries items using a filter function
189
- * @param {Function} filter - Filter function
190
- * @returns {T[]} Filtered items
191
- */
192
- query: (filter: (item: T) => boolean): T[] => options.data.query(filter),
193
-
194
- /**
195
- * Sorts items using a comparison function
196
- * @param {Function} compareFn - Comparison function
197
- * @returns {Promise<void>} Promise that resolves when sorting is complete
198
- */
199
- sort: async (compareFn?: (a: T, b: T) => number) => {
200
- await options.data.sort(compareFn);
201
- return component;
202
- },
203
-
204
- /**
205
- * Gets the number of items in the list
206
- * @returns {number} Number of items
207
- */
208
- getSize: (): number => options.data.getSize(),
209
-
210
- /**
211
- * Checks if the list is empty
212
- * @returns {boolean} True if list is empty
213
- */
214
- isEmpty: (): boolean => options.data.isEmpty(),
215
-
216
- /**
217
- * Checks if the list is currently loading
218
- * @returns {boolean} True if loading
219
- */
220
- isLoading: (): boolean => options.data.isLoading(),
221
-
222
- /**
223
- * Gets the current error state
224
- * @returns {string | null} Error message if any, null otherwise
225
- */
226
- getError: (): string | null => options.data.getError(),
227
-
228
- // Selection operations (if enabled)
229
- ...(options.selection && {
230
- /**
231
- * Selects an item
232
- * @param {string} id - Item ID to select
233
- * @returns {Object} Component instance for chaining
234
- */
235
- selectItem: (id: string) => {
236
- options.selection!.selectItem(id);
237
- return component;
238
- },
239
-
240
- /**
241
- * Deselects an item
242
- * @param {string} id - Item ID to deselect
243
- * @returns {Object} Component instance for chaining
244
- */
245
- deselectItem: (id: string) => {
246
- options.selection!.deselectItem(id);
247
- return component;
248
- },
249
-
250
- /**
251
- * Selects all items
252
- * @returns {Object} Component instance for chaining
253
- */
254
- selectAll: () => {
255
- options.selection!.selectAll();
256
- return component;
257
- },
258
-
259
- /**
260
- * Deselects all items
261
- * @returns {Object} Component instance for chaining
262
- */
263
- deselectAll: () => {
264
- options.selection!.deselectAll();
265
- return component;
266
- },
267
-
268
- /**
269
- * Gets all selected items
270
- * @returns {T[]} Array of selected items
271
- */
272
- getSelectedItems: (): T[] => options.selection!.getSelectedItems(),
273
-
274
- /**
275
- * Gets IDs of all selected items
276
- * @returns {string[]} Array of selected item IDs
277
- */
278
- getSelectedIds: (): string[] => options.selection!.getSelectedIds(),
279
- }),
280
-
281
- // Scrolling operations
282
- /**
283
- * Scrolls to a specific item by ID
284
- * @param {string} id - Item ID to scroll to
285
- * @param {string} position - Position ('start', 'center', 'end')
286
- * @returns {Object} Component instance for chaining
287
- */
288
- scrollToItem: (
289
- id: string,
290
- position: "start" | "center" | "end" = "start"
291
- ) => {
292
- // Provide fallback implementation if scrolling methods not available
293
- if (options.scrolling.scrollToItem) {
294
- options.scrolling.scrollToItem(id, position);
295
- } else {
296
- console.warn("scrollToItem not implemented");
297
- }
298
- return component;
299
- },
300
-
301
- /**
302
- * Scrolls to a specific index
303
- * @param {number} index - Index to scroll to
304
- * @param {string} position - Position ('start', 'center', 'end')
305
- * @returns {Object} Component instance for chaining
306
- */
307
- scrollToIndex: (
308
- index: number,
309
- position: "start" | "center" | "end" = "start"
310
- ) => {
311
- // Provide fallback implementation if scrolling methods not available
312
- if (options.scrolling.scrollToIndex) {
313
- options.scrolling.scrollToIndex(index, position);
314
- } else {
315
- console.warn("scrollToIndex not implemented");
316
- }
317
- return component;
318
- },
319
-
320
- /**
321
- * Scrolls to a specific page
322
- * @param {number} page - Page number to scroll to
323
- * @param {string} position - Position ('start', 'center', 'end')
324
- * @returns {Promise<Object>} Promise that resolves with component instance
325
- */
326
- scrollToPage: async (
327
- page: number,
328
- position: "start" | "center" | "end" = "start"
329
- ) => {
330
- // Provide fallback implementation if scrolling methods not available
331
- if (options.scrolling.scrollToPage) {
332
- await options.scrolling.scrollToPage(page, position);
333
- } else {
334
- console.warn("scrollToPage not implemented");
335
- }
336
- return component;
337
- },
338
-
339
- // Performance operations
340
- /**
341
- * Gets performance metrics
342
- * @returns {Object} Performance metrics
343
- */
344
- getMetrics: () => options.performance.getMetrics(),
345
-
346
- /**
347
- * Resets performance metrics
348
- * @returns {Object} Component instance for chaining
349
- */
350
- resetMetrics: () => {
351
- options.performance.resetMetrics();
352
- return component;
353
- },
354
-
355
- // Template operations
356
- /**
357
- * Sets a new template for rendering items
358
- * @param {any} template - New template
359
- */
360
- setTemplate: (template: any): void => {
361
- options.template.setTemplate(template);
362
- },
363
-
364
- /**
365
- * Gets the current template
366
- * @returns {any} Current template
367
- */
368
- getTemplate: () => options.template.getTemplate(),
369
-
370
- // Event operations
371
- /**
372
- * Adds an event listener
373
- * @param {string} event - Event name
374
- * @param {Function} handler - Event handler
375
- * @returns {Object} Component instance for chaining
376
- */
377
- on: (event: string, handler: Function) => {
378
- options.events.on(event, handler);
379
- return component;
380
- },
381
-
382
- /**
383
- * Removes an event listener
384
- * @param {string} event - Event name
385
- * @param {Function} handler - Event handler
386
- * @returns {Object} Component instance for chaining
387
- */
388
- off: (event: string, handler: Function) => {
389
- options.events.off(event, handler);
390
- return component;
391
- },
392
-
393
- /**
394
- * Emits an event
395
- * @param {string} event - Event name
396
- * @param {any} data - Event data
397
- */
398
- emit: (event: string, data: any): void => {
399
- options.events.emit(event, data);
400
- },
401
-
402
- /**
403
- * Subscribes to events using observer pattern
404
- * @param {Function} observer - Observer function
405
- * @returns {Function} Unsubscribe function
406
- */
407
- subscribe: (observer: Function): Function => {
408
- return options.events.subscribe(observer);
409
- },
410
-
411
- // Lifecycle operations
412
- /**
413
- * Destroys the component and cleans up resources
414
- */
415
- destroy: (): void => {
416
- options.lifecycle.destroy();
417
- },
418
-
419
- // Configuration access
420
- /**
421
- * Gets component configuration
422
- * @returns {Object} Component configuration
423
- */
424
- getConfig: () => options.config,
425
- };
426
- };
427
-
428
- export default withApi;
@@ -1,31 +0,0 @@
1
- /**
2
- * mtrl-addons List Component Features
3
- *
4
- * List-specific features and enhancements.
5
- * Follows mtrl patterns for component features.
6
- */
7
-
8
- // Re-export core compose features that are commonly used with lists
9
- export {
10
- withCollection,
11
- withStyling,
12
- withSelection,
13
- withPerformance,
14
- type CollectionConfig,
15
- type CollectionComponent,
16
- type StylingConfig,
17
- type StylingComponent,
18
- type SelectionConfig,
19
- type SelectionComponent,
20
- type PerformanceConfig,
21
- type PerformanceComponent,
22
- } from "../../../core/compose/features";
23
-
24
- // List-specific features
25
- export { withApi } from "./api";
26
- export { withListManager } from "./list-manager";
27
-
28
- // Future list-specific features will be exported here
29
- // export { withVirtualScroll } from './virtual-scroll';
30
- // export { withInfiniteScroll } from './infinite-scroll';
31
- // export { withDataGrid } from './data-grid';