vibe-design-system 2.8.50 → 2.8.53
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
|
@@ -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
|
-
|
|
1496
|
-
|
|
1497
|
-
if (
|
|
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
|
|
|
@@ -1603,7 +1655,15 @@ function buildProfileRenderLine(profile, RenderTarget, argsFallback) {
|
|
|
1603
1655
|
)},`;
|
|
1604
1656
|
case "SAFE":
|
|
1605
1657
|
return ` render: (args = {}) => ${suspense(`React.createElement(${RenderTarget}, args)`)},`;
|
|
1606
|
-
|
|
1658
|
+
case "VARIANT": {
|
|
1659
|
+
// Wrap in inline-block div to prevent vertical stretching caused by
|
|
1660
|
+
// global SidebarProvider/flex decorators or layout: "fullscreen" in preview.
|
|
1661
|
+
const argsParam = argsFallback ? "(args = {})" : "(args)";
|
|
1662
|
+
const propsArg = argsFallback ? `{ ...args${argsFallback} }` : "args";
|
|
1663
|
+
const inner = suspense(`React.createElement(${RenderTarget}, ${propsArg})`);
|
|
1664
|
+
return ` render: ${argsParam} => React.createElement('div', { style: { display: 'inline-block' } }, ${inner}),`;
|
|
1665
|
+
}
|
|
1666
|
+
default: { // CONFIGURED
|
|
1607
1667
|
const argsParam = argsFallback ? "(args = {})" : "(args)";
|
|
1608
1668
|
const propsArg = argsFallback ? `{ ...args${argsFallback} }` : "args";
|
|
1609
1669
|
return ` render: ${argsParam} => ${suspense(`React.createElement(${RenderTarget}, ${propsArg})`)},`;
|
|
@@ -1693,7 +1753,7 @@ function buildStoryFileContent(comp) {
|
|
|
1693
1753
|
}
|
|
1694
1754
|
|
|
1695
1755
|
if (RECIPES[componentName]) {
|
|
1696
|
-
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);
|
|
1697
1757
|
}
|
|
1698
1758
|
|
|
1699
1759
|
const lines = [];
|
|
@@ -1750,10 +1810,13 @@ function buildStoryFileContent(comp) {
|
|
|
1750
1810
|
lines.push(`type Story = StoryObj<typeof meta>;`);
|
|
1751
1811
|
lines.push("");
|
|
1752
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
|
+
|
|
1753
1816
|
// Component-specific stories for non-variant components (Input, Textarea, etc.)
|
|
1754
|
-
//
|
|
1755
|
-
|
|
1756
|
-
if (!
|
|
1817
|
+
// Skip buildSpecialStories when multi-dimension detection found CVA dimensions —
|
|
1818
|
+
// generic detection produces better stories than hardcoded ones.
|
|
1819
|
+
if (!hasDimensions) {
|
|
1757
1820
|
const specialStories = buildSpecialStories(componentName, variants);
|
|
1758
1821
|
if (specialStories) {
|
|
1759
1822
|
lines.push(specialStories);
|
|
@@ -1768,9 +1831,6 @@ function buildStoryFileContent(comp) {
|
|
|
1768
1831
|
const renderLine = buildProfileRenderLine(profile, RenderTarget, argsFallback);
|
|
1769
1832
|
const childrenArgLine = buildProfileChildrenArgLine(profile);
|
|
1770
1833
|
|
|
1771
|
-
// Multi-dimension story generation: variant × size × disabled × AllVariants grid
|
|
1772
|
-
const hasDimensions = Object.keys(variantMap.dimensions).length > 0 || variantMap.booleanStates.length > 0;
|
|
1773
|
-
|
|
1774
1834
|
if (hasDimensions) {
|
|
1775
1835
|
const multiStories = buildMultiDimensionStories(
|
|
1776
1836
|
variantMap, renderLine, childrenArgLine, defaultArgLines, componentName
|
|
@@ -1796,6 +1856,96 @@ function buildStoryFileContent(comp) {
|
|
|
1796
1856
|
return lines.join("\n");
|
|
1797
1857
|
}
|
|
1798
1858
|
|
|
1859
|
+
/**
|
|
1860
|
+
* Fallback grid system scanner — reads source files for Tailwind grid patterns
|
|
1861
|
+
* when scan.mjs didn't produce gridSystem data.
|
|
1862
|
+
*/
|
|
1863
|
+
function scanGridSystemFallback() {
|
|
1864
|
+
const srcDirs = [
|
|
1865
|
+
path.join(PROJECT_ROOT, "src"),
|
|
1866
|
+
path.join(PROJECT_ROOT, "client/src"),
|
|
1867
|
+
path.join(PROJECT_ROOT, "app"),
|
|
1868
|
+
];
|
|
1869
|
+
const breakpoints = {}; // { "md": { count, topFiles: [] }, ... }
|
|
1870
|
+
const gridCols = {}; // { "2": { count }, "3": { count }, ... }
|
|
1871
|
+
const gaps = {}; // { "4": { count }, "6": { count }, ... }
|
|
1872
|
+
const maxWidths = {}; // { "7xl": count, ... }
|
|
1873
|
+
let containerCount = 0;
|
|
1874
|
+
|
|
1875
|
+
const BP_NAMES = ["sm", "md", "lg", "xl", "2xl"];
|
|
1876
|
+
const bpRe = /\b(sm|md|lg|xl|2xl):/g;
|
|
1877
|
+
const colRe = /\bgrid-cols-(\w+)/g;
|
|
1878
|
+
const gapRe = /\bgap-(\w+)/g;
|
|
1879
|
+
const maxWRe = /\bmax-w-(\w+)/g;
|
|
1880
|
+
const containerRe = /\bcontainer\b/g;
|
|
1881
|
+
|
|
1882
|
+
function walkFiles(dir) {
|
|
1883
|
+
if (!fs.existsSync(dir)) return;
|
|
1884
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
1885
|
+
for (const entry of entries) {
|
|
1886
|
+
const full = path.join(dir, entry.name);
|
|
1887
|
+
if (entry.isDirectory()) {
|
|
1888
|
+
if (["node_modules", ".next", "dist", "build", ".storybook", "stories"].includes(entry.name)) continue;
|
|
1889
|
+
walkFiles(full);
|
|
1890
|
+
} else if (/\.(tsx|jsx|ts|js|css)$/.test(entry.name)) {
|
|
1891
|
+
try {
|
|
1892
|
+
const content = fs.readFileSync(full, "utf-8");
|
|
1893
|
+
const relFile = path.relative(PROJECT_ROOT, full).replace(/^(client\/)?src\//, "");
|
|
1894
|
+
const shortName = path.basename(relFile, path.extname(relFile));
|
|
1895
|
+
|
|
1896
|
+
// Breakpoints
|
|
1897
|
+
let m;
|
|
1898
|
+
while ((m = bpRe.exec(content)) !== null) {
|
|
1899
|
+
const bp = m[1];
|
|
1900
|
+
if (!breakpoints[bp]) breakpoints[bp] = { count: 0, topFiles: [] };
|
|
1901
|
+
breakpoints[bp].count++;
|
|
1902
|
+
if (!breakpoints[bp].topFiles.includes(shortName) && breakpoints[bp].topFiles.length < 5) {
|
|
1903
|
+
breakpoints[bp].topFiles.push(shortName);
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
// Grid columns
|
|
1908
|
+
while ((m = colRe.exec(content)) !== null) {
|
|
1909
|
+
const col = m[1];
|
|
1910
|
+
if (!gridCols[col]) gridCols[col] = { count: 0, topFiles: [] };
|
|
1911
|
+
gridCols[col].count++;
|
|
1912
|
+
if (!gridCols[col].topFiles.includes(shortName) && gridCols[col].topFiles.length < 5) {
|
|
1913
|
+
gridCols[col].topFiles.push(shortName);
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
// Gaps
|
|
1918
|
+
while ((m = gapRe.exec(content)) !== null) {
|
|
1919
|
+
const gap = m[1];
|
|
1920
|
+
if (!gaps[gap]) gaps[gap] = { count: 0, topFiles: [] };
|
|
1921
|
+
gaps[gap].count++;
|
|
1922
|
+
if (!gaps[gap].topFiles.includes(shortName) && gaps[gap].topFiles.length < 5) {
|
|
1923
|
+
gaps[gap].topFiles.push(shortName);
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1927
|
+
// Max widths
|
|
1928
|
+
while ((m = maxWRe.exec(content)) !== null) {
|
|
1929
|
+
const mw = m[1];
|
|
1930
|
+
if (!maxWidths[mw]) maxWidths[mw] = 0;
|
|
1931
|
+
maxWidths[mw]++;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
// Container
|
|
1935
|
+
const cMatches = content.match(containerRe);
|
|
1936
|
+
if (cMatches) containerCount += cMatches.length;
|
|
1937
|
+
|
|
1938
|
+
} catch { /* skip unreadable files */ }
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
for (const dir of srcDirs) walkFiles(dir);
|
|
1944
|
+
|
|
1945
|
+
if (Object.keys(breakpoints).length === 0 && Object.keys(gridCols).length === 0) return null;
|
|
1946
|
+
return { breakpoints, gridCols, gaps, maxWidths, containerCount };
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1799
1949
|
function writeFoundationsStories(foundations) {
|
|
1800
1950
|
const foundationsDir = path.join(STORIES_DIR, "foundations");
|
|
1801
1951
|
ensureDir(foundationsDir);
|
|
@@ -2275,7 +2425,11 @@ function writeFoundationsStories(foundations) {
|
|
|
2275
2425
|
console.log("[VDS] Wrote " + path.relative(PROJECT_ROOT, path.join(foundationsDir, "Icons.stories.tsx")));
|
|
2276
2426
|
}
|
|
2277
2427
|
|
|
2278
|
-
|
|
2428
|
+
// Fallback: if scan.mjs didn't produce gridSystem data, scan source files directly
|
|
2429
|
+
let gridSystem = foundations?.gridSystem || null;
|
|
2430
|
+
if (!gridSystem || (Object.keys(gridSystem.breakpoints || {}).length === 0 && Object.keys(gridSystem.gridCols || {}).length === 0)) {
|
|
2431
|
+
gridSystem = scanGridSystemFallback();
|
|
2432
|
+
}
|
|
2279
2433
|
if (gridSystem && (Object.keys(gridSystem.breakpoints || {}).length > 0 || Object.keys(gridSystem.gridCols || {}).length > 0)) {
|
|
2280
2434
|
const bpEntries = Object.entries(gridSystem.breakpoints || {});
|
|
2281
2435
|
const colEntries = Object.entries(gridSystem.gridCols || {});
|