vibe-design-system 2.8.0 → 2.8.2

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.0",
3
+ "version": "2.8.2",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1382,7 +1382,72 @@ function extractFoundations() {
1382
1382
  if (count < 1) continue;
1383
1383
  const name = "arbitrary-" + hex.slice(1).toLowerCase();
1384
1384
  colors[name] = { value: hex, source: "arbitrary-tailwind", frequency: count };
1385
+ existingHexValues.add(hexUpper);
1385
1386
  }
1387
+
1388
+ // ── Inline style hex renkleri (style={{ color: '#AEF33F' }}) ─────────────────
1389
+ const INLINE_STYLE_HEX = /(?:color|background(?:Color)?|borderColor|fill|stroke|outlineColor|caretColor|accentColor)\s*:\s*['"]?(#[0-9a-fA-F]{3,8})['"]?/g;
1390
+ const inlineColors = new Map();
1391
+ for (const file of allTsxFiles) {
1392
+ try {
1393
+ const content = fs.readFileSync(file, "utf-8");
1394
+ for (const match of content.matchAll(INLINE_STYLE_HEX)) {
1395
+ const hex = match[1].toUpperCase();
1396
+ inlineColors.set(hex, (inlineColors.get(hex) || 0) + 1);
1397
+ }
1398
+ } catch (_) {}
1399
+ }
1400
+ for (const [hex, count] of inlineColors) {
1401
+ if (existingHexValues.has(hex)) continue;
1402
+ const key = "inline-" + hex.slice(1).toLowerCase();
1403
+ if (!colors[key]) {
1404
+ colors[key] = { value: hex, source: "inline-style", frequency: count };
1405
+ existingHexValues.add(hex);
1406
+ }
1407
+ }
1408
+
1409
+ // ── CSS dosyalarındaki hex renkler (color: #AEF33F, --brand: #AEF33F) ────────
1410
+ const CSS_PROP_HEX = /(?:--|color|background(?:-color)?|border(?:-color)?|fill|stroke|outline(?:-color)?|accent-color|caret-color)\s*[:\s]\s*(#[0-9a-fA-F]{3,8})\b/gi;
1411
+ const CSS_VAR_HEX = /(--[\w-]+)\s*:\s*(#[0-9a-fA-F]{3,8})\b/g;
1412
+ const allCssFiles = [];
1413
+ const walkCss = (dir) => {
1414
+ if (!fs.existsSync(dir)) return;
1415
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
1416
+ const full = path.join(dir, e.name);
1417
+ if (e.isDirectory() && !["node_modules", "dist", ".next", "build"].includes(e.name)) walkCss(full);
1418
+ else if (e.isFile() && /\.(css|scss|sass|less)$/i.test(e.name)) allCssFiles.push(full);
1419
+ }
1420
+ };
1421
+ walkCss(SRC_DIR);
1422
+ for (const name of ["index.css", "globals.css", "styles.css"]) {
1423
+ const p = path.join(PROJECT_ROOT, name);
1424
+ if (fs.existsSync(p)) allCssFiles.push(p);
1425
+ }
1426
+ for (const file of allCssFiles) {
1427
+ try {
1428
+ const content = fs.readFileSync(file, "utf-8");
1429
+ for (const match of content.matchAll(CSS_VAR_HEX)) {
1430
+ const varName = match[1];
1431
+ const hex = match[2].toUpperCase();
1432
+ if (existingHexValues.has(hex)) continue;
1433
+ const key = varName.replace(/^--/, "css-");
1434
+ if (!colors[key]) {
1435
+ colors[key] = { value: hex, source: "css-variable", cssVar: varName };
1436
+ existingHexValues.add(hex);
1437
+ }
1438
+ }
1439
+ for (const match of content.matchAll(CSS_PROP_HEX)) {
1440
+ const hex = match[1].toUpperCase();
1441
+ if (existingHexValues.has(hex)) continue;
1442
+ const key = "css-" + hex.slice(1).toLowerCase();
1443
+ if (!colors[key]) {
1444
+ colors[key] = { value: hex, source: "css-file", file: path.relative(PROJECT_ROOT, file) };
1445
+ existingHexValues.add(hex);
1446
+ }
1447
+ }
1448
+ } catch (_) {}
1449
+ }
1450
+
1386
1451
  // ── FALLBACK 2: Google Fonts URL ──────────────────────────
1387
1452
  const GFONTS_PATTERN = /family=([A-Za-z+]+)(?::.*?)?(?:&|$)/g;
1388
1453
  const fontFileCandidates = [
@@ -170,6 +170,40 @@ function getPreviewPath(projectRoot) {
170
170
  return null;
171
171
  }
172
172
 
173
+ // React Router hooks that require a Router wrapper in Storybook
174
+ const ROUTER_HOOKS = new Set([
175
+ "useLocation", "useNavigate", "useParams", "useSearchParams",
176
+ "useMatch", "useHref", "useResolvedPath", "useOutlet", "useOutletContext",
177
+ "useMatches", "useRouteError", "useNavigation", "useRevalidator",
178
+ ]);
179
+
180
+ function detectRouterPackage(projectRoot) {
181
+ const pkgPath = path.join(projectRoot, "package.json");
182
+ if (!fs.existsSync(pkgPath)) return null;
183
+ try {
184
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
185
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
186
+ if (deps["react-router-dom"]) return "react-router-dom";
187
+ if (deps["react-router"]) return "react-router";
188
+ } catch (_) {}
189
+ return null;
190
+ }
191
+
192
+ function projectUsesRouterHooks(projectRoot) {
193
+ const srcDir = path.join(projectRoot, "src");
194
+ if (!fs.existsSync(srcDir)) return false;
195
+ const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join(projectRoot, "src", r));
196
+ for (const file of files) {
197
+ try {
198
+ const content = fs.readFileSync(file, "utf-8");
199
+ for (const hook of ROUTER_HOOKS) {
200
+ if (new RegExp("\\b" + hook + "\\s*[(<(]").test(content)) return true;
201
+ }
202
+ } catch (_) {}
203
+ }
204
+ return false;
205
+ }
206
+
173
207
  /** Detect if project uses react-dnd (useDrag, useDrop, or import from react-dnd). */
174
208
  function detectReactDnd(projectRoot) {
175
209
  const srcDir = path.join(projectRoot, "src");
@@ -231,6 +265,12 @@ function collectProvidersAndWarnings(projectRoot) {
231
265
  hooksWithoutProvider.add(hook);
232
266
  }
233
267
  }
268
+ // MemoryRouter: wrap components that use React Router hooks
269
+ const routerPackage = detectRouterPackage(projectRoot);
270
+ if (routerPackage && projectUsesRouterHooks(projectRoot) && !providersToAdd.some((p) => p.name === "MemoryRouter")) {
271
+ providersToAdd.unshift({ name: "MemoryRouter", importPath: routerPackage, props: "{ initialEntries: [\"/\"] }" });
272
+ console.log("[VDS] React Router tespit edildi → MemoryRouter decorator ekleniyor.");
273
+ }
234
274
  if (detectReactDnd(projectRoot) && !providersToAdd.some((p) => p.name === "DndProvider")) {
235
275
  providersToAdd.unshift({
236
276
  name: "DndProvider",