mtrl-addons 0.1.2 → 0.2.1

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 (115) hide show
  1. package/build.js +139 -86
  2. package/package.json +13 -4
  3. package/scripts/debug/vlist-selection.ts +121 -0
  4. package/src/components/index.ts +5 -41
  5. package/src/components/{list → vlist}/config.ts +66 -95
  6. package/src/components/vlist/constants.ts +23 -0
  7. package/src/components/vlist/features/api.ts +322 -0
  8. package/src/components/vlist/features/index.ts +10 -0
  9. package/src/components/vlist/features/selection.ts +444 -0
  10. package/src/components/vlist/features/viewport.ts +65 -0
  11. package/src/components/vlist/index.ts +16 -0
  12. package/src/components/{list → vlist}/types.ts +104 -26
  13. package/src/components/vlist/vlist.ts +92 -0
  14. package/src/core/compose/features/gestures/index.ts +227 -0
  15. package/src/core/compose/features/gestures/longpress.ts +383 -0
  16. package/src/core/compose/features/gestures/pan.ts +424 -0
  17. package/src/core/compose/features/gestures/pinch.ts +475 -0
  18. package/src/core/compose/features/gestures/rotate.ts +485 -0
  19. package/src/core/compose/features/gestures/swipe.ts +492 -0
  20. package/src/core/compose/features/gestures/tap.ts +334 -0
  21. package/src/core/compose/features/index.ts +2 -38
  22. package/src/core/compose/index.ts +13 -29
  23. package/src/core/gestures/index.ts +31 -0
  24. package/src/core/gestures/longpress.ts +68 -0
  25. package/src/core/gestures/manager.ts +418 -0
  26. package/src/core/gestures/pan.ts +48 -0
  27. package/src/core/gestures/pinch.ts +58 -0
  28. package/src/core/gestures/rotate.ts +58 -0
  29. package/src/core/gestures/swipe.ts +66 -0
  30. package/src/core/gestures/tap.ts +45 -0
  31. package/src/core/gestures/types.ts +387 -0
  32. package/src/core/gestures/utils.ts +128 -0
  33. package/src/core/index.ts +27 -151
  34. package/src/core/layout/schema.ts +73 -35
  35. package/src/core/layout/types.ts +5 -2
  36. package/src/core/viewport/constants.ts +140 -0
  37. package/src/core/viewport/features/base.ts +73 -0
  38. package/src/core/viewport/features/collection.ts +882 -0
  39. package/src/core/viewport/features/events.ts +130 -0
  40. package/src/core/viewport/features/index.ts +20 -0
  41. package/src/core/{list-manager/features/viewport → viewport/features}/item-size.ts +27 -30
  42. package/src/core/{list-manager/features/viewport → viewport/features}/loading.ts +4 -4
  43. package/src/core/viewport/features/momentum.ts +260 -0
  44. package/src/core/viewport/features/placeholders.ts +335 -0
  45. package/src/core/viewport/features/rendering.ts +568 -0
  46. package/src/core/viewport/features/scrollbar.ts +434 -0
  47. package/src/core/viewport/features/scrolling.ts +618 -0
  48. package/src/core/viewport/features/utils.ts +88 -0
  49. package/src/core/viewport/features/virtual.ts +384 -0
  50. package/src/core/viewport/index.ts +31 -0
  51. package/src/core/viewport/types.ts +133 -0
  52. package/src/core/viewport/utils/speed-tracker.ts +79 -0
  53. package/src/core/viewport/viewport.ts +246 -0
  54. package/src/index.ts +0 -7
  55. package/src/styles/components/_vlist.scss +331 -0
  56. package/src/styles/index.scss +1 -1
  57. package/test/components/vlist-selection.test.ts +240 -0
  58. package/test/components/vlist.test.ts +63 -0
  59. package/test/core/collection/adapter.test.ts +161 -0
  60. package/bun.lock +0 -792
  61. package/src/components/list/api.ts +0 -314
  62. package/src/components/list/constants.ts +0 -56
  63. package/src/components/list/features/api.ts +0 -428
  64. package/src/components/list/features/index.ts +0 -31
  65. package/src/components/list/features/list-manager.ts +0 -502
  66. package/src/components/list/index.ts +0 -39
  67. package/src/components/list/list.ts +0 -234
  68. package/src/core/collection/base-collection.ts +0 -100
  69. package/src/core/collection/collection-composer.ts +0 -178
  70. package/src/core/collection/collection.ts +0 -745
  71. package/src/core/collection/constants.ts +0 -172
  72. package/src/core/collection/events.ts +0 -428
  73. package/src/core/collection/features/api/loading.ts +0 -279
  74. package/src/core/collection/features/operations/data-operations.ts +0 -147
  75. package/src/core/collection/index.ts +0 -104
  76. package/src/core/collection/state.ts +0 -497
  77. package/src/core/collection/types.ts +0 -404
  78. package/src/core/compose/features/collection.ts +0 -119
  79. package/src/core/compose/features/selection.ts +0 -213
  80. package/src/core/compose/features/styling.ts +0 -108
  81. package/src/core/list-manager/api.ts +0 -599
  82. package/src/core/list-manager/config.ts +0 -593
  83. package/src/core/list-manager/constants.ts +0 -268
  84. package/src/core/list-manager/features/api.ts +0 -58
  85. package/src/core/list-manager/features/collection/collection.ts +0 -705
  86. package/src/core/list-manager/features/collection/index.ts +0 -17
  87. package/src/core/list-manager/features/viewport/constants.ts +0 -42
  88. package/src/core/list-manager/features/viewport/index.ts +0 -16
  89. package/src/core/list-manager/features/viewport/placeholders.ts +0 -281
  90. package/src/core/list-manager/features/viewport/rendering.ts +0 -575
  91. package/src/core/list-manager/features/viewport/scrollbar.ts +0 -495
  92. package/src/core/list-manager/features/viewport/scrolling.ts +0 -795
  93. package/src/core/list-manager/features/viewport/template.ts +0 -220
  94. package/src/core/list-manager/features/viewport/viewport.ts +0 -654
  95. package/src/core/list-manager/features/viewport/virtual.ts +0 -309
  96. package/src/core/list-manager/index.ts +0 -279
  97. package/src/core/list-manager/list-manager.ts +0 -206
  98. package/src/core/list-manager/types.ts +0 -439
  99. package/src/core/list-manager/utils/calculations.ts +0 -290
  100. package/src/core/list-manager/utils/range-calculator.ts +0 -349
  101. package/src/core/list-manager/utils/speed-tracker.ts +0 -273
  102. package/src/styles/components/_list.scss +0 -244
  103. package/src/types/mtrl.d.ts +0 -6
  104. package/test/components/list.test.ts +0 -256
  105. package/test/core/collection/failed-ranges.test.ts +0 -270
  106. package/test/core/compose/features.test.ts +0 -183
  107. package/test/core/list-manager/features/collection.test.ts +0 -704
  108. package/test/core/list-manager/features/viewport.test.ts +0 -698
  109. package/test/core/list-manager/list-manager.test.ts +0 -593
  110. package/test/core/list-manager/utils/calculations.test.ts +0 -433
  111. package/test/core/list-manager/utils/range-calculator.test.ts +0 -569
  112. package/test/core/list-manager/utils/speed-tracker.test.ts +0 -530
  113. package/tsconfig.build.json +0 -23
  114. /package/src/components/{list → vlist}/features.ts +0 -0
  115. /package/src/core/{compose → viewport}/features/performance.ts +0 -0
@@ -1,404 +0,0 @@
1
- /**
2
- * Core types for the mtrl-addons collection system (Pure Data Layer)
3
- *
4
- * These types define the foundational interfaces and contracts
5
- * for pure data management with zero UI concerns.
6
- */
7
-
8
- /**
9
- * Base item interface - all collection items must extend this
10
- */
11
- export interface CollectionItem {
12
- id: string;
13
- [key: string]: any;
14
- }
15
-
16
- /**
17
- * Collection configuration options (DATA ONLY)
18
- */
19
- export interface CollectionConfig<T extends CollectionItem = CollectionItem> {
20
- /**
21
- * Static array of items to display
22
- */
23
- items?: T[];
24
-
25
- /**
26
- * Data adapter for API integration
27
- */
28
- adapter?: CollectionAdapter<T>;
29
-
30
- /**
31
- * Transform function for processing items
32
- */
33
- transform?: (item: any) => T;
34
-
35
- /**
36
- * Validation function for items
37
- */
38
- validate?: (item: T) => boolean;
39
-
40
- /**
41
- * Normalization function for data consistency
42
- */
43
- normalize?: (items: T[]) => T[];
44
-
45
- /**
46
- * Data persistence configuration
47
- */
48
- persistence?: PersistenceConfig;
49
-
50
- /**
51
- * Data caching configuration
52
- */
53
- cache?: CacheConfig;
54
-
55
- /**
56
- * Web worker configuration for background processing
57
- */
58
- webWorkers?: WebWorkerConfig;
59
-
60
- /**
61
- * Data prefetching configuration
62
- */
63
- prefetch?: PrefetchConfig;
64
-
65
- /**
66
- * Initial collection capacity for optimization
67
- */
68
- initialCapacity?: number;
69
-
70
- /**
71
- * Page size for pagination
72
- */
73
- pageSize?: number;
74
-
75
- /**
76
- * Limit for API requests (items per request)
77
- */
78
- limit?: number;
79
-
80
- /**
81
- * Range size for virtual scrolling (items to load per range)
82
- */
83
- rangeSize?: number;
84
-
85
- // NO UI properties: container, template, className, ariaLabel
86
- }
87
-
88
- /**
89
- * Data persistence configuration
90
- */
91
- export interface PersistenceConfig {
92
- strategy: "localStorage" | "indexedDB" | "custom";
93
- key: string;
94
- version?: number;
95
- encryption?: boolean;
96
- compression?: boolean;
97
- syncInterval?: number;
98
- maxAge?: number;
99
- }
100
-
101
- /**
102
- * Data caching configuration
103
- */
104
- export interface CacheConfig {
105
- strategy: "memory" | "lru" | "custom";
106
- maxSize: number;
107
- maxAge: number;
108
- invalidationStrategy?: "time" | "version" | "manual";
109
- }
110
-
111
- /**
112
- * Web worker configuration for background processing
113
- */
114
- export interface WebWorkerConfig {
115
- enabled: boolean;
116
- workerScript?: string;
117
- operations: Array<"transform" | "validate" | "normalize" | "filter" | "sort">;
118
- maxWorkers?: number;
119
- transferableObjects?: boolean;
120
- }
121
-
122
- /**
123
- * Data prefetching configuration
124
- */
125
- export interface PrefetchConfig {
126
- enabled: boolean;
127
- adjacentPages?: number;
128
- preloadThreshold?: number;
129
- maxCacheSize?: number;
130
- }
131
-
132
- /**
133
- * Data adapter interface for API integration
134
- */
135
- export interface CollectionAdapter<T extends CollectionItem = CollectionItem> {
136
- /**
137
- * Read data from the source
138
- */
139
- read(params?: AdapterParams): Promise<AdapterResponse<T>>;
140
-
141
- /**
142
- * Create new items in the source (optional)
143
- */
144
- create?(items: Omit<T, "id">[]): Promise<AdapterResponse<T>>;
145
-
146
- /**
147
- * Update existing items in the source (optional)
148
- */
149
- update?(items: Partial<T>[]): Promise<AdapterResponse<T>>;
150
-
151
- /**
152
- * Delete items from the source (optional)
153
- */
154
- delete?(ids: string[]): Promise<void>;
155
- }
156
-
157
- /**
158
- * Adapter parameters for data operations
159
- */
160
- export interface AdapterParams {
161
- // Pagination parameters
162
- page?: number;
163
- limit?: number;
164
- offset?: number;
165
- cursor?: string;
166
-
167
- // Data filtering/sorting
168
- search?: string;
169
- filters?: Record<string, any>;
170
- sort?: Array<{
171
- field: string;
172
- direction: "asc" | "desc";
173
- }>;
174
-
175
- // Custom parameters
176
- [key: string]: any;
177
- }
178
-
179
- /**
180
- * Adapter response structure
181
- */
182
- export interface AdapterResponse<T extends CollectionItem = CollectionItem> {
183
- /**
184
- * Array of items
185
- */
186
- items: T[];
187
-
188
- /**
189
- * Pagination and response metadata
190
- */
191
- meta?: {
192
- total?: number;
193
- page?: number;
194
- limit?: number;
195
- hasNext?: boolean;
196
- hasPrev?: boolean;
197
- cursor?: string;
198
- filter?: Record<string, any>;
199
- sort?: Array<{ field: string; direction: "asc" | "desc" }>;
200
- };
201
-
202
- /**
203
- * Error information if operation failed
204
- */
205
- error?: {
206
- message: string;
207
- code?: string;
208
- details?: any;
209
- };
210
- }
211
-
212
- /**
213
- * Collection data events (NO UI EVENTS)
214
- */
215
- export enum CollectionDataEvents {
216
- // Data lifecycle
217
- ITEMS_LOADED = "items:loaded",
218
- ITEMS_ADDED = "items:added",
219
- ITEMS_UPDATED = "items:updated",
220
- ITEMS_REMOVED = "items:removed",
221
- ITEMS_CLEARED = "items:cleared",
222
-
223
- // Data state
224
- LOADING_START = "loading:start",
225
- LOADING_END = "loading:end",
226
- ERROR_OCCURRED = "error:occurred",
227
-
228
- // Data operations
229
- CACHE_HIT = "cache:hit",
230
- CACHE_MISS = "cache:miss",
231
- SYNC_START = "sync:start",
232
- SYNC_COMPLETE = "sync:complete",
233
-
234
- // Background operations
235
- PREFETCH_START = "prefetch:start",
236
- PREFETCH_COMPLETE = "prefetch:complete",
237
- WORKER_TASK_START = "worker:task:start",
238
- WORKER_TASK_COMPLETE = "worker:task:complete",
239
- }
240
-
241
- /**
242
- * Collection observer function type
243
- */
244
- export type CollectionObserver<T extends CollectionItem = CollectionItem> = (
245
- payload: CollectionEventPayload<T>
246
- ) => void;
247
-
248
- /**
249
- * Unsubscribe function type
250
- */
251
- export type CollectionUnsubscribe = () => void;
252
-
253
- /**
254
- * Collection event payload
255
- */
256
- export interface CollectionEventPayload<
257
- T extends CollectionItem = CollectionItem
258
- > {
259
- event: CollectionDataEvents;
260
- data?: any;
261
- items?: T[];
262
- error?: Error;
263
- timestamp: number;
264
- source: "collection";
265
- }
266
-
267
- /**
268
- * Aggregation operation types
269
- */
270
- export interface AggregateOperation {
271
- field: string;
272
- operation: "sum" | "count" | "avg" | "min" | "max" | "distinct";
273
- alias?: string;
274
- }
275
-
276
- /**
277
- * Base collection interface (minimal core)
278
- * Only essential data operations - everything else is added via plugins
279
- */
280
- export interface BaseCollection<T extends CollectionItem = CollectionItem> {
281
- // Core data access
282
- getItems(): T[];
283
- getItem(id: string): T | undefined;
284
- getSize(): number;
285
- getTotalCount(): number;
286
-
287
- // Basic state
288
- isLoading(): boolean;
289
- getError(): Error | null;
290
-
291
- // State management (for plugins)
292
- getState(): any;
293
- setState(newState: any): void;
294
-
295
- // Event system (for plugins)
296
- subscribe(observer: (payload: any) => void): () => void;
297
- emit(event: string, data: any): void;
298
-
299
- // Lifecycle
300
- destroy(): void;
301
-
302
- // Plugin internals (not part of public API)
303
- _config: CollectionConfig<T>;
304
- _stateStore: any;
305
- _eventEmitter: any;
306
- }
307
-
308
- /**
309
- * Main collection interface (PURE DATA MANAGEMENT)
310
- */
311
- export interface Collection<T extends CollectionItem = CollectionItem> {
312
- // Data operations
313
- getItems(): T[];
314
- getItem(id: string): T | undefined;
315
- addItems(items: T[]): Promise<T[]>;
316
- updateItems(items: Partial<T>[]): Promise<T[]>;
317
- removeItems(ids: string[]): Promise<void>;
318
- clearItems(): Promise<void>;
319
-
320
- // Data queries
321
- filter(predicate: (item: T) => boolean): T[];
322
- sort(compareFn: (a: T, b: T) => number): T[];
323
- search(query: string, fields?: string[]): T[];
324
- aggregate(operations: AggregateOperation[]): any;
325
-
326
- // Data loading
327
- loadPage(page: number): Promise<AdapterResponse<T>>;
328
- loadMore(): Promise<AdapterResponse<T>>;
329
- refresh(): Promise<AdapterResponse<T>>;
330
- prefetch(pages: number[]): Promise<void>;
331
-
332
- // Data state
333
- getSize(): number;
334
- getTotalCount(): number;
335
- isLoading(): boolean;
336
- getError(): Error | null;
337
- hasNext(): boolean;
338
- getCurrentPage(): number;
339
-
340
- // Data persistence
341
- save(): Promise<void>;
342
- load(): Promise<void>;
343
- clearCache(): Promise<void>;
344
- sync(): Promise<void>;
345
-
346
- // Events (data events only)
347
- subscribe(observer: CollectionObserver<T>): CollectionUnsubscribe;
348
- emit(event: CollectionDataEvents, data: any): void;
349
-
350
- // Lifecycle
351
- destroy(): void;
352
-
353
- // Plugin system for data features
354
- use(plugin: CollectionPlugin): Collection<T>;
355
-
356
- // NO UI methods: scrollTo, render, setTemplate, element, etc.
357
- }
358
-
359
- /**
360
- * Plugin interface for data features
361
- */
362
- export interface CollectionPlugin<T = any> {
363
- name: string;
364
- version: string;
365
- dependencies?: string[];
366
-
367
- install(collection: Collection<any>, config: T): void;
368
- uninstall?(collection: Collection<any>): void;
369
- }
370
-
371
- /**
372
- * Data validation types
373
- */
374
- export interface ValidationConfig {
375
- schema?: any;
376
- sanitize?: boolean;
377
- strict?: boolean;
378
- customValidators?: Record<string, (value: any) => boolean>;
379
- }
380
-
381
- export interface ValidationError {
382
- field: string;
383
- message: string;
384
- code: string;
385
- value: any;
386
- }
387
-
388
- /**
389
- * Background processing types
390
- */
391
- export interface WorkerTask {
392
- id: string;
393
- operation: string;
394
- data: any;
395
- priority: "low" | "normal" | "high";
396
- timeout?: number;
397
- }
398
-
399
- export interface WorkerResult {
400
- taskId: string;
401
- result: any;
402
- duration: number;
403
- error?: Error;
404
- }
@@ -1,119 +0,0 @@
1
- /**
2
- * @module core/compose/features
3
- * @description Collection integration feature for components
4
- */
5
-
6
- import { createCollection } from "../../collection";
7
- import type { ListItem } from "../../../components/list/types";
8
- import type { TemplateEngineType } from "../../collection/types";
9
-
10
- /**
11
- * Configuration for collection feature
12
- */
13
- export interface CollectionConfig<T extends ListItem = ListItem> {
14
- container?: HTMLElement;
15
- items?: T[];
16
- adapter?: any;
17
- transform?: (item: any) => T;
18
- validate?: (item: T) => boolean;
19
- template?: any;
20
- templateEngine?: TemplateEngineType;
21
- initialCapacity?: number;
22
- [key: string]: any;
23
- }
24
-
25
- /**
26
- * Component with collection capabilities
27
- */
28
- export interface CollectionComponent<T extends ListItem = ListItem> {
29
- // Collection methods
30
- add: (items: T | T[]) => Promise<void>;
31
- update: (id: string, updates: Partial<T>) => Promise<void>;
32
- remove: (id: string) => Promise<void>;
33
- clear: () => Promise<void>;
34
- getItems: () => T[];
35
- getItem: (id: string) => T | undefined;
36
- query: (filter: (item: T) => boolean) => T[];
37
- sort: (compareFn?: (a: T, b: T) => number) => Promise<void>;
38
- getSize: () => number;
39
- isEmpty: () => boolean;
40
- isLoading: () => boolean;
41
- getError: () => string | null;
42
- subscribe: (event: string, handler: Function) => void;
43
- refresh: () => Promise<void>;
44
- render: () => void;
45
- setTemplate: (template: any) => void;
46
- getTemplate: () => any;
47
-
48
- // Internal collection reference
49
- _collection?: any;
50
- }
51
-
52
- /**
53
- * Default template for collection items
54
- */
55
- function getDefaultCollectionTemplate() {
56
- return {
57
- tag: "div",
58
- className: "mtrl-collection-item",
59
- attributes: { "data-id": "{{id}}", role: "listitem" },
60
- children: [
61
- {
62
- tag: "div",
63
- className: "mtrl-collection-item__content",
64
- textContent: "{{name || id}}",
65
- },
66
- ],
67
- };
68
- }
69
-
70
- /**
71
- * Adds collection functionality to a component
72
- *
73
- * @param config - Collection configuration
74
- * @returns Component enhancer that adds collection capabilities
75
- *
76
- * @example
77
- * ```typescript
78
- * const component = pipe(
79
- * createBase,
80
- * withElement(),
81
- * withCollection({
82
- * items: myData,
83
- * template: myTemplate,
84
- * adapter: myAdapter
85
- * })
86
- * )(config);
87
- * ```
88
- */
89
- export function withCollection<T extends ListItem = ListItem>(
90
- config: CollectionConfig<T>
91
- ) {
92
- return (component: any): any & CollectionComponent<T> => {
93
- console.log("🗂️ [MTRL-ADDONS] Adding collection capabilities");
94
-
95
- // Create the collection using the component's element as container
96
- const collection = createCollection({
97
- container: component.element,
98
- items: config.items,
99
- adapter: config.adapter,
100
- transform: config.transform,
101
- validate: config.validate,
102
- template: config.template || getDefaultCollectionTemplate(),
103
- templateEngine: config.templateEngine,
104
- initialCapacity: config.initialCapacity,
105
- });
106
-
107
- // Merge collection methods into component
108
- return {
109
- ...component,
110
- ...collection,
111
-
112
- // Keep original element reference from withElement
113
- element: component.element,
114
-
115
- // Store collection reference for internal use
116
- _collection: collection,
117
- };
118
- };
119
- }