mtrl-addons 0.2.1 → 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.
- package/{src/components/index.ts → dist/components/index.d.ts} +0 -2
- package/dist/components/vlist/config.d.ts +86 -0
- package/{src/components/vlist/constants.ts → dist/components/vlist/constants.d.ts} +10 -11
- package/dist/components/vlist/features/api.d.ts +7 -0
- package/{src/components/vlist/features/index.ts → dist/components/vlist/features/index.d.ts} +0 -2
- package/dist/components/vlist/features/selection.d.ts +6 -0
- package/dist/components/vlist/features/viewport.d.ts +9 -0
- package/dist/components/vlist/features.d.ts +31 -0
- package/{src/components/vlist/index.ts → dist/components/vlist/index.d.ts} +1 -9
- package/dist/components/vlist/types.d.ts +596 -0
- package/dist/components/vlist/vlist.d.ts +29 -0
- package/dist/core/compose/features/gestures/index.d.ts +86 -0
- package/dist/core/compose/features/gestures/longpress.d.ts +85 -0
- package/dist/core/compose/features/gestures/pan.d.ts +108 -0
- package/dist/core/compose/features/gestures/pinch.d.ts +111 -0
- package/dist/core/compose/features/gestures/rotate.d.ts +111 -0
- package/dist/core/compose/features/gestures/swipe.d.ts +149 -0
- package/dist/core/compose/features/gestures/tap.d.ts +79 -0
- package/{src/core/compose/features/index.ts → dist/core/compose/features/index.d.ts} +1 -2
- package/{src/core/compose/index.ts → dist/core/compose/index.d.ts} +2 -11
- package/{src/core/gestures/index.ts → dist/core/gestures/index.d.ts} +1 -20
- package/dist/core/gestures/longpress.d.ts +23 -0
- package/dist/core/gestures/manager.d.ts +14 -0
- package/dist/core/gestures/pan.d.ts +12 -0
- package/dist/core/gestures/pinch.d.ts +14 -0
- package/dist/core/gestures/rotate.d.ts +14 -0
- package/dist/core/gestures/swipe.d.ts +20 -0
- package/dist/core/gestures/tap.d.ts +12 -0
- package/dist/core/gestures/types.d.ts +320 -0
- package/dist/core/gestures/utils.d.ts +57 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/layout/config.d.ts +33 -0
- package/dist/core/layout/index.d.ts +51 -0
- package/dist/core/layout/jsx.d.ts +65 -0
- package/dist/core/layout/schema.d.ts +112 -0
- package/dist/core/layout/types.d.ts +69 -0
- package/dist/core/viewport/constants.d.ts +105 -0
- package/dist/core/viewport/features/base.d.ts +14 -0
- package/dist/core/viewport/features/collection.d.ts +41 -0
- package/dist/core/viewport/features/events.d.ts +13 -0
- package/{src/core/viewport/features/index.ts → dist/core/viewport/features/index.d.ts} +0 -7
- package/dist/core/viewport/features/item-size.d.ts +30 -0
- package/dist/core/viewport/features/loading.d.ts +34 -0
- package/dist/core/viewport/features/momentum.d.ts +17 -0
- package/dist/core/viewport/features/performance.d.ts +53 -0
- package/dist/core/viewport/features/placeholders.d.ts +38 -0
- package/dist/core/viewport/features/rendering.d.ts +16 -0
- package/dist/core/viewport/features/scrollbar.d.ts +26 -0
- package/dist/core/viewport/features/scrolling.d.ts +16 -0
- package/dist/core/viewport/features/utils.d.ts +43 -0
- package/dist/core/viewport/features/virtual.d.ts +18 -0
- package/{src/core/viewport/index.ts → dist/core/viewport/index.d.ts} +1 -17
- package/dist/core/viewport/types.d.ts +96 -0
- package/dist/core/viewport/utils/speed-tracker.d.ts +22 -0
- package/dist/core/viewport/viewport.d.ts +11 -0
- package/{src/index.ts → dist/index.d.ts} +0 -4
- package/dist/index.js +5143 -0
- package/dist/index.mjs +5111 -0
- package/dist/styles.css +254 -0
- package/dist/styles.css.map +1 -0
- package/package.json +6 -1
- package/src/styles/components/_vlist.scss +234 -213
- package/.cursorrules +0 -117
- package/AI.md +0 -241
- package/build.js +0 -201
- package/scripts/analyze-orphaned-functions.ts +0 -387
- package/scripts/debug/vlist-selection.ts +0 -121
- package/src/components/vlist/config.ts +0 -323
- package/src/components/vlist/features/api.ts +0 -322
- package/src/components/vlist/features/selection.ts +0 -444
- package/src/components/vlist/features/viewport.ts +0 -65
- package/src/components/vlist/features.ts +0 -112
- package/src/components/vlist/types.ts +0 -591
- package/src/components/vlist/vlist.ts +0 -92
- package/src/core/compose/features/gestures/index.ts +0 -227
- package/src/core/compose/features/gestures/longpress.ts +0 -383
- package/src/core/compose/features/gestures/pan.ts +0 -424
- package/src/core/compose/features/gestures/pinch.ts +0 -475
- package/src/core/compose/features/gestures/rotate.ts +0 -485
- package/src/core/compose/features/gestures/swipe.ts +0 -492
- package/src/core/compose/features/gestures/tap.ts +0 -334
- package/src/core/gestures/longpress.ts +0 -68
- package/src/core/gestures/manager.ts +0 -418
- package/src/core/gestures/pan.ts +0 -48
- package/src/core/gestures/pinch.ts +0 -58
- package/src/core/gestures/rotate.ts +0 -58
- package/src/core/gestures/swipe.ts +0 -66
- package/src/core/gestures/tap.ts +0 -45
- package/src/core/gestures/types.ts +0 -387
- package/src/core/gestures/utils.ts +0 -128
- package/src/core/index.ts +0 -43
- package/src/core/layout/config.ts +0 -102
- package/src/core/layout/index.ts +0 -168
- package/src/core/layout/jsx.ts +0 -174
- package/src/core/layout/schema.ts +0 -1001
- package/src/core/layout/types.ts +0 -95
- package/src/core/viewport/constants.ts +0 -140
- package/src/core/viewport/features/base.ts +0 -73
- package/src/core/viewport/features/collection.ts +0 -882
- package/src/core/viewport/features/events.ts +0 -130
- package/src/core/viewport/features/item-size.ts +0 -271
- package/src/core/viewport/features/loading.ts +0 -263
- package/src/core/viewport/features/momentum.ts +0 -260
- package/src/core/viewport/features/performance.ts +0 -161
- package/src/core/viewport/features/placeholders.ts +0 -335
- package/src/core/viewport/features/rendering.ts +0 -568
- package/src/core/viewport/features/scrollbar.ts +0 -434
- package/src/core/viewport/features/scrolling.ts +0 -618
- package/src/core/viewport/features/utils.ts +0 -88
- package/src/core/viewport/features/virtual.ts +0 -384
- package/src/core/viewport/types.ts +0 -133
- package/src/core/viewport/utils/speed-tracker.ts +0 -79
- package/src/core/viewport/viewport.ts +0 -246
- package/test/benchmarks/layout/advanced.test.ts +0 -656
- package/test/benchmarks/layout/comparison.test.ts +0 -519
- package/test/benchmarks/layout/performance-comparison.test.ts +0 -274
- package/test/benchmarks/layout/real-components.test.ts +0 -733
- package/test/benchmarks/layout/simple.test.ts +0 -321
- package/test/benchmarks/layout/stress.test.ts +0 -990
- package/test/collection/basic.test.ts +0 -304
- package/test/components/vlist-selection.test.ts +0 -240
- package/test/components/vlist.test.ts +0 -63
- package/test/core/collection/adapter.test.ts +0 -161
- package/test/core/collection/collection.test.ts +0 -394
- package/test/core/layout/layout.test.ts +0 -201
- package/test/utils/dom-helpers.ts +0 -275
- package/test/utils/performance-helpers.ts +0 -392
- package/tsconfig.json +0 -20
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VList Types - Virtual List with direct viewport integration
|
|
3
|
+
*/
|
|
4
|
+
import type { BaseComponent, ElementComponent } from "mtrl";
|
|
5
|
+
/** Options for removeItemById */
|
|
6
|
+
export interface RemoveItemOptions {
|
|
7
|
+
/** Track as pending removal to filter from future fetches (default: true) */
|
|
8
|
+
trackPending?: boolean;
|
|
9
|
+
/** Timeout in ms to clear pending removal (default: 5000) */
|
|
10
|
+
pendingTimeout?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CollectionItem {
|
|
13
|
+
id: string | number;
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}
|
|
16
|
+
export interface CollectionConfig<T = any> {
|
|
17
|
+
adapter?: {
|
|
18
|
+
read(params?: any): Promise<{
|
|
19
|
+
items: T[];
|
|
20
|
+
meta?: any;
|
|
21
|
+
error?: any;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface Collection<T = any> {
|
|
26
|
+
loadMissingRanges?: (range: {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
}, reason?: string) => Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
import type { ViewportComponent } from "../../core/viewport/types";
|
|
32
|
+
/**
|
|
33
|
+
* List item interface - extends collection item
|
|
34
|
+
*/
|
|
35
|
+
export interface ListItem extends CollectionItem {
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* List adapter interface - extends collection adapter
|
|
39
|
+
*/
|
|
40
|
+
export interface ListAdapter<T extends ListItem = ListItem> {
|
|
41
|
+
read(params?: ListAdapterParams): Promise<ListAdapterResponse<T>>;
|
|
42
|
+
write?(items: T[]): Promise<ListAdapterResponse<T>>;
|
|
43
|
+
delete?(ids: string[]): Promise<ListAdapterResponse<T>>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* List adapter parameters
|
|
47
|
+
*/
|
|
48
|
+
export interface ListAdapterParams {
|
|
49
|
+
page?: number;
|
|
50
|
+
pageSize?: number;
|
|
51
|
+
offset?: number;
|
|
52
|
+
cursor?: string;
|
|
53
|
+
search?: string;
|
|
54
|
+
filters?: Record<string, any>;
|
|
55
|
+
sort?: {
|
|
56
|
+
field: string;
|
|
57
|
+
direction: "asc" | "desc";
|
|
58
|
+
}[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* List adapter response
|
|
62
|
+
*/
|
|
63
|
+
export interface ListAdapterResponse<T extends ListItem = ListItem> {
|
|
64
|
+
items: T[];
|
|
65
|
+
meta?: {
|
|
66
|
+
total?: number;
|
|
67
|
+
page?: number;
|
|
68
|
+
pageSize?: number;
|
|
69
|
+
hasNext?: boolean;
|
|
70
|
+
hasPrev?: boolean;
|
|
71
|
+
cursor?: string;
|
|
72
|
+
};
|
|
73
|
+
error?: {
|
|
74
|
+
message: string;
|
|
75
|
+
code?: string;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* List template definition
|
|
80
|
+
*/
|
|
81
|
+
export type ListTemplate = (item: any, index: number) => string | HTMLElement;
|
|
82
|
+
/**
|
|
83
|
+
* List item template function
|
|
84
|
+
*/
|
|
85
|
+
export type ListItemTemplate<T = any> = (item: T, index: number) => string | HTMLElement;
|
|
86
|
+
/**
|
|
87
|
+
* List scroll behavior configuration
|
|
88
|
+
*/
|
|
89
|
+
export interface ListScrollConfig {
|
|
90
|
+
/** Enable virtual scrolling */
|
|
91
|
+
virtual?: boolean;
|
|
92
|
+
/** Item size (fixed) or 'auto' for dynamic - height for vertical, width for horizontal */
|
|
93
|
+
itemSize?: number | "auto";
|
|
94
|
+
/** Number of items to render outside viewport */
|
|
95
|
+
overscan?: number;
|
|
96
|
+
/** Enable scroll animations */
|
|
97
|
+
animation?: boolean;
|
|
98
|
+
/** Restore scroll position on reload */
|
|
99
|
+
restorePosition?: boolean;
|
|
100
|
+
/** Enable item measurement for dynamic sizing (default: false) */
|
|
101
|
+
measureItems?: boolean;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* List styling configuration
|
|
105
|
+
*/
|
|
106
|
+
export interface ListStyleConfig {
|
|
107
|
+
/** CSS class prefix */
|
|
108
|
+
prefix?: string;
|
|
109
|
+
/** Component name for class generation */
|
|
110
|
+
componentName?: string;
|
|
111
|
+
/** Additional CSS classes */
|
|
112
|
+
className?: string;
|
|
113
|
+
/** List variant */
|
|
114
|
+
variant?: "default" | "dense" | "comfortable";
|
|
115
|
+
/** List density */
|
|
116
|
+
density?: "default" | "compact" | "comfortable";
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* List event handlers
|
|
120
|
+
*/
|
|
121
|
+
export interface ListEventHandlers<T = any> {
|
|
122
|
+
/** Item click handler */
|
|
123
|
+
onItemClick?: (item: T, index: number, event: MouseEvent) => void;
|
|
124
|
+
/** Item selection change */
|
|
125
|
+
onSelectionChange?: (selectedItems: T[], selectedIndices: number[]) => void;
|
|
126
|
+
/** Scroll event */
|
|
127
|
+
onScroll?: (scrollTop: number, direction: "up" | "down" | "none") => void;
|
|
128
|
+
/** Viewport change event */
|
|
129
|
+
onViewportChange?: (visibleRange: {
|
|
130
|
+
start: number;
|
|
131
|
+
end: number;
|
|
132
|
+
}) => void;
|
|
133
|
+
/** Load more data event */
|
|
134
|
+
onLoadMore?: (direction: "forward" | "backward") => void | Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* List selection configuration
|
|
138
|
+
*/
|
|
139
|
+
export interface ListSelectionConfig {
|
|
140
|
+
/** Enable selection */
|
|
141
|
+
enabled?: boolean;
|
|
142
|
+
/** Selection mode */
|
|
143
|
+
mode?: "single" | "multiple" | "none";
|
|
144
|
+
/** Initially selected indices */
|
|
145
|
+
selectedIndices?: number[];
|
|
146
|
+
/** Selection change callback */
|
|
147
|
+
onSelectionChange?: (selectedItems: any[], selectedIndices: number[]) => void;
|
|
148
|
+
/** Require keyboard modifiers for multi-select (default: false) */
|
|
149
|
+
requireModifiers?: boolean;
|
|
150
|
+
/** Automatically select first item after initial load (default: false) */
|
|
151
|
+
autoSelectFirst?: boolean;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* List orientation configuration
|
|
155
|
+
*/
|
|
156
|
+
export interface ListOrientationConfig {
|
|
157
|
+
/** List orientation */
|
|
158
|
+
orientation?: "horizontal" | "vertical";
|
|
159
|
+
/** Whether to auto-detect orientation based on container */
|
|
160
|
+
autoDetect?: boolean;
|
|
161
|
+
/** Reverse direction (RTL for horizontal, bottom-to-top for vertical) */
|
|
162
|
+
reverse?: boolean;
|
|
163
|
+
/** Cross-axis alignment */
|
|
164
|
+
crossAxisAlignment?: "start" | "center" | "end" | "stretch";
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* List pagination configuration
|
|
168
|
+
*/
|
|
169
|
+
export interface ListPaginationConfig {
|
|
170
|
+
/** Pagination strategy */
|
|
171
|
+
strategy?: "page" | "offset" | "cursor";
|
|
172
|
+
/** Fixed page size/limit (overrides viewport-based calculation) */
|
|
173
|
+
limit?: number;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Complete List component configuration
|
|
177
|
+
*/
|
|
178
|
+
export interface ListConfig<T extends ListItem = ListItem> extends ListStyleConfig {
|
|
179
|
+
collection?: Partial<CollectionConfig<T>>;
|
|
180
|
+
listManager?: Partial<any>;
|
|
181
|
+
pagination?: ListPaginationConfig;
|
|
182
|
+
/** Container element or selector */
|
|
183
|
+
container?: HTMLElement | string;
|
|
184
|
+
/** List orientation configuration */
|
|
185
|
+
orientation?: ListOrientationConfig;
|
|
186
|
+
/** Item template function */
|
|
187
|
+
template?: ListItemTemplate<T>;
|
|
188
|
+
/** Static items (for non-API lists) */
|
|
189
|
+
items?: T[];
|
|
190
|
+
/** Data adapter (can be passed at top level or nested under collection) */
|
|
191
|
+
adapter?: ListAdapter<T>;
|
|
192
|
+
/** Scroll behavior configuration */
|
|
193
|
+
scroll?: ListScrollConfig;
|
|
194
|
+
/** Selection configuration */
|
|
195
|
+
selection?: ListSelectionConfig;
|
|
196
|
+
/** Event handlers */
|
|
197
|
+
on?: ListEventHandlers<T>;
|
|
198
|
+
/** Enable debugging */
|
|
199
|
+
debug?: boolean;
|
|
200
|
+
/** Accessibility label */
|
|
201
|
+
ariaLabel?: string;
|
|
202
|
+
/** Loading message template */
|
|
203
|
+
loadingTemplate?: string | (() => string | HTMLElement);
|
|
204
|
+
/** Empty state template */
|
|
205
|
+
emptyTemplate?: string | (() => string | HTMLElement);
|
|
206
|
+
/** Error state template */
|
|
207
|
+
errorTemplate?: string | ((error: Error) => string | HTMLElement);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* List state interface
|
|
211
|
+
*/
|
|
212
|
+
export interface ListState {
|
|
213
|
+
/** Current loading state */
|
|
214
|
+
isLoading: boolean;
|
|
215
|
+
/** Current error state */
|
|
216
|
+
error: Error | null;
|
|
217
|
+
/** Whether list is empty */
|
|
218
|
+
isEmpty: boolean;
|
|
219
|
+
/** Current scroll position */
|
|
220
|
+
scrollTop: number;
|
|
221
|
+
/** Current visible range */
|
|
222
|
+
visibleRange: {
|
|
223
|
+
start: number;
|
|
224
|
+
end: number;
|
|
225
|
+
count: number;
|
|
226
|
+
};
|
|
227
|
+
/** Current render range */
|
|
228
|
+
renderRange: {
|
|
229
|
+
start: number;
|
|
230
|
+
end: number;
|
|
231
|
+
count: number;
|
|
232
|
+
};
|
|
233
|
+
/** Selected item indices */
|
|
234
|
+
selectedIndices: number[];
|
|
235
|
+
/** Total number of items */
|
|
236
|
+
totalItems: number;
|
|
237
|
+
/** Whether virtual scrolling is active */
|
|
238
|
+
isVirtual: boolean;
|
|
239
|
+
/** Whether scrolling animations are enabled */
|
|
240
|
+
animationEnabled: boolean;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* List item rendering context
|
|
244
|
+
*/
|
|
245
|
+
export interface ListItemContext<T = any> {
|
|
246
|
+
/** Item data */
|
|
247
|
+
item: T;
|
|
248
|
+
/** Item index */
|
|
249
|
+
index: number;
|
|
250
|
+
/** Whether item is selected */
|
|
251
|
+
isSelected: boolean;
|
|
252
|
+
/** Whether item is visible in viewport */
|
|
253
|
+
isVisible: boolean;
|
|
254
|
+
/** Whether item is in render range */
|
|
255
|
+
isInRenderRange: boolean;
|
|
256
|
+
/** Item element (if rendered) */
|
|
257
|
+
element?: HTMLElement;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* List component events
|
|
261
|
+
*/
|
|
262
|
+
export interface ListEvents<T = any> {
|
|
263
|
+
/** Item clicked */
|
|
264
|
+
"item:click": {
|
|
265
|
+
item: T;
|
|
266
|
+
index: number;
|
|
267
|
+
event: MouseEvent;
|
|
268
|
+
};
|
|
269
|
+
/** Item selected/deselected */
|
|
270
|
+
"item:selection:change": {
|
|
271
|
+
item: T;
|
|
272
|
+
index: number;
|
|
273
|
+
isSelected: boolean;
|
|
274
|
+
};
|
|
275
|
+
/** Selection changed */
|
|
276
|
+
"selection:change": {
|
|
277
|
+
selectedItems: T[];
|
|
278
|
+
selectedIndices: number[];
|
|
279
|
+
};
|
|
280
|
+
/** Scroll position changed */
|
|
281
|
+
"scroll:change": {
|
|
282
|
+
scrollTop: number;
|
|
283
|
+
direction: "up" | "down" | "none";
|
|
284
|
+
};
|
|
285
|
+
/** Viewport changed */
|
|
286
|
+
"viewport:change": {
|
|
287
|
+
visibleRange: {
|
|
288
|
+
start: number;
|
|
289
|
+
end: number;
|
|
290
|
+
count: number;
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
/** Load more triggered */
|
|
294
|
+
"load:more": {
|
|
295
|
+
direction: "forward" | "backward";
|
|
296
|
+
};
|
|
297
|
+
/** Data loaded */
|
|
298
|
+
"data:loaded": {
|
|
299
|
+
items: T[];
|
|
300
|
+
total: number;
|
|
301
|
+
};
|
|
302
|
+
/** Loading state changed */
|
|
303
|
+
"loading:change": {
|
|
304
|
+
isLoading: boolean;
|
|
305
|
+
};
|
|
306
|
+
/** Error occurred */
|
|
307
|
+
error: {
|
|
308
|
+
error: Error;
|
|
309
|
+
};
|
|
310
|
+
/** List rendered */
|
|
311
|
+
"render:complete": {
|
|
312
|
+
renderRange: {
|
|
313
|
+
start: number;
|
|
314
|
+
end: number;
|
|
315
|
+
count: number;
|
|
316
|
+
};
|
|
317
|
+
};
|
|
318
|
+
/** Item updated */
|
|
319
|
+
"item:updated": {
|
|
320
|
+
item: T;
|
|
321
|
+
index: number;
|
|
322
|
+
previousItem: T;
|
|
323
|
+
wasVisible: boolean;
|
|
324
|
+
};
|
|
325
|
+
/** Viewport range loaded (data available for range) */
|
|
326
|
+
"viewport:range-loaded": {
|
|
327
|
+
range: {
|
|
328
|
+
start: number;
|
|
329
|
+
end: number;
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* List component API
|
|
335
|
+
*/
|
|
336
|
+
export interface ListAPI<T extends ListItem = ListItem> {
|
|
337
|
+
/** Load data */
|
|
338
|
+
loadData(): Promise<void>;
|
|
339
|
+
/** Reload data */
|
|
340
|
+
reload(): Promise<void>;
|
|
341
|
+
/** Clear all data */
|
|
342
|
+
clear(): void;
|
|
343
|
+
/** Add items */
|
|
344
|
+
addItems(items: T[], position?: "start" | "end"): void;
|
|
345
|
+
/** Remove items by indices */
|
|
346
|
+
removeItems(indices: number[]): void;
|
|
347
|
+
/**
|
|
348
|
+
* Remove item at a specific index
|
|
349
|
+
* Removes the item from the collection, updates totalItems, and triggers re-render
|
|
350
|
+
* @param index - The index of the item to remove
|
|
351
|
+
* @returns true if item was found and removed, false otherwise
|
|
352
|
+
*/
|
|
353
|
+
removeItem(index: number): boolean;
|
|
354
|
+
/**
|
|
355
|
+
* Remove item by ID
|
|
356
|
+
* Finds the item in the collection by its ID and removes it
|
|
357
|
+
* Updates totalItems and triggers re-render of visible items
|
|
358
|
+
* Optionally tracks as pending removal to filter from future fetches
|
|
359
|
+
* @param id - The item ID to find and remove
|
|
360
|
+
* @param options - Remove options (trackPending, pendingTimeout)
|
|
361
|
+
* @returns true if item was found and removed, false otherwise
|
|
362
|
+
*/
|
|
363
|
+
removeItemById(id: string | number, options?: RemoveItemOptions): boolean;
|
|
364
|
+
/**
|
|
365
|
+
* Check if an item ID is pending removal
|
|
366
|
+
* @param id - The item ID to check
|
|
367
|
+
* @returns true if the item is pending removal
|
|
368
|
+
*/
|
|
369
|
+
isPendingRemoval(id: string | number): boolean;
|
|
370
|
+
/**
|
|
371
|
+
* Get all pending removal IDs
|
|
372
|
+
* @returns Set of pending removal IDs
|
|
373
|
+
*/
|
|
374
|
+
getPendingRemovals(): Set<string | number>;
|
|
375
|
+
/**
|
|
376
|
+
* Clear a specific pending removal
|
|
377
|
+
* @param id - The item ID to clear from pending removals
|
|
378
|
+
*/
|
|
379
|
+
clearPendingRemoval(id: string | number): void;
|
|
380
|
+
/**
|
|
381
|
+
* Clear all pending removals
|
|
382
|
+
*/
|
|
383
|
+
clearAllPendingRemovals(): void;
|
|
384
|
+
/**
|
|
385
|
+
* Filter items array to exclude pending removals
|
|
386
|
+
* Utility method for use in collection adapters
|
|
387
|
+
* @param items - Array of items to filter
|
|
388
|
+
* @returns Filtered array without pending removal items
|
|
389
|
+
*/
|
|
390
|
+
filterPendingRemovals<I extends {
|
|
391
|
+
id?: any;
|
|
392
|
+
_id?: any;
|
|
393
|
+
}>(items: I[]): I[];
|
|
394
|
+
/** Update item at index */
|
|
395
|
+
updateItem(index: number, item: T): void;
|
|
396
|
+
/**
|
|
397
|
+
* Update item by ID
|
|
398
|
+
* Finds the item in the collection by its ID and updates it with new data
|
|
399
|
+
* Re-renders the item if currently visible in the viewport
|
|
400
|
+
* @param id - The item ID to find
|
|
401
|
+
* @param data - Partial data to merge with existing item, or full item replacement
|
|
402
|
+
* @param options - Update options
|
|
403
|
+
* @returns true if item was found and updated, false otherwise
|
|
404
|
+
*/
|
|
405
|
+
updateItemById(id: string | number, data: Partial<T>, options?: {
|
|
406
|
+
/** If true, replace the entire item instead of merging (default: false) */
|
|
407
|
+
replace?: boolean;
|
|
408
|
+
/** If true, re-render even if not visible (default: false) */
|
|
409
|
+
forceRender?: boolean;
|
|
410
|
+
}): boolean;
|
|
411
|
+
/** Get item at index */
|
|
412
|
+
getItem(index: number): T | undefined;
|
|
413
|
+
/** Get all items */
|
|
414
|
+
getItems(): T[];
|
|
415
|
+
/** Get total item count */
|
|
416
|
+
getItemCount(): number;
|
|
417
|
+
/** Scroll to item index */
|
|
418
|
+
scrollToIndex(index: number, alignment?: "start" | "center" | "end"): Promise<void>;
|
|
419
|
+
/** Scroll to top */
|
|
420
|
+
scrollToTop(): Promise<void>;
|
|
421
|
+
/** Scroll to bottom */
|
|
422
|
+
scrollToBottom(): Promise<void>;
|
|
423
|
+
/** Get current scroll position */
|
|
424
|
+
getScrollPosition(): number;
|
|
425
|
+
/** Enable or disable scroll animations */
|
|
426
|
+
setAnimationEnabled(enabled: boolean): void;
|
|
427
|
+
/** Get current animation enabled state */
|
|
428
|
+
getAnimationEnabled(): boolean;
|
|
429
|
+
/** Toggle animation on/off */
|
|
430
|
+
toggleAnimation(): void;
|
|
431
|
+
/** Select items by indices */
|
|
432
|
+
selectItems(indices: number[]): void;
|
|
433
|
+
/** Deselect items by indices */
|
|
434
|
+
deselectItems(indices: number[]): void;
|
|
435
|
+
/** Clear selection */
|
|
436
|
+
clearSelection(): void;
|
|
437
|
+
/** Get selected items */
|
|
438
|
+
getSelectedItems(): T[];
|
|
439
|
+
/** Get selected indices */
|
|
440
|
+
getSelectedIndices(): number[];
|
|
441
|
+
/** Check if item is selected */
|
|
442
|
+
isSelected(index: number): boolean;
|
|
443
|
+
/** Select an item by its ID
|
|
444
|
+
* @param id - The ID of the item to select
|
|
445
|
+
* @param silent - If true, selection won't emit change event (default: false)
|
|
446
|
+
*/
|
|
447
|
+
selectById(id: string | number, silent?: boolean): boolean;
|
|
448
|
+
/**
|
|
449
|
+
* Select item at index, scrolling and waiting for data if needed
|
|
450
|
+
* Handles virtual scrolling by loading data before selecting
|
|
451
|
+
*/
|
|
452
|
+
selectAtIndex(index: number): Promise<boolean>;
|
|
453
|
+
/**
|
|
454
|
+
* Select next item relative to current selection
|
|
455
|
+
* Handles virtual scrolling by loading data before selecting
|
|
456
|
+
* @returns Promise resolving to true if selection changed, false if at end
|
|
457
|
+
*/
|
|
458
|
+
selectNext(): Promise<boolean>;
|
|
459
|
+
/**
|
|
460
|
+
* Select previous item relative to current selection
|
|
461
|
+
* Handles virtual scrolling by loading data before selecting
|
|
462
|
+
* @returns Promise resolving to true if selection changed, false if at start
|
|
463
|
+
*/
|
|
464
|
+
selectPrevious(): Promise<boolean>;
|
|
465
|
+
/** Get current list state */
|
|
466
|
+
getState(): ListState;
|
|
467
|
+
/** Check if list is loading */
|
|
468
|
+
isLoading(): boolean;
|
|
469
|
+
/** Check if list has error */
|
|
470
|
+
hasError(): boolean;
|
|
471
|
+
/** Check if list is empty */
|
|
472
|
+
isEmpty(): boolean;
|
|
473
|
+
/** Force re-render */
|
|
474
|
+
render(): void;
|
|
475
|
+
/** Update viewport */
|
|
476
|
+
updateViewport(): void;
|
|
477
|
+
/** Get visible range */
|
|
478
|
+
getVisibleRange(): {
|
|
479
|
+
start: number;
|
|
480
|
+
end: number;
|
|
481
|
+
count: number;
|
|
482
|
+
};
|
|
483
|
+
/** Get render range */
|
|
484
|
+
getRenderRange(): {
|
|
485
|
+
start: number;
|
|
486
|
+
end: number;
|
|
487
|
+
count: number;
|
|
488
|
+
};
|
|
489
|
+
/** Update item template */
|
|
490
|
+
setTemplate(template: ListItemTemplate<T>): void;
|
|
491
|
+
/** Set loading template */
|
|
492
|
+
setLoadingTemplate(template: string | (() => string | HTMLElement)): void;
|
|
493
|
+
/** Set empty template */
|
|
494
|
+
setEmptyTemplate(template: string | (() => string | HTMLElement)): void;
|
|
495
|
+
/** Set error template */
|
|
496
|
+
setErrorTemplate(template: string | ((error: Error) => string | HTMLElement)): void;
|
|
497
|
+
/** Update list configuration */
|
|
498
|
+
updateConfig(config: Partial<ListConfig<T>>): void;
|
|
499
|
+
/** Get current configuration */
|
|
500
|
+
getConfig(): ListConfig<T>;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* List component interface (extends mtrl component patterns)
|
|
504
|
+
*/
|
|
505
|
+
export interface ListComponent<T extends ListItem = ListItem> extends BaseComponent, ElementComponent, ListAPI<T> {
|
|
506
|
+
/** Collection instance (data layer) */
|
|
507
|
+
collection: Collection<T>;
|
|
508
|
+
/** List manager instance (performance layer) */
|
|
509
|
+
listManager: any;
|
|
510
|
+
/** Current list state */
|
|
511
|
+
state: ListState;
|
|
512
|
+
/** List configuration */
|
|
513
|
+
config: ListConfig<T>;
|
|
514
|
+
/** Component lifecycle methods */
|
|
515
|
+
lifecycle: {
|
|
516
|
+
init(): void;
|
|
517
|
+
destroy(): void;
|
|
518
|
+
update(): void;
|
|
519
|
+
};
|
|
520
|
+
/** Event system (inherited from BaseComponent) */
|
|
521
|
+
on<K extends keyof ListEvents<T>>(event: K, handler: (payload: ListEvents<T>[K]) => void): void;
|
|
522
|
+
emit<K extends keyof ListEvents<T>>(event: K, payload: ListEvents<T>[K]): void;
|
|
523
|
+
off<K extends keyof ListEvents<T>>(event: K, handler?: (payload: ListEvents<T>[K]) => void): void;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* List performance metrics
|
|
527
|
+
*/
|
|
528
|
+
export interface ListPerformanceMetrics {
|
|
529
|
+
renderCount: number;
|
|
530
|
+
scrollCount: number;
|
|
531
|
+
averageRenderTime: number;
|
|
532
|
+
averageScrollTime: number;
|
|
533
|
+
memoryUsage: number;
|
|
534
|
+
virtualizedItems: number;
|
|
535
|
+
recycledElements: number;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* List feature options
|
|
539
|
+
*/
|
|
540
|
+
export interface ListFeatures {
|
|
541
|
+
virtualScroll?: boolean;
|
|
542
|
+
selection?: boolean;
|
|
543
|
+
styling?: boolean;
|
|
544
|
+
performance?: boolean;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* VList configuration interface
|
|
548
|
+
*/
|
|
549
|
+
export interface VListConfig<T extends ListItem = ListItem> {
|
|
550
|
+
parent?: HTMLElement | string;
|
|
551
|
+
container?: HTMLElement | string;
|
|
552
|
+
class?: string;
|
|
553
|
+
className?: string;
|
|
554
|
+
prefix?: string;
|
|
555
|
+
ariaLabel?: string;
|
|
556
|
+
debug?: boolean;
|
|
557
|
+
initialScrollIndex?: number;
|
|
558
|
+
selectId?: string | number;
|
|
559
|
+
autoLoad?: boolean;
|
|
560
|
+
items?: T[];
|
|
561
|
+
template?: (item: T, index: number) => string | HTMLElement | any[] | Record<string, any>;
|
|
562
|
+
collection?: {
|
|
563
|
+
adapter?: ListAdapter<T>;
|
|
564
|
+
transform?: (item: T) => T;
|
|
565
|
+
};
|
|
566
|
+
pagination?: {
|
|
567
|
+
strategy?: "page" | "offset" | "cursor";
|
|
568
|
+
limit?: number;
|
|
569
|
+
};
|
|
570
|
+
virtual?: {
|
|
571
|
+
itemSize?: number;
|
|
572
|
+
overscan?: number;
|
|
573
|
+
};
|
|
574
|
+
scrolling?: {
|
|
575
|
+
orientation?: "vertical" | "horizontal";
|
|
576
|
+
animation?: boolean;
|
|
577
|
+
measureItems?: boolean;
|
|
578
|
+
};
|
|
579
|
+
performance?: {
|
|
580
|
+
recycleElements?: boolean;
|
|
581
|
+
bufferSize?: number;
|
|
582
|
+
renderDebounce?: number;
|
|
583
|
+
maxConcurrentRequests?: number;
|
|
584
|
+
/** Velocity threshold (px/ms) above which data loading is cancelled and placeholders are shown. Default: 2 */
|
|
585
|
+
cancelLoadThreshold?: number;
|
|
586
|
+
};
|
|
587
|
+
selection?: ListSelectionConfig;
|
|
588
|
+
on?: ListEventHandlers<T>;
|
|
589
|
+
}
|
|
590
|
+
export type VListComponent<T extends ListItem = ListItem> = ListComponent<T> & {
|
|
591
|
+
viewport: ViewportComponent["viewport"];
|
|
592
|
+
};
|
|
593
|
+
export type VListItem = ListItem;
|
|
594
|
+
export type VListAPI<T extends ListItem = ListItem> = ListAPI<T>;
|
|
595
|
+
export type VListState = ListState;
|
|
596
|
+
export type VListEvents<T = any> = ListEvents<T>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VList Component - Virtual List with direct viewport integration
|
|
3
|
+
*
|
|
4
|
+
* A simplified virtual list that uses the viewport feature directly
|
|
5
|
+
* without the list-manager abstraction layer.
|
|
6
|
+
*/
|
|
7
|
+
import type { VListConfig, VListComponent, VListItem } from "./types";
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new VList component using direct viewport integration
|
|
10
|
+
*
|
|
11
|
+
* @param {VListConfig} config - List configuration options
|
|
12
|
+
* @returns {VListComponent} A fully configured virtual list component
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const vlist = createVList({
|
|
17
|
+
* container: '#my-list',
|
|
18
|
+
* collection: myAdapter,
|
|
19
|
+
* rangeSize: 20,
|
|
20
|
+
* paginationStrategy: 'page',
|
|
21
|
+
* template: (item, index) => [
|
|
22
|
+
* { class: 'viewport-item', attributes: { 'data-id': item.id }},
|
|
23
|
+
* [{ class: 'viewport-item__name', text: item.name }],
|
|
24
|
+
* [{ class: 'viewport-item__value', text: item.value }]
|
|
25
|
+
* ]
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare const createVList: <T extends VListItem = VListItem>(config?: VListConfig<T>) => VListComponent<T>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/compose/features
|
|
3
|
+
* @description Adds gesture recognition capabilities to components
|
|
4
|
+
*/
|
|
5
|
+
import { BaseComponent, ElementComponent } from "mtrl";
|
|
6
|
+
import { GestureManager, GestureConfig, GestureHandler } from "../../../gestures";
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for gestures feature
|
|
9
|
+
*/
|
|
10
|
+
export interface GesturesFeatureConfig extends GestureConfig {
|
|
11
|
+
/**
|
|
12
|
+
* Whether to enable gesture recognition immediately
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
enableGestures?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Initial gesture event handlers
|
|
18
|
+
*/
|
|
19
|
+
gestureHandlers?: Record<string, GestureHandler>;
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Component with gesture recognition capabilities
|
|
24
|
+
*/
|
|
25
|
+
export interface GesturesComponent extends BaseComponent {
|
|
26
|
+
/**
|
|
27
|
+
* Gesture manager instance
|
|
28
|
+
*/
|
|
29
|
+
gestures: GestureManager;
|
|
30
|
+
/**
|
|
31
|
+
* Add a gesture event handler
|
|
32
|
+
* @param eventType - Type of gesture event
|
|
33
|
+
* @param handler - Event handler function
|
|
34
|
+
* @returns GesturesComponent for chaining
|
|
35
|
+
*/
|
|
36
|
+
onGesture: (eventType: string, handler: GestureHandler) => GesturesComponent;
|
|
37
|
+
/**
|
|
38
|
+
* Remove a gesture event handler
|
|
39
|
+
* @param eventType - Type of gesture event
|
|
40
|
+
* @param handler - Event handler function
|
|
41
|
+
* @returns GesturesComponent for chaining
|
|
42
|
+
*/
|
|
43
|
+
offGesture: (eventType: string, handler: GestureHandler) => GesturesComponent;
|
|
44
|
+
/**
|
|
45
|
+
* Check if a gesture type is supported on the current device
|
|
46
|
+
* @param gestureType - Type of gesture to check
|
|
47
|
+
* @returns Whether the gesture is supported
|
|
48
|
+
*/
|
|
49
|
+
isGestureSupported: (gestureType: string) => boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Enable gesture recognition
|
|
52
|
+
* @returns GesturesComponent for chaining
|
|
53
|
+
*/
|
|
54
|
+
enableGestures: () => GesturesComponent;
|
|
55
|
+
/**
|
|
56
|
+
* Disable gesture recognition
|
|
57
|
+
* @returns GesturesComponent for chaining
|
|
58
|
+
*/
|
|
59
|
+
disableGestures: () => GesturesComponent;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Adds gesture recognition capabilities to a component.
|
|
63
|
+
* This is a comprehensive gesture feature that adds support for all gesture types.
|
|
64
|
+
* For more lightweight, specific gestures, use the individual gesture features.
|
|
65
|
+
*
|
|
66
|
+
* @param config - Configuration object containing gesture settings
|
|
67
|
+
* @returns Function that enhances a component with gesture capabilities
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* // Add gesture recognition to a component
|
|
72
|
+
* const component = pipe(
|
|
73
|
+
* createBase,
|
|
74
|
+
* withElement(...),
|
|
75
|
+
* withGestures({
|
|
76
|
+
* swipeThreshold: 50,
|
|
77
|
+
* gestureHandlers: {
|
|
78
|
+
* 'tap': (e) => handleTap(e),
|
|
79
|
+
* 'swipeleft': (e) => navigateForward(e),
|
|
80
|
+
* 'swiperight': (e) => navigateBack(e)
|
|
81
|
+
* }
|
|
82
|
+
* })
|
|
83
|
+
* )(config);
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare const withGestures: (config?: GesturesFeatureConfig) => <C extends ElementComponent>(component: C) => C & GesturesComponent;
|