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
|
@@ -5,19 +5,10 @@
|
|
|
5
5
|
* Follows mtrl patterns for component configuration.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
createElementConfig as coreCreateElementConfig,
|
|
11
|
-
} from "mtrl/src/core/config/component";
|
|
12
|
-
import { LIST_DEFAULTS, LIST_CLASSES } from "./constants";
|
|
8
|
+
import { createComponentConfig, createElementConfig } from "mtrl";
|
|
9
|
+
import { VLIST_CLASSES } from "./constants";
|
|
13
10
|
import type { ListConfig, ListItem } from "./types";
|
|
14
11
|
import type { ListComponent } from "./types";
|
|
15
|
-
import { DATA_PAGINATION } from "../../core/collection/constants";
|
|
16
|
-
import { VIRTUAL_SCROLLING } from "../../core/list-manager/constants";
|
|
17
|
-
import {
|
|
18
|
-
convertRenderItemToTemplate,
|
|
19
|
-
getDefaultTemplate,
|
|
20
|
-
} from "../../core/list-manager/features/viewport/template";
|
|
21
12
|
|
|
22
13
|
/**
|
|
23
14
|
* Default configuration for the mtrl-addons List component
|
|
@@ -42,15 +33,14 @@ export const defaultConfig: Partial<ListConfig> = {
|
|
|
42
33
|
// Scroll settings
|
|
43
34
|
scroll: {
|
|
44
35
|
virtual: true,
|
|
45
|
-
itemSize:
|
|
46
|
-
estimatedItemSize: 50,
|
|
36
|
+
itemSize: 50,
|
|
47
37
|
overscan: 5,
|
|
48
38
|
animation: false,
|
|
49
39
|
restorePosition: false,
|
|
50
40
|
},
|
|
51
41
|
|
|
52
42
|
// Component settings
|
|
53
|
-
className:
|
|
43
|
+
className: VLIST_CLASSES.LIST,
|
|
54
44
|
prefix: "mtrl",
|
|
55
45
|
componentName: "list",
|
|
56
46
|
ariaLabel: "List",
|
|
@@ -62,6 +52,59 @@ export const defaultConfig: Partial<ListConfig> = {
|
|
|
62
52
|
* @param {ListConfig} config - User provided configuration
|
|
63
53
|
* @returns {ListConfig} Complete configuration with defaults applied
|
|
64
54
|
*/
|
|
55
|
+
// Minimal converter to avoid hardcoding external helpers
|
|
56
|
+
function convertRenderItemToTemplate(render: any) {
|
|
57
|
+
if (typeof render === "function") return render;
|
|
58
|
+
if (render && typeof render === "object") {
|
|
59
|
+
const { headline, supporting, leading, trailing } = render as any;
|
|
60
|
+
return (item: any, index: number) => {
|
|
61
|
+
const container = document.createElement("div");
|
|
62
|
+
container.className = "mtrl-list-item";
|
|
63
|
+
if (leading) {
|
|
64
|
+
const el = document.createElement("div");
|
|
65
|
+
el.className = "mtrl-list-item__leading";
|
|
66
|
+
el.innerHTML =
|
|
67
|
+
typeof leading === "function"
|
|
68
|
+
? leading(item, index)
|
|
69
|
+
: String(leading);
|
|
70
|
+
container.appendChild(el);
|
|
71
|
+
}
|
|
72
|
+
const content = document.createElement("div");
|
|
73
|
+
content.className = "mtrl-list-item__content";
|
|
74
|
+
if (headline) {
|
|
75
|
+
const h = document.createElement("div");
|
|
76
|
+
h.className = "mtrl-list-item__headline";
|
|
77
|
+
h.innerHTML =
|
|
78
|
+
typeof headline === "function"
|
|
79
|
+
? headline(item, index)
|
|
80
|
+
: String(headline);
|
|
81
|
+
content.appendChild(h);
|
|
82
|
+
}
|
|
83
|
+
if (supporting) {
|
|
84
|
+
const s = document.createElement("div");
|
|
85
|
+
s.className = "mtrl-list-item__supporting";
|
|
86
|
+
s.innerHTML =
|
|
87
|
+
typeof supporting === "function"
|
|
88
|
+
? supporting(item, index)
|
|
89
|
+
: String(supporting);
|
|
90
|
+
content.appendChild(s);
|
|
91
|
+
}
|
|
92
|
+
container.appendChild(content);
|
|
93
|
+
if (trailing) {
|
|
94
|
+
const el = document.createElement("div");
|
|
95
|
+
el.className = "mtrl-list-item__trailing";
|
|
96
|
+
el.innerHTML =
|
|
97
|
+
typeof trailing === "function"
|
|
98
|
+
? trailing(item, index)
|
|
99
|
+
: String(trailing);
|
|
100
|
+
container.appendChild(el);
|
|
101
|
+
}
|
|
102
|
+
return container;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return (item: any) => String(item);
|
|
106
|
+
}
|
|
107
|
+
|
|
65
108
|
export function createBaseConfig<T extends ListItem = ListItem>(
|
|
66
109
|
config: ListConfig<T> = {}
|
|
67
110
|
): Required<ListConfig<T>> {
|
|
@@ -74,15 +117,14 @@ export function createBaseConfig<T extends ListItem = ListItem>(
|
|
|
74
117
|
);
|
|
75
118
|
}
|
|
76
119
|
|
|
77
|
-
|
|
78
|
-
|
|
120
|
+
const mergedConfig = createComponentConfig(
|
|
121
|
+
defaultConfig as any,
|
|
122
|
+
config as any,
|
|
123
|
+
"list"
|
|
124
|
+
) as any;
|
|
79
125
|
|
|
80
126
|
// Convert renderItem object to template function if provided
|
|
81
|
-
if (
|
|
82
|
-
(config as any).renderItem &&
|
|
83
|
-
typeof (config as any).renderItem === "object" &&
|
|
84
|
-
!mergedConfig.template
|
|
85
|
-
) {
|
|
127
|
+
if ((config as any).renderItem && !mergedConfig.template) {
|
|
86
128
|
mergedConfig.template = convertRenderItemToTemplate(
|
|
87
129
|
(config as any).renderItem
|
|
88
130
|
);
|
|
@@ -114,11 +156,10 @@ export function getElementConfig<T extends ListItem = ListItem>(
|
|
|
114
156
|
"aria-label": config.ariaLabel || "List",
|
|
115
157
|
};
|
|
116
158
|
|
|
117
|
-
|
|
118
|
-
return coreCreateElementConfig(config, {
|
|
159
|
+
return createElementConfig(config as any, {
|
|
119
160
|
tag: "div",
|
|
120
161
|
attributes,
|
|
121
|
-
className:
|
|
162
|
+
className: VLIST_CLASSES.LIST,
|
|
122
163
|
});
|
|
123
164
|
}
|
|
124
165
|
|
|
@@ -274,79 +315,9 @@ export const validateConfig = (config: ListConfig): void => {
|
|
|
274
315
|
export const getCollectionConfig = (config: ListConfig) => ({
|
|
275
316
|
adapter: config.adapter,
|
|
276
317
|
items: config.items,
|
|
277
|
-
|
|
278
|
-
cache: config.collection?.cache || {
|
|
318
|
+
cache: (config.collection as any)?.cache || {
|
|
279
319
|
enabled: true,
|
|
280
320
|
maxSize: 1000,
|
|
281
321
|
ttl: 300000, // 5 minutes
|
|
282
322
|
},
|
|
283
323
|
});
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Creates List Manager configuration from List config
|
|
287
|
-
*/
|
|
288
|
-
export const getListManagerConfig = (config: ListConfig) => ({
|
|
289
|
-
// Container
|
|
290
|
-
container: config.container,
|
|
291
|
-
|
|
292
|
-
// Collection configuration
|
|
293
|
-
collection: getCollectionConfig(config),
|
|
294
|
-
|
|
295
|
-
// Template configuration
|
|
296
|
-
template: {
|
|
297
|
-
template: config.template,
|
|
298
|
-
},
|
|
299
|
-
|
|
300
|
-
// Component prefix
|
|
301
|
-
prefix: config.prefix || "mtrl",
|
|
302
|
-
|
|
303
|
-
// Orientation configuration
|
|
304
|
-
orientation: {
|
|
305
|
-
orientation: config.orientation?.orientation || "vertical",
|
|
306
|
-
autoDetect: config.orientation?.autoDetect || false,
|
|
307
|
-
reverse: config.orientation?.reverse || false,
|
|
308
|
-
crossAxisAlignment: config.orientation?.crossAxisAlignment || "stretch",
|
|
309
|
-
},
|
|
310
|
-
|
|
311
|
-
// Virtual scrolling
|
|
312
|
-
virtual: {
|
|
313
|
-
enabled: config.scroll?.virtual ?? true,
|
|
314
|
-
itemSize: config.scroll?.itemSize ?? "auto",
|
|
315
|
-
estimatedItemSize: config.scroll?.estimatedItemSize ?? 50,
|
|
316
|
-
overscan: config.scroll?.overscan ?? VIRTUAL_SCROLLING.DEFAULT_OVERSCAN,
|
|
317
|
-
...config.listManager?.virtual,
|
|
318
|
-
},
|
|
319
|
-
|
|
320
|
-
// Element recycling
|
|
321
|
-
recycling: {
|
|
322
|
-
enabled: config.listManager?.recycling?.enabled ?? true,
|
|
323
|
-
maxPoolSize: config.listManager?.recycling?.maxPoolSize ?? 100,
|
|
324
|
-
minPoolSize: config.listManager?.recycling?.minPoolSize ?? 10,
|
|
325
|
-
...config.listManager?.recycling,
|
|
326
|
-
},
|
|
327
|
-
|
|
328
|
-
// Intersection observers
|
|
329
|
-
intersection: {
|
|
330
|
-
pagination: {
|
|
331
|
-
enabled: true,
|
|
332
|
-
rootMargin: "200px",
|
|
333
|
-
threshold: 0.1,
|
|
334
|
-
...config.listManager?.intersection?.pagination,
|
|
335
|
-
},
|
|
336
|
-
loading: {
|
|
337
|
-
enabled: true,
|
|
338
|
-
...config.listManager?.intersection?.loading,
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
|
|
342
|
-
// Performance configuration
|
|
343
|
-
performance: {
|
|
344
|
-
frameScheduling: true,
|
|
345
|
-
memoryCleanup: true,
|
|
346
|
-
...config.listManager?.performance,
|
|
347
|
-
},
|
|
348
|
-
|
|
349
|
-
// Debug and styling
|
|
350
|
-
debug: config.debug || false,
|
|
351
|
-
componentName: "list-manager",
|
|
352
|
-
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mtrl-addons List Component Constants
|
|
3
|
+
*
|
|
4
|
+
* Constants for the addons list component.
|
|
5
|
+
* Note: Base mtrl list functionality is handled by mtrl core.
|
|
6
|
+
* These constants are for addons-specific features only.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* CSS class names for VList component
|
|
11
|
+
* Following BEM convention: component__element--modifier
|
|
12
|
+
* Note: mtrl prefix is added automatically by core DOM classes system
|
|
13
|
+
*/
|
|
14
|
+
export const VLIST_CLASSES = {
|
|
15
|
+
/** List element */
|
|
16
|
+
LIST: "vlist",
|
|
17
|
+
/** List item */
|
|
18
|
+
ITEM: "viewport-item",
|
|
19
|
+
/** Selected list item */
|
|
20
|
+
SELECTED: "viewport-item--selected",
|
|
21
|
+
/** Empty state */
|
|
22
|
+
EMPTY: "vlist--empty",
|
|
23
|
+
} as const;
|