vibe-design-system 2.5.10 → 2.5.11

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/bin/init.js CHANGED
@@ -63,18 +63,21 @@ const preview: Preview = {
63
63
  "Foundations",
64
64
  ["Introduction", "Page to Components", "Colors", "Typography", "Brand", "Icons", "Component Suggestions", "Changelog"],
65
65
  "Layout",
66
- ["Navigation", "Footer", "ScrollToTop"],
67
66
  "Components",
68
67
  "Actions",
69
68
  "Data Display",
70
69
  "Examples",
71
- ["Pages"],
72
70
  ],
73
71
  },
74
72
  },
75
73
  },
76
74
  decorators: [
77
- (Story) => React.createElement(MemoryRouter, null, React.createElement(Story, null)),
75
+ (Story, context) => {
76
+ const needsRouter = context.parameters?.router !== false;
77
+ return needsRouter
78
+ ? React.createElement(MemoryRouter, null, React.createElement(Story, null))
79
+ : React.createElement(Story, null);
80
+ },
78
81
  ],
79
82
  };
80
83
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-design-system",
3
- "version": "2.5.10",
3
+ "version": "2.5.11",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -774,6 +774,24 @@ function parseCssVarBlock(block) {
774
774
  return out;
775
775
  }
776
776
 
777
+ /** Return only theme.extend.colors from tailwind config (user-defined colors), not the default Tailwind palette. */
778
+ function getTailwindExtendColors() {
779
+ try {
780
+ const twPath = path.join(PROJECT_ROOT, "tailwind.config.js");
781
+ const twPathMjs = path.join(PROJECT_ROOT, "tailwind.config.mjs");
782
+ let config = null;
783
+ if (fs.existsSync(twPath)) {
784
+ config = projectRequire(twPath);
785
+ } else if (fs.existsSync(twPathMjs)) {
786
+ config = projectRequire(twPathMjs);
787
+ }
788
+ if (config && typeof config === "object" && config.default) config = config.default;
789
+ return config?.theme?.extend?.colors ?? null;
790
+ } catch (_) {
791
+ return null;
792
+ }
793
+ }
794
+
777
795
  /** Resolve Tailwind theme for boxShadow, spacing, screens, zIndex, motion. Uses resolveConfig when available. */
778
796
  function getTailwindTheme() {
779
797
  const empty = { shadows: {}, spacing: {}, breakpoints: {}, zIndex: {}, transitionDuration: {}, transitionTimingFunction: {}, animation: {}, colors: {} };
@@ -1041,9 +1059,9 @@ function extractFoundations() {
1041
1059
  const foundationsColors = { ...colors };
1042
1060
  if (Object.keys(colorsDark).length > 0) foundationsColors._dark = colorsDark;
1043
1061
 
1044
- const twTheme = getTailwindTheme();
1045
- if (twTheme.colors && typeof twTheme.colors === "object") {
1046
- for (const [key, val] of Object.entries(twTheme.colors)) {
1062
+ const extendColors = getTailwindExtendColors();
1063
+ if (extendColors && typeof extendColors === "object") {
1064
+ for (const [key, val] of Object.entries(extendColors)) {
1047
1065
  if (typeof val === "string" && (val.startsWith("#") || /^[a-z]/.test(val))) {
1048
1066
  foundationsColors[key] = { value: val, hex: val.startsWith("#") ? val : val };
1049
1067
  } else if (typeof val === "object" && val !== null && !Array.isArray(val)) {
@@ -1054,6 +1072,7 @@ function extractFoundations() {
1054
1072
  }
1055
1073
  }
1056
1074
 
1075
+ const twTheme = getTailwindTheme();
1057
1076
  const normalizeThemeObj = (obj) => {
1058
1077
  if (!obj || typeof obj !== "object") return {};
1059
1078
  const out = {};
@@ -350,6 +350,12 @@ function needsRouter(source) {
350
350
  return false;
351
351
  }
352
352
 
353
+ /** Detect if component provides its own router (BrowserRouter or RouterProvider). Preview should not wrap with MemoryRouter. */
354
+ function usesOwnRouter(source) {
355
+ if (!source || typeof source !== "string") return false;
356
+ return /\bBrowserRouter\b|\bRouterProvider\b/.test(source);
357
+ }
358
+
353
359
  /** Void HTML elements: img, input, hr, br — must not receive children. If component wraps one and has children in props, omit children in story args. */
354
360
  function componentWrapsVoidElement(source) {
355
361
  if (!source || typeof source !== "string") return false;
@@ -486,7 +492,6 @@ function buildSpecialStories(componentName, variants) {
486
492
  function buildRecipeStoryContent(comp, componentName, importPath, title, source, exportStyle, recipe) {
487
493
  const lines = [];
488
494
  lines.push(`import type { Meta, StoryObj } from "@storybook/react";`);
489
- const useRouterDecorator = needsRouter(source);
490
495
  if (exportStyle === "default") {
491
496
  lines.push(`import ${componentName} from "${importPath}";`);
492
497
  if (recipe.imports?.length) {
@@ -507,18 +512,14 @@ function buildRecipeStoryContent(comp, componentName, importPath, title, source,
507
512
  for (const ext of recipe.extraImports || []) {
508
513
  lines.push(`import { ${ext.names.join(", ")} } from "${ext.from}";`);
509
514
  }
510
- if (useRouterDecorator) lines.push(`import { MemoryRouter } from "react-router-dom";`);
515
+ const skipPreviewRouter = usesOwnRouter(source);
511
516
  lines.push("");
512
517
  lines.push(`const meta = {`);
513
518
  lines.push(` title: ${JSON.stringify(title)},`);
514
519
  lines.push(` component: ComponentRef,`);
515
520
  lines.push(` tags: ["autodocs"],`);
516
- if (useRouterDecorator) {
517
- lines.push(` decorators: [(Story) => (`);
518
- lines.push(` <MemoryRouter>`);
519
- lines.push(` <Story />`);
520
- lines.push(` </MemoryRouter>`);
521
- lines.push(` )],`);
521
+ if (skipPreviewRouter) {
522
+ lines.push(` parameters: { router: false },`);
522
523
  }
523
524
  lines.push(`} satisfies Meta<typeof ComponentRef>;`);
524
525
  lines.push("");
@@ -619,22 +620,14 @@ function buildStoryFileContent(comp) {
619
620
  lines.push(`const ComponentRef = ${namedAlias} ?? ${defaultAlias};`);
620
621
  }
621
622
 
622
- const useRouterDecorator = needsRouter(source);
623
- if (useRouterDecorator) {
624
- lines.push(`import { MemoryRouter } from "react-router-dom";`);
625
- }
626
-
623
+ const skipPreviewRouter = usesOwnRouter(source);
627
624
  lines.push("");
628
625
  lines.push(`const meta = {`);
629
626
  lines.push(` title: ${JSON.stringify(title)},`);
630
627
  lines.push(` component: ComponentRef,`);
631
628
  lines.push(` tags: ["autodocs"],`);
632
- if (useRouterDecorator) {
633
- lines.push(` decorators: [(Story) => (`);
634
- lines.push(` <MemoryRouter>`);
635
- lines.push(` <Story />`);
636
- lines.push(` </MemoryRouter>`);
637
- lines.push(` )],`);
629
+ if (skipPreviewRouter) {
630
+ lines.push(` parameters: { router: false },`);
638
631
  }
639
632
  lines.push(`} satisfies Meta<typeof ComponentRef>;`);
640
633
  lines.push("");