vibe-design-system 2.8.51 → 2.8.54

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.8.51",
3
+ "version": "2.8.54",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "homepage": "https://vibedesign.tech",
6
6
  "repository": {
@@ -1429,7 +1429,7 @@ function buildSpecialStories(componentName, variants) {
1429
1429
  return "";
1430
1430
  }
1431
1431
 
1432
- function buildRecipeStoryContent(comp, componentName, importPath, title, source, exportStyle, recipe, defaultArgLines = [], lucideImports = [], iconPropNames = [], needReact = false) {
1432
+ function buildRecipeStoryContent(comp, componentName, importPath, title, source, exportStyle, recipe, defaultArgLines = [], lucideImports = [], iconPropNames = [], needReact = false, variantMap = null) {
1433
1433
  const lines = [];
1434
1434
  lines.push(`// @vds-regenerate — VDS auto-generated. Remove this line to prevent overwrite.`);
1435
1435
  lines.push(`import type { Meta, StoryObj } from "@storybook/react";`);
@@ -1492,14 +1492,66 @@ function buildRecipeStoryContent(comp, componentName, importPath, title, source,
1492
1492
  lines.push(`export default meta;`);
1493
1493
  lines.push(`type Story = StoryObj<typeof meta>;`);
1494
1494
  lines.push("");
1495
- lines.push(`export const Default: Story = {`);
1496
- lines.push(` render: ${effectiveRecipe.render},`);
1497
- if (defaultArgLines.length > 0) {
1495
+ // --- Dimension-aware recipe stories ---
1496
+ const hasDims = variantMap && Object.keys(variantMap.dimensions).length > 0;
1497
+ if (hasDims) {
1498
+ const primaryDim = variantMap.primaryDimension || Object.keys(variantMap.dimensions)[0];
1499
+ const primaryInfo = variantMap.dimensions[primaryDim];
1500
+ const primaryValues = primaryInfo?.values || [];
1501
+ const primaryDefault = primaryInfo?.default || primaryValues[0];
1502
+
1503
+ // Default story (primary default variant)
1504
+ lines.push(`export const Default: Story = {`);
1505
+ lines.push(` render: ${effectiveRecipe.render},`);
1498
1506
  lines.push(` args: {`);
1507
+ lines.push(` ${primaryDim}: ${JSON.stringify(primaryDefault)},`);
1499
1508
  for (const line of defaultArgLines) lines.push(line);
1500
1509
  lines.push(` },`);
1510
+ lines.push(`};`);
1511
+
1512
+ // Per-variant stories for remaining primary values
1513
+ for (const val of primaryValues) {
1514
+ if (val === primaryDefault) continue;
1515
+ const storyName = val.charAt(0).toUpperCase() + val.slice(1);
1516
+ lines.push("");
1517
+ lines.push(`export const ${storyName}: Story = {`);
1518
+ lines.push(` render: ${effectiveRecipe.render},`);
1519
+ lines.push(` args: {`);
1520
+ lines.push(` ${primaryDim}: ${JSON.stringify(val)},`);
1521
+ for (const line of defaultArgLines) lines.push(line);
1522
+ lines.push(` },`);
1523
+ lines.push(`};`);
1524
+ }
1525
+
1526
+ // Secondary dimensions (e.g., size) — skip default value, one story per non-default
1527
+ const secondaryDims = Object.keys(variantMap.dimensions).filter(d => d !== primaryDim);
1528
+ for (const dim of secondaryDims) {
1529
+ const dimInfo = variantMap.dimensions[dim];
1530
+ const dimDefault = dimInfo?.default || dimInfo?.values?.[0];
1531
+ for (const val of dimInfo?.values || []) {
1532
+ if (val === dimDefault) continue;
1533
+ const storyName = `${dim.charAt(0).toUpperCase() + dim.slice(1)}${val.charAt(0).toUpperCase() + val.slice(1)}`;
1534
+ lines.push("");
1535
+ lines.push(`export const ${storyName}: Story = {`);
1536
+ lines.push(` render: ${effectiveRecipe.render},`);
1537
+ lines.push(` args: {`);
1538
+ lines.push(` ${dim}: ${JSON.stringify(val)},`);
1539
+ for (const line of defaultArgLines) lines.push(line);
1540
+ lines.push(` },`);
1541
+ lines.push(`};`);
1542
+ }
1543
+ }
1544
+ } else {
1545
+ // Original: single Default story
1546
+ lines.push(`export const Default: Story = {`);
1547
+ lines.push(` render: ${effectiveRecipe.render},`);
1548
+ if (defaultArgLines.length > 0) {
1549
+ lines.push(` args: {`);
1550
+ for (const line of defaultArgLines) lines.push(line);
1551
+ lines.push(` },`);
1552
+ }
1553
+ lines.push(`};`);
1501
1554
  }
1502
- lines.push(`};`);
1503
1555
  return lines.join("\n");
1504
1556
  }
1505
1557
 
@@ -1701,7 +1753,7 @@ function buildStoryFileContent(comp) {
1701
1753
  }
1702
1754
 
1703
1755
  if (RECIPES[componentName]) {
1704
- return buildRecipeStoryContent(comp, componentName, importPath, title, source, exportStyle, RECIPES[componentName], defaultArgLines, lucideImports, iconPropNames, needReact);
1756
+ return buildRecipeStoryContent(comp, componentName, importPath, title, source, exportStyle, RECIPES[componentName], defaultArgLines, lucideImports, iconPropNames, needReact, variantMap);
1705
1757
  }
1706
1758
 
1707
1759
  const lines = [];
@@ -1758,10 +1810,13 @@ function buildStoryFileContent(comp) {
1758
1810
  lines.push(`type Story = StoryObj<typeof meta>;`);
1759
1811
  lines.push("");
1760
1812
 
1813
+ // Multi-dimension story generation: variant × size × disabled × AllVariants grid
1814
+ const hasDimensions = Object.keys(variantMap.dimensions).length > 0 || variantMap.booleanStates.length > 0;
1815
+
1761
1816
  // Component-specific stories for non-variant components (Input, Textarea, etc.)
1762
- // Button and Badge are now handled generically by multi-dimension detection.
1763
- const skipSpecialFor = new Set(["Button", "Badge"]);
1764
- if (!skipSpecialFor.has(componentName)) {
1817
+ // Skip buildSpecialStories when multi-dimension detection found CVA dimensions
1818
+ // generic detection produces better stories than hardcoded ones.
1819
+ if (!hasDimensions) {
1765
1820
  const specialStories = buildSpecialStories(componentName, variants);
1766
1821
  if (specialStories) {
1767
1822
  lines.push(specialStories);
@@ -1776,9 +1831,6 @@ function buildStoryFileContent(comp) {
1776
1831
  const renderLine = buildProfileRenderLine(profile, RenderTarget, argsFallback);
1777
1832
  const childrenArgLine = buildProfileChildrenArgLine(profile);
1778
1833
 
1779
- // Multi-dimension story generation: variant × size × disabled × AllVariants grid
1780
- const hasDimensions = Object.keys(variantMap.dimensions).length > 0 || variantMap.booleanStates.length > 0;
1781
-
1782
1834
  if (hasDimensions) {
1783
1835
  const multiStories = buildMultiDimensionStories(
1784
1836
  variantMap, renderLine, childrenArgLine, defaultArgLines, componentName
@@ -1855,15 +1907,21 @@ function scanGridSystemFallback() {
1855
1907
  // Grid columns
1856
1908
  while ((m = colRe.exec(content)) !== null) {
1857
1909
  const col = m[1];
1858
- if (!gridCols[col]) gridCols[col] = { count: 0 };
1910
+ if (!gridCols[col]) gridCols[col] = { count: 0, topFiles: [] };
1859
1911
  gridCols[col].count++;
1912
+ if (!gridCols[col].topFiles.includes(shortName) && gridCols[col].topFiles.length < 5) {
1913
+ gridCols[col].topFiles.push(shortName);
1914
+ }
1860
1915
  }
1861
1916
 
1862
1917
  // Gaps
1863
1918
  while ((m = gapRe.exec(content)) !== null) {
1864
1919
  const gap = m[1];
1865
- if (!gaps[gap]) gaps[gap] = { count: 0 };
1920
+ if (!gaps[gap]) gaps[gap] = { count: 0, topFiles: [] };
1866
1921
  gaps[gap].count++;
1922
+ if (!gaps[gap].topFiles.includes(shortName) && gaps[gap].topFiles.length < 5) {
1923
+ gaps[gap].topFiles.push(shortName);
1924
+ }
1867
1925
  }
1868
1926
 
1869
1927
  // Max widths
@@ -2519,11 +2577,11 @@ function writeFoundationsStories(foundations) {
2519
2577
  " </p>",
2520
2578
  " <p style={{ margin: \"0 0 12px\", fontSize: 12, color: \"#475569\" }}>gap-* values across all components.</p>",
2521
2579
  " <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 8 }}>",
2522
- " {(gapEntries as [string, number][]).map(([val, count]) => (",
2580
+ " {(gapEntries as [string, { count: number; topFiles: string[] }][]).map(([val, data]) => (",
2523
2581
  " <span key={val} style={{ display: \"flex\", alignItems: \"center\", gap: 6,",
2524
2582
  " background: \"#0a0f1a\", border: \"1px solid #1e293b\", borderRadius: 6, padding: \"5px 10px\", fontSize: 12 }}>",
2525
2583
  " <code style={{ color: \"#67e8f9\" }}>gap-{val}</code>",
2526
- " <span style={{ color: \"#475569\", fontSize: 11 }}>×{count}</span>",
2584
+ " <span style={{ color: \"#475569\", fontSize: 11 }}>×{data.count}</span>",
2527
2585
  " </span>",
2528
2586
  " ))}",
2529
2587
  " </div>",
@@ -3325,9 +3383,12 @@ function writeCursorRules(components, foundations) {
3325
3383
  const gridSystem = foundations?.gridSystem;
3326
3384
  if (gridSystem) {
3327
3385
  lines.push(`## 📐 Spacing & Layout (detected in this project)`);
3328
- if (Object.keys(gaps).length > 0) {
3329
- const gapLine = Object.entries(gaps).sort((a,b)=>b[1]-a[1]).slice(0,8)
3330
- .map(([v, c]) => `\`gap-${v}\` ×${c}`).join(" · ");
3386
+ const _gaps = gridSystem.gaps || {};
3387
+ if (Object.keys(_gaps).length > 0) {
3388
+ const gapLine = Object.entries(_gaps)
3389
+ .sort((a,b) => (typeof b[1] === "object" ? b[1].count : b[1]) - (typeof a[1] === "object" ? a[1].count : a[1]))
3390
+ .slice(0,8)
3391
+ .map(([v, d]) => `\`gap-${v}\` ×${typeof d === "object" ? d.count : d}`).join(" · ");
3331
3392
  lines.push(`**Common gaps:** ${gapLine}`);
3332
3393
  }
3333
3394
  if (Object.keys(gridSystem.gridCols || {}).length > 0) {