vibe-design-system 2.3.1 → 2.4.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-design-system",
3
- "version": "2.3.1",
3
+ "version": "2.4.1",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -453,31 +453,42 @@ function humanizeName(filePath) {
453
453
  }
454
454
 
455
455
  const COMPONENT_SUGGESTION_KEYWORDS = [
456
- { re: /\bcard\b/i, name: "Card" },
457
- { re: /\bsection\b/i, name: "Section" },
458
- { re: /\bitem\b/i, name: "Item" },
459
- { re: /\bbadge\b/i, name: "Badge" },
460
- { re: /\brow\b/i, name: "Row" },
461
- { re: /\bgrid\b/i, name: "Grid" },
462
- { re: /\bhero\b/i, name: "Hero" },
463
- { re: /\bcta\b/i, name: "Cta" },
464
- { re: /\bstat\b/i, name: "Stat" },
465
- { re: /\bprice\b/i, name: "Pricing" },
466
- { re: /\bfeature\b/i, name: "Feature" },
467
- { re: /\bbutton\b/i, name: "Button" },
468
- { re: /\btag\b/i, name: "Tag" },
469
- { re: /\bchip\b/i, name: "Chip" },
470
- { re: /\btile\b/i, name: "Tile" },
471
- { re: /\bbanner\b/i, name: "Banner" },
456
+ "card",
457
+ "grid",
458
+ "section",
459
+ "hero",
460
+ "cta",
461
+ "nav",
462
+ "footer",
463
+ "header",
464
+ "form",
465
+ "modal",
466
+ "badge",
467
+ "item",
468
+ "row",
469
+ "list",
470
+ "container",
471
+ "wrapper",
472
+ "panel",
473
+ "banner",
474
+ "stat",
472
475
  ];
473
476
 
474
- function suggestNameFromPattern(pattern, index) {
475
- const parts = [];
476
- for (const { re, name } of COMPONENT_SUGGESTION_KEYWORDS) {
477
- if (re.test(pattern)) parts.push(name);
477
+ function suggestNameFromPattern(pattern) {
478
+ const words = pattern
479
+ .split(/\s+/)
480
+ .flatMap((c) => c.split("-"))
481
+ .filter(Boolean);
482
+ for (const w of words) {
483
+ const lower = w.toLowerCase();
484
+ if (COMPONENT_SUGGESTION_KEYWORDS.includes(lower)) {
485
+ return lower.charAt(0).toUpperCase() + lower.slice(1);
486
+ }
478
487
  }
479
- if (parts.length > 0) return parts.join("");
480
- return "Block" + (index + 1);
488
+ if (/\bflex\b/.test(pattern) && /\bitems-center\b/.test(pattern)) return "FlexRow";
489
+ if (/\brounded\b/.test(pattern) && /\bborder\b/.test(pattern)) return "Card";
490
+ if (/^max-w|^mx-auto|^container$/i.test(pattern.split(/\s+/)[0] || "")) return "Container";
491
+ return "Container";
481
492
  }
482
493
 
483
494
  /** Scan src/pages/*.tsx for repeated className clusters; return component suggestions. */
@@ -516,11 +527,9 @@ function extractComponentSuggestions() {
516
527
  }
517
528
 
518
529
  const suggestions = [];
519
- let blockIndex = 0;
520
530
  for (const [pattern, { count, files, snippet }] of byPattern.entries()) {
521
531
  if (count < 2) continue;
522
- const suggestedName = suggestNameFromPattern(pattern, blockIndex);
523
- if (suggestedName.startsWith("Block")) blockIndex += 1;
532
+ const suggestedName = suggestNameFromPattern(pattern);
524
533
  suggestions.push({
525
534
  suggestedName,
526
535
  occurrences: count,
@@ -778,10 +787,11 @@ function extractFoundations() {
778
787
  let allTsxFiles = [];
779
788
  try {
780
789
  const { globSync } = projectRequire("glob");
790
+ const ROOT = PROJECT_ROOT;
781
791
  allTsxFiles = globSync("src/**/*.{tsx,jsx,ts,js}", {
782
- cwd: PROJECT_ROOT,
792
+ cwd: ROOT,
783
793
  absolute: true,
784
- ignore: ["**/node_modules/**", "**/*.stories.*", "**/dist/**", "**/vds-output*"],
794
+ ignore: ["**/*.stories.*", "**/node_modules/**"],
785
795
  });
786
796
  } catch (_) {
787
797
  function walkDir(dir, list) {
@@ -68,7 +68,7 @@ const RECIPES = {
68
68
  )`,
69
69
  },
70
70
  Dialog: {
71
- imports: ["DialogTrigger", "DialogContent", "DialogHeader", "DialogTitle", "DialogDescription"],
71
+ imports: ["DialogTrigger", "DialogContent", "DialogHeader", "DialogTitle", "DialogDescription", "DialogClose"],
72
72
  render: `(args) => (
73
73
  <ComponentRef {...args}>
74
74
  <DialogTrigger asChild><button>Open Dialog</button></DialogTrigger>
@@ -77,6 +77,7 @@ const RECIPES = {
77
77
  <DialogTitle>Dialog Title</DialogTitle>
78
78
  <DialogDescription>This is a dialog description.</DialogDescription>
79
79
  </DialogHeader>
80
+ <DialogClose asChild><button>Close</button></DialogClose>
80
81
  </DialogContent>
81
82
  </ComponentRef>
82
83
  )`,
@@ -304,8 +305,8 @@ const RECIPES = {
304
305
  <CarouselItem><div className="p-4 text-center border rounded">Slide 2</div></CarouselItem>
305
306
  <CarouselItem><div className="p-4 text-center border rounded">Slide 3</div></CarouselItem>
306
307
  </CarouselContent>
307
- <CarouselPrevious />
308
- <CarouselNext />
308
+ <CarouselPrevious aria-label="Previous slide" />
309
+ <CarouselNext aria-label="Next slide" />
309
310
  </ComponentRef>
310
311
  )`,
311
312
  },
@@ -752,15 +753,13 @@ function writeFoundationsStories(foundations) {
752
753
  "",
753
754
  "export const Default: Story = {",
754
755
  " render: () => (",
755
- " <div>",
756
- " <h2 style={{ marginBottom: 16 }}>Logo and favicon paths</h2>",
757
- " <ul style={{ listStyle: \"none\", padding: 0 }}>",
758
- " {assets.length === 0 ? <li>No brand assets found.</li> : assets.map((a, i) => (",
759
- " <li key={i} style={{ padding: \"8px 0\", borderBottom: \"1px solid #222\" }}>",
760
- " <strong>{a.type || \"asset\"}</strong>: <code>{a.path || a.name || \"\"}</code>",
761
- " </li>",
762
- " ))}",
763
- " </ul>",
756
+ " <div style={{ display: \"flex\", gap: 24, flexWrap: \"wrap\", padding: 24 }}>",
757
+ " {assets.length === 0 ? <p>No brand assets found.</p> : assets.map((a, i) => (",
758
+ " <div key={i} style={{ textAlign: \"center\" }}>",
759
+ " <img src={\"/\" + String(a.path || \"\").replace(\"public/\", \"\")} style={{ maxHeight: 80, maxWidth: 160, objectFit: \"contain\" }} alt={a.name || \"\"} />",
760
+ " <div style={{ fontSize: 11, marginTop: 8, color: \"#666\" }}>{a.name || a.type || \"asset\"}</div>",
761
+ " </div>",
762
+ " ))}",
764
763
  " </div>",
765
764
  " ),",
766
765
  "};",
@@ -831,7 +830,7 @@ function writeChangelogStory(changelog) {
831
830
  " render: () => (",
832
831
  " <div style={{ fontFamily: \"monospace\", padding: 24 }}>",
833
832
  " <h2>CHANGELOG</h2>",
834
- " {changelog.length === 0 ? <p>No changes recorded yet. Run npm run vds again after making changes.</p> : changelog.map((entry) => (",
833
+ " {changelog.length === 0 ? <p>No changes recorded yet.</p> : changelog.map((entry) => (",
835
834
  " <div key={entry.version}>",
836
835
  " <h3>v{entry.version} — {entry.date}</h3>",
837
836
  " {entry.changes.map((c, i) => <div key={i}>{c.type}: {c.name ?? c.key ?? \"\"}</div>)}",