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
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
// src/core/viewport/features/placeholders.ts
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Placeholder Feature - Smart placeholder generation
|
|
5
|
-
* Analyzes first loaded data to generate realistic masked placeholders
|
|
6
|
-
* Shows placeholders while data is loading
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { ViewportContext } from "../types";
|
|
10
|
-
import type { CollectionComponent } from "./collection";
|
|
11
|
-
import { VIEWPORT_CONSTANTS } from "../constants";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Configuration for placeholder feature
|
|
15
|
-
*/
|
|
16
|
-
export interface PlaceholderConfig {
|
|
17
|
-
enabled?: boolean;
|
|
18
|
-
analyzeFirstLoad?: boolean;
|
|
19
|
-
maskCharacter?: string;
|
|
20
|
-
randomLengthVariance?: boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Field structure for placeholder generation
|
|
25
|
-
*/
|
|
26
|
-
interface FieldStructure {
|
|
27
|
-
minLength: number;
|
|
28
|
-
maxLength: number;
|
|
29
|
-
avgLength: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface PlaceholderComponent {
|
|
33
|
-
placeholders: {
|
|
34
|
-
analyzeDataStructure: (items: any[]) => void;
|
|
35
|
-
hasAnalyzedStructure: () => boolean;
|
|
36
|
-
generatePlaceholderItem: (index: number) => any;
|
|
37
|
-
generatePlaceholderItems: (range: { start: number; end: number }) => any[];
|
|
38
|
-
showPlaceholders: (range: { start: number; end: number }) => void;
|
|
39
|
-
isPlaceholder: (item: any) => boolean;
|
|
40
|
-
replacePlaceholders: (items: any[], offset: number) => void;
|
|
41
|
-
clear: () => void;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Adds placeholder functionality to viewport component
|
|
47
|
-
*/
|
|
48
|
-
export function withPlaceholders(config: PlaceholderConfig = {}) {
|
|
49
|
-
return <T extends ViewportContext & CollectionComponent>(
|
|
50
|
-
component: T
|
|
51
|
-
): T & PlaceholderComponent => {
|
|
52
|
-
const {
|
|
53
|
-
enabled = true,
|
|
54
|
-
analyzeFirstLoad = true,
|
|
55
|
-
maskCharacter = VIEWPORT_CONSTANTS.PLACEHOLDER.MASK_CHARACTER,
|
|
56
|
-
randomLengthVariance = VIEWPORT_CONSTANTS.PLACEHOLDER
|
|
57
|
-
.RANDOM_LENGTH_VARIANCE,
|
|
58
|
-
} = config;
|
|
59
|
-
|
|
60
|
-
// State
|
|
61
|
-
let fieldStructures: Map<string, FieldStructure> | null = null;
|
|
62
|
-
let hasAnalyzed = false;
|
|
63
|
-
let placeholderIdCounter = 0;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Analyze data structure from first loaded items
|
|
67
|
-
*/
|
|
68
|
-
const analyzeDataStructure = (items: any[]): void => {
|
|
69
|
-
if (!enabled || hasAnalyzed || !items.length) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// console.log(
|
|
74
|
-
// `🔍 [PLACEHOLDERS] Analyzing data structure from ${items.length} items`
|
|
75
|
-
// );
|
|
76
|
-
|
|
77
|
-
const structures = new Map<string, FieldStructure>();
|
|
78
|
-
const sampleSize = Math.min(
|
|
79
|
-
items.length,
|
|
80
|
-
VIEWPORT_CONSTANTS.PLACEHOLDER.MAX_SAMPLE_SIZE
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Analyze each field across all sample items
|
|
84
|
-
const fieldStats = new Map<string, number[]>();
|
|
85
|
-
|
|
86
|
-
for (let i = 0; i < sampleSize; i++) {
|
|
87
|
-
const item = items[i];
|
|
88
|
-
if (!item || typeof item !== "object") continue;
|
|
89
|
-
|
|
90
|
-
Object.keys(item).forEach((field) => {
|
|
91
|
-
// Skip internal fields
|
|
92
|
-
if (
|
|
93
|
-
field.startsWith("_") ||
|
|
94
|
-
field === VIEWPORT_CONSTANTS.PLACEHOLDER.PLACEHOLDER_FLAG
|
|
95
|
-
) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const value = String(item[field] || "");
|
|
100
|
-
const length = value.length;
|
|
101
|
-
|
|
102
|
-
if (!fieldStats.has(field)) {
|
|
103
|
-
fieldStats.set(field, []);
|
|
104
|
-
}
|
|
105
|
-
fieldStats.get(field)!.push(length);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Calculate statistics for each field
|
|
110
|
-
fieldStats.forEach((lengths, field) => {
|
|
111
|
-
if (lengths.length === 0) return;
|
|
112
|
-
|
|
113
|
-
const minLength = Math.min(...lengths);
|
|
114
|
-
const maxLength = Math.max(...lengths);
|
|
115
|
-
const avgLength = Math.round(
|
|
116
|
-
lengths.reduce((sum, len) => sum + len, 0) / lengths.length
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
structures.set(field, {
|
|
120
|
-
minLength,
|
|
121
|
-
maxLength,
|
|
122
|
-
avgLength,
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
fieldStructures = structures;
|
|
127
|
-
hasAnalyzed = true;
|
|
128
|
-
|
|
129
|
-
// console.log(
|
|
130
|
-
// `✅ [PLACEHOLDERS] Structure analyzed:`,
|
|
131
|
-
// Object.fromEntries(structures)
|
|
132
|
-
// );
|
|
133
|
-
|
|
134
|
-
// Emit event
|
|
135
|
-
component.emit?.("viewport:placeholders-structure-analyzed", {
|
|
136
|
-
structure: Object.fromEntries(structures),
|
|
137
|
-
});
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Generate a single placeholder item
|
|
142
|
-
*/
|
|
143
|
-
const generatePlaceholderItem = (index: number): any => {
|
|
144
|
-
const placeholder: Record<string, any> = {
|
|
145
|
-
id: `placeholder-${placeholderIdCounter++}`,
|
|
146
|
-
[VIEWPORT_CONSTANTS.PLACEHOLDER.PLACEHOLDER_FLAG]: true,
|
|
147
|
-
_index: index,
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
if (!fieldStructures || fieldStructures.size === 0) {
|
|
151
|
-
// No structure analyzed yet - return basic placeholder
|
|
152
|
-
placeholder.label = maskCharacter.repeat(10);
|
|
153
|
-
return placeholder;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Generate fields based on analyzed structure
|
|
157
|
-
fieldStructures.forEach((structure, field) => {
|
|
158
|
-
let length: number;
|
|
159
|
-
|
|
160
|
-
if (
|
|
161
|
-
randomLengthVariance &&
|
|
162
|
-
structure.minLength !== structure.maxLength
|
|
163
|
-
) {
|
|
164
|
-
// Random length within range
|
|
165
|
-
length = Math.floor(
|
|
166
|
-
Math.random() * (structure.maxLength - structure.minLength + 1) +
|
|
167
|
-
structure.minLength
|
|
168
|
-
);
|
|
169
|
-
} else {
|
|
170
|
-
// Use average length
|
|
171
|
-
length = structure.avgLength;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Apply some variation to make it look more natural
|
|
175
|
-
if (randomLengthVariance && Math.random() < 0.3) {
|
|
176
|
-
length = Math.max(1, length + Math.floor(Math.random() * 3) - 1);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
placeholder[field] = maskCharacter.repeat(length);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
return placeholder;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Generate multiple placeholder items
|
|
187
|
-
*/
|
|
188
|
-
const generatePlaceholderItems = (range: {
|
|
189
|
-
start: number;
|
|
190
|
-
end: number;
|
|
191
|
-
}): any[] => {
|
|
192
|
-
const items: any[] = [];
|
|
193
|
-
for (let i = range.start; i <= range.end; i++) {
|
|
194
|
-
items.push(generatePlaceholderItem(i));
|
|
195
|
-
}
|
|
196
|
-
return items;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Show placeholders for a range
|
|
201
|
-
*/
|
|
202
|
-
const showPlaceholders = (range: { start: number; end: number }): void => {
|
|
203
|
-
if (!enabled) return;
|
|
204
|
-
|
|
205
|
-
const placeholders = generatePlaceholderItems(range);
|
|
206
|
-
|
|
207
|
-
// Update items array
|
|
208
|
-
if (component.items) {
|
|
209
|
-
for (let i = 0; i < placeholders.length; i++) {
|
|
210
|
-
const index = range.start + i;
|
|
211
|
-
if (!component.items[index]) {
|
|
212
|
-
component.items[index] = placeholders[i];
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
console.log(
|
|
218
|
-
`🔄 [PLACEHOLDERS] Showing ${placeholders.length} placeholders for range ${range.start}-${range.end}`
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
// Emit event
|
|
222
|
-
component.emit?.("viewport:placeholders-shown", {
|
|
223
|
-
range,
|
|
224
|
-
count: placeholders.length,
|
|
225
|
-
});
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Check if an item is a placeholder
|
|
230
|
-
*/
|
|
231
|
-
const isPlaceholder = (item: any): boolean => {
|
|
232
|
-
return (
|
|
233
|
-
item &&
|
|
234
|
-
typeof item === "object" &&
|
|
235
|
-
item[VIEWPORT_CONSTANTS.PLACEHOLDER.PLACEHOLDER_FLAG] === true
|
|
236
|
-
);
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Replace placeholders with real data
|
|
241
|
-
*/
|
|
242
|
-
const replacePlaceholders = (items: any[], offset: number): void => {
|
|
243
|
-
if (!component.items) return;
|
|
244
|
-
|
|
245
|
-
let replacedCount = 0;
|
|
246
|
-
|
|
247
|
-
for (let i = 0; i < items.length; i++) {
|
|
248
|
-
const index = offset + i;
|
|
249
|
-
const currentItem = component.items[index];
|
|
250
|
-
|
|
251
|
-
if (isPlaceholder(currentItem)) {
|
|
252
|
-
component.items[index] = items[i];
|
|
253
|
-
replacedCount++;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (replacedCount > 0) {
|
|
258
|
-
console.log(
|
|
259
|
-
`✨ [PLACEHOLDERS] Replaced ${replacedCount} placeholders at offset ${offset}`
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
// Emit event
|
|
263
|
-
component.emit?.("viewport:placeholders-replaced", {
|
|
264
|
-
offset,
|
|
265
|
-
count: replacedCount,
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Clear all placeholder state
|
|
272
|
-
*/
|
|
273
|
-
const clear = (): void => {
|
|
274
|
-
fieldStructures = null;
|
|
275
|
-
hasAnalyzed = false;
|
|
276
|
-
placeholderIdCounter = 0;
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
// Initialize function
|
|
280
|
-
const initialize = () => {
|
|
281
|
-
if (!enabled) return;
|
|
282
|
-
|
|
283
|
-
// Listen for first data load to analyze structure
|
|
284
|
-
if (analyzeFirstLoad) {
|
|
285
|
-
const handleRangeLoaded = (data: any) => {
|
|
286
|
-
if (!hasAnalyzed && data.items && data.items.length > 0) {
|
|
287
|
-
analyzeDataStructure(data.items);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Replace any placeholders with real data
|
|
291
|
-
replacePlaceholders(data.items, data.offset);
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
component.on?.("viewport:range-loaded", handleRangeLoaded);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Show initial placeholders if configured
|
|
298
|
-
const totalItems = component.collection?.getTotalItems() || 0;
|
|
299
|
-
if (totalItems > 0) {
|
|
300
|
-
const initialRange = {
|
|
301
|
-
start: 0,
|
|
302
|
-
end: Math.min(
|
|
303
|
-
VIEWPORT_CONSTANTS.PLACEHOLDER.MAX_SAMPLE_SIZE - 1,
|
|
304
|
-
totalItems - 1
|
|
305
|
-
),
|
|
306
|
-
};
|
|
307
|
-
showPlaceholders(initialRange);
|
|
308
|
-
}
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
// Cleanup function
|
|
312
|
-
const destroy = () => {
|
|
313
|
-
clear();
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
// Store functions for viewport to call
|
|
317
|
-
(component as any)._placeholdersInitialize = initialize;
|
|
318
|
-
(component as any)._placeholdersDestroy = destroy;
|
|
319
|
-
|
|
320
|
-
// Return enhanced component
|
|
321
|
-
return {
|
|
322
|
-
...component,
|
|
323
|
-
placeholders: {
|
|
324
|
-
analyzeDataStructure,
|
|
325
|
-
hasAnalyzedStructure: () => hasAnalyzed,
|
|
326
|
-
generatePlaceholderItem,
|
|
327
|
-
generatePlaceholderItems,
|
|
328
|
-
showPlaceholders,
|
|
329
|
-
isPlaceholder,
|
|
330
|
-
replacePlaceholders,
|
|
331
|
-
clear,
|
|
332
|
-
},
|
|
333
|
-
};
|
|
334
|
-
};
|
|
335
|
-
}
|