vibe-design-system 2.8.56 → 2.8.58
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 +18 -9
- package/package.json +1 -1
- package/vds-core-template/story-generator.mjs +81 -2
package/bin/init.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import fs from "fs";
|
|
16
16
|
import path from "path";
|
|
17
17
|
import { fileURLToPath } from "url";
|
|
18
|
-
import { spawnSync } from "child_process";
|
|
18
|
+
import { spawnSync, spawn } from "child_process";
|
|
19
19
|
|
|
20
20
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
21
21
|
const INSTALLER_ROOT = path.join(__dirname, "..");
|
|
@@ -610,12 +610,11 @@ function ensureVdsConfig(projectRoot, srcPrefix) {
|
|
|
610
610
|
const configPath = path.join(projectRoot, "vds.config.js");
|
|
611
611
|
if (fs.existsSync(configPath)) return;
|
|
612
612
|
|
|
613
|
-
//
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
: ` // includeGroups: ["shadcn", "UI"], // Uncomment to generate stories for shadcn/ui primitives\n`;
|
|
613
|
+
// includeGroups is intentionally OFF by default.
|
|
614
|
+
// shadcn/ui base components (Button, Avatar, Badge…) are generic library primitives —
|
|
615
|
+
// most projects only want their custom sections and page components in Storybook.
|
|
616
|
+
// To include shadcn/ui components: add includeGroups: ["shadcn", "UI", "ui"] to vds.config.js.
|
|
617
|
+
const includeGroupsLine = ` // includeGroups: ["shadcn", "UI"], // Uncomment to add shadcn/ui primitive stories\n`;
|
|
619
618
|
|
|
620
619
|
const content = `/**
|
|
621
620
|
* VDS Configuration — auto-created by VDS installer
|
|
@@ -715,8 +714,18 @@ runStorybookAdapt(projectRoot);
|
|
|
715
714
|
|
|
716
715
|
// ADIM 8
|
|
717
716
|
console.log("\n✅ VDS kuruldu!");
|
|
718
|
-
console.log("→ npm run storybook — design system'ı aç (localhost:6006)");
|
|
719
|
-
console.log("→ npm run storybook:bg — Storybook'u arka planda başlat (Cursor kapansa bile çalışır)");
|
|
720
717
|
console.log("→ npm run vds:stories — tarama + story + provider (tek komut)");
|
|
721
718
|
console.log("→ npm run vds:watch — otomatik güncelleme (watch modu)");
|
|
722
719
|
console.log("\nNot: Storybook başlarken (Node 24+) DEP0190 uyarısı çıkarsa Storybook kaynaklıdır, güvenle yok sayabilirsiniz.\n");
|
|
720
|
+
|
|
721
|
+
// ADIM 10 — Storybook'u otomatik başlat
|
|
722
|
+
console.log("🚀 Storybook başlatılıyor → http://localhost:6006\n");
|
|
723
|
+
const sbProc = spawn("npm", ["run", "storybook"], {
|
|
724
|
+
stdio: "inherit",
|
|
725
|
+
cwd: projectRoot,
|
|
726
|
+
shell: process.platform === "win32",
|
|
727
|
+
});
|
|
728
|
+
sbProc.on("error", (err) => {
|
|
729
|
+
console.error("[VDS] Storybook başlatılamadı:", err.message);
|
|
730
|
+
console.log("→ Manuel başlatmak için: npm run storybook");
|
|
731
|
+
});
|
package/package.json
CHANGED
|
@@ -246,10 +246,9 @@ const RECIPES = {
|
|
|
246
246
|
)`,
|
|
247
247
|
},
|
|
248
248
|
Avatar: {
|
|
249
|
-
imports: ["
|
|
249
|
+
imports: ["AvatarFallback"],
|
|
250
250
|
render: `(args) => (
|
|
251
251
|
<ComponentRef {...args}>
|
|
252
|
-
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
253
252
|
<AvatarFallback>JD</AvatarFallback>
|
|
254
253
|
</ComponentRef>
|
|
255
254
|
)`,
|
|
@@ -881,6 +880,58 @@ const COMPONENT_EXTRA_ARGS = {
|
|
|
881
880
|
...(VDS_CONFIG.componentExtraArgs ?? {}),
|
|
882
881
|
};
|
|
883
882
|
|
|
883
|
+
// ---------------------------------------------------------------------------
|
|
884
|
+
// USAGE SCANNER — reads project sources to find actual component usage patterns
|
|
885
|
+
// e.g. <Button className="bg-[#5409da] text-white rounded-[10px]"> → generates
|
|
886
|
+
// a "ProjectPrimary" story with the real project styling instead of generic CVA variants.
|
|
887
|
+
// ---------------------------------------------------------------------------
|
|
888
|
+
const _SCAN_IGNORE_DIRS = new Set(["node_modules", ".next", "dist", "build", ".git", ".storybook"]);
|
|
889
|
+
|
|
890
|
+
function scanComponentUsages(componentName, projectRoot) {
|
|
891
|
+
const uiPathFrag = path.join("components", "ui") + path.sep;
|
|
892
|
+
const classNameCounts = new Map(); // className → count
|
|
893
|
+
|
|
894
|
+
function walk(dir) {
|
|
895
|
+
let entries;
|
|
896
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
897
|
+
for (const e of entries) {
|
|
898
|
+
if (_SCAN_IGNORE_DIRS.has(e.name)) continue;
|
|
899
|
+
const full = path.join(dir, e.name);
|
|
900
|
+
if (e.isDirectory()) { walk(full); continue; }
|
|
901
|
+
if (!/\.(tsx|jsx|ts|js)$/.test(e.name)) continue;
|
|
902
|
+
if (full.includes(uiPathFrag)) continue; // Skip ui/ directory itself
|
|
903
|
+
if (e.name.includes(".stories.")) continue; // Skip story files
|
|
904
|
+
let src;
|
|
905
|
+
try { src = fs.readFileSync(full, "utf-8"); } catch { continue; }
|
|
906
|
+
if (!src.includes(`<${componentName}`)) continue;
|
|
907
|
+
|
|
908
|
+
// Match <ComponentName ... > or <ComponentName ... />
|
|
909
|
+
const re = new RegExp(`<${componentName}(?:\\s+([^>]*?))?(?:\\s*/>|\\s*>)`, "g");
|
|
910
|
+
let m;
|
|
911
|
+
while ((m = re.exec(src)) !== null) {
|
|
912
|
+
const propsStr = m[1] || "";
|
|
913
|
+
// Extract className="..." — single or double quotes
|
|
914
|
+
const classM = propsStr.match(/className=["']([^"']+)["']/);
|
|
915
|
+
if (!classM) continue;
|
|
916
|
+
const cn = classM[1].trim();
|
|
917
|
+
if (!cn) continue;
|
|
918
|
+
// Only include usages that have project-specific (non-CVA) styling
|
|
919
|
+
// i.e. hex colors, arbitrary Tailwind values, custom font families
|
|
920
|
+
const hasCustomStyling = /bg-\[|text-\[|rounded-\[|#[0-9a-fA-F]{3,8}|\[font-family:/.test(cn);
|
|
921
|
+
if (!hasCustomStyling) continue;
|
|
922
|
+
classNameCounts.set(cn, (classNameCounts.get(cn) || 0) + 1);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
walk(projectRoot);
|
|
928
|
+
|
|
929
|
+
return [...classNameCounts.entries()]
|
|
930
|
+
.sort((a, b) => b[1] - a[1])
|
|
931
|
+
.slice(0, 4)
|
|
932
|
+
.map(([className, count]) => ({ className, count }));
|
|
933
|
+
}
|
|
934
|
+
|
|
884
935
|
/** Render'da args'a uygulanacak fallback (useState(estimate.toString()) gibi kullanımlar için; args/Controls undefined yapsa bile). */
|
|
885
936
|
const RENDER_ARGS_FALLBACKS = {
|
|
886
937
|
TaskEstimateInput: ", estimate: (args && args.estimate) ?? 0, value: (args && args.value) ?? 0, task: (args && args.task) ?? { id: \"1\", title: \"Example\", estimate: 0 }",
|
|
@@ -1867,6 +1918,28 @@ function buildStoryFileContent(comp) {
|
|
|
1867
1918
|
lines.push(`};`);
|
|
1868
1919
|
}
|
|
1869
1920
|
|
|
1921
|
+
// --- Project-specific usage stories ---
|
|
1922
|
+
// Scan actual component usages in project source. If custom className overrides found
|
|
1923
|
+
// (hex colors, arbitrary Tailwind values), append stories that show the REAL project styling.
|
|
1924
|
+
const usagePatterns = scanComponentUsages(componentName, PROJECT_ROOT);
|
|
1925
|
+
if (usagePatterns.length > 0) {
|
|
1926
|
+
const usageStoryNames = ["ProjectPrimary", "ProjectSecondary", "ProjectTertiary", "ProjectQuaternary"];
|
|
1927
|
+
lines.push("");
|
|
1928
|
+
lines.push(`// — Project-specific stories auto-detected from actual ${componentName} usage in this codebase.`);
|
|
1929
|
+
lines.push(`// These reflect how ${componentName} is styled in the project, not generic variants.`);
|
|
1930
|
+
for (let i = 0; i < usagePatterns.length; i++) {
|
|
1931
|
+
const { className } = usagePatterns[i];
|
|
1932
|
+
const sName = usageStoryNames[i];
|
|
1933
|
+
lines.push(`export const ${sName}: Story = {`);
|
|
1934
|
+
lines.push(` render: () => (`);
|
|
1935
|
+
lines.push(` <ComponentRef className="${className}">`);
|
|
1936
|
+
lines.push(` ${componentName}`);
|
|
1937
|
+
lines.push(` </ComponentRef>`);
|
|
1938
|
+
lines.push(` ),`);
|
|
1939
|
+
lines.push(`};`);
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1870
1943
|
return lines.join("\n");
|
|
1871
1944
|
}
|
|
1872
1945
|
|
|
@@ -3496,6 +3569,12 @@ function main() {
|
|
|
3496
3569
|
if (!onlyName) {
|
|
3497
3570
|
try {
|
|
3498
3571
|
const existing = fs.readdirSync(STORIES_DIR);
|
|
3572
|
+
// Remove macOS copy artifacts: "Button.stories 2.tsx", "Badge.stories 3.tsx", etc.
|
|
3573
|
+
for (const name of existing) {
|
|
3574
|
+
if (/\.stories \d+\.(tsx|ts|jsx|js)$/.test(name)) {
|
|
3575
|
+
try { fs.unlinkSync(path.join(STORIES_DIR, name)); } catch { /* ignore */ }
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
3499
3578
|
for (const name of existing) {
|
|
3500
3579
|
if (name === "foundations") continue;
|
|
3501
3580
|
if (
|