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
package/build.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// build.js
|
|
2
2
|
import { mkdir } from "fs/promises";
|
|
3
3
|
import { existsSync } from "fs";
|
|
4
|
-
import { join, dirname } from "path";
|
|
4
|
+
import { join, dirname, extname } from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
|
+
import { watch } from "fs";
|
|
6
7
|
|
|
7
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
9
|
const isWatch = process.argv.includes("--watch");
|
|
@@ -14,10 +15,92 @@ const isProduction =
|
|
|
14
15
|
const DIST_DIR = join(__dirname, "dist");
|
|
15
16
|
const JS_OUTPUT = join(DIST_DIR, "index.js");
|
|
16
17
|
const MJS_OUTPUT = join(DIST_DIR, "index.mjs");
|
|
18
|
+
const CSS_OUTPUT = join(DIST_DIR, "styles.css");
|
|
19
|
+
const STYLES_ENTRY = join(__dirname, "src/styles/index.scss");
|
|
17
20
|
|
|
18
21
|
// Log build mode
|
|
19
22
|
console.log(`Building in ${isProduction ? "PRODUCTION" : "DEVELOPMENT"} mode`);
|
|
20
23
|
|
|
24
|
+
const buildStyles = async () => {
|
|
25
|
+
console.log("┌─────────────────────────────────────────");
|
|
26
|
+
console.log("│ SCSS Build");
|
|
27
|
+
console.log("│ Mode:", isProduction ? "PRODUCTION" : "DEVELOPMENT");
|
|
28
|
+
console.log("└─────────────────────────────────────────");
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
// Check if source file exists
|
|
32
|
+
if (!existsSync(STYLES_ENTRY)) {
|
|
33
|
+
console.log("⚠️ No SCSS entry found at", STYLES_ENTRY);
|
|
34
|
+
return true; // Not an error, just no styles to build
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Build sass arguments
|
|
38
|
+
const sassArgs = [
|
|
39
|
+
"sass",
|
|
40
|
+
STYLES_ENTRY,
|
|
41
|
+
CSS_OUTPUT,
|
|
42
|
+
isProduction ? "--style=compressed" : "--style=expanded",
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// Add source map in development
|
|
46
|
+
if (!isProduction) {
|
|
47
|
+
sassArgs.push("--source-map");
|
|
48
|
+
} else {
|
|
49
|
+
sassArgs.push("--no-source-map");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const sassProcess = Bun.spawn(["npx", ...sassArgs], {
|
|
53
|
+
cwd: __dirname,
|
|
54
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const stdout = await new Response(sassProcess.stdout).text();
|
|
58
|
+
const stderr = await new Response(sassProcess.stderr).text();
|
|
59
|
+
const exitCode = await sassProcess.exited;
|
|
60
|
+
|
|
61
|
+
if (exitCode !== 0) {
|
|
62
|
+
console.error("❌ SCSS build failed");
|
|
63
|
+
if (stdout.trim()) console.error("STDOUT:", stdout);
|
|
64
|
+
if (stderr.trim()) console.error("STDERR:", stderr);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Get file size
|
|
69
|
+
const cssSize = existsSync(CSS_OUTPUT)
|
|
70
|
+
? (await Bun.file(CSS_OUTPUT).size) / 1024
|
|
71
|
+
: 0;
|
|
72
|
+
|
|
73
|
+
console.log("✓ SCSS build successful");
|
|
74
|
+
console.log(` CSS bundle: ${cssSize.toFixed(2)} KB`);
|
|
75
|
+
|
|
76
|
+
return true;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("❌ SCSS build error:", error.message);
|
|
79
|
+
|
|
80
|
+
// Check if sass is available
|
|
81
|
+
try {
|
|
82
|
+
const checkSass = Bun.spawn(["npx", "sass", "--version"], {
|
|
83
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
84
|
+
});
|
|
85
|
+
const versionExitCode = await checkSass.exited;
|
|
86
|
+
|
|
87
|
+
if (versionExitCode !== 0) {
|
|
88
|
+
console.error("💡 Sass compiler not found. Install it with:");
|
|
89
|
+
console.error(" npm install -D sass");
|
|
90
|
+
console.error(" or");
|
|
91
|
+
console.error(" bun add -D sass");
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
console.error("💡 Sass compiler not found. Install it with:");
|
|
95
|
+
console.error(" npm install -D sass");
|
|
96
|
+
console.error(" or");
|
|
97
|
+
console.error(" bun add -D sass");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
21
104
|
const buildApp = async () => {
|
|
22
105
|
try {
|
|
23
106
|
console.log("┌─────────────────────────────────────────");
|
|
@@ -64,34 +147,104 @@ const buildApp = async () => {
|
|
|
64
147
|
|
|
65
148
|
console.log("✓ JavaScript build successful");
|
|
66
149
|
console.log(
|
|
67
|
-
` CJS bundle: ${((await Bun.file(JS_OUTPUT).size) / 1024).toFixed(2)} KB
|
|
150
|
+
` CJS bundle: ${((await Bun.file(JS_OUTPUT).size) / 1024).toFixed(2)} KB`,
|
|
68
151
|
);
|
|
69
152
|
console.log(
|
|
70
153
|
` ESM bundle: ${((await Bun.file(MJS_OUTPUT).size) / 1024).toFixed(
|
|
71
|
-
2
|
|
72
|
-
)} KB
|
|
154
|
+
2,
|
|
155
|
+
)} KB`,
|
|
73
156
|
);
|
|
74
157
|
|
|
75
|
-
// Generate type definitions
|
|
158
|
+
// Generate type definitions with better error handling
|
|
76
159
|
console.log("Generating TypeScript declarations...");
|
|
77
|
-
const tscProcess = Bun.spawn(["tsc", "--project", "tsconfig.build.json"], {
|
|
78
|
-
cwd: __dirname,
|
|
79
|
-
});
|
|
80
160
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
161
|
+
try {
|
|
162
|
+
const tscProcess = Bun.spawn(
|
|
163
|
+
["tsc", "--emitDeclarationOnly", "--outDir", DIST_DIR],
|
|
164
|
+
{
|
|
165
|
+
cwd: __dirname,
|
|
166
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
167
|
+
},
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// Capture stdout and stderr
|
|
171
|
+
const stdout = await new Response(tscProcess.stdout).text();
|
|
172
|
+
const stderr = await new Response(tscProcess.stderr).text();
|
|
173
|
+
|
|
174
|
+
const tscExitCode = await tscProcess.exited;
|
|
175
|
+
|
|
176
|
+
if (tscExitCode !== 0) {
|
|
177
|
+
console.warn(
|
|
178
|
+
"⚠️ TypeScript declaration generation had errors (non-blocking)",
|
|
179
|
+
);
|
|
180
|
+
if (stdout.trim()) {
|
|
181
|
+
console.warn(
|
|
182
|
+
"STDOUT:",
|
|
183
|
+
stdout.slice(0, 500) + (stdout.length > 500 ? "..." : ""),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
if (stderr.trim()) {
|
|
187
|
+
console.warn(
|
|
188
|
+
"STDERR:",
|
|
189
|
+
stderr.slice(0, 500) + (stderr.length > 500 ? "..." : ""),
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Check if tsc is available
|
|
194
|
+
const whichResult = Bun.spawn(["which", "tsc"], {
|
|
195
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
196
|
+
});
|
|
197
|
+
const tscPath = await new Response(whichResult.stdout).text();
|
|
198
|
+
if (!tscPath.trim()) {
|
|
199
|
+
console.error(
|
|
200
|
+
"💡 TypeScript compiler (tsc) not found. Install it with:",
|
|
201
|
+
);
|
|
202
|
+
console.error(" npm install -g typescript");
|
|
203
|
+
console.error(" or");
|
|
204
|
+
console.error(" bun add -g typescript");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Continue build despite tsc errors (JS bundles are still valid)
|
|
88
208
|
return true;
|
|
89
209
|
}
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
210
|
|
|
93
|
-
|
|
94
|
-
|
|
211
|
+
console.log("✓ TypeScript declarations generated");
|
|
212
|
+
if (stdout.trim()) {
|
|
213
|
+
console.log("TSC output:", stdout);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return true;
|
|
217
|
+
} catch (tscError) {
|
|
218
|
+
console.warn("⚠️ Error running TypeScript compiler:", tscError.message);
|
|
219
|
+
|
|
220
|
+
// Check if TypeScript is installed
|
|
221
|
+
try {
|
|
222
|
+
const checkTsc = Bun.spawn(["tsc", "--version"], {
|
|
223
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
224
|
+
});
|
|
225
|
+
const versionOutput = await new Response(checkTsc.stdout).text();
|
|
226
|
+
const versionExitCode = await checkTsc.exited;
|
|
227
|
+
|
|
228
|
+
if (versionExitCode === 0) {
|
|
229
|
+
console.log("TypeScript version:", versionOutput.trim());
|
|
230
|
+
} else {
|
|
231
|
+
console.warn(
|
|
232
|
+
"💡 TypeScript compiler not properly installed. Install with:",
|
|
233
|
+
);
|
|
234
|
+
console.warn(" npm install -g typescript");
|
|
235
|
+
console.warn(" or");
|
|
236
|
+
console.warn(" bun add -g typescript");
|
|
237
|
+
}
|
|
238
|
+
} catch (versionError) {
|
|
239
|
+
console.warn("💡 TypeScript compiler not found. Install it with:");
|
|
240
|
+
console.warn(" npm install -g typescript");
|
|
241
|
+
console.warn(" or");
|
|
242
|
+
console.warn(" bun add -g typescript");
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Continue build despite tsc errors (JS bundles are still valid)
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
95
248
|
} catch (error) {
|
|
96
249
|
console.error("❌ JavaScript build error:", error);
|
|
97
250
|
console.error(error.stack);
|
|
@@ -99,6 +252,12 @@ const buildApp = async () => {
|
|
|
99
252
|
}
|
|
100
253
|
};
|
|
101
254
|
|
|
255
|
+
const buildAll = async () => {
|
|
256
|
+
const jsSuccess = await buildApp();
|
|
257
|
+
const cssSuccess = await buildStyles();
|
|
258
|
+
return jsSuccess && cssSuccess;
|
|
259
|
+
};
|
|
260
|
+
|
|
102
261
|
const build = async () => {
|
|
103
262
|
try {
|
|
104
263
|
const startTime = Date.now();
|
|
@@ -113,8 +272,8 @@ const build = async () => {
|
|
|
113
272
|
// Create output directory
|
|
114
273
|
await mkdir(DIST_DIR, { recursive: true });
|
|
115
274
|
|
|
116
|
-
// Build JavaScript
|
|
117
|
-
const
|
|
275
|
+
// Build JavaScript and CSS
|
|
276
|
+
const buildSuccess = await buildAll();
|
|
118
277
|
|
|
119
278
|
const buildTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
120
279
|
|
|
@@ -124,18 +283,88 @@ const build = async () => {
|
|
|
124
283
|
console.log("│ 👀 Watching for changes...");
|
|
125
284
|
console.log("└───────────────────────────────────────────────");
|
|
126
285
|
|
|
127
|
-
// Watch
|
|
286
|
+
// Watch src directory for changes
|
|
287
|
+
const srcDir = join(__dirname, "src");
|
|
288
|
+
let debounceTimer = null;
|
|
289
|
+
let isBuilding = false;
|
|
290
|
+
|
|
291
|
+
const rebuild = async (changedFile) => {
|
|
292
|
+
if (isBuilding) return;
|
|
293
|
+
isBuilding = true;
|
|
294
|
+
|
|
295
|
+
const ext = changedFile ? extname(changedFile) : "";
|
|
296
|
+
const isStyleChange = [".scss", ".css"].includes(ext);
|
|
297
|
+
const isJsChange = [".ts", ".tsx"].includes(ext);
|
|
298
|
+
|
|
299
|
+
console.log("");
|
|
300
|
+
console.log("┌───────────────────────────────────────────────");
|
|
301
|
+
console.log(
|
|
302
|
+
`│ 🔄 Change detected${changedFile ? ` (${changedFile})` : ""}, rebuilding...`,
|
|
303
|
+
);
|
|
304
|
+
console.log("└───────────────────────────────────────────────");
|
|
305
|
+
|
|
306
|
+
const rebuildStart = Date.now();
|
|
307
|
+
let success;
|
|
308
|
+
|
|
309
|
+
// Selective rebuild based on file type
|
|
310
|
+
if (isStyleChange) {
|
|
311
|
+
success = await buildStyles();
|
|
312
|
+
} else if (isJsChange) {
|
|
313
|
+
success = await buildApp();
|
|
314
|
+
} else {
|
|
315
|
+
success = await buildAll();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const rebuildTime = ((Date.now() - rebuildStart) / 1000).toFixed(2);
|
|
319
|
+
|
|
320
|
+
console.log("");
|
|
321
|
+
console.log(
|
|
322
|
+
`│ ${success ? "✅" : "⚠️"} Rebuild completed in ${rebuildTime}s`,
|
|
323
|
+
);
|
|
324
|
+
console.log("│ 👀 Watching for changes...");
|
|
325
|
+
console.log("└───────────────────────────────────────────────");
|
|
326
|
+
|
|
327
|
+
isBuilding = false;
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
const watchHandler = (eventType, filename) => {
|
|
331
|
+
if (!filename) return;
|
|
332
|
+
|
|
333
|
+
// Only watch .ts, .tsx, .scss and .css files
|
|
334
|
+
const ext = extname(filename);
|
|
335
|
+
if (![".ts", ".tsx", ".scss", ".css"].includes(ext)) return;
|
|
336
|
+
|
|
337
|
+
// Debounce rapid changes
|
|
338
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
339
|
+
debounceTimer = setTimeout(() => {
|
|
340
|
+
rebuild(filename);
|
|
341
|
+
}, 100);
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// Watch recursively using fs.watch
|
|
345
|
+
const watchDir = (dir) => {
|
|
346
|
+
watch(dir, { recursive: true }, watchHandler);
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
watchDir(srcDir);
|
|
350
|
+
console.log(`│ Watching: ${srcDir}`);
|
|
351
|
+
|
|
352
|
+
// Keep process alive
|
|
353
|
+
process.on("SIGINT", () => {
|
|
354
|
+
console.log("\n│ 👋 Stopping watch mode...");
|
|
355
|
+
process.exit(0);
|
|
356
|
+
});
|
|
128
357
|
} else {
|
|
129
358
|
console.log("");
|
|
130
359
|
console.log("┌───────────────────────────────────────────────");
|
|
131
360
|
console.log(`│ ✅ Build completed in ${buildTime}s`);
|
|
132
|
-
if (!
|
|
361
|
+
if (!buildSuccess) {
|
|
133
362
|
console.log("│ ⚠️ Build completed with some errors");
|
|
134
363
|
}
|
|
135
364
|
console.log("└───────────────────────────────────────────────");
|
|
136
365
|
|
|
137
366
|
// Only exit with error code in non-watch mode if there were failures
|
|
138
|
-
if (!isWatch && !
|
|
367
|
+
if (!isWatch && !buildSuccess) {
|
|
139
368
|
process.exit(1);
|
|
140
369
|
}
|
|
141
370
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mtrl-addons",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Additional components and utilities for the mtrl system, featuring forms, specialized elements, and extended functionality for modern applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -10,8 +10,15 @@
|
|
|
10
10
|
"dev": "bun run ./build.js --watch",
|
|
11
11
|
"test": "bun test",
|
|
12
12
|
"prepublishOnly": "bun run build",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
13
|
+
"server:start": "pm2 start ../mtrl-app/ecosystem.config.js",
|
|
14
|
+
"server:stop": "pm2 stop mtrl-app",
|
|
15
|
+
"server:reload": "pm2 restart mtrl-app",
|
|
16
|
+
"server:logs": "pm2 logs mtrl-app",
|
|
17
|
+
"link:mtrl": "rm -rf node_modules/mtrl && ln -sf ../../mtrl node_modules/mtrl",
|
|
18
|
+
"debug:vlist": "bun run ../mtrl-app/scripts/debug/vlist examples/vlist",
|
|
19
|
+
"debug:vlist:interactive": "bun run ../mtrl-app/scripts/debug/vlist examples/vlist --interactive",
|
|
20
|
+
"debug:vlist-cursor": "bun run ../mtrl-app/scripts/debug/vlist examples/vlist-cursor",
|
|
21
|
+
"debug:vlist-cursor:interactive": "bun run ../mtrl-app/scripts/debug/vlist examples/vlist-cursor --interactive"
|
|
15
22
|
},
|
|
16
23
|
"repository": {
|
|
17
24
|
"type": "git",
|
|
@@ -27,13 +34,16 @@
|
|
|
27
34
|
"author": "floor",
|
|
28
35
|
"license": "MIT",
|
|
29
36
|
"peerDependencies": {
|
|
30
|
-
"mtrl": "^0.
|
|
37
|
+
"mtrl": "^0.5.1"
|
|
31
38
|
},
|
|
32
39
|
"devDependencies": {
|
|
40
|
+
"@types/jsdom": "^21.1.7",
|
|
33
41
|
"@types/node": "^20.0.0",
|
|
34
42
|
"bun-types": "^1.0.0",
|
|
43
|
+
"jsdom": "^26.1.0",
|
|
35
44
|
"madge": "^8.0.0",
|
|
36
45
|
"mtrl": "^0.2.8",
|
|
46
|
+
"sass": "^1.94.2",
|
|
37
47
|
"standard": "^17.0.0",
|
|
38
48
|
"typescript": "^5.0.0"
|
|
39
49
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// scripts/debug/vlist-selection.ts
|
|
2
|
+
|
|
3
|
+
import puppeteer from "puppeteer";
|
|
4
|
+
|
|
5
|
+
async function testVListSelection() {
|
|
6
|
+
console.log("🎯 Testing VList Selection Feature");
|
|
7
|
+
|
|
8
|
+
const browser = await puppeteer.launch({
|
|
9
|
+
headless: false,
|
|
10
|
+
devtools: true,
|
|
11
|
+
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const page = await browser.newPage();
|
|
15
|
+
|
|
16
|
+
// Listen to console logs
|
|
17
|
+
page.on("console", (msg) => {
|
|
18
|
+
const text = msg.text();
|
|
19
|
+
if (text.includes("[Selection]") || text.includes("selection")) {
|
|
20
|
+
console.log(`💬 [${msg.type().toUpperCase()}] ${text}`);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
await page.goto("http://localhost:4000/examples/vlist-addons");
|
|
25
|
+
|
|
26
|
+
// Wait for list to load
|
|
27
|
+
await page.waitForSelector(".mtrl-viewport-item", { timeout: 5000 });
|
|
28
|
+
|
|
29
|
+
console.log("📋 Page loaded, looking for list items...");
|
|
30
|
+
|
|
31
|
+
// Get info about items
|
|
32
|
+
const itemInfo = await page.evaluate(() => {
|
|
33
|
+
const items = document.querySelectorAll(".mtrl-viewport-item");
|
|
34
|
+
const firstItem = items[0];
|
|
35
|
+
const listItem = firstItem?.querySelector(".list-item, .user-item");
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
viewportItemCount: items.length,
|
|
39
|
+
firstViewportItemClasses: firstItem?.className,
|
|
40
|
+
firstViewportItemDataIndex: firstItem?.getAttribute("data-index"),
|
|
41
|
+
firstListItemClasses: listItem?.className,
|
|
42
|
+
firstListItemDataId: listItem?.getAttribute("data-id"),
|
|
43
|
+
hasClickHandler: !!(window as any).listExample?.userList,
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
console.log("📊 Item info:", itemInfo);
|
|
48
|
+
|
|
49
|
+
// Click on the first item
|
|
50
|
+
console.log("🖱️ Clicking on first item...");
|
|
51
|
+
await page.click(".mtrl-viewport-item:first-child");
|
|
52
|
+
|
|
53
|
+
// Wait a bit for selection to process
|
|
54
|
+
await page.waitForTimeout(500);
|
|
55
|
+
|
|
56
|
+
// Check if selection class was applied
|
|
57
|
+
const selectionInfo = await page.evaluate(() => {
|
|
58
|
+
const firstItem = document.querySelector(".mtrl-viewport-item:first-child");
|
|
59
|
+
const listItem = firstItem?.querySelector(".list-item, .user-item");
|
|
60
|
+
const selectedItems = document.querySelectorAll(
|
|
61
|
+
".mtrl-list-item--selected"
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
hasSelectionClass: listItem?.classList.contains(
|
|
66
|
+
"mtrl-list-item--selected"
|
|
67
|
+
),
|
|
68
|
+
listItemClasses: listItem?.className,
|
|
69
|
+
selectedCount: selectedItems.length,
|
|
70
|
+
userListExists: !!(window as any).listExample?.userList,
|
|
71
|
+
hasSelectItems:
|
|
72
|
+
typeof (window as any).listExample?.userList?.selectItems ===
|
|
73
|
+
"function",
|
|
74
|
+
hasGetSelectedItems:
|
|
75
|
+
typeof (window as any).listExample?.userList?.getSelectedItems ===
|
|
76
|
+
"function",
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
console.log("✅ Selection info after click:", selectionInfo);
|
|
81
|
+
|
|
82
|
+
// Try programmatic selection
|
|
83
|
+
console.log("🔧 Testing programmatic selection...");
|
|
84
|
+
const programmaticResult = await page.evaluate(() => {
|
|
85
|
+
const userList = (window as any).listExample?.userList;
|
|
86
|
+
if (userList && userList.selectItems) {
|
|
87
|
+
userList.selectItems([0, 1, 2]);
|
|
88
|
+
const selected = userList.getSelectedItems
|
|
89
|
+
? userList.getSelectedItems()
|
|
90
|
+
: [];
|
|
91
|
+
return {
|
|
92
|
+
success: true,
|
|
93
|
+
selectedCount: selected.length,
|
|
94
|
+
selectedIds: selected.map((item: any) => item.id),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return { success: false, reason: "No selectItems method" };
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
console.log("📊 Programmatic selection result:", programmaticResult);
|
|
101
|
+
|
|
102
|
+
// Final check
|
|
103
|
+
await page.waitForTimeout(500);
|
|
104
|
+
const finalState = await page.evaluate(() => {
|
|
105
|
+
const selectedElements = document.querySelectorAll(
|
|
106
|
+
".mtrl-list-item--selected"
|
|
107
|
+
);
|
|
108
|
+
return {
|
|
109
|
+
selectedElementCount: selectedElements.length,
|
|
110
|
+
selectedClasses: Array.from(selectedElements).map((el) => el.className),
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
console.log("🎯 Final selection state:", finalState);
|
|
115
|
+
|
|
116
|
+
// Keep browser open for inspection
|
|
117
|
+
console.log("✨ Test complete. Browser will stay open for inspection.");
|
|
118
|
+
console.log("Press Ctrl+C to exit.");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
testVListSelection().catch(console.error);
|
package/src/components/index.ts
CHANGED
|
@@ -1,45 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Components Module Exports
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Central export point for all components
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
export {
|
|
9
|
-
|
|
10
|
-
// Export list types and utilities
|
|
11
|
-
export type {
|
|
12
|
-
ListConfig,
|
|
13
|
-
ListComponent,
|
|
14
|
-
ListAPI,
|
|
15
|
-
ListState,
|
|
16
|
-
ListEvents,
|
|
17
|
-
ListItemTemplate,
|
|
18
|
-
ListScrollConfig,
|
|
19
|
-
ListSelectionConfig,
|
|
20
|
-
ListEventHandlers,
|
|
21
|
-
ListItemContext,
|
|
22
|
-
} from "./list";
|
|
23
|
-
|
|
24
|
-
// List configuration utilities
|
|
25
|
-
export {
|
|
26
|
-
createBaseConfig,
|
|
27
|
-
getElementConfig,
|
|
28
|
-
getApiConfig,
|
|
29
|
-
getCollectionConfig,
|
|
30
|
-
getListManagerConfig,
|
|
31
|
-
validateConfig,
|
|
32
|
-
} from "./list";
|
|
33
|
-
|
|
34
|
-
// List features
|
|
35
|
-
export { withListManager } from "./list/features/list-manager";
|
|
36
|
-
export { withAPI } from "./list/api";
|
|
37
|
-
|
|
38
|
-
// Components will be exported here as they're added
|
|
39
|
-
// For example:
|
|
40
|
-
// export { VirtualList } from './virtual-list';
|
|
41
|
-
// export { DataTable } from './data-table';
|
|
42
|
-
// export { InfiniteScroll } from './infinite-scroll';
|
|
43
|
-
|
|
44
|
-
// Currently no other components - this is the foundation for future components
|
|
45
|
-
export const componentsVersion = "0.1.0";
|
|
7
|
+
// VList component (virtual list with viewport)
|
|
8
|
+
export { createVList } from "./vlist";
|
|
9
|
+
export type { VListConfig, VListComponent } from "./vlist/types";
|