vibe-design-system 2.8.49 → 2.8.51

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.49",
3
+ "version": "2.8.51",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "homepage": "https://vibedesign.tech",
6
6
  "repository": {
@@ -677,7 +677,9 @@ function buildMultiDimensionStories(variantMap, renderLine, childrenArgLine, def
677
677
  lines.push(` ${primaryDimension}: "${dimensions[primaryDimension].default || dimensions[primaryDimension].values[0]}",`);
678
678
  }
679
679
  lines.push(` ${dimName}: "${val}",`);
680
- if (childrenArgLine(componentName)) lines.push(childrenArgLine(componentName));
680
+ // For icon size use a short symbol; otherwise use component name
681
+ const childLabel = val === "icon" ? "\u2726" : componentName;
682
+ if (childrenArgLine(childLabel)) lines.push(childrenArgLine(childLabel));
681
683
  for (const line of filteredArgLines) lines.push(line);
682
684
  lines.push(` },`);
683
685
  lines.push(`};`);
@@ -709,29 +711,51 @@ function buildMultiDimensionStories(variantMap, renderLine, childrenArgLine, def
709
711
  const secondaryDim = secondaryDimensions.find((d) => dimensions[d] && dimensions[d].values.length >= 2);
710
712
 
711
713
  lines.push(`export const AllVariants: Story = {`);
712
- lines.push(` render: () => (`);
713
- lines.push(` <div style={{ display: "flex", flexDirection: "column", gap: 16, padding: 16 }}>`);
714
+ lines.push(` parameters: { layout: "padded" },`);
715
+ lines.push(` render: () => {`);
714
716
 
715
717
  if (secondaryDim) {
716
718
  const secondaryValues = dimensions[secondaryDim].values;
719
+ const colCount = secondaryValues.length;
720
+
721
+ // Style constants for the grid
722
+ lines.push(` const hdr: React.CSSProperties = { textAlign: "center", fontSize: 11, fontWeight: 600, color: "#6b7280", fontFamily: "monospace", textTransform: "uppercase", letterSpacing: "0.05em", padding: "0 4px" };`);
723
+ lines.push(` const lbl: React.CSSProperties = { fontSize: 12, fontWeight: 500, color: "#374151", fontFamily: "monospace" };`);
724
+ lines.push(` const cell: React.CSSProperties = { display: "flex", justifyContent: "center", alignItems: "center" };`);
725
+ lines.push(` return (`);
726
+ lines.push(` <div style={{ padding: 24 }}>`);
727
+ lines.push(` <div style={{ display: "grid", gridTemplateColumns: "100px repeat(${colCount}, minmax(80px, 1fr))", gap: "16px 12px", alignItems: "center" }}>`);
728
+
729
+ // Header row: empty corner + secondary dimension labels
730
+ lines.push(` <div />`);
731
+ for (const sVal of secondaryValues) {
732
+ lines.push(` <div style={hdr}>${sVal}</div>`);
733
+ }
734
+
735
+ // Data rows: primary label + component cells
717
736
  for (const pVal of primaryValues) {
718
- lines.push(` <div style={{ display: "flex", flexWrap: "wrap", gap: 8, alignItems: "center" }}>`);
719
- lines.push(` <span style={{ width: 90, fontSize: 12, color: "#888", fontFamily: "monospace" }}>${pVal}</span>`);
737
+ lines.push(` <div style={lbl}>${pVal}</div>`);
720
738
  for (const sVal of secondaryValues) {
721
- lines.push(` <ComponentRef ${primaryDimension}="${pVal}" ${secondaryDim}="${sVal}">${pVal}</ComponentRef>`);
739
+ const childText = sVal === "icon" ? "\u2726" : componentName;
740
+ lines.push(` <div style={cell}><ComponentRef ${primaryDimension}="${pVal}" ${secondaryDim}="${sVal}">${childText}</ComponentRef></div>`);
722
741
  }
723
- lines.push(` </div>`);
724
742
  }
743
+
744
+ lines.push(` </div>`);
745
+ lines.push(` </div>`);
746
+ lines.push(` );`);
725
747
  } else {
726
- lines.push(` <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>`);
748
+ // No secondary dimension labeled flex layout
749
+ lines.push(` return (`);
750
+ lines.push(` <div style={{ display: "flex", flexWrap: "wrap", gap: 12, padding: 24, alignItems: "center" }}>`);
727
751
  for (const val of primaryValues) {
728
- lines.push(` <ComponentRef ${primaryDimension}="${val}">${val}</ComponentRef>`);
752
+ lines.push(` <ComponentRef ${primaryDimension}="${val}">${componentName}</ComponentRef>`);
729
753
  }
730
754
  lines.push(` </div>`);
755
+ lines.push(` );`);
731
756
  }
732
757
 
733
- lines.push(` </div>`);
734
- lines.push(` ),`);
758
+ lines.push(` },`);
735
759
  lines.push(`};`);
736
760
  }
737
761
 
@@ -1579,7 +1603,15 @@ function buildProfileRenderLine(profile, RenderTarget, argsFallback) {
1579
1603
  )},`;
1580
1604
  case "SAFE":
1581
1605
  return ` render: (args = {}) => ${suspense(`React.createElement(${RenderTarget}, args)`)},`;
1582
- default: { // CONFIGURED, VARIANT
1606
+ case "VARIANT": {
1607
+ // Wrap in inline-block div to prevent vertical stretching caused by
1608
+ // global SidebarProvider/flex decorators or layout: "fullscreen" in preview.
1609
+ const argsParam = argsFallback ? "(args = {})" : "(args)";
1610
+ const propsArg = argsFallback ? `{ ...args${argsFallback} }` : "args";
1611
+ const inner = suspense(`React.createElement(${RenderTarget}, ${propsArg})`);
1612
+ return ` render: ${argsParam} => React.createElement('div', { style: { display: 'inline-block' } }, ${inner}),`;
1613
+ }
1614
+ default: { // CONFIGURED
1583
1615
  const argsParam = argsFallback ? "(args = {})" : "(args)";
1584
1616
  const propsArg = argsFallback ? `{ ...args${argsFallback} }` : "args";
1585
1617
  return ` render: ${argsParam} => ${suspense(`React.createElement(${RenderTarget}, ${propsArg})`)},`;
@@ -1595,7 +1627,7 @@ function buildProfileRenderLine(profile, RenderTarget, argsFallback) {
1595
1627
  */
1596
1628
  function buildProfileChildrenArgLine(profile) {
1597
1629
  return (label) => {
1598
- if (profile === "WRAPPER") return ` children: ${JSON.stringify(label)},`;
1630
+ if (profile === "WRAPPER" || profile === "VARIANT") return ` children: ${JSON.stringify(label)},`;
1599
1631
  return null;
1600
1632
  };
1601
1633
  }
@@ -1697,6 +1729,8 @@ function buildStoryFileContent(comp) {
1697
1729
  lines.push(` component: ComponentRef,`);
1698
1730
  // SECTION: no props/args → autodocs tries to render React.lazy without Suspense → useRef crash
1699
1731
  if (profile !== "SECTION") lines.push(` tags: ["autodocs"],`);
1732
+ // Center small components (VARIANT, WRAPPER, CONFIGURED, SAFE) to prevent vertical stretching
1733
+ if (profile !== "SECTION") lines.push(` parameters: { layout: "centered" },`);
1700
1734
 
1701
1735
  // Build argTypes from extracted TypeScript props + icon-specific overrides
1702
1736
  const argTypeEntries = [];
@@ -1770,6 +1804,90 @@ function buildStoryFileContent(comp) {
1770
1804
  return lines.join("\n");
1771
1805
  }
1772
1806
 
1807
+ /**
1808
+ * Fallback grid system scanner — reads source files for Tailwind grid patterns
1809
+ * when scan.mjs didn't produce gridSystem data.
1810
+ */
1811
+ function scanGridSystemFallback() {
1812
+ const srcDirs = [
1813
+ path.join(PROJECT_ROOT, "src"),
1814
+ path.join(PROJECT_ROOT, "client/src"),
1815
+ path.join(PROJECT_ROOT, "app"),
1816
+ ];
1817
+ const breakpoints = {}; // { "md": { count, topFiles: [] }, ... }
1818
+ const gridCols = {}; // { "2": { count }, "3": { count }, ... }
1819
+ const gaps = {}; // { "4": { count }, "6": { count }, ... }
1820
+ const maxWidths = {}; // { "7xl": count, ... }
1821
+ let containerCount = 0;
1822
+
1823
+ const BP_NAMES = ["sm", "md", "lg", "xl", "2xl"];
1824
+ const bpRe = /\b(sm|md|lg|xl|2xl):/g;
1825
+ const colRe = /\bgrid-cols-(\w+)/g;
1826
+ const gapRe = /\bgap-(\w+)/g;
1827
+ const maxWRe = /\bmax-w-(\w+)/g;
1828
+ const containerRe = /\bcontainer\b/g;
1829
+
1830
+ function walkFiles(dir) {
1831
+ if (!fs.existsSync(dir)) return;
1832
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
1833
+ for (const entry of entries) {
1834
+ const full = path.join(dir, entry.name);
1835
+ if (entry.isDirectory()) {
1836
+ if (["node_modules", ".next", "dist", "build", ".storybook", "stories"].includes(entry.name)) continue;
1837
+ walkFiles(full);
1838
+ } else if (/\.(tsx|jsx|ts|js|css)$/.test(entry.name)) {
1839
+ try {
1840
+ const content = fs.readFileSync(full, "utf-8");
1841
+ const relFile = path.relative(PROJECT_ROOT, full).replace(/^(client\/)?src\//, "");
1842
+ const shortName = path.basename(relFile, path.extname(relFile));
1843
+
1844
+ // Breakpoints
1845
+ let m;
1846
+ while ((m = bpRe.exec(content)) !== null) {
1847
+ const bp = m[1];
1848
+ if (!breakpoints[bp]) breakpoints[bp] = { count: 0, topFiles: [] };
1849
+ breakpoints[bp].count++;
1850
+ if (!breakpoints[bp].topFiles.includes(shortName) && breakpoints[bp].topFiles.length < 5) {
1851
+ breakpoints[bp].topFiles.push(shortName);
1852
+ }
1853
+ }
1854
+
1855
+ // Grid columns
1856
+ while ((m = colRe.exec(content)) !== null) {
1857
+ const col = m[1];
1858
+ if (!gridCols[col]) gridCols[col] = { count: 0 };
1859
+ gridCols[col].count++;
1860
+ }
1861
+
1862
+ // Gaps
1863
+ while ((m = gapRe.exec(content)) !== null) {
1864
+ const gap = m[1];
1865
+ if (!gaps[gap]) gaps[gap] = { count: 0 };
1866
+ gaps[gap].count++;
1867
+ }
1868
+
1869
+ // Max widths
1870
+ while ((m = maxWRe.exec(content)) !== null) {
1871
+ const mw = m[1];
1872
+ if (!maxWidths[mw]) maxWidths[mw] = 0;
1873
+ maxWidths[mw]++;
1874
+ }
1875
+
1876
+ // Container
1877
+ const cMatches = content.match(containerRe);
1878
+ if (cMatches) containerCount += cMatches.length;
1879
+
1880
+ } catch { /* skip unreadable files */ }
1881
+ }
1882
+ }
1883
+ }
1884
+
1885
+ for (const dir of srcDirs) walkFiles(dir);
1886
+
1887
+ if (Object.keys(breakpoints).length === 0 && Object.keys(gridCols).length === 0) return null;
1888
+ return { breakpoints, gridCols, gaps, maxWidths, containerCount };
1889
+ }
1890
+
1773
1891
  function writeFoundationsStories(foundations) {
1774
1892
  const foundationsDir = path.join(STORIES_DIR, "foundations");
1775
1893
  ensureDir(foundationsDir);
@@ -2249,7 +2367,11 @@ function writeFoundationsStories(foundations) {
2249
2367
  console.log("[VDS] Wrote " + path.relative(PROJECT_ROOT, path.join(foundationsDir, "Icons.stories.tsx")));
2250
2368
  }
2251
2369
 
2252
- const gridSystem = foundations?.gridSystem;
2370
+ // Fallback: if scan.mjs didn't produce gridSystem data, scan source files directly
2371
+ let gridSystem = foundations?.gridSystem || null;
2372
+ if (!gridSystem || (Object.keys(gridSystem.breakpoints || {}).length === 0 && Object.keys(gridSystem.gridCols || {}).length === 0)) {
2373
+ gridSystem = scanGridSystemFallback();
2374
+ }
2253
2375
  if (gridSystem && (Object.keys(gridSystem.breakpoints || {}).length > 0 || Object.keys(gridSystem.gridCols || {}).length > 0)) {
2254
2376
  const bpEntries = Object.entries(gridSystem.breakpoints || {});
2255
2377
  const colEntries = Object.entries(gridSystem.gridCols || {});