@work-rjkashyap/unified-ui 0.3.2 → 0.3.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/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
 
11
11
  ### 🚀 Features
12
12
 
13
+ - Add motion tokens for animation consistency
14
+ - Introduced motion tokens in `motion.ts` for durations, easings, springs, and stagger timings to standardize animations across the design system. ([65feea0](https://github.com/imrj05/unified-ui/commit/65feea0c5ab3b43d3aa6a4300aedda58b9769fad))
15
+ ## [0.3.2] — 2026-03-09
16
+
17
+ ### 🚀 Features
18
+
13
19
  - Update composer.json version to 0.0.5, add PHP config integration, and enhance InitCommand ([26cacd4](https://github.com/imrj05/unified-ui/commit/26cacd4b8a16ea4cc31d7894c5fb0dbbb0541f8a))
14
20
  - Update composer.json version to 0.0.4 and enhance InitCommand with skip-npm option ([0ce9f0e](https://github.com/imrj05/unified-ui/commit/0ce9f0eb0e9da9bdf8e421a27571b160b343e293))
15
21
  - Update composer.json version and enhance InitCommand for app.js and app.css patching ([67ee978](https://github.com/imrj05/unified-ui/commit/67ee97825c2c89ef7c2da15bc41532c1aa776da7))
@@ -45,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
45
51
 
46
52
  ### 🏗️ Miscellaneous
47
53
 
54
+ - **changelog:** Auto-update unreleased entries [skip ci] ([7fb15c9](https://github.com/imrj05/unified-ui/commit/7fb15c907a060b6c15d65fd85e073ed1cbcff740))
48
55
  - **changelog:** Auto-update unreleased entries [skip ci] ([7dbe966](https://github.com/imrj05/unified-ui/commit/7dbe96600fe84196757a878c4256a3e3cb0f6682))
49
56
  - **changelog:** Auto-update unreleased entries [skip ci] ([6569725](https://github.com/imrj05/unified-ui/commit/656972599dd7703317fbd6b184b95050aca092d8))
50
57
  - **changelog:** Auto-update unreleased entries [skip ci] ([57bfcc3](https://github.com/imrj05/unified-ui/commit/57bfcc37256d43487f773bddda7d8c70e7c89b31))
package/bin/cli.mjs CHANGED
@@ -27,12 +27,12 @@ import { execSync } from "node:child_process";
27
27
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
28
28
  import { dirname, join, resolve } from "node:path";
29
29
  import { createInterface } from "node:readline";
30
+
30
31
  // ---------------------------------------------------------------------------
31
32
  // Config
32
33
  // ---------------------------------------------------------------------------
33
34
  const REGISTRY_BASE_URL =
34
- process.env.UNIFIED_UI_REGISTRY_URL ||
35
- "https://www.unified-ui.space/r";
35
+ process.env.UNIFIED_UI_REGISTRY_URL || "https://www.unified-ui.space/r";
36
36
  const CONFIG_FILE = "unified-ui.json";
37
37
  // ---------------------------------------------------------------------------
38
38
  // Starter kit templates
@@ -333,6 +333,248 @@ async function installNpmDeps(deps, root) {
333
333
  );
334
334
  }
335
335
  }
336
+ async function installNpmDevDeps(deps, root) {
337
+ if (deps.length === 0) return;
338
+ const pm = await detectPackageManager(root);
339
+ const cmd = getInstallCommand(pm, deps)
340
+ .replace(" add ", " add -D ")
341
+ .replace(" install ", " install -D ");
342
+ logStep("📦", `Installing dev dependencies with ${c("cyan", pm)}...`);
343
+ logStep(" ", c("dim", cmd));
344
+ try {
345
+ execSync(cmd, { cwd: root, stdio: "pipe" });
346
+ logStep("✓", c("green", `${deps.length} dev package(s) installed`));
347
+ } catch (_err) {
348
+ logStep(
349
+ "⚠",
350
+ c("yellow", `Auto-install failed. Run manually:\n ${cmd}`),
351
+ );
352
+ }
353
+ }
354
+ // ---------------------------------------------------------------------------
355
+ // Vite + Tailwind CSS detection & setup
356
+ // ---------------------------------------------------------------------------
357
+ function detectViteConfig(root) {
358
+ for (const name of [
359
+ "vite.config.ts",
360
+ "vite.config.js",
361
+ "vite.config.mjs",
362
+ "vite.config.mts",
363
+ ]) {
364
+ if (existsSync(join(root, name))) return name;
365
+ }
366
+ return null;
367
+ }
368
+ function hasDependency(root, pkg) {
369
+ try {
370
+ const raw = readFileSync(join(root, "package.json"), "utf-8");
371
+ const json = JSON.parse(raw);
372
+ const all = {
373
+ ...json.dependencies,
374
+ ...json.devDependencies,
375
+ ...json.peerDependencies,
376
+ };
377
+ return Boolean(all[pkg]);
378
+ } catch {
379
+ return false;
380
+ }
381
+ }
382
+ async function setupTailwindForVite(root, config) {
383
+ const viteConfigName = detectViteConfig(root);
384
+ if (!viteConfigName) return; // Not a Vite project
385
+
386
+ logStep("🔍", "Detected Vite project");
387
+
388
+ // 1. Install tailwindcss + @tailwindcss/vite if missing
389
+ const missingDevDeps = [];
390
+ if (!hasDependency(root, "tailwindcss")) missingDevDeps.push("tailwindcss");
391
+ if (!hasDependency(root, "@tailwindcss/vite"))
392
+ missingDevDeps.push("@tailwindcss/vite");
393
+ if (missingDevDeps.length > 0) {
394
+ await installNpmDevDeps(missingDevDeps, root);
395
+ } else {
396
+ logStep("✓", c("dim", "tailwindcss + @tailwindcss/vite already installed"));
397
+ }
398
+
399
+ // 2. Patch vite.config to add tailwindcss plugin, path import, and @ alias
400
+ const viteConfigPath = join(root, viteConfigName);
401
+ let viteContent = readFileSync(viteConfigPath, "utf-8");
402
+ let viteModified = false;
403
+
404
+ // 2a. Add @tailwindcss/vite import + plugin
405
+ if (!viteContent.includes("@tailwindcss/vite")) {
406
+ const tailwindImport = 'import tailwindcss from "@tailwindcss/vite";\n';
407
+ const importMatch = viteContent.match(/^(import\s.+\n)+/m);
408
+ if (importMatch) {
409
+ const lastImportEnd = importMatch.index + importMatch[0].length;
410
+ viteContent =
411
+ viteContent.slice(0, lastImportEnd) +
412
+ tailwindImport +
413
+ viteContent.slice(lastImportEnd);
414
+ } else {
415
+ viteContent = tailwindImport + viteContent;
416
+ }
417
+ if (viteContent.includes("plugins:")) {
418
+ viteContent = viteContent.replace(
419
+ /plugins:\s*\[/,
420
+ "plugins: [\n tailwindcss(),",
421
+ );
422
+ } else if (viteContent.includes("defineConfig({")) {
423
+ viteContent = viteContent.replace(
424
+ /defineConfig\(\{/,
425
+ "defineConfig({\n plugins: [tailwindcss()],",
426
+ );
427
+ }
428
+ viteModified = true;
429
+ } else {
430
+ logStep("✓", c("dim", `${viteConfigName} already has @tailwindcss/vite`));
431
+ }
432
+
433
+ // 2b. Add path import + resolve.alias for @
434
+ if (
435
+ !viteContent.includes("node:path") &&
436
+ !viteContent.match(/import\s+path\s+from\s+["']path["']/)
437
+ ) {
438
+ const pathImport = 'import path from "node:path";\n';
439
+ const importMatch = viteContent.match(/^(import\s.+\n)+/m);
440
+ if (importMatch) {
441
+ const lastImportEnd = importMatch.index + importMatch[0].length;
442
+ viteContent =
443
+ viteContent.slice(0, lastImportEnd) +
444
+ pathImport +
445
+ viteContent.slice(lastImportEnd);
446
+ } else {
447
+ viteContent = pathImport + viteContent;
448
+ }
449
+ viteModified = true;
450
+ }
451
+
452
+ if (
453
+ !viteContent.includes("resolve:") &&
454
+ !viteContent.includes("resolve.alias")
455
+ ) {
456
+ // Add resolve.alias block before the closing of defineConfig
457
+ const resolveBlock = ` resolve: {\n alias: {\n "@": path.resolve(__dirname, "src"),\n },\n },`;
458
+ if (viteContent.includes("plugins:")) {
459
+ // Insert after plugins block — find the plugins array closing and add after
460
+ viteContent = viteContent.replace(
461
+ /(plugins:\s*\[[\s\S]*?\],?\n)/m,
462
+ `$1${resolveBlock}\n`,
463
+ );
464
+ } else if (viteContent.includes("defineConfig({")) {
465
+ viteContent = viteContent.replace(
466
+ /defineConfig\(\{/,
467
+ `defineConfig({\n${resolveBlock}`,
468
+ );
469
+ }
470
+ viteModified = true;
471
+ } else {
472
+ logStep("✓", c("dim", `${viteConfigName} already has resolve.alias`));
473
+ }
474
+
475
+ if (viteModified) {
476
+ writeFileSync(viteConfigPath, viteContent);
477
+ logStep(
478
+ "✓",
479
+ `Patched ${c("cyan", viteConfigName)} with Tailwind CSS plugin + @ alias`,
480
+ );
481
+ }
482
+
483
+ // 2c. Patch tsconfig to add @/* path alias
484
+ const tsconfigCandidates = ["tsconfig.app.json", "tsconfig.json"];
485
+ for (const tscName of tsconfigCandidates) {
486
+ const tscPath = join(root, tscName);
487
+ if (!existsSync(tscPath)) continue;
488
+ const tscContent = readFileSync(tscPath, "utf-8");
489
+ if (tscContent.includes('"@/*"')) {
490
+ logStep("✓", c("dim", `${tscName} already has @/* path alias`));
491
+ break;
492
+ }
493
+ try {
494
+ // Strip comments for JSON parsing (single-line // comments)
495
+ const stripped = tscContent.replace(/^\s*\/\/.*$/gm, "");
496
+ const tsconfig = JSON.parse(stripped);
497
+ if (!tsconfig.compilerOptions) tsconfig.compilerOptions = {};
498
+ if (!tsconfig.compilerOptions.paths) tsconfig.compilerOptions.paths = {};
499
+ tsconfig.compilerOptions.paths["@/*"] = ["./src/*"];
500
+ // Also ensure baseUrl is set for paths to work
501
+ if (!tsconfig.compilerOptions.baseUrl) {
502
+ tsconfig.compilerOptions.baseUrl = ".";
503
+ }
504
+ writeFileSync(tscPath, `${JSON.stringify(tsconfig, null, 2)}\n`);
505
+ logStep("✓", `Patched ${c("cyan", tscName)} with @/* path alias`);
506
+ } catch {
507
+ logStep(
508
+ "⚠",
509
+ c("yellow", `Could not patch ${tscName} — add @/* path alias manually`),
510
+ );
511
+ }
512
+ break;
513
+ }
514
+
515
+ // 3. Patch CSS entry file
516
+ const srcDir = join(root, config.srcDir);
517
+ const cssCandidates = [
518
+ "index.css",
519
+ "App.css",
520
+ "style.css",
521
+ "main.css",
522
+ "globals.css",
523
+ ];
524
+ let cssPath = null;
525
+ for (const name of cssCandidates) {
526
+ const candidate = join(srcDir, name);
527
+ if (existsSync(candidate)) {
528
+ cssPath = candidate;
529
+ break;
530
+ }
531
+ }
532
+ if (!cssPath) {
533
+ // Create src/index.css if no CSS file found
534
+ cssPath = join(srcDir, "index.css");
535
+ }
536
+ const tailwindDirective = '@import "tailwindcss";';
537
+ const unifiedUiImport = '@import "@/styles/unified-ui.css";';
538
+ if (existsSync(cssPath)) {
539
+ let cssContent = readFileSync(cssPath, "utf-8");
540
+ let modified = false;
541
+ if (!cssContent.includes(tailwindDirective)) {
542
+ cssContent = `${tailwindDirective}\n${cssContent}`;
543
+ modified = true;
544
+ }
545
+ if (!cssContent.includes(unifiedUiImport)) {
546
+ // Insert right after the tailwindcss import
547
+ cssContent = cssContent.replace(
548
+ tailwindDirective,
549
+ `${tailwindDirective}\n${unifiedUiImport}`,
550
+ );
551
+ modified = true;
552
+ }
553
+ if (modified) {
554
+ writeFileSync(cssPath, cssContent);
555
+ logStep(
556
+ "✓",
557
+ `Updated ${c("cyan", cssPath.replace(`${root}/`, ""))} with Tailwind imports`,
558
+ );
559
+ } else {
560
+ logStep(
561
+ "✓",
562
+ c(
563
+ "dim",
564
+ `${cssPath.replace(`${root}/`, "")} already has Tailwind imports`,
565
+ ),
566
+ );
567
+ }
568
+ } else {
569
+ const content = `${tailwindDirective}\n${unifiedUiImport}\n`;
570
+ mkdirSync(dirname(cssPath), { recursive: true });
571
+ writeFileSync(cssPath, content);
572
+ logStep(
573
+ "✓",
574
+ `Created ${c("cyan", cssPath.replace(`${root}/`, ""))} with Tailwind imports`,
575
+ );
576
+ }
577
+ }
336
578
  // ---------------------------------------------------------------------------
337
579
  // File writer
338
580
  // ---------------------------------------------------------------------------
@@ -1757,9 +1999,12 @@ async function cmdInit(positional = [], flags = {}) {
1757
1999
  }
1758
2000
  // Install base npm deps
1759
2001
  await installNpmDeps(
1760
- ["class-variance-authority", "clsx", "tailwind-merge"],
2002
+ ["class-variance-authority", "clsx", "tailwind-merge", "lucide-react"],
1761
2003
  config.root,
1762
2004
  );
2005
+ // Set up Tailwind CSS for Vite projects
2006
+ log();
2007
+ await setupTailwindForVite(config.root, config);
1763
2008
  log();
1764
2009
  logStep("🎉", c("green", "Project initialized! Start adding components:"));
1765
2010
  log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@work-rjkashyap/unified-ui",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "A scalable, token-driven React design system with 75+ components, built with Tailwind CSS v4, Radix UI, and Framer Motion.",
5
5
  "author": "Rajeshwar Kashyap",
6
6
  "license": "MIT",