shru-design-system 0.1.5 → 0.1.8
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/README.md +96 -166
- package/dist/index.d.mts +54 -1
- package/dist/index.d.ts +54 -1
- package/dist/index.js +232 -104
- package/dist/index.mjs +222 -105
- package/package.json +7 -1
- package/scripts/apply-theme-sync.js +59 -23
- package/scripts/applyThemeSync.js +285 -0
- package/scripts/init.js +192 -367
- package/scripts/themeConfig.js +214 -0
- package/scripts/themeUtils.js +452 -0
- package/scripts/tokens/base.json +46 -0
- package/scripts/tokens/palettes.json +47 -0
- package/scripts/tokens/themes/animation/brisk.json +10 -0
- package/scripts/tokens/themes/animation/gentle.json +10 -0
- package/scripts/tokens/themes/color/dark.json +25 -0
- package/scripts/tokens/themes/color/white.json +25 -0
- package/scripts/tokens/themes/custom/brand.json +14 -0
- package/scripts/tokens/themes/custom/minimal.json +17 -0
- package/scripts/tokens/themes/density/comfortable.json +12 -0
- package/scripts/tokens/themes/density/compact.json +12 -0
- package/scripts/tokens/themes/shape/sharp.json +8 -0
- package/scripts/tokens/themes/shape/smooth.json +8 -0
- package/scripts/tokens/themes/typography/sans.json +7 -0
- package/scripts/tokens/themes/typography/serif.json +7 -0
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/scripts/init.js
CHANGED
|
@@ -272,6 +272,129 @@ function createCSSFile() {
|
|
|
272
272
|
log('Created src/index.css', 'green');
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Get the library's token files directory
|
|
277
|
+
* When running from node_modules, this will be scripts/tokens
|
|
278
|
+
*/
|
|
279
|
+
function getLibraryTokensPath() {
|
|
280
|
+
// __dirname is scripts/ when running from node_modules
|
|
281
|
+
// So scripts/tokens is at __dirname/tokens
|
|
282
|
+
const libraryTokensPath = path.join(__dirname, 'tokens');
|
|
283
|
+
|
|
284
|
+
// Check if tokens exist in scripts/tokens (published package)
|
|
285
|
+
if (fs.existsSync(libraryTokensPath)) {
|
|
286
|
+
return libraryTokensPath;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Recursively copy directory, preserving user files
|
|
294
|
+
* Only copies/updates files that were created by the library
|
|
295
|
+
*/
|
|
296
|
+
function copyDirectory(src, dest) {
|
|
297
|
+
if (!fs.existsSync(src)) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Create destination directory
|
|
302
|
+
if (!fs.existsSync(dest)) {
|
|
303
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
307
|
+
let copiedCount = 0;
|
|
308
|
+
|
|
309
|
+
for (const entry of entries) {
|
|
310
|
+
const srcPath = path.join(src, entry.name);
|
|
311
|
+
const destPath = path.join(dest, entry.name);
|
|
312
|
+
|
|
313
|
+
if (entry.isDirectory()) {
|
|
314
|
+
const subCopied = copyDirectory(srcPath, destPath);
|
|
315
|
+
if (subCopied) copiedCount += subCopied;
|
|
316
|
+
} else if (entry.isFile() && entry.name.endsWith('.json')) {
|
|
317
|
+
// For JSON files, check if it's a library file or user file
|
|
318
|
+
try {
|
|
319
|
+
const srcContent = JSON.parse(fs.readFileSync(srcPath, 'utf8'));
|
|
320
|
+
const isLibraryFile = srcContent._createdBy && srcContent._createdBy.includes(LIBRARY_NAME.split(' ')[0]);
|
|
321
|
+
|
|
322
|
+
if (isLibraryFile) {
|
|
323
|
+
// Always update library files
|
|
324
|
+
fs.copyFileSync(srcPath, destPath);
|
|
325
|
+
copiedCount++;
|
|
326
|
+
} else if (!fs.existsSync(destPath)) {
|
|
327
|
+
// New library file that doesn't exist in dest
|
|
328
|
+
fs.copyFileSync(srcPath, destPath);
|
|
329
|
+
copiedCount++;
|
|
330
|
+
}
|
|
331
|
+
// If dest exists and is not a library file, preserve it (user's custom file)
|
|
332
|
+
} catch (e) {
|
|
333
|
+
// If JSON parsing fails, just copy it
|
|
334
|
+
if (!fs.existsSync(destPath)) {
|
|
335
|
+
fs.copyFileSync(srcPath, destPath);
|
|
336
|
+
copiedCount++;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
} else {
|
|
340
|
+
// Non-JSON files: copy if doesn't exist
|
|
341
|
+
if (!fs.existsSync(destPath)) {
|
|
342
|
+
fs.copyFileSync(srcPath, destPath);
|
|
343
|
+
copiedCount++;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return copiedCount;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Read a token file from the library
|
|
353
|
+
*/
|
|
354
|
+
function readLibraryTokenFile(relativePath) {
|
|
355
|
+
const libraryTokensPath = getLibraryTokensPath();
|
|
356
|
+
if (!libraryTokensPath) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const filePath = path.join(libraryTokensPath, relativePath);
|
|
361
|
+
if (!fs.existsSync(filePath)) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
try {
|
|
366
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
367
|
+
return JSON.parse(content);
|
|
368
|
+
} catch (e) {
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Migrate old token structure to new structure
|
|
375
|
+
*/
|
|
376
|
+
function migrateTokenStructure(data) {
|
|
377
|
+
if (!data || typeof data !== 'object') {
|
|
378
|
+
return data;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const migrated = JSON.parse(JSON.stringify(data)); // Deep clone
|
|
382
|
+
|
|
383
|
+
// Migrate typography.font → font
|
|
384
|
+
if (migrated.typography && migrated.typography.font) {
|
|
385
|
+
migrated.font = migrated.typography.font;
|
|
386
|
+
delete migrated.typography;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Migrate shape.radius → radius
|
|
390
|
+
if (migrated.shape && migrated.shape.radius) {
|
|
391
|
+
migrated.radius = migrated.shape.radius;
|
|
392
|
+
delete migrated.shape;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return migrated;
|
|
396
|
+
}
|
|
397
|
+
|
|
275
398
|
function createTokenFiles() {
|
|
276
399
|
const publicDir = path.join(process.cwd(), 'public');
|
|
277
400
|
const tokensDir = path.join(publicDir, 'tokens');
|
|
@@ -288,381 +411,83 @@ function createTokenFiles() {
|
|
|
288
411
|
fs.mkdirSync(themesDir, { recursive: true });
|
|
289
412
|
}
|
|
290
413
|
|
|
291
|
-
//
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
log('Found old token structure in base.json, updating...', 'yellow');
|
|
301
|
-
}
|
|
302
|
-
} catch (e) {
|
|
303
|
-
needsUpdate = true;
|
|
414
|
+
// Try to copy token files from library
|
|
415
|
+
const libraryTokensPath = getLibraryTokensPath();
|
|
416
|
+
if (libraryTokensPath) {
|
|
417
|
+
log(`Copying token files from library...`, 'blue');
|
|
418
|
+
const copiedCount = copyDirectory(libraryTokensPath, tokensDir);
|
|
419
|
+
if (copiedCount > 0) {
|
|
420
|
+
log(`Token files copied from library successfully! (${copiedCount} files)`, 'green');
|
|
421
|
+
} else {
|
|
422
|
+
log('All token files already exist. Checking for updates...', 'green');
|
|
304
423
|
}
|
|
305
|
-
}
|
|
306
|
-
if (!fs.existsSync(basePath) || needsUpdate) {
|
|
307
|
-
const baseJson = {
|
|
308
|
-
"_createdBy": LIBRARY_NAME,
|
|
309
|
-
"color": {
|
|
310
|
-
"primary": "{palette.blue.500}",
|
|
311
|
-
"primary-hover": "{palette.blue.600}",
|
|
312
|
-
"primary-foreground": "{palette.white}",
|
|
313
|
-
"secondary": "{palette.gray.100}",
|
|
314
|
-
"secondary-foreground": "{palette.gray.900}",
|
|
315
|
-
"background": "{palette.white}",
|
|
316
|
-
"foreground": "{palette.gray.900}",
|
|
317
|
-
"card": "{palette.white}",
|
|
318
|
-
"card-foreground": "{palette.gray.900}",
|
|
319
|
-
"popover": "{palette.white}",
|
|
320
|
-
"popover-foreground": "{palette.gray.900}",
|
|
321
|
-
"muted": "{palette.gray.100}",
|
|
322
|
-
"muted-foreground": "{palette.gray.500}",
|
|
323
|
-
"accent": "{palette.gray.100}",
|
|
324
|
-
"accent-foreground": "{palette.gray.900}",
|
|
325
|
-
"destructive": "{palette.red.500}",
|
|
326
|
-
"destructive-foreground": "{palette.white}",
|
|
327
|
-
"border": "{palette.gray.200}",
|
|
328
|
-
"input": "{palette.gray.200}",
|
|
329
|
-
"ring": "{palette.gray.400}",
|
|
330
|
-
"skeleton": "{palette.gray.200}"
|
|
331
|
-
},
|
|
332
|
-
"spacing": {
|
|
333
|
-
"component": {
|
|
334
|
-
"xs": "0.25rem",
|
|
335
|
-
"sm": "0.5rem",
|
|
336
|
-
"md": "1rem",
|
|
337
|
-
"lg": "1.5rem",
|
|
338
|
-
"xl": "2rem"
|
|
339
|
-
},
|
|
340
|
-
"base": "0.25rem"
|
|
341
|
-
},
|
|
342
|
-
"font": {
|
|
343
|
-
"body": "var(--font-sans)",
|
|
344
|
-
"sans": "var(--font-sans)",
|
|
345
|
-
"mono": "var(--font-mono)"
|
|
346
|
-
},
|
|
347
|
-
"radius": {
|
|
348
|
-
"button": "0.375rem",
|
|
349
|
-
"card": "0.5rem",
|
|
350
|
-
"input": "0.375rem"
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
fs.writeFileSync(basePath, JSON.stringify(baseJson, null, 2));
|
|
354
|
-
log('Created/Updated public/tokens/base.json', 'green');
|
|
355
424
|
} else {
|
|
356
|
-
log('
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
//
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
"700": "#374151",
|
|
377
|
-
"800": "#1f2937",
|
|
378
|
-
"900": "#111827",
|
|
379
|
-
"950": "#030712"
|
|
380
|
-
},
|
|
381
|
-
"blue": {
|
|
382
|
-
"50": "#eff6ff",
|
|
383
|
-
"100": "#dbeafe",
|
|
384
|
-
"200": "#bfdbfe",
|
|
385
|
-
"300": "#93c5fd",
|
|
386
|
-
"400": "#60a5fa",
|
|
387
|
-
"500": "#3b82f6",
|
|
388
|
-
"600": "#2563eb",
|
|
389
|
-
"700": "#1d4ed8",
|
|
390
|
-
"800": "#1e40af",
|
|
391
|
-
"900": "#1e3a8a",
|
|
392
|
-
"950": "#172554"
|
|
393
|
-
},
|
|
394
|
-
"red": {
|
|
395
|
-
"50": "#fef2f2",
|
|
396
|
-
"100": "#fee2e2",
|
|
397
|
-
"200": "#fecaca",
|
|
398
|
-
"300": "#fca5a5",
|
|
399
|
-
"400": "#f87171",
|
|
400
|
-
"500": "#ef4444",
|
|
401
|
-
"600": "#dc2626",
|
|
402
|
-
"700": "#b91c1c",
|
|
403
|
-
"800": "#991b1b",
|
|
404
|
-
"900": "#7f1d1d",
|
|
405
|
-
"950": "#450a0a"
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
};
|
|
409
|
-
fs.writeFileSync(palettesPath, JSON.stringify(palettesJson, null, 2));
|
|
410
|
-
log('Created public/tokens/palettes.json', 'green');
|
|
411
|
-
} else {
|
|
412
|
-
log('public/tokens/palettes.json already exists. Skipping...', 'yellow');
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// Create theme directories and files
|
|
416
|
-
const themeCategories = ['color', 'typography', 'shape', 'density', 'animation', 'custom'];
|
|
417
|
-
|
|
418
|
-
themeCategories.forEach(category => {
|
|
419
|
-
const categoryDir = path.join(themesDir, category);
|
|
420
|
-
if (!fs.existsSync(categoryDir)) {
|
|
421
|
-
fs.mkdirSync(categoryDir, { recursive: true });
|
|
422
|
-
}
|
|
423
|
-
});
|
|
425
|
+
log('Library token files not found, creating default token files...', 'yellow');
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Check and migrate old token structures
|
|
429
|
+
const tokenFilesToCheck = [
|
|
430
|
+
'base.json',
|
|
431
|
+
'palettes.json',
|
|
432
|
+
'themes/color/white.json',
|
|
433
|
+
'themes/color/dark.json',
|
|
434
|
+
'themes/typography/sans.json',
|
|
435
|
+
'themes/typography/serif.json',
|
|
436
|
+
'themes/shape/smooth.json',
|
|
437
|
+
'themes/shape/sharp.json',
|
|
438
|
+
'themes/density/comfortable.json',
|
|
439
|
+
'themes/density/compact.json',
|
|
440
|
+
'themes/animation/gentle.json',
|
|
441
|
+
'themes/animation/brisk.json',
|
|
442
|
+
'themes/custom/brand.json',
|
|
443
|
+
'themes/custom/minimal.json'
|
|
444
|
+
];
|
|
424
445
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
"secondary": "{palette.gray.100}",
|
|
440
|
-
"secondary-foreground": "{palette.gray.900}",
|
|
441
|
-
"muted": "{palette.gray.100}",
|
|
442
|
-
"muted-foreground": "{palette.gray.500}",
|
|
443
|
-
"accent": "{palette.gray.100}",
|
|
444
|
-
"accent-foreground": "{palette.gray.900}",
|
|
445
|
-
"destructive": "{palette.red.500}",
|
|
446
|
-
"destructive-foreground": "{palette.white}",
|
|
447
|
-
"border": "{palette.gray.200}",
|
|
448
|
-
"input": "{palette.gray.200}",
|
|
449
|
-
"ring": "{palette.gray.400}",
|
|
450
|
-
"skeleton": "{palette.gray.200}"
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
fs.writeFileSync(whiteThemePath, JSON.stringify(whiteTheme, null, 2));
|
|
454
|
-
log('Created public/tokens/themes/color/white.json', 'green');
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// Create color/dark.json
|
|
458
|
-
const darkThemePath = path.join(themesDir, 'color', 'dark.json');
|
|
459
|
-
if (!fs.existsSync(darkThemePath)) {
|
|
460
|
-
const darkTheme = {
|
|
461
|
-
"_createdBy": LIBRARY_NAME,
|
|
462
|
-
"color": {
|
|
463
|
-
"primary": "{palette.blue.400}",
|
|
464
|
-
"primary-foreground": "{palette.gray.900}",
|
|
465
|
-
"background": "{palette.gray.900}",
|
|
466
|
-
"foreground": "{palette.gray.50}",
|
|
467
|
-
"card": "{palette.gray.800}",
|
|
468
|
-
"card-foreground": "{palette.gray.50}",
|
|
469
|
-
"popover": "{palette.gray.800}",
|
|
470
|
-
"popover-foreground": "{palette.gray.50}",
|
|
471
|
-
"secondary": "{palette.gray.800}",
|
|
472
|
-
"secondary-foreground": "{palette.gray.50}",
|
|
473
|
-
"muted": "{palette.gray.800}",
|
|
474
|
-
"muted-foreground": "{palette.gray.400}",
|
|
475
|
-
"accent": "{palette.gray.800}",
|
|
476
|
-
"accent-foreground": "{palette.gray.50}",
|
|
477
|
-
"destructive": "{palette.red.500}",
|
|
478
|
-
"destructive-foreground": "{palette.white}",
|
|
479
|
-
"border": "{palette.gray.700}",
|
|
480
|
-
"input": "{palette.gray.700}",
|
|
481
|
-
"ring": "{palette.gray.600}",
|
|
482
|
-
"skeleton": "{palette.gray.700}"
|
|
483
|
-
}
|
|
484
|
-
};
|
|
485
|
-
fs.writeFileSync(darkThemePath, JSON.stringify(darkTheme, null, 2));
|
|
486
|
-
log('Created public/tokens/themes/color/dark.json', 'green');
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// Create typography/sans.json (or update if old structure exists)
|
|
490
|
-
const sansThemePath = path.join(themesDir, 'typography', 'sans.json');
|
|
491
|
-
let needsUpdate = false;
|
|
492
|
-
if (fs.existsSync(sansThemePath)) {
|
|
493
|
-
try {
|
|
494
|
-
const existing = JSON.parse(fs.readFileSync(sansThemePath, 'utf8'));
|
|
495
|
-
// Check if it has old structure (typography.font instead of font)
|
|
496
|
-
if (existing.typography && existing.typography.font) {
|
|
497
|
-
needsUpdate = true;
|
|
498
|
-
log('Found old token structure in typography/sans.json, updating...', 'yellow');
|
|
499
|
-
}
|
|
500
|
-
} catch (e) {
|
|
501
|
-
needsUpdate = true;
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
if (!fs.existsSync(sansThemePath) || needsUpdate) {
|
|
505
|
-
const sansTheme = {
|
|
506
|
-
"_createdBy": LIBRARY_NAME,
|
|
507
|
-
"font": {
|
|
508
|
-
"body": "system-ui, -apple-system, sans-serif",
|
|
509
|
-
"sans": "system-ui, -apple-system, sans-serif"
|
|
510
|
-
}
|
|
511
|
-
};
|
|
512
|
-
fs.writeFileSync(sansThemePath, JSON.stringify(sansTheme, null, 2));
|
|
513
|
-
log('Created/Updated public/tokens/themes/typography/sans.json', 'green');
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// Create typography/serif.json (or update if old structure exists)
|
|
517
|
-
const serifThemePath = path.join(themesDir, 'typography', 'serif.json');
|
|
518
|
-
needsUpdate = false;
|
|
519
|
-
if (fs.existsSync(serifThemePath)) {
|
|
520
|
-
try {
|
|
521
|
-
const existing = JSON.parse(fs.readFileSync(serifThemePath, 'utf8'));
|
|
522
|
-
if (existing.typography && existing.typography.font) {
|
|
523
|
-
needsUpdate = true;
|
|
524
|
-
log('Found old token structure in typography/serif.json, updating...', 'yellow');
|
|
525
|
-
}
|
|
526
|
-
} catch (e) {
|
|
527
|
-
needsUpdate = true;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
if (!fs.existsSync(serifThemePath) || needsUpdate) {
|
|
531
|
-
const serifTheme = {
|
|
532
|
-
"_createdBy": LIBRARY_NAME,
|
|
533
|
-
"font": {
|
|
534
|
-
"body": "Georgia, serif",
|
|
535
|
-
"sans": "Georgia, serif"
|
|
536
|
-
}
|
|
537
|
-
};
|
|
538
|
-
fs.writeFileSync(serifThemePath, JSON.stringify(serifTheme, null, 2));
|
|
539
|
-
log('Created/Updated public/tokens/themes/typography/serif.json', 'green');
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Create shape/smooth.json (or update if old structure exists)
|
|
543
|
-
const smoothThemePath = path.join(themesDir, 'shape', 'smooth.json');
|
|
544
|
-
needsUpdate = false;
|
|
545
|
-
if (fs.existsSync(smoothThemePath)) {
|
|
546
|
-
try {
|
|
547
|
-
const existing = JSON.parse(fs.readFileSync(smoothThemePath, 'utf8'));
|
|
548
|
-
if (existing.shape && existing.shape.radius) {
|
|
549
|
-
needsUpdate = true;
|
|
550
|
-
log('Found old token structure in shape/smooth.json, updating...', 'yellow');
|
|
551
|
-
}
|
|
552
|
-
} catch (e) {
|
|
553
|
-
needsUpdate = true;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (!fs.existsSync(smoothThemePath) || needsUpdate) {
|
|
557
|
-
const smoothTheme = {
|
|
558
|
-
"_createdBy": LIBRARY_NAME,
|
|
559
|
-
"radius": {
|
|
560
|
-
"button": "0.5rem",
|
|
561
|
-
"card": "0.75rem",
|
|
562
|
-
"input": "0.5rem"
|
|
563
|
-
}
|
|
564
|
-
};
|
|
565
|
-
fs.writeFileSync(smoothThemePath, JSON.stringify(smoothTheme, null, 2));
|
|
566
|
-
log('Created/Updated public/tokens/themes/shape/smooth.json', 'green');
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// Create shape/sharp.json (or update if old structure exists)
|
|
570
|
-
const sharpThemePath = path.join(themesDir, 'shape', 'sharp.json');
|
|
571
|
-
needsUpdate = false;
|
|
572
|
-
if (fs.existsSync(sharpThemePath)) {
|
|
573
|
-
try {
|
|
574
|
-
const existing = JSON.parse(fs.readFileSync(sharpThemePath, 'utf8'));
|
|
575
|
-
if (existing.shape && existing.shape.radius) {
|
|
576
|
-
needsUpdate = true;
|
|
577
|
-
log('Found old token structure in shape/sharp.json, updating...', 'yellow');
|
|
578
|
-
}
|
|
579
|
-
} catch (e) {
|
|
580
|
-
needsUpdate = true;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
if (!fs.existsSync(sharpThemePath) || needsUpdate) {
|
|
584
|
-
const sharpTheme = {
|
|
585
|
-
"_createdBy": LIBRARY_NAME,
|
|
586
|
-
"radius": {
|
|
587
|
-
"button": "0",
|
|
588
|
-
"card": "0",
|
|
589
|
-
"input": "0"
|
|
590
|
-
}
|
|
591
|
-
};
|
|
592
|
-
fs.writeFileSync(sharpThemePath, JSON.stringify(sharpTheme, null, 2));
|
|
593
|
-
log('Created/Updated public/tokens/themes/shape/sharp.json', 'green');
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
// Create density/comfortable.json
|
|
597
|
-
const comfortableThemePath = path.join(themesDir, 'density', 'comfortable.json');
|
|
598
|
-
if (!fs.existsSync(comfortableThemePath)) {
|
|
599
|
-
const comfortableTheme = {
|
|
600
|
-
"_createdBy": LIBRARY_NAME,
|
|
601
|
-
"spacing": {
|
|
602
|
-
"component": {
|
|
603
|
-
"xs": "0.5rem",
|
|
604
|
-
"sm": "0.75rem",
|
|
605
|
-
"md": "1.25rem",
|
|
606
|
-
"lg": "2rem",
|
|
607
|
-
"xl": "2.5rem"
|
|
446
|
+
tokenFilesToCheck.forEach(relativePath => {
|
|
447
|
+
const destPath = path.join(tokensDir, relativePath);
|
|
448
|
+
|
|
449
|
+
// If file exists, check if it needs migration
|
|
450
|
+
if (fs.existsSync(destPath)) {
|
|
451
|
+
try {
|
|
452
|
+
const existing = JSON.parse(fs.readFileSync(destPath, 'utf8'));
|
|
453
|
+
const migrated = migrateTokenStructure(existing);
|
|
454
|
+
|
|
455
|
+
// Check if migration changed the structure
|
|
456
|
+
if (JSON.stringify(existing) !== JSON.stringify(migrated)) {
|
|
457
|
+
migrated._createdBy = LIBRARY_NAME;
|
|
458
|
+
fs.writeFileSync(destPath, JSON.stringify(migrated, null, 2));
|
|
459
|
+
log(`Migrated ${relativePath} to new structure`, 'yellow');
|
|
608
460
|
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const compactThemePath = path.join(themesDir, 'density', 'compact.json');
|
|
617
|
-
if (!fs.existsSync(compactThemePath)) {
|
|
618
|
-
const compactTheme = {
|
|
619
|
-
"_createdBy": LIBRARY_NAME,
|
|
620
|
-
"spacing": {
|
|
621
|
-
"component": {
|
|
622
|
-
"xs": "0.25rem",
|
|
623
|
-
"sm": "0.5rem",
|
|
624
|
-
"md": "0.75rem",
|
|
625
|
-
"lg": "1rem",
|
|
626
|
-
"xl": "1.5rem"
|
|
461
|
+
} catch (e) {
|
|
462
|
+
// If file is corrupted, try to read from library
|
|
463
|
+
const libraryData = readLibraryTokenFile(relativePath);
|
|
464
|
+
if (libraryData) {
|
|
465
|
+
libraryData._createdBy = LIBRARY_NAME;
|
|
466
|
+
fs.writeFileSync(destPath, JSON.stringify(libraryData, null, 2));
|
|
467
|
+
log(`Restored ${relativePath} from library`, 'green');
|
|
627
468
|
}
|
|
628
469
|
}
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
const gentleTheme = {
|
|
638
|
-
"_createdBy": LIBRARY_NAME,
|
|
639
|
-
"animation": {
|
|
640
|
-
"duration": {
|
|
641
|
-
"fast": "150ms",
|
|
642
|
-
"normal": "300ms",
|
|
643
|
-
"slow": "500ms"
|
|
470
|
+
} else {
|
|
471
|
+
// File doesn't exist, try to read from library
|
|
472
|
+
const libraryData = readLibraryTokenFile(relativePath);
|
|
473
|
+
if (libraryData) {
|
|
474
|
+
// Ensure directory exists
|
|
475
|
+
const destDir = path.dirname(destPath);
|
|
476
|
+
if (!fs.existsSync(destDir)) {
|
|
477
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
644
478
|
}
|
|
479
|
+
|
|
480
|
+
libraryData._createdBy = LIBRARY_NAME;
|
|
481
|
+
fs.writeFileSync(destPath, JSON.stringify(libraryData, null, 2));
|
|
482
|
+
log(`Created ${relativePath} from library`, 'green');
|
|
645
483
|
}
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
if (!fs.existsSync(briskThemePath)) {
|
|
654
|
-
const briskTheme = {
|
|
655
|
-
"_createdBy": LIBRARY_NAME,
|
|
656
|
-
"animation": {
|
|
657
|
-
"duration": {
|
|
658
|
-
"fast": "100ms",
|
|
659
|
-
"normal": "200ms",
|
|
660
|
-
"slow": "300ms"
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
fs.writeFileSync(briskThemePath, JSON.stringify(briskTheme, null, 2));
|
|
665
|
-
log('Created public/tokens/themes/animation/brisk.json', 'green');
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// If library tokens not found, we can't create files (user needs to install package properly)
|
|
488
|
+
if (!libraryTokensPath) {
|
|
489
|
+
log('Warning: Could not find library token files. Make sure the package is properly installed.', 'yellow');
|
|
490
|
+
return;
|
|
666
491
|
}
|
|
667
492
|
}
|
|
668
493
|
|