@vuer-ai/vuer-uikit 0.0.98 → 0.0.100

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.
Files changed (78) hide show
  1. package/dist/SyncScroll/SyncScroll.cjs +9 -9
  2. package/dist/SyncScroll/SyncScroll.mjs +2 -2
  3. package/dist/SyncScroll/index.cjs +9 -9
  4. package/dist/SyncScroll/index.mjs +2 -2
  5. package/dist/chunk-AIYM5PFP.cjs +66 -0
  6. package/dist/chunk-OWEYAVGT.mjs +62 -0
  7. package/dist/{chunk-7GWDO25E.cjs → chunk-XBTBTLID.cjs} +2 -2
  8. package/dist/{chunk-TTYSYGVE.mjs → chunk-XGXWOY3U.mjs} +2 -2
  9. package/dist/dial/DialPanel.cjs +23 -22
  10. package/dist/dial/DialPanel.mjs +22 -21
  11. package/dist/dial/index.cjs +39 -38
  12. package/dist/dial/index.mjs +22 -21
  13. package/dist/dial/wrapped-inputs/ControlledInputs.cjs +26 -25
  14. package/dist/dial/wrapped-inputs/ControlledInputs.mjs +22 -21
  15. package/dist/dial/wrapped-inputs/DialInputs.cjs +33 -32
  16. package/dist/dial/wrapped-inputs/DialInputs.mjs +22 -21
  17. package/dist/dial/wrapped-inputs/DialVectorInput.cjs +23 -22
  18. package/dist/dial/wrapped-inputs/DialVectorInput.mjs +22 -21
  19. package/dist/dial/wrapped-inputs/index.cjs +38 -37
  20. package/dist/dial/wrapped-inputs/index.mjs +22 -21
  21. package/dist/highlight-cursor/cursor-provider.cjs +3 -3
  22. package/dist/highlight-cursor/cursor-provider.mjs +2 -2
  23. package/dist/highlight-cursor/enhanced-components.cjs +1 -1
  24. package/dist/highlight-cursor/enhanced-components.mjs +1 -1
  25. package/dist/highlight-cursor/index.cjs +3 -3
  26. package/dist/highlight-cursor/index.mjs +2 -2
  27. package/dist/index.cjs +151 -138
  28. package/dist/index.css +7 -1
  29. package/dist/index.d.cts +1 -0
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.mjs +22 -21
  32. package/dist/ui/DialBadge.cjs +28 -0
  33. package/dist/ui/DialBadge.d.cts +33 -0
  34. package/dist/ui/DialBadge.d.ts +33 -0
  35. package/dist/ui/DialBadge.mjs +11 -0
  36. package/dist/ui/UIKitBadge.cjs +5 -5
  37. package/dist/ui/UIKitBadge.mjs +1 -1
  38. package/dist/ui/badge.d.cts +1 -1
  39. package/dist/ui/badge.d.ts +1 -1
  40. package/dist/ui/index.cjs +77 -64
  41. package/dist/ui/index.d.cts +1 -0
  42. package/dist/ui/index.d.ts +1 -0
  43. package/dist/ui/index.mjs +18 -17
  44. package/dist/ui/inputs/index.cjs +15 -15
  45. package/dist/ui/inputs/index.mjs +3 -3
  46. package/dist/ui/inputs/input.d.cts +1 -1
  47. package/dist/ui/inputs/input.d.ts +1 -1
  48. package/dist/ui/inputs/number-inputs/index.cjs +10 -10
  49. package/dist/ui/inputs/number-inputs/index.mjs +2 -2
  50. package/dist/ui/select.d.cts +1 -1
  51. package/dist/ui/select.d.ts +1 -1
  52. package/dist/ui/textarea.d.cts +1 -1
  53. package/dist/ui/textarea.d.ts +1 -1
  54. package/dist/ui/tree-view-legacy.cjs +8 -8
  55. package/dist/ui/tree-view-legacy.mjs +4 -4
  56. package/dist/ui/waterfall/index.cjs +6 -6
  57. package/dist/ui/waterfall/index.mjs +5 -5
  58. package/package.json +2 -7
  59. package/src/ui/DialBadge.tsx +97 -0
  60. package/src/ui/index.ts +1 -0
  61. package/cli/dial-cli.js +0 -833
  62. package/dist/chunk-4KWGGESI.cjs +0 -494
  63. package/dist/chunk-A5LCX2UQ.cjs +0 -208
  64. package/dist/chunk-BEJIZ56L.mjs +0 -300
  65. package/dist/chunk-C7VGRU3O.mjs +0 -283
  66. package/dist/chunk-O66RESRR.cjs +0 -285
  67. package/dist/chunk-VA3PEYFM.mjs +0 -489
  68. package/dist/chunk-VBBJSIY7.cjs +0 -308
  69. package/dist/chunk-WWGF6TBZ.mjs +0 -206
  70. package/dist/chunk-ZGN4UEJR.cjs +0 -679
  71. package/dist/chunk-ZQLRMOUW.mjs +0 -661
  72. package/src/cli/dial-cli.ts +0 -1133
  73. package/dist/{chunk-XMUP5MIM.mjs → chunk-G3EIVAVR.mjs} +0 -0
  74. package/dist/{chunk-7IS37C3P.cjs → chunk-K4I4YU6N.cjs} +1 -1
  75. package/dist/{chunk-OX2U5RAG.cjs → chunk-KFPS5CCR.cjs} +0 -0
  76. package/dist/{chunk-2OZK5DY5.mjs → chunk-KXKEZ3MH.mjs} +1 -1
  77. package/dist/{chunk-LJMNHTTG.cjs → chunk-OEI7NCF6.cjs} +4 -4
  78. package/dist/{chunk-W4JCKCW7.mjs → chunk-QHPFLC2O.mjs} +4 -4
package/cli/dial-cli.js DELETED
@@ -1,833 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/cli/dial-cli.ts
4
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
5
- import { basename, dirname, join, resolve } from "path";
6
- import { parseArgs } from "util";
7
- import { fileURLToPath } from "url";
8
- import { execSync } from "child_process";
9
- import * as docgen from "react-docgen-typescript";
10
- import * as ts from "typescript";
11
- function getVersionInfo() {
12
- try {
13
- const __filename2 = fileURLToPath(import.meta.url);
14
- const __dirname2 = dirname(__filename2);
15
- const possiblePaths = [
16
- resolve(__dirname2, "../package.json"),
17
- // Built version: cli/dial-cli.js -> package.json
18
- resolve(__dirname2, "../../package.json")
19
- // Source version: src/cli/dial-cli.ts -> package.json
20
- ];
21
- let packageJson = null;
22
- for (const path of possiblePaths) {
23
- try {
24
- if (existsSync(path)) {
25
- packageJson = JSON.parse(readFileSync(path, "utf-8"));
26
- break;
27
- }
28
- } catch {
29
- }
30
- }
31
- const version = packageJson?.version || "unknown";
32
- let gitHash;
33
- try {
34
- gitHash = execSync("git rev-parse --short HEAD", { encoding: "utf-8", cwd: dirname(__dirname2) }).trim();
35
- } catch {
36
- gitHash = void 0;
37
- }
38
- return { version, gitHash };
39
- } catch (error) {
40
- return { version: "unknown" };
41
- }
42
- }
43
- function parseTypeAlias(sourceFile, typeName) {
44
- let typeDefinition = null;
45
- function visit(node) {
46
- if (ts.isTypeAliasDeclaration(node) && node.name.text === typeName) {
47
- typeDefinition = {
48
- name: typeName,
49
- kind: "typeAlias",
50
- raw: node.getFullText().trim()
51
- };
52
- const fullText = node.getFullText();
53
- const jsDocMatch = fullText.match(/\/\*\*([\s\S]*?)\*\//);
54
- if (jsDocMatch) {
55
- const jsDocContent = jsDocMatch[1];
56
- typeDefinition.dialTags = parseDialTags(jsDocContent);
57
- typeDefinition.jsDoc = jsDocContent.trim();
58
- }
59
- if (ts.isTupleTypeNode(node.type)) {
60
- typeDefinition.type = "tuple";
61
- typeDefinition.elements = [];
62
- node.type.elements.forEach((element, index) => {
63
- const elementData = {
64
- index,
65
- raw: element.getFullText().trim()
66
- };
67
- if (ts.isNamedTupleMember(element)) {
68
- elementData.name = element.name?.getText();
69
- elementData.type = element.type?.getText();
70
- const sourceText = element.getFullText();
71
- const commentMatch = sourceText.match(/\/\/(.+)/);
72
- if (commentMatch) {
73
- elementData.comment = commentMatch[1].trim();
74
- const dialTags = {};
75
- const minMatch = commentMatch[1].match(/@dial-min\s+([\d.]+)/);
76
- if (minMatch) {
77
- dialTags.min = parseFloat(minMatch[1]);
78
- elementData.min = dialTags.min;
79
- }
80
- const maxMatch = commentMatch[1].match(/@dial-max\s+([\d.]+)/);
81
- if (maxMatch) {
82
- dialTags.max = parseFloat(maxMatch[1]);
83
- elementData.max = dialTags.max;
84
- }
85
- const stepMatch = commentMatch[1].match(/@dial-step\s+([\d.]+)/);
86
- if (stepMatch) {
87
- dialTags.step = parseFloat(stepMatch[1]);
88
- elementData.step = dialTags.step;
89
- }
90
- const dtypeMatch = commentMatch[1].match(/@dial-dtype\s+(\w+)/);
91
- if (dtypeMatch) {
92
- dialTags.dtype = dtypeMatch[1];
93
- elementData.dtype = dtypeMatch[1];
94
- } else {
95
- elementData.dtype = "number";
96
- }
97
- elementData.dialTags = dialTags;
98
- }
99
- }
100
- typeDefinition.elements.push(elementData);
101
- });
102
- } else if (ts.isArrayTypeNode(node.type)) {
103
- typeDefinition.type = "array";
104
- typeDefinition.elementType = node.type.elementType?.getText();
105
- } else {
106
- typeDefinition.type = "other";
107
- typeDefinition.typeNode = node.type ? node.type.getText() : "unknown";
108
- }
109
- }
110
- ts.forEachChild(node, visit);
111
- }
112
- visit(sourceFile);
113
- return typeDefinition;
114
- }
115
- function parseInterfaceProperties(sourceFile, interfaceName) {
116
- const properties = [];
117
- let interfaceDialTags = {};
118
- const groupConfigs = {};
119
- function visit(node) {
120
- if (ts.isInterfaceDeclaration(node) && node.name.text === interfaceName) {
121
- const interfaceJsDocNodes = ts.getJSDocCommentsAndTags(node);
122
- if (interfaceJsDocNodes && interfaceJsDocNodes.length > 0) {
123
- const interfaceFullText = interfaceJsDocNodes[0].getFullText();
124
- interfaceDialTags = parseDialTags(interfaceFullText);
125
- const lines = interfaceFullText.split("\n");
126
- lines.forEach((line) => {
127
- const groupMatch = line.match(/@dial\s+(\w+)(.*)/);
128
- if (groupMatch) {
129
- const groupName = groupMatch[1];
130
- const configStr = groupMatch[2];
131
- if (configStr.includes("@dial-no-wrap")) {
132
- groupConfigs[groupName] = { noWrap: true };
133
- }
134
- }
135
- });
136
- }
137
- node.members.forEach((member) => {
138
- if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
139
- const propName = member.name.text;
140
- const jsDocNodes = ts.getJSDocCommentsAndTags(member);
141
- let propertyDialTags = {};
142
- if (jsDocNodes && jsDocNodes.length > 0) {
143
- const fullText = jsDocNodes[0].getFullText();
144
- propertyDialTags = parseDialTags(fullText);
145
- }
146
- const mergedDialTags = { ...interfaceDialTags, ...propertyDialTags };
147
- const prop = {
148
- name: propName,
149
- dtype: mergedDialTags.dtype || "number"
150
- };
151
- if (mergedDialTags.min !== void 0) prop.min = mergedDialTags.min;
152
- if (mergedDialTags.max !== void 0) prop.max = mergedDialTags.max;
153
- if (mergedDialTags.step !== void 0) prop.step = mergedDialTags.step;
154
- if (mergedDialTags.icon) prop.icon = mergedDialTags.icon;
155
- if (mergedDialTags.grouping || mergedDialTags.column || mergedDialTags.rowCount || mergedDialTags.colCount || mergedDialTags.labelPosition || mergedDialTags.noWrap) {
156
- prop.tags = {};
157
- if (mergedDialTags.grouping) {
158
- prop.tags.grouping = mergedDialTags.grouping;
159
- if (groupConfigs[mergedDialTags.grouping]?.noWrap) {
160
- prop.tags.noWrap = true;
161
- }
162
- }
163
- if (mergedDialTags.column) prop.tags.layout = "column";
164
- if (mergedDialTags.rowCount) prop.tags.row = mergedDialTags.rowCount;
165
- if (mergedDialTags.colCount) prop.tags.col = mergedDialTags.colCount;
166
- if (mergedDialTags.labelPosition) prop.tags.labelPosition = mergedDialTags.labelPosition;
167
- if (mergedDialTags.noWrap) prop.tags.noWrap = true;
168
- }
169
- properties.push(prop);
170
- }
171
- });
172
- }
173
- ts.forEachChild(node, visit);
174
- }
175
- visit(sourceFile);
176
- return properties;
177
- }
178
- function parseDialTags(description) {
179
- const dialTags = {};
180
- if (!description) return dialTags;
181
- if (/@dial-ignore\b/i.test(description)) {
182
- dialTags.ignore = true;
183
- return dialTags;
184
- }
185
- const groupingPattern = /@dial\s+(transform|visibility|geometry|segments)\b/gm;
186
- let match;
187
- while ((match = groupingPattern.exec(description)) !== null) {
188
- dialTags.grouping = match[1];
189
- }
190
- const propertyPattern = /@dial-([\w-]+)(?:\s+([^\n@]+?))?(?:\n|@|$)/gm;
191
- while ((match = propertyPattern.exec(description)) !== null) {
192
- const [, key, value] = match;
193
- switch (key) {
194
- case "options":
195
- if (value) {
196
- try {
197
- dialTags.options = JSON.parse(value);
198
- } catch {
199
- dialTags.options = value;
200
- }
201
- }
202
- break;
203
- case "min":
204
- case "max":
205
- case "step":
206
- if (value) {
207
- dialTags[key] = parseFloat(value);
208
- }
209
- break;
210
- case "col":
211
- case "column":
212
- dialTags.column = true;
213
- break;
214
- case "row":
215
- if (value && /^\d+$/.test(value)) {
216
- dialTags.rowCount = parseInt(value, 10);
217
- }
218
- break;
219
- case "col-3":
220
- case "col-2":
221
- case "col-4": {
222
- const colMatch = key.match(/col-(\d+)/);
223
- if (colMatch) {
224
- dialTags.colCount = parseInt(colMatch[1], 10);
225
- }
226
- break;
227
- }
228
- case "row-3":
229
- case "row-2":
230
- case "row-4": {
231
- const rowMatch = key.match(/row-(\d+)/);
232
- if (rowMatch) {
233
- dialTags.rowCount = parseInt(rowMatch[1], 10);
234
- }
235
- break;
236
- }
237
- case "dtype":
238
- if (value) {
239
- dialTags.dtype = value.trim();
240
- }
241
- break;
242
- case "dtypes":
243
- if (value) {
244
- dialTags.dtypes = value.split(",").map((s) => s.trim());
245
- }
246
- break;
247
- case "type":
248
- if (value) {
249
- dialTags.type = value.trim();
250
- }
251
- break;
252
- case "icon":
253
- if (value) {
254
- dialTags.icon = value.trim();
255
- }
256
- break;
257
- case "default":
258
- if (value) {
259
- try {
260
- dialTags.default = JSON.parse(value);
261
- } catch {
262
- dialTags.default = value.trim();
263
- }
264
- }
265
- break;
266
- case "placeholders":
267
- if (value) {
268
- dialTags.placeholders = value.split(",").map((s) => s.trim());
269
- }
270
- break;
271
- case "tooltips":
272
- if (value) {
273
- dialTags.tooltips = value.split(",").map((s) => s.trim());
274
- }
275
- break;
276
- case "mins":
277
- if (value) {
278
- dialTags.mins = value.split(",").map((s) => parseFloat(s.trim()));
279
- }
280
- break;
281
- case "maxs":
282
- if (value) {
283
- dialTags.maxs = value.split(",").map((s) => parseFloat(s.trim()));
284
- }
285
- break;
286
- case "steps":
287
- if (value) {
288
- dialTags.steps = value.split(",").map((s) => parseFloat(s.trim()));
289
- }
290
- break;
291
- case "label-left":
292
- case "left":
293
- dialTags.labelPosition = "left";
294
- break;
295
- case "label-right":
296
- case "right":
297
- dialTags.labelPosition = "right";
298
- break;
299
- case "label-center":
300
- case "label-middle":
301
- case "center":
302
- case "middle":
303
- dialTags.labelPosition = "center";
304
- break;
305
- case "label-top":
306
- case "top":
307
- dialTags.labelPosition = "top";
308
- break;
309
- case "label-bottom":
310
- case "bottom":
311
- dialTags.labelPosition = "bottom";
312
- break;
313
- case "label-inline":
314
- case "inline":
315
- dialTags.labelPosition = "inline";
316
- break;
317
- case "no-wrap":
318
- dialTags.noWrap = true;
319
- break;
320
- default:
321
- break;
322
- }
323
- }
324
- return dialTags;
325
- }
326
- function propToDialSchema(propName, propData, groupConfigs) {
327
- const description = propData.description || "";
328
- const dialTags = parseDialTags(description);
329
- if (dialTags.ignore) {
330
- return null;
331
- }
332
- let dtype = dialTags.dtype;
333
- if (!dtype) {
334
- const type = propData.type;
335
- const typeName = type?.name || "";
336
- if (typeName === "boolean") {
337
- dtype = "boolean";
338
- } else if (typeName === "number") {
339
- dtype = "number";
340
- } else if (typeName.includes("[]")) {
341
- dtype = "array";
342
- } else {
343
- dtype = "string";
344
- }
345
- }
346
- const schema = {
347
- name: propName,
348
- dtype
349
- };
350
- if (dialTags.default !== void 0) {
351
- schema.value = dialTags.default;
352
- } else {
353
- const defaultValue = propData.defaultValue;
354
- if (defaultValue?.value) {
355
- try {
356
- schema.value = JSON.parse(defaultValue.value);
357
- } catch {
358
- schema.value = defaultValue.value;
359
- }
360
- }
361
- }
362
- if (dialTags.min !== void 0) schema.min = dialTags.min;
363
- if (dialTags.max !== void 0) schema.max = dialTags.max;
364
- if (dialTags.step !== void 0) schema.step = dialTags.step;
365
- if (dialTags.options) schema.options = dialTags.options;
366
- if (dialTags.icon) schema.icon = dialTags.icon;
367
- if (dialTags.placeholders) schema.placeholders = dialTags.placeholders;
368
- if (dialTags.tooltips) schema.tooltips = dialTags.tooltips;
369
- if (dialTags.dtypes) schema.dtypes = dialTags.dtypes;
370
- if (dialTags.mins) schema.mins = dialTags.mins;
371
- if (dialTags.maxs) schema.maxs = dialTags.maxs;
372
- if (dialTags.steps) schema.steps = dialTags.steps;
373
- const tags = {};
374
- if (dialTags.grouping) {
375
- tags.grouping = dialTags.grouping;
376
- if (groupConfigs && groupConfigs[dialTags.grouping]?.noWrap) {
377
- tags.noWrap = true;
378
- }
379
- }
380
- if (dialTags.column) {
381
- tags.col = true;
382
- }
383
- if (dialTags.rowCount) {
384
- tags.row = dialTags.rowCount;
385
- tags.layout = "row";
386
- }
387
- if (dialTags.colCount) {
388
- tags.col = dialTags.colCount;
389
- tags.layout = "column";
390
- }
391
- if (dialTags.labelPosition) {
392
- tags.labelPosition = dialTags.labelPosition;
393
- }
394
- if (Object.keys(tags).length > 0) {
395
- schema.tags = tags;
396
- }
397
- return schema;
398
- }
399
- async function processFile(filePath, outputDir, options, flags = {}) {
400
- if (!flags.quiet) {
401
- console.log(`
402
- \u{1F4E6} Processing ${filePath}...`);
403
- }
404
- const docs = docgen.parse(filePath, options);
405
- const sourceCode = readFileSync(filePath, "utf-8");
406
- const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true);
407
- const enhancedMetadata = docs.map((doc) => {
408
- const dialSchema = [];
409
- const groupConfigs = {};
410
- if (doc.description) {
411
- const componentTags = parseDialTags(doc.description);
412
- const descLines = doc.description.split("\n");
413
- descLines.forEach((line) => {
414
- const groupMatch = line.match(/@dial\s+(\w+)(.*)/);
415
- if (groupMatch) {
416
- const groupName = groupMatch[1];
417
- const configStr = groupMatch[2];
418
- if (configStr.includes("@dial-no-wrap")) {
419
- groupConfigs[groupName] = { noWrap: true };
420
- }
421
- }
422
- });
423
- }
424
- const propsInterfaceName = doc.displayName + "Props";
425
- function findInterfaceJSDoc(node) {
426
- if (ts.isInterfaceDeclaration(node) && node.name.text === propsInterfaceName) {
427
- const interfaceJsDocNodes = ts.getJSDocCommentsAndTags(node);
428
- if (interfaceJsDocNodes && interfaceJsDocNodes.length > 0) {
429
- const interfaceFullText = interfaceJsDocNodes[0].getFullText();
430
- const lines = interfaceFullText.split("\n");
431
- lines.forEach((line) => {
432
- const groupMatch = line.match(/@dial\s+(\w+)(.*)/);
433
- if (groupMatch) {
434
- const groupName = groupMatch[1];
435
- const configStr = groupMatch[2];
436
- if (configStr.includes("@dial-no-wrap")) {
437
- groupConfigs[groupName] = { noWrap: true };
438
- }
439
- }
440
- });
441
- }
442
- }
443
- ts.forEachChild(node, findInterfaceJSDoc);
444
- }
445
- findInterfaceJSDoc(sourceFile);
446
- for (const [propName, propData] of Object.entries(doc.props || {})) {
447
- const propDescription = propData.description || "";
448
- const propDialTags = parseDialTags(propDescription);
449
- if (propDialTags.ignore) {
450
- continue;
451
- }
452
- const propType = propData.type;
453
- const referencedType = propDialTags.type || propType?.name;
454
- if (referencedType) {
455
- const typeDefinition = parseTypeAlias(sourceFile, referencedType);
456
- if (typeDefinition) {
457
- const schema = propToDialSchema(propName, propData, groupConfigs);
458
- if (!schema) {
459
- continue;
460
- }
461
- if (typeDefinition.elements && typeDefinition.elements.length > 0) {
462
- schema.dtype = "vector";
463
- const mins = [];
464
- const maxs = [];
465
- const steps = [];
466
- const dtypes = [];
467
- const placeholders = [];
468
- const tooltips = [];
469
- typeDefinition.elements.forEach((element) => {
470
- if (element.name) {
471
- mins.push(element.min !== void 0 ? element.min : 0);
472
- maxs.push(element.max !== void 0 ? element.max : 100);
473
- steps.push(element.step !== void 0 ? element.step : 1);
474
- dtypes.push(element.dtype || "number");
475
- placeholders.push(element.name);
476
- const tooltip = element.name.includes("Segments") ? `${element.name.replace("Segments", " segments")}` : element.name.charAt(0).toUpperCase() + element.name.slice(1);
477
- tooltips.push(tooltip);
478
- }
479
- });
480
- if (mins.length > 0) schema.mins = mins;
481
- if (maxs.length > 0) schema.maxs = maxs;
482
- if (steps.length > 0) schema.steps = steps;
483
- if (dtypes.length > 0) schema.dtypes = dtypes;
484
- if (placeholders.length > 0) schema.placeholders = placeholders;
485
- if (tooltips.length > 0) schema.tooltips = tooltips;
486
- schema.typeDefinition = typeDefinition;
487
- }
488
- dialSchema.push(schema);
489
- const interfaceProps = parseInterfaceProperties(sourceFile, referencedType);
490
- interfaceProps.forEach((prop) => {
491
- dialSchema.push({
492
- ...prop,
493
- name: `${propName}.${prop.name}`,
494
- tags: {
495
- grouping: "nested",
496
- parent: propName,
497
- hidden: true,
498
- metadata: true
499
- }
500
- });
501
- });
502
- } else {
503
- const schema = propToDialSchema(propName, propData, groupConfigs);
504
- if (schema) {
505
- dialSchema.push(schema);
506
- }
507
- }
508
- } else {
509
- const schema = propToDialSchema(propName, propData, groupConfigs);
510
- if (schema) {
511
- dialSchema.push(schema);
512
- }
513
- }
514
- }
515
- return {
516
- displayName: doc.displayName,
517
- description: doc.description,
518
- dialSchema,
519
- groupConfigs,
520
- props: doc.props
521
- };
522
- });
523
- if (!existsSync(outputDir)) {
524
- mkdirSync(outputDir, { recursive: true });
525
- }
526
- const baseName = basename(filePath, ".tsx").toLowerCase();
527
- writeFileSync(join(outputDir, `${baseName}-raw.json`), JSON.stringify(docs, null, 2));
528
- if (!flags.quiet) {
529
- console.log(`\u{1F4DD} Wrote raw metadata to ${baseName}-raw.json`);
530
- }
531
- writeFileSync(
532
- join(outputDir, `${baseName}-combined.json`),
533
- JSON.stringify(enhancedMetadata, null, 2)
534
- );
535
- if (!flags.quiet) {
536
- console.log(`\u{1F4DD} Wrote enhanced metadata to ${baseName}-combined.json`);
537
- }
538
- const schemas = enhancedMetadata.map((c) => {
539
- const groups = Object.entries(c.groupConfigs || {}).map(([name, config]) => ({
540
- name,
541
- ...config
542
- }));
543
- return {
544
- component: c.displayName,
545
- schemas: c.dialSchema,
546
- groups: groups.length > 0 ? groups : void 0,
547
- config: c.dialConfig
548
- };
549
- });
550
- writeFileSync(join(outputDir, `${baseName}-schemas.json`), JSON.stringify(schemas, null, 2));
551
- if (!flags.quiet) {
552
- console.log(`\u{1F4DD} Wrote dial schemas to ${baseName}-schemas.json`);
553
- }
554
- if (flags.verbose && enhancedMetadata.length > 0) {
555
- console.log("\n\u{1F4CA} Generated dial schemas:");
556
- enhancedMetadata.forEach((meta) => {
557
- console.log(`
558
- Component: ${meta.displayName}`);
559
- console.log(` Properties: ${meta.dialSchema.length}`);
560
- if (meta.dialSchema.length > 0) {
561
- console.log(` Sample schema:`);
562
- console.log(JSON.stringify(meta.dialSchema[0], null, 4).split("\n").map((line) => " " + line).join("\n"));
563
- }
564
- });
565
- }
566
- }
567
- function getHelpText() {
568
- const { version, gitHash } = getVersionInfo();
569
- const versionString = gitHash ? `v${version} (${gitHash})` : `v${version}`;
570
- return `
571
- dial-cli - Generate dial metadata from TypeScript/React components
572
-
573
- SYNOPSIS
574
- dial-cli [options] <file.tsx> [file2.tsx ...]
575
-
576
- DESCRIPTION
577
- The dial-cli tool parses TypeScript and React component files to extract
578
- @dial annotations from JSDoc comments and generates JSON metadata files
579
- that can be used to automatically create UI controls.
580
-
581
- The tool generates three types of output files for each input:
582
- \u2022 *-raw.json - Raw output from react-docgen-typescript
583
- \u2022 *-combined.json - Enhanced metadata with dial schema information
584
- \u2022 *-schemas.json - Just the dial schemas for UI generation
585
-
586
- OPTIONS
587
- -o, --output <dir>
588
- Output directory for generated metadata files (default: ./metadata)
589
-
590
- -i, --ignore <prop>
591
- Property names or patterns to exclude from dial schema generation
592
- Can be specified multiple times: -i prop1 -i prop2
593
- Or as a comma-separated list: -i prop1,prop2,prop3
594
- Supports glob patterns: -i "*Style" -i "on*" -i "_*"
595
-
596
- -h, --help
597
- Display this help message and exit
598
-
599
- -v, --version
600
- Display version information and exit
601
-
602
- --verbose
603
- Enable verbose output with detailed processing information
604
-
605
- --quiet
606
- Suppress all output except errors
607
-
608
- DIAL ANNOTATIONS
609
- The tool recognizes the following @dial annotations in JSDoc comments:
610
-
611
- Grouping:
612
- @dial <group> Group related properties (transform, visibility, etc.)
613
-
614
- Property Configuration:
615
- @dial-dtype <type> Data type (vector3, euler, boolean, int, etc.)
616
- @dial-min <number> Minimum value for numeric inputs
617
- @dial-max <number> Maximum value for numeric inputs
618
- @dial-step <number> Step increment for numeric inputs
619
- @dial-default <value> Default value (overrides component default)
620
- @dial-options [...] Array of preset values
621
- @dial-icon <name> Lucide icon name for the control
622
- @dial-ignore Exclude this property from dial schema generation
623
-
624
- FormLayout:
625
- @dial-col-<n> Display in column layout with n columns
626
- @dial-row-<n> Display in row layout with n items per row
627
- @dial-label-<pos> Label position (left, right, top, bottom, inline)
628
-
629
- Vector Types:
630
- @dial-mins <n,n,n> Comma-separated min values for vector elements
631
- @dial-maxs <n,n,n> Comma-separated max values for vector elements
632
- @dial-steps <n,n,n> Comma-separated step values for vector elements
633
- @dial-dtypes <t,t,t> Comma-separated data types for vector elements
634
-
635
- EXAMPLES
636
- Generate metadata for a single component:
637
- $ dial-cli MyComponent.tsx
638
-
639
- Specify a custom output directory:
640
- $ dial-cli -o ./docs/metadata MyComponent.tsx
641
-
642
- Process multiple files:
643
- $ dial-cli Component1.tsx Component2.tsx Component3.tsx
644
-
645
- Process all components in a directory:
646
- $ dial-cli src/components/*.tsx
647
-
648
- Generate metadata with verbose output:
649
- $ dial-cli --verbose MyComponent.tsx
650
-
651
- Exclude specific properties from schema generation:
652
- $ dial-cli -i className -i style -i children MyComponent.tsx
653
- $ dial-cli --ignore ref,key,id MyComponent.tsx
654
-
655
- EXAMPLE COMPONENT
656
- interface Props {
657
- /**
658
- * Position in 3D space
659
- * @dial transform
660
- * @dial-dtype vector3
661
- * @dial-mins -10,-10,-10
662
- * @dial-maxs 10,10,10
663
- * @dial-steps 0.1,0.1,0.1
664
- * @dial-icon Move3d
665
- */
666
- position: [number, number, number];
667
-
668
- /**
669
- * Visibility toggle
670
- * @dial visibility
671
- * @dial-dtype boolean
672
- * @dial-icon Eye
673
- */
674
- visible: boolean;
675
- }
676
-
677
- FILES
678
- The tool generates the following files in the output directory:
679
-
680
- <component>-raw.json
681
- Raw docgen output with all prop information
682
-
683
- <component>-combined.json
684
- Enhanced metadata including dial schemas and type definitions
685
-
686
- <component>-schemas.json
687
- Extracted dial schemas ready for UI generation
688
-
689
- ENVIRONMENT
690
- NODE_ENV
691
- Set to 'development' for debug output
692
-
693
- SEE ALSO
694
- Documentation: https://uikit.vuer.ai/dial
695
- GitHub: https://github.com/vuer-ai/vuer-uikit
696
-
697
- VERSION
698
- dial-cli ${versionString} (part of @vuer-ai/vuer-uikit)
699
-
700
- AUTHORS
701
- Vuer AI Team <team@vuer.ai>
702
- `;
703
- }
704
- async function main() {
705
- const { values, positionals } = parseArgs({
706
- args: process.argv.slice(2),
707
- options: {
708
- output: {
709
- type: "string",
710
- short: "o",
711
- default: "./metadata"
712
- },
713
- ignore: {
714
- type: "string",
715
- short: "i",
716
- multiple: true,
717
- default: []
718
- },
719
- help: {
720
- type: "boolean",
721
- short: "h"
722
- },
723
- version: {
724
- type: "boolean",
725
- short: "v"
726
- },
727
- verbose: {
728
- type: "boolean"
729
- },
730
- quiet: {
731
- type: "boolean"
732
- }
733
- },
734
- allowPositionals: true
735
- });
736
- if (values.version) {
737
- const { version, gitHash } = getVersionInfo();
738
- const versionString = gitHash ? `v${version} (${gitHash})` : `v${version}`;
739
- console.log(`dial-cli ${versionString} (part of @vuer-ai/vuer-uikit)`);
740
- process.exit(0);
741
- }
742
- if (values.help || positionals.length === 0) {
743
- console.log(getHelpText());
744
- process.exit(0);
745
- }
746
- if (positionals.length === 1 && (positionals[0] === "man" || positionals[0] === "help")) {
747
- console.log(getHelpText());
748
- process.exit(0);
749
- }
750
- const outputDir = resolve(process.cwd(), values.output);
751
- const ignoreList = [];
752
- const ignoreValues = values.ignore;
753
- if (ignoreValues) {
754
- if (Array.isArray(ignoreValues)) {
755
- ignoreValues.forEach((val) => {
756
- ignoreList.push(...val.split(",").map((s) => s.trim()));
757
- });
758
- } else if (typeof ignoreValues === "string") {
759
- ignoreList.push(...ignoreValues.split(",").map((s) => s.trim()));
760
- }
761
- }
762
- const options = {
763
- savePropValueAsString: true,
764
- shouldExtractLiteralValuesFromEnum: true,
765
- shouldRemoveUndefinedFromOptional: true,
766
- propFilter: (prop) => {
767
- if (prop.name === "ref" || prop.name === "key") {
768
- return false;
769
- }
770
- for (const pattern of ignoreList) {
771
- if (pattern.includes("*") || pattern.includes("?")) {
772
- const regex = new RegExp("^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$");
773
- if (regex.test(prop.name)) {
774
- return false;
775
- }
776
- } else if (prop.name === pattern) {
777
- return false;
778
- }
779
- }
780
- return true;
781
- }
782
- };
783
- const flags = {
784
- verbose: values.verbose,
785
- quiet: values.quiet,
786
- ignoreList
787
- };
788
- if (!flags.quiet) {
789
- const { version, gitHash } = getVersionInfo();
790
- const versionString = gitHash ? `v${version} (${gitHash})` : `v${version}`;
791
- console.log(`\u{1F680} Dial Documentation Generator ${versionString}`);
792
- console.log(`\u{1F4C2} Output directory: ${outputDir}`);
793
- if (flags.verbose && ignoreList.length > 0) {
794
- console.log(`\u{1F6AB} Ignoring properties: ${ignoreList.join(", ")}`);
795
- }
796
- }
797
- let filesProcessed = 0;
798
- let filesErrored = 0;
799
- for (const file of positionals) {
800
- const filePath = resolve(process.cwd(), file);
801
- if (!existsSync(filePath)) {
802
- console.error(`\u274C File not found: ${filePath}`);
803
- filesErrored++;
804
- continue;
805
- }
806
- try {
807
- await processFile(filePath, outputDir, options, flags);
808
- filesProcessed++;
809
- } catch (error) {
810
- console.error(`\u274C Error processing ${filePath}:`, error);
811
- filesErrored++;
812
- }
813
- }
814
- if (!flags.quiet) {
815
- console.log("\n\u2705 Documentation generation complete!");
816
- if (flags.verbose) {
817
- console.log(` Files processed: ${filesProcessed}`);
818
- if (filesErrored > 0) {
819
- console.log(` Files with errors: ${filesErrored}`);
820
- }
821
- }
822
- }
823
- }
824
- main().catch((error) => {
825
- console.error("Fatal error:", error);
826
- process.exit(1);
827
- });
828
- export {
829
- parseDialTags,
830
- parseInterfaceProperties,
831
- parseTypeAlias,
832
- propToDialSchema
833
- };