vibe-design-system 2.4.0 → 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.4.0",
3
+ "version": "2.4.1",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -452,39 +452,43 @@ function humanizeName(filePath) {
452
452
  return base.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
453
453
  }
454
454
 
455
- // Priority order: first match in pattern wins
456
- const COMPONENT_SUGGESTION_KEYWORDS_ORDERED = [
457
- { re: /\bcard\b/i, name: "Card" },
458
- { re: /\bsection\b/i, name: "Section" },
459
- { re: /\bgrid\b/i, name: "Grid" },
460
- { re: /\bhero\b/i, name: "Hero" },
461
- { re: /\bcta\b/i, name: "Cta" },
462
- { re: /\bnav\b/i, name: "Nav" },
463
- { re: /\bfooter\b/i, name: "Footer" },
464
- { re: /\bheader\b/i, name: "Header" },
465
- { re: /\bform\b/i, name: "Form" },
466
- { re: /\bmodal\b/i, name: "Modal" },
467
- { re: /\bbadge\b/i, name: "Badge" },
468
- { re: /\bitem\b/i, name: "Item" },
469
- { re: /\brow\b/i, name: "Row" },
470
- { re: /\blist\b/i, name: "List" },
455
+ const COMPONENT_SUGGESTION_KEYWORDS = [
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",
471
475
  ];
472
476
 
473
477
  function suggestNameFromPattern(pattern) {
474
- for (const { re, name } of COMPONENT_SUGGESTION_KEYWORDS_ORDERED) {
475
- if (re.test(pattern)) return name;
476
- }
477
- const firstToken = pattern.split(/\s+/)[0] || "";
478
- if (/^max-w|^mx-auto|^container$/i.test(firstToken)) return "Container";
479
- if (/^flex\b/i.test(firstToken)) return "FlexRow";
480
- if (/^grid\b/i.test(firstToken)) return "Grid";
481
- if (firstToken.length > 0) {
482
- const pascal = firstToken
483
- .replace(/-([a-z0-9])/gi, (_, c) => c.toUpperCase())
484
- .replace(/^(.)/, (_, c) => c.toUpperCase());
485
- return pascal.replace(/[^a-zA-Z0-9]/g, "") || "Block";
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
+ }
486
487
  }
487
- return "Block";
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";
488
492
  }
489
493
 
490
494
  /** Scan src/pages/*.tsx for repeated className clusters; return component suggestions. */
@@ -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
  "};",