vibe-design-system 2.3.1 → 2.4.0

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.0",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -452,32 +452,39 @@ function humanizeName(filePath) {
452
452
  return base.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
453
453
  }
454
454
 
455
- const COMPONENT_SUGGESTION_KEYWORDS = [
455
+ // Priority order: first match in pattern wins
456
+ const COMPONENT_SUGGESTION_KEYWORDS_ORDERED = [
456
457
  { re: /\bcard\b/i, name: "Card" },
457
458
  { 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
459
  { re: /\bgrid\b/i, name: "Grid" },
462
460
  { re: /\bhero\b/i, name: "Hero" },
463
461
  { 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" },
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" },
472
471
  ];
473
472
 
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);
473
+ 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
486
  }
479
- if (parts.length > 0) return parts.join("");
480
- return "Block" + (index + 1);
487
+ return "Block";
481
488
  }
482
489
 
483
490
  /** Scan src/pages/*.tsx for repeated className clusters; return component suggestions. */
@@ -516,11 +523,9 @@ function extractComponentSuggestions() {
516
523
  }
517
524
 
518
525
  const suggestions = [];
519
- let blockIndex = 0;
520
526
  for (const [pattern, { count, files, snippet }] of byPattern.entries()) {
521
527
  if (count < 2) continue;
522
- const suggestedName = suggestNameFromPattern(pattern, blockIndex);
523
- if (suggestedName.startsWith("Block")) blockIndex += 1;
528
+ const suggestedName = suggestNameFromPattern(pattern);
524
529
  suggestions.push({
525
530
  suggestedName,
526
531
  occurrences: count,
@@ -778,10 +783,11 @@ function extractFoundations() {
778
783
  let allTsxFiles = [];
779
784
  try {
780
785
  const { globSync } = projectRequire("glob");
786
+ const ROOT = PROJECT_ROOT;
781
787
  allTsxFiles = globSync("src/**/*.{tsx,jsx,ts,js}", {
782
- cwd: PROJECT_ROOT,
788
+ cwd: ROOT,
783
789
  absolute: true,
784
- ignore: ["**/node_modules/**", "**/*.stories.*", "**/dist/**", "**/vds-output*"],
790
+ ignore: ["**/*.stories.*", "**/node_modules/**"],
785
791
  });
786
792
  } catch (_) {
787
793
  function walkDir(dir, list) {
@@ -831,7 +831,7 @@ function writeChangelogStory(changelog) {
831
831
  " render: () => (",
832
832
  " <div style={{ fontFamily: \"monospace\", padding: 24 }}>",
833
833
  " <h2>CHANGELOG</h2>",
834
- " {changelog.length === 0 ? <p>No changes recorded yet. Run npm run vds again after making changes.</p> : changelog.map((entry) => (",
834
+ " {changelog.length === 0 ? <p>No changes recorded yet.</p> : changelog.map((entry) => (",
835
835
  " <div key={entry.version}>",
836
836
  " <h3>v{entry.version} — {entry.date}</h3>",
837
837
  " {entry.changes.map((c, i) => <div key={i}>{c.type}: {c.name ?? c.key ?? \"\"}</div>)}",