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.
- package/AI.md +28 -230
- package/CLAUDE.md +882 -0
- package/build.js +253 -24
- package/package.json +14 -4
- package/scripts/debug/vlist-selection.ts +121 -0
- package/src/components/index.ts +5 -41
- package/src/components/{list → vlist}/config.ts +66 -95
- package/src/components/vlist/constants.ts +23 -0
- package/src/components/vlist/features/api.ts +626 -0
- package/src/components/vlist/features/index.ts +10 -0
- package/src/components/vlist/features/selection.ts +436 -0
- package/src/components/vlist/features/viewport.ts +59 -0
- package/src/components/vlist/index.ts +17 -0
- package/src/components/{list → vlist}/types.ts +242 -32
- package/src/components/vlist/vlist.ts +92 -0
- package/src/core/compose/features/gestures/index.ts +227 -0
- package/src/core/compose/features/gestures/longpress.ts +383 -0
- package/src/core/compose/features/gestures/pan.ts +424 -0
- package/src/core/compose/features/gestures/pinch.ts +475 -0
- package/src/core/compose/features/gestures/rotate.ts +485 -0
- package/src/core/compose/features/gestures/swipe.ts +492 -0
- package/src/core/compose/features/gestures/tap.ts +334 -0
- package/src/core/compose/features/index.ts +2 -38
- package/src/core/compose/index.ts +13 -29
- package/src/core/gestures/index.ts +31 -0
- package/src/core/gestures/longpress.ts +68 -0
- package/src/core/gestures/manager.ts +418 -0
- package/src/core/gestures/pan.ts +48 -0
- package/src/core/gestures/pinch.ts +58 -0
- package/src/core/gestures/rotate.ts +58 -0
- package/src/core/gestures/swipe.ts +66 -0
- package/src/core/gestures/tap.ts +45 -0
- package/src/core/gestures/types.ts +387 -0
- package/src/core/gestures/utils.ts +128 -0
- package/src/core/index.ts +27 -151
- package/src/core/layout/schema.ts +153 -72
- package/src/core/layout/types.ts +5 -2
- package/src/core/viewport/constants.ts +145 -0
- package/src/core/viewport/features/base.ts +73 -0
- package/src/core/viewport/features/collection.ts +1182 -0
- package/src/core/viewport/features/events.ts +130 -0
- package/src/core/viewport/features/index.ts +20 -0
- package/src/core/{list-manager/features/viewport → viewport/features}/item-size.ts +31 -34
- package/src/core/{list-manager/features/viewport → viewport/features}/loading.ts +4 -4
- package/src/core/viewport/features/momentum.ts +269 -0
- package/src/core/viewport/features/placeholders.ts +335 -0
- package/src/core/viewport/features/rendering.ts +962 -0
- package/src/core/viewport/features/scrollbar.ts +434 -0
- package/src/core/viewport/features/scrolling.ts +634 -0
- package/src/core/viewport/features/utils.ts +94 -0
- package/src/core/viewport/features/virtual.ts +525 -0
- package/src/core/viewport/index.ts +31 -0
- package/src/core/viewport/types.ts +133 -0
- package/src/core/viewport/utils/speed-tracker.ts +79 -0
- package/src/core/viewport/viewport.ts +265 -0
- package/src/index.ts +0 -7
- package/src/styles/components/_vlist.scss +352 -0
- package/src/styles/index.scss +1 -1
- package/test/components/vlist-selection.test.ts +240 -0
- package/test/components/vlist.test.ts +63 -0
- package/test/core/collection/adapter.test.ts +161 -0
- package/bun.lock +0 -792
- package/src/components/list/api.ts +0 -314
- package/src/components/list/constants.ts +0 -56
- package/src/components/list/features/api.ts +0 -428
- package/src/components/list/features/index.ts +0 -31
- package/src/components/list/features/list-manager.ts +0 -502
- package/src/components/list/index.ts +0 -39
- package/src/components/list/list.ts +0 -234
- package/src/core/collection/base-collection.ts +0 -100
- package/src/core/collection/collection-composer.ts +0 -178
- package/src/core/collection/collection.ts +0 -745
- package/src/core/collection/constants.ts +0 -172
- package/src/core/collection/events.ts +0 -428
- package/src/core/collection/features/api/loading.ts +0 -279
- package/src/core/collection/features/operations/data-operations.ts +0 -147
- package/src/core/collection/index.ts +0 -104
- package/src/core/collection/state.ts +0 -497
- package/src/core/collection/types.ts +0 -404
- package/src/core/compose/features/collection.ts +0 -119
- package/src/core/compose/features/selection.ts +0 -213
- package/src/core/compose/features/styling.ts +0 -108
- package/src/core/list-manager/api.ts +0 -599
- package/src/core/list-manager/config.ts +0 -593
- package/src/core/list-manager/constants.ts +0 -268
- package/src/core/list-manager/features/api.ts +0 -58
- package/src/core/list-manager/features/collection/collection.ts +0 -705
- package/src/core/list-manager/features/collection/index.ts +0 -17
- package/src/core/list-manager/features/viewport/constants.ts +0 -42
- package/src/core/list-manager/features/viewport/index.ts +0 -16
- package/src/core/list-manager/features/viewport/placeholders.ts +0 -281
- package/src/core/list-manager/features/viewport/rendering.ts +0 -575
- package/src/core/list-manager/features/viewport/scrollbar.ts +0 -495
- package/src/core/list-manager/features/viewport/scrolling.ts +0 -795
- package/src/core/list-manager/features/viewport/template.ts +0 -220
- package/src/core/list-manager/features/viewport/viewport.ts +0 -654
- package/src/core/list-manager/features/viewport/virtual.ts +0 -309
- package/src/core/list-manager/index.ts +0 -279
- package/src/core/list-manager/list-manager.ts +0 -206
- package/src/core/list-manager/types.ts +0 -439
- package/src/core/list-manager/utils/calculations.ts +0 -290
- package/src/core/list-manager/utils/range-calculator.ts +0 -349
- package/src/core/list-manager/utils/speed-tracker.ts +0 -273
- package/src/styles/components/_list.scss +0 -244
- package/src/types/mtrl.d.ts +0 -6
- package/test/components/list.test.ts +0 -256
- package/test/core/collection/failed-ranges.test.ts +0 -270
- package/test/core/compose/features.test.ts +0 -183
- package/test/core/list-manager/features/collection.test.ts +0 -704
- package/test/core/list-manager/features/viewport.test.ts +0 -698
- package/test/core/list-manager/list-manager.test.ts +0 -593
- package/test/core/list-manager/utils/calculations.test.ts +0 -433
- package/test/core/list-manager/utils/range-calculator.test.ts +0 -569
- package/test/core/list-manager/utils/speed-tracker.test.ts +0 -530
- package/tsconfig.build.json +0 -23
- /package/src/components/{list → vlist}/features.ts +0 -0
- /package/src/core/{compose → viewport}/features/performance.ts +0 -0
|
@@ -1,593 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* List Manager Configuration System
|
|
3
|
-
*
|
|
4
|
-
* Provides configuration utilities, defaults, and validation for the List Manager.
|
|
5
|
-
* Follows mtrl patterns for component configuration.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { ListManagerConfig } from "./types";
|
|
9
|
-
import {
|
|
10
|
-
VIRTUAL_SCROLLING,
|
|
11
|
-
ELEMENT_RECYCLING,
|
|
12
|
-
VIEWPORT,
|
|
13
|
-
PERFORMANCE,
|
|
14
|
-
SCROLL,
|
|
15
|
-
ORIENTATION,
|
|
16
|
-
LIST_MANAGER_DEFAULTS,
|
|
17
|
-
} from "./constants";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Default configuration for orientation management
|
|
21
|
-
*/
|
|
22
|
-
export const defaultOrientationConfig = {
|
|
23
|
-
orientation: ORIENTATION.DEFAULT_ORIENTATION,
|
|
24
|
-
autoDetect: false,
|
|
25
|
-
reverse: ORIENTATION.REVERSE_DIRECTION,
|
|
26
|
-
crossAxisAlignment: ORIENTATION.DEFAULT_CROSS_AXIS_ALIGNMENT,
|
|
27
|
-
} as const;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Default configuration for virtual scrolling
|
|
31
|
-
*/
|
|
32
|
-
export const defaultVirtualConfig = {
|
|
33
|
-
enabled: true,
|
|
34
|
-
itemSize: 84,
|
|
35
|
-
estimatedItemSize: 84,
|
|
36
|
-
overscan: VIRTUAL_SCROLLING.DEFAULT_OVERSCAN,
|
|
37
|
-
windowSize: 20,
|
|
38
|
-
measureItems: false, // Disable item measurement by default
|
|
39
|
-
} as const;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Default configuration for element recycling
|
|
43
|
-
*/
|
|
44
|
-
export const defaultRecyclingConfig = {
|
|
45
|
-
enabled: true,
|
|
46
|
-
maxPoolSize: ELEMENT_RECYCLING.DEFAULT_MAX_POOL_SIZE,
|
|
47
|
-
minPoolSize: ELEMENT_RECYCLING.DEFAULT_MIN_POOL_SIZE,
|
|
48
|
-
strategy: ELEMENT_RECYCLING.DEFAULT_STRATEGY,
|
|
49
|
-
} as const;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Default configuration for scroll behavior
|
|
53
|
-
*/
|
|
54
|
-
export const defaultScrollConfig = {
|
|
55
|
-
smooth: false,
|
|
56
|
-
restore: false,
|
|
57
|
-
programmatic: true,
|
|
58
|
-
behavior: SCROLL.DEFAULT_BEHAVIOR,
|
|
59
|
-
easing: SCROLL.DEFAULT_EASING,
|
|
60
|
-
duration: SCROLL.DEFAULT_EASING_DURATION,
|
|
61
|
-
} as const;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Default configuration for intersection observers
|
|
65
|
-
*/
|
|
66
|
-
export const defaultIntersectionConfig = {
|
|
67
|
-
pagination: {
|
|
68
|
-
enabled: true,
|
|
69
|
-
rootMargin: VIEWPORT.DEFAULT_INTERSECTION_ROOT_MARGIN,
|
|
70
|
-
threshold: VIEWPORT.DEFAULT_INTERSECTION_THRESHOLD,
|
|
71
|
-
},
|
|
72
|
-
loading: {
|
|
73
|
-
enabled: true,
|
|
74
|
-
rootMargin: "100px",
|
|
75
|
-
threshold: 0.1,
|
|
76
|
-
},
|
|
77
|
-
preload: {
|
|
78
|
-
enabled: false,
|
|
79
|
-
threshold: 0.8,
|
|
80
|
-
prefetchPages: 2,
|
|
81
|
-
},
|
|
82
|
-
} as const;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Default configuration for performance features
|
|
86
|
-
*/
|
|
87
|
-
export const defaultPerformanceConfig = {
|
|
88
|
-
enabled: LIST_MANAGER_DEFAULTS.PERFORMANCE_ENABLED,
|
|
89
|
-
frameScheduling: true,
|
|
90
|
-
memoryCleanup: true,
|
|
91
|
-
fpsMonitoring: false,
|
|
92
|
-
trackFPS: true,
|
|
93
|
-
fpsTarget: PERFORMANCE.DEFAULT_FPS_TARGET,
|
|
94
|
-
trackMemory: false,
|
|
95
|
-
memoryThreshold: PERFORMANCE.MEMORY_WARNING_THRESHOLD,
|
|
96
|
-
} as const;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Default configuration for height measurement
|
|
100
|
-
*/
|
|
101
|
-
export const defaultHeightMeasurementConfig = {
|
|
102
|
-
enabled: true,
|
|
103
|
-
strategy: "dynamic",
|
|
104
|
-
estimatedHeight: 50,
|
|
105
|
-
cacheSize: 1000,
|
|
106
|
-
dynamicMeasurement: true,
|
|
107
|
-
} as const;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Complete default configuration for List Manager
|
|
111
|
-
*/
|
|
112
|
-
export const defaultListManagerConfig: Required<ListManagerConfig> = {
|
|
113
|
-
// Container
|
|
114
|
-
container: null,
|
|
115
|
-
|
|
116
|
-
// Component identification
|
|
117
|
-
componentName: "list-manager",
|
|
118
|
-
prefix: "mtrl",
|
|
119
|
-
|
|
120
|
-
// Orientation configuration
|
|
121
|
-
orientation: defaultOrientationConfig,
|
|
122
|
-
|
|
123
|
-
// Virtual scrolling configuration
|
|
124
|
-
virtual: defaultVirtualConfig,
|
|
125
|
-
|
|
126
|
-
// Element recycling configuration
|
|
127
|
-
recycling: defaultRecyclingConfig,
|
|
128
|
-
|
|
129
|
-
// Scroll behavior configuration
|
|
130
|
-
scroll: defaultScrollConfig,
|
|
131
|
-
|
|
132
|
-
// Intersection observer configuration
|
|
133
|
-
intersection: defaultIntersectionConfig,
|
|
134
|
-
|
|
135
|
-
// Performance configuration
|
|
136
|
-
performance: defaultPerformanceConfig,
|
|
137
|
-
|
|
138
|
-
// Height measurement configuration
|
|
139
|
-
heightMeasurement: defaultHeightMeasurementConfig,
|
|
140
|
-
|
|
141
|
-
// Template configuration
|
|
142
|
-
template: undefined as any,
|
|
143
|
-
|
|
144
|
-
// Collection configuration
|
|
145
|
-
collection: undefined as any,
|
|
146
|
-
|
|
147
|
-
// Static items
|
|
148
|
-
items: undefined as any,
|
|
149
|
-
|
|
150
|
-
// Debug mode
|
|
151
|
-
debug: false,
|
|
152
|
-
} as const;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Creates a validated List Manager configuration with defaults applied
|
|
156
|
-
* @param config - User provided configuration
|
|
157
|
-
* @returns Complete configuration with defaults
|
|
158
|
-
*/
|
|
159
|
-
export function createListManagerConfig(
|
|
160
|
-
config: ListManagerConfig = {}
|
|
161
|
-
): Required<ListManagerConfig> {
|
|
162
|
-
console.log("🔧 [LIST-MANAGER] Creating configuration");
|
|
163
|
-
|
|
164
|
-
// Validate container if provided
|
|
165
|
-
if (config.container) {
|
|
166
|
-
validateContainer(config.container);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Deep merge configuration with defaults
|
|
170
|
-
const mergedConfig = {
|
|
171
|
-
...defaultListManagerConfig,
|
|
172
|
-
...config,
|
|
173
|
-
|
|
174
|
-
// Deep merge nested objects
|
|
175
|
-
orientation: {
|
|
176
|
-
...defaultListManagerConfig.orientation,
|
|
177
|
-
...config.orientation,
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
virtual: {
|
|
181
|
-
...defaultListManagerConfig.virtual,
|
|
182
|
-
...config.virtual,
|
|
183
|
-
},
|
|
184
|
-
|
|
185
|
-
recycling: {
|
|
186
|
-
...defaultListManagerConfig.recycling,
|
|
187
|
-
...config.recycling,
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
scroll: {
|
|
191
|
-
...defaultListManagerConfig.scroll,
|
|
192
|
-
...config.scroll,
|
|
193
|
-
},
|
|
194
|
-
|
|
195
|
-
intersection: {
|
|
196
|
-
pagination: {
|
|
197
|
-
...defaultListManagerConfig.intersection.pagination,
|
|
198
|
-
...config.intersection?.pagination,
|
|
199
|
-
},
|
|
200
|
-
loading: {
|
|
201
|
-
...defaultListManagerConfig.intersection.loading,
|
|
202
|
-
...config.intersection?.loading,
|
|
203
|
-
},
|
|
204
|
-
preload: {
|
|
205
|
-
...defaultListManagerConfig.intersection.preload,
|
|
206
|
-
...config.intersection?.preload,
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
performance: {
|
|
211
|
-
...defaultListManagerConfig.performance,
|
|
212
|
-
...config.performance,
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
heightMeasurement: {
|
|
216
|
-
...defaultListManagerConfig.heightMeasurement,
|
|
217
|
-
...config.heightMeasurement,
|
|
218
|
-
},
|
|
219
|
-
} as Required<ListManagerConfig>;
|
|
220
|
-
|
|
221
|
-
// Validate the merged configuration
|
|
222
|
-
validateListManagerConfig(mergedConfig);
|
|
223
|
-
|
|
224
|
-
console.log("✅ [LIST-MANAGER] Configuration created and validated");
|
|
225
|
-
return mergedConfig;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Validates container element
|
|
230
|
-
* @param container - Container element or selector
|
|
231
|
-
*/
|
|
232
|
-
export function validateContainer(
|
|
233
|
-
container: HTMLElement | string | null
|
|
234
|
-
): void {
|
|
235
|
-
if (!container) return;
|
|
236
|
-
|
|
237
|
-
if (typeof container === "string") {
|
|
238
|
-
const element = document.querySelector(container);
|
|
239
|
-
if (!element) {
|
|
240
|
-
throw new Error(`List Manager container element not found: ${container}`);
|
|
241
|
-
}
|
|
242
|
-
} else if (!(container instanceof HTMLElement)) {
|
|
243
|
-
throw new Error(
|
|
244
|
-
"List Manager container must be an HTMLElement or CSS selector string"
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Validates complete List Manager configuration
|
|
251
|
-
* @param config - Configuration to validate
|
|
252
|
-
*/
|
|
253
|
-
export function validateListManagerConfig(
|
|
254
|
-
config: Required<ListManagerConfig>
|
|
255
|
-
): void {
|
|
256
|
-
// Validate virtual scrolling configuration
|
|
257
|
-
if (config.virtual.enabled) {
|
|
258
|
-
if (
|
|
259
|
-
typeof config.virtual.estimatedItemSize === "number" &&
|
|
260
|
-
config.virtual.estimatedItemSize <= 0
|
|
261
|
-
) {
|
|
262
|
-
throw new Error("List Manager estimated item height must be positive");
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (config.virtual.overscan < 0) {
|
|
266
|
-
throw new Error("List Manager overscan must be non-negative");
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (config.virtual.windowSize && config.virtual.windowSize <= 0) {
|
|
270
|
-
throw new Error("List Manager window size must be positive");
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Validate recycling configuration
|
|
275
|
-
if (config.recycling.enabled) {
|
|
276
|
-
if (config.recycling.maxPoolSize <= 0) {
|
|
277
|
-
throw new Error("List Manager max pool size must be positive");
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (config.recycling.minPoolSize < 0) {
|
|
281
|
-
throw new Error("List Manager min pool size must be non-negative");
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (config.recycling.minPoolSize > config.recycling.maxPoolSize) {
|
|
285
|
-
throw new Error("List Manager min pool size cannot exceed max pool size");
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Validate intersection observer configuration
|
|
290
|
-
if (config.intersection.pagination.enabled) {
|
|
291
|
-
if (
|
|
292
|
-
config.intersection.pagination.threshold < 0 ||
|
|
293
|
-
config.intersection.pagination.threshold > 1
|
|
294
|
-
) {
|
|
295
|
-
throw new Error(
|
|
296
|
-
"List Manager pagination threshold must be between 0 and 1"
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (config.intersection.loading.enabled) {
|
|
302
|
-
if (
|
|
303
|
-
config.intersection.loading.threshold < 0 ||
|
|
304
|
-
config.intersection.loading.threshold > 1
|
|
305
|
-
) {
|
|
306
|
-
throw new Error("List Manager loading threshold must be between 0 and 1");
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Validate performance configuration
|
|
311
|
-
if (config.performance.enabled) {
|
|
312
|
-
if (config.performance.fpsTarget && config.performance.fpsTarget <= 0) {
|
|
313
|
-
throw new Error("List Manager FPS target must be positive");
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (
|
|
317
|
-
config.performance.memoryThreshold &&
|
|
318
|
-
config.performance.memoryThreshold <= 0
|
|
319
|
-
) {
|
|
320
|
-
throw new Error("List Manager memory threshold must be positive");
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Validate height measurement configuration
|
|
325
|
-
if (config.heightMeasurement.enabled) {
|
|
326
|
-
if (config.heightMeasurement.estimatedHeight <= 0) {
|
|
327
|
-
throw new Error("List Manager estimated height must be positive");
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (config.heightMeasurement.cacheSize < 0) {
|
|
331
|
-
throw new Error("List Manager cache size must be non-negative");
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Validate orientation configuration
|
|
336
|
-
const validOrientations = ["vertical", "horizontal"];
|
|
337
|
-
if (!validOrientations.includes(config.orientation.orientation)) {
|
|
338
|
-
throw new Error(
|
|
339
|
-
`List Manager orientation must be one of: ${validOrientations.join(", ")}`
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
const validAlignments = ["start", "center", "end", "stretch"];
|
|
344
|
-
if (!validAlignments.includes(config.orientation.crossAxisAlignment)) {
|
|
345
|
-
throw new Error(
|
|
346
|
-
`List Manager cross axis alignment must be one of: ${validAlignments.join(
|
|
347
|
-
", "
|
|
348
|
-
)}`
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Creates configuration for specific features
|
|
355
|
-
*/
|
|
356
|
-
export const getFeatureConfigs = (config: Required<ListManagerConfig>) => ({
|
|
357
|
-
/**
|
|
358
|
-
* Gets orientation feature configuration
|
|
359
|
-
*/
|
|
360
|
-
orientation: () => ({
|
|
361
|
-
orientation: config.orientation.orientation,
|
|
362
|
-
autoDetect: config.orientation.autoDetect,
|
|
363
|
-
reverse: config.orientation.reverse,
|
|
364
|
-
crossAxisAlignment: config.orientation.crossAxisAlignment,
|
|
365
|
-
prefix: config.prefix,
|
|
366
|
-
componentName: config.componentName,
|
|
367
|
-
}),
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Gets viewport feature configuration
|
|
371
|
-
*/
|
|
372
|
-
viewport: () => ({
|
|
373
|
-
heightStrategy: "dynamic" as const,
|
|
374
|
-
heightBuffer: 2,
|
|
375
|
-
itemHeight: config.virtual.itemSize,
|
|
376
|
-
estimatedItemHeight: config.virtual.estimatedItemSize,
|
|
377
|
-
overscan: config.virtual.overscan,
|
|
378
|
-
windowSize: config.virtual.windowSize,
|
|
379
|
-
enabled: config.virtual.enabled,
|
|
380
|
-
prefix: config.prefix,
|
|
381
|
-
componentName: config.componentName,
|
|
382
|
-
}),
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Gets item size management configuration
|
|
386
|
-
*/
|
|
387
|
-
itemSize: () => ({
|
|
388
|
-
strategy: (config.virtual.itemSize === "auto"
|
|
389
|
-
? "dynamic"
|
|
390
|
-
: "fixed") as const,
|
|
391
|
-
defaultHeight:
|
|
392
|
-
typeof config.virtual.itemSize === "number"
|
|
393
|
-
? config.virtual.itemSize
|
|
394
|
-
: config.virtual.estimatedItemSize,
|
|
395
|
-
estimatedHeight: config.virtual.estimatedItemSize,
|
|
396
|
-
cacheSize: config.heightMeasurement.cacheSize,
|
|
397
|
-
enabled: config.heightMeasurement.enabled,
|
|
398
|
-
prefix: config.prefix,
|
|
399
|
-
componentName: config.componentName,
|
|
400
|
-
}),
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Gets recycling feature configuration
|
|
404
|
-
*/
|
|
405
|
-
recycling: () => ({
|
|
406
|
-
enabled: config.recycling.enabled,
|
|
407
|
-
maxPoolSize: config.recycling.maxPoolSize,
|
|
408
|
-
minPoolSize: config.recycling.minPoolSize,
|
|
409
|
-
recyclingStrategy: config.recycling.strategy,
|
|
410
|
-
prefix: config.prefix,
|
|
411
|
-
componentName: config.componentName,
|
|
412
|
-
}),
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Gets scroll behavior configuration
|
|
416
|
-
*/
|
|
417
|
-
scroll: () => ({
|
|
418
|
-
smooth: config.scroll.smooth,
|
|
419
|
-
restorePosition: config.scroll.restore,
|
|
420
|
-
behavior: config.scroll.behavior,
|
|
421
|
-
easing: config.scroll.easing,
|
|
422
|
-
duration: config.scroll.duration,
|
|
423
|
-
programmatic: config.scroll.programmatic,
|
|
424
|
-
prefix: config.prefix,
|
|
425
|
-
componentName: config.componentName,
|
|
426
|
-
}),
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Gets intersection observer configurations
|
|
430
|
-
*/
|
|
431
|
-
intersection: () => ({
|
|
432
|
-
pagination: {
|
|
433
|
-
enabled: config.intersection.pagination.enabled,
|
|
434
|
-
rootMargin: config.intersection.pagination.rootMargin,
|
|
435
|
-
threshold: config.intersection.pagination.threshold,
|
|
436
|
-
prefix: config.prefix,
|
|
437
|
-
componentName: config.componentName,
|
|
438
|
-
},
|
|
439
|
-
loading: {
|
|
440
|
-
enabled: config.intersection.loading.enabled,
|
|
441
|
-
rootMargin: config.intersection.loading.rootMargin,
|
|
442
|
-
threshold: config.intersection.loading.threshold,
|
|
443
|
-
prefix: config.prefix,
|
|
444
|
-
componentName: config.componentName,
|
|
445
|
-
},
|
|
446
|
-
preload: {
|
|
447
|
-
enabled: config.intersection.preload.enabled,
|
|
448
|
-
threshold: config.intersection.preload.threshold,
|
|
449
|
-
prefetchPages: config.intersection.preload.prefetchPages,
|
|
450
|
-
prefix: config.prefix,
|
|
451
|
-
componentName: config.componentName,
|
|
452
|
-
},
|
|
453
|
-
}),
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Gets performance feature configuration
|
|
457
|
-
*/
|
|
458
|
-
performance: () => ({
|
|
459
|
-
enabled: config.performance.enabled,
|
|
460
|
-
frameScheduling: config.performance.frameScheduling,
|
|
461
|
-
memoryCleanup: config.performance.memoryCleanup,
|
|
462
|
-
fpsMonitoring: config.performance.fpsMonitoring,
|
|
463
|
-
trackFPS: config.performance.trackFPS,
|
|
464
|
-
fpsTarget: config.performance.fpsTarget,
|
|
465
|
-
trackMemory: config.performance.trackMemory,
|
|
466
|
-
memoryThreshold: config.performance.memoryThreshold,
|
|
467
|
-
prefix: config.prefix,
|
|
468
|
-
componentName: config.componentName,
|
|
469
|
-
}),
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Configuration presets for common use cases
|
|
474
|
-
*/
|
|
475
|
-
export const configPresets = {
|
|
476
|
-
/**
|
|
477
|
-
* High performance configuration for large datasets
|
|
478
|
-
*/
|
|
479
|
-
highPerformance: (): Partial<ListManagerConfig> => ({
|
|
480
|
-
virtual: {
|
|
481
|
-
enabled: true,
|
|
482
|
-
overscan: 5,
|
|
483
|
-
windowSize: 20,
|
|
484
|
-
},
|
|
485
|
-
recycling: {
|
|
486
|
-
enabled: true,
|
|
487
|
-
maxPoolSize: 200,
|
|
488
|
-
minPoolSize: 20,
|
|
489
|
-
},
|
|
490
|
-
performance: {
|
|
491
|
-
enabled: true,
|
|
492
|
-
frameScheduling: true,
|
|
493
|
-
memoryCleanup: true,
|
|
494
|
-
fpsMonitoring: true,
|
|
495
|
-
trackFPS: true,
|
|
496
|
-
trackMemory: true,
|
|
497
|
-
},
|
|
498
|
-
intersection: {
|
|
499
|
-
pagination: { enabled: true },
|
|
500
|
-
loading: { enabled: true },
|
|
501
|
-
preload: { enabled: true, prefetchPages: 3 },
|
|
502
|
-
},
|
|
503
|
-
}),
|
|
504
|
-
|
|
505
|
-
/**
|
|
506
|
-
* Simple configuration for small datasets
|
|
507
|
-
*/
|
|
508
|
-
simple: (): Partial<ListManagerConfig> => ({
|
|
509
|
-
virtual: {
|
|
510
|
-
enabled: false,
|
|
511
|
-
},
|
|
512
|
-
recycling: {
|
|
513
|
-
enabled: false,
|
|
514
|
-
},
|
|
515
|
-
performance: {
|
|
516
|
-
enabled: false,
|
|
517
|
-
},
|
|
518
|
-
intersection: {
|
|
519
|
-
pagination: { enabled: false },
|
|
520
|
-
loading: { enabled: false },
|
|
521
|
-
preload: { enabled: false },
|
|
522
|
-
},
|
|
523
|
-
}),
|
|
524
|
-
|
|
525
|
-
/**
|
|
526
|
-
* Balanced configuration for medium datasets
|
|
527
|
-
*/
|
|
528
|
-
balanced: (): Partial<ListManagerConfig> => ({
|
|
529
|
-
virtual: {
|
|
530
|
-
enabled: true,
|
|
531
|
-
overscan: 3,
|
|
532
|
-
windowSize: 15,
|
|
533
|
-
},
|
|
534
|
-
recycling: {
|
|
535
|
-
enabled: true,
|
|
536
|
-
maxPoolSize: 100,
|
|
537
|
-
minPoolSize: 10,
|
|
538
|
-
},
|
|
539
|
-
performance: {
|
|
540
|
-
enabled: true,
|
|
541
|
-
frameScheduling: true,
|
|
542
|
-
memoryCleanup: false,
|
|
543
|
-
fpsMonitoring: false,
|
|
544
|
-
},
|
|
545
|
-
intersection: {
|
|
546
|
-
pagination: { enabled: true },
|
|
547
|
-
loading: { enabled: true },
|
|
548
|
-
preload: { enabled: false },
|
|
549
|
-
},
|
|
550
|
-
}),
|
|
551
|
-
};
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* Configuration debugging utilities
|
|
555
|
-
*/
|
|
556
|
-
export const configDebug = {
|
|
557
|
-
/**
|
|
558
|
-
* Logs configuration details
|
|
559
|
-
*/
|
|
560
|
-
logConfig: (config: Required<ListManagerConfig>): void => {
|
|
561
|
-
if (!config.debug) return;
|
|
562
|
-
|
|
563
|
-
console.group("🔧 [LIST-MANAGER] Configuration Details");
|
|
564
|
-
console.log("📦 Virtual Scrolling:", config.virtual);
|
|
565
|
-
console.log("♻️ Element Recycling:", config.recycling);
|
|
566
|
-
console.log("📏 Scroll Behavior:", config.scroll);
|
|
567
|
-
console.log("👀 Intersection:", config.intersection);
|
|
568
|
-
console.log("⚡ Performance:", config.performance);
|
|
569
|
-
console.log("📐 Height Measurement:", config.heightMeasurement);
|
|
570
|
-
console.log("🧭 Orientation:", config.orientation);
|
|
571
|
-
console.groupEnd();
|
|
572
|
-
},
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Validates configuration and reports issues
|
|
576
|
-
*/
|
|
577
|
-
validateAndReport: (config: ListManagerConfig): string[] => {
|
|
578
|
-
const issues: string[] = [];
|
|
579
|
-
|
|
580
|
-
try {
|
|
581
|
-
const fullConfig = createListManagerConfig(config);
|
|
582
|
-
console.log("✅ Configuration validation passed");
|
|
583
|
-
return issues;
|
|
584
|
-
} catch (error) {
|
|
585
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
586
|
-
issues.push(message);
|
|
587
|
-
console.error("❌ Configuration validation failed:", message);
|
|
588
|
-
return issues;
|
|
589
|
-
}
|
|
590
|
-
},
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
export default createListManagerConfig;
|