vibe-design-system 2.8.16 → 2.8.19
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
|
@@ -1730,6 +1730,8 @@ function extractTokenUsage() {
|
|
|
1730
1730
|
const radiusCounts = new Map();
|
|
1731
1731
|
const animateCounts = new Map();
|
|
1732
1732
|
const textSizeCounts = new Map();
|
|
1733
|
+
// Per-file tracking: token → Map<componentName, count>
|
|
1734
|
+
const textSizeFiles = new Map();
|
|
1733
1735
|
|
|
1734
1736
|
// Spacing utilities: gap-*, p-*, px-*, py-*, pt-*, pb-*, pl-*, pr-*, m-*, mx-*, my-*, mt-*, mb-*, ml-*, mr-*, space-*, w-*, h-*
|
|
1735
1737
|
const spacingRe = /\b(gap|p|px|py|pt|pb|pl|pr|m|mx|my|mt|mb|ml|mr|space-x|space-y|w|h|size|inset|top|bottom|left|right|min-w|min-h|max-w|max-h)-((?:\d+(\.\d+)?|px|full|screen|auto|fit|max|min|svh|dvh|svw|dvw))\b/g;
|
|
@@ -1792,11 +1794,16 @@ function extractTokenUsage() {
|
|
|
1792
1794
|
animateCounts.set(key, (animateCounts.get(key) || 0) + 1);
|
|
1793
1795
|
}
|
|
1794
1796
|
|
|
1795
|
-
// Text sizes
|
|
1797
|
+
// Text sizes — global count + per-component breakdown
|
|
1798
|
+
const componentName = path.basename(rel).replace(/\.(tsx|jsx|ts|js)$/, "");
|
|
1796
1799
|
const textSizeUtilReCopy = new RegExp(textSizeUtilRe.source, "g");
|
|
1797
1800
|
while ((m = textSizeUtilReCopy.exec(content)) !== null) {
|
|
1798
1801
|
const key = `text-${m[1]}`;
|
|
1799
1802
|
textSizeCounts.set(key, (textSizeCounts.get(key) || 0) + 1);
|
|
1803
|
+
// Per-file
|
|
1804
|
+
if (!textSizeFiles.has(key)) textSizeFiles.set(key, new Map());
|
|
1805
|
+
const fm = textSizeFiles.get(key);
|
|
1806
|
+
fm.set(componentName, (fm.get(componentName) || 0) + 1);
|
|
1800
1807
|
}
|
|
1801
1808
|
}
|
|
1802
1809
|
|
|
@@ -1812,10 +1819,75 @@ function extractTokenUsage() {
|
|
|
1812
1819
|
zIndex: toTop(zIndexCounts, 10),
|
|
1813
1820
|
radius: toTop(radiusCounts, 10),
|
|
1814
1821
|
animations: toTop(animateCounts, 8),
|
|
1815
|
-
textSizes: toTop(textSizeCounts, 12),
|
|
1822
|
+
textSizes: toTop(textSizeCounts, 12).map(({ token, count }) => ({
|
|
1823
|
+
token,
|
|
1824
|
+
count,
|
|
1825
|
+
// Top 5 components that use this text size most
|
|
1826
|
+
topFiles: [...(textSizeFiles.get(token) || new Map()).entries()]
|
|
1827
|
+
.sort((a, b) => b[1] - a[1])
|
|
1828
|
+
.slice(0, 5)
|
|
1829
|
+
.map(([name]) => name),
|
|
1830
|
+
})),
|
|
1816
1831
|
};
|
|
1817
1832
|
}
|
|
1818
1833
|
|
|
1834
|
+
function extractColorUsage(colorNames) {
|
|
1835
|
+
if (!fs.existsSync(SRC_DIR)) return {};
|
|
1836
|
+
if (!Array.isArray(colorNames) || colorNames.length === 0) return {};
|
|
1837
|
+
const files = getAllTsxJsxInDir(SRC_DIR);
|
|
1838
|
+
if (!Array.isArray(files) || files.length === 0) return {};
|
|
1839
|
+
|
|
1840
|
+
const nameSet = new Set(colorNames);
|
|
1841
|
+
const usage = {};
|
|
1842
|
+
for (const name of colorNames) {
|
|
1843
|
+
usage[name] = { bg: 0, text: 0, border: 0, other: 0, topFiles: new Map() };
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// Single-pass regex: matches bg-primary, text-card-foreground, border-chart-1, etc.
|
|
1847
|
+
const colorUtilRe = /\b(bg|text|border|fill|stroke|ring|from|to|via|outline)-([\w][\w-]*)/g;
|
|
1848
|
+
|
|
1849
|
+
for (const rel of files) {
|
|
1850
|
+
if (rel.includes("stories")) continue;
|
|
1851
|
+
let content;
|
|
1852
|
+
try {
|
|
1853
|
+
content = fs.readFileSync(path.join(SRC_DIR, rel), "utf-8");
|
|
1854
|
+
} catch (_) { continue; }
|
|
1855
|
+
const componentName = path.basename(rel).replace(/\.(tsx|jsx|ts|js)$/, "");
|
|
1856
|
+
|
|
1857
|
+
let m;
|
|
1858
|
+
const reCopy = new RegExp(colorUtilRe.source, "g");
|
|
1859
|
+
while ((m = reCopy.exec(content)) !== null) {
|
|
1860
|
+
const prefix = m[1];
|
|
1861
|
+
const token = m[2];
|
|
1862
|
+
if (!nameSet.has(token)) continue;
|
|
1863
|
+
if (prefix === "bg") usage[token].bg++;
|
|
1864
|
+
else if (prefix === "text") usage[token].text++;
|
|
1865
|
+
else if (prefix === "border") usage[token].border++;
|
|
1866
|
+
else usage[token].other++;
|
|
1867
|
+
usage[token].topFiles.set(componentName, (usage[token].topFiles.get(componentName) || 0) + 1);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
const result = {};
|
|
1872
|
+
for (const name of colorNames) {
|
|
1873
|
+
const data = usage[name];
|
|
1874
|
+
const total = data.bg + data.text + data.border + data.other;
|
|
1875
|
+
if (total > 0) {
|
|
1876
|
+
result[name] = {
|
|
1877
|
+
bg: data.bg,
|
|
1878
|
+
text: data.text,
|
|
1879
|
+
border: data.border,
|
|
1880
|
+
total,
|
|
1881
|
+
topFiles: [...data.topFiles.entries()]
|
|
1882
|
+
.sort((a, b) => b[1] - a[1])
|
|
1883
|
+
.slice(0, 5)
|
|
1884
|
+
.map(([n]) => n),
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
return result;
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1819
1891
|
function extractButtonUsage() {
|
|
1820
1892
|
if (!fs.existsSync(SRC_DIR)) return null;
|
|
1821
1893
|
const files = getAllTsxJsxInDir(SRC_DIR);
|
|
@@ -1928,6 +2000,9 @@ function scan() {
|
|
|
1928
2000
|
if (tokenUsage) {
|
|
1929
2001
|
foundations.tokenUsage = tokenUsage;
|
|
1930
2002
|
}
|
|
2003
|
+
const colorNames = Object.keys(foundations.colors || {}).filter((k) => k !== "_dark");
|
|
2004
|
+
const colorUsage = extractColorUsage(colorNames);
|
|
2005
|
+
if (Object.keys(colorUsage).length > 0) foundations.colorUsage = colorUsage;
|
|
1931
2006
|
const componentSuggestions = extractComponentSuggestions();
|
|
1932
2007
|
const unreleasedSectionCandidates = extractUnreleasedSectionCandidates();
|
|
1933
2008
|
const output = {
|
|
@@ -1240,53 +1240,192 @@ function buildStoryFileContent(comp) {
|
|
|
1240
1240
|
return lines.join("\n");
|
|
1241
1241
|
}
|
|
1242
1242
|
|
|
1243
|
-
/** Build color entries from foundations.colors (skip _dark; flatten to { name, hex }). */
|
|
1244
|
-
function getColorEntries(colors) {
|
|
1245
|
-
if (!colors || typeof colors !== "object") return [];
|
|
1246
|
-
const entries = [];
|
|
1247
|
-
for (const [name, v] of Object.entries(colors)) {
|
|
1248
|
-
if (name === "_dark") continue;
|
|
1249
|
-
const hex = v && (v.hex ?? (typeof v.value === "string" && v.value.startsWith("#") ? v.value : null));
|
|
1250
|
-
const value = v && v.value;
|
|
1251
|
-
if (hex) entries.push({ name, hex });
|
|
1252
|
-
else if (value) entries.push({ name, hex: value });
|
|
1253
|
-
}
|
|
1254
|
-
return entries;
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
1243
|
function writeFoundationsStories(foundations) {
|
|
1258
1244
|
const foundationsDir = path.join(STORIES_DIR, "foundations");
|
|
1259
1245
|
ensureDir(foundationsDir);
|
|
1260
1246
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1247
|
+
// ── Colors story ──────────────────────────────────────────────────────────
|
|
1248
|
+
{
|
|
1249
|
+
const rawColors = foundations?.colors || {};
|
|
1250
|
+
const colorUsage = foundations?.colorUsage || {};
|
|
1251
|
+
|
|
1252
|
+
const NON_COLOR_KEYS = new Set(["font-weight-medium", "font-weight-normal"]);
|
|
1253
|
+
|
|
1254
|
+
const DESCRIPTIONS = {
|
|
1255
|
+
background: "Page background",
|
|
1256
|
+
foreground: "Default text color",
|
|
1257
|
+
card: "Card / panel background",
|
|
1258
|
+
"card-foreground": "Text on cards",
|
|
1259
|
+
popover: "Popover background",
|
|
1260
|
+
"popover-foreground": "Text in popovers",
|
|
1261
|
+
primary: "Brand color — CTAs, active states",
|
|
1262
|
+
"primary-foreground": "Text on primary backgrounds",
|
|
1263
|
+
secondary: "Secondary actions, subtle UI",
|
|
1264
|
+
"secondary-foreground": "Text on secondary",
|
|
1265
|
+
muted: "Muted backgrounds, disabled",
|
|
1266
|
+
"muted-foreground": "Placeholder, secondary text",
|
|
1267
|
+
accent: "Hover states, highlights",
|
|
1268
|
+
"accent-foreground": "Text on accent backgrounds",
|
|
1269
|
+
destructive: "Errors, delete actions",
|
|
1270
|
+
"destructive-foreground": "Text on destructive",
|
|
1271
|
+
border: "Border / divider color",
|
|
1272
|
+
input: "Input border",
|
|
1273
|
+
"input-background": "Input fill",
|
|
1274
|
+
"switch-background": "Toggle switch track",
|
|
1275
|
+
ring: "Focus ring",
|
|
1276
|
+
"chart-1": "Chart series 1",
|
|
1277
|
+
"chart-2": "Chart series 2",
|
|
1278
|
+
"chart-3": "Chart series 3",
|
|
1279
|
+
"chart-4": "Chart series 4",
|
|
1280
|
+
"chart-5": "Chart series 5",
|
|
1281
|
+
sidebar: "Sidebar background",
|
|
1282
|
+
"sidebar-foreground": "Sidebar text",
|
|
1283
|
+
"sidebar-primary": "Sidebar active item",
|
|
1284
|
+
"sidebar-primary-foreground": "Text on sidebar active",
|
|
1285
|
+
"sidebar-accent": "Sidebar hover / subtle",
|
|
1286
|
+
"sidebar-accent-foreground": "Text on sidebar hover",
|
|
1287
|
+
"sidebar-border": "Sidebar dividers",
|
|
1288
|
+
"sidebar-ring": "Sidebar focus ring",
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
const GROUP_DEFS = [
|
|
1292
|
+
{ key: "brand", label: "Brand & Primary", tokens: ["primary", "primary-foreground", "secondary", "secondary-foreground"] },
|
|
1293
|
+
{ key: "surfaces", label: "Surfaces", tokens: ["background", "foreground", "card", "card-foreground", "popover", "popover-foreground", "muted", "muted-foreground"] },
|
|
1294
|
+
{ key: "ui", label: "UI States", tokens: ["accent", "accent-foreground", "border", "input", "input-background", "switch-background", "ring"] },
|
|
1295
|
+
{ key: "status", label: "Status", tokens: ["destructive", "destructive-foreground"] },
|
|
1296
|
+
{ key: "charts", label: "Charts", tokens: ["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"] },
|
|
1297
|
+
{ key: "sidebar", label: "Sidebar", tokens: ["sidebar", "sidebar-foreground", "sidebar-primary", "sidebar-primary-foreground", "sidebar-accent", "sidebar-accent-foreground", "sidebar-border", "sidebar-ring"] },
|
|
1298
|
+
];
|
|
1299
|
+
|
|
1300
|
+
const assignedTokens = new Set();
|
|
1301
|
+
const colorGroups = GROUP_DEFS.map((group) => {
|
|
1302
|
+
const colors = group.tokens
|
|
1303
|
+
.filter((name) => rawColors[name] && !NON_COLOR_KEYS.has(name))
|
|
1304
|
+
.map((name) => {
|
|
1305
|
+
assignedTokens.add(name);
|
|
1306
|
+
const c = rawColors[name];
|
|
1307
|
+
const hex = c?.hex || c?.value || "";
|
|
1308
|
+
const u = colorUsage[name] || null;
|
|
1309
|
+
return { name, hex, cssVar: `--${name}`, description: DESCRIPTIONS[name] || "", usage: u };
|
|
1310
|
+
});
|
|
1311
|
+
return { key: group.key, label: group.label, colors };
|
|
1312
|
+
}).filter((g) => g.colors.length > 0);
|
|
1313
|
+
|
|
1314
|
+
// Arbitrary / one-off colors (not assigned to a group, not css-* noise, not font-weight)
|
|
1315
|
+
const arbitraryColors = Object.entries(rawColors)
|
|
1316
|
+
.filter(([name, c]) =>
|
|
1317
|
+
!assignedTokens.has(name) &&
|
|
1318
|
+
!NON_COLOR_KEYS.has(name) &&
|
|
1319
|
+
!name.startsWith("css-") &&
|
|
1320
|
+
(name.startsWith("arbitrary-") || name.startsWith("inline-") ||
|
|
1321
|
+
(!name.startsWith("css-") && !assignedTokens.has(name)))
|
|
1322
|
+
)
|
|
1323
|
+
.map(([name, c]) => {
|
|
1324
|
+
const hex = c?.hex || c?.value || "";
|
|
1325
|
+
if (!hex) return null;
|
|
1326
|
+
const u = colorUsage[name] || null;
|
|
1327
|
+
return { name, hex, usage: u };
|
|
1328
|
+
})
|
|
1329
|
+
.filter(Boolean)
|
|
1330
|
+
.slice(0, 60); // cap to avoid extremely long stories
|
|
1331
|
+
|
|
1332
|
+
const colorsContent = [
|
|
1264
1333
|
"import type { Meta, StoryObj } from \"@storybook/react\";",
|
|
1265
1334
|
"",
|
|
1266
1335
|
"const meta = { title: \"Foundations/Colors\" } satisfies Meta;",
|
|
1267
1336
|
"export default meta;",
|
|
1268
1337
|
"type Story = StoryObj;",
|
|
1269
1338
|
"",
|
|
1270
|
-
`const colors = ${JSON.stringify(
|
|
1339
|
+
`const colorGroups: { key: string; label: string; colors: { name: string; hex: string; cssVar: string; description: string; usage: { bg: number; text: number; border: number; total: number; topFiles: string[] } | null }[] }[] = ${JSON.stringify(colorGroups)};`,
|
|
1340
|
+
`const arbitraryColors: { name: string; hex: string; usage: { total: number } | null }[] = ${JSON.stringify(arbitraryColors)};`,
|
|
1341
|
+
"",
|
|
1342
|
+
"function isLight(hex: string): boolean {",
|
|
1343
|
+
" try {",
|
|
1344
|
+
" const h = hex.replace('#','');",
|
|
1345
|
+
" if (h.length < 3) return true;",
|
|
1346
|
+
" const r = parseInt(h.slice(0,2),16), g = parseInt(h.slice(2,4),16), b = parseInt(h.slice(4,6),16);",
|
|
1347
|
+
" return (r*299 + g*587 + b*114) / 1000 > 155;",
|
|
1348
|
+
" } catch { return true; }",
|
|
1349
|
+
"}",
|
|
1271
1350
|
"",
|
|
1272
1351
|
"export const Default: Story = {",
|
|
1273
1352
|
" render: () => (",
|
|
1274
|
-
" <div style={{
|
|
1275
|
-
" {
|
|
1276
|
-
"
|
|
1277
|
-
"
|
|
1278
|
-
"
|
|
1279
|
-
"
|
|
1280
|
-
"
|
|
1353
|
+
" <div style={{ fontFamily: \"system-ui,sans-serif\", padding: 32, background: \"#f8fafc\", minHeight: 500 }}>",
|
|
1354
|
+
" <h2 style={{ fontSize: 20, fontWeight: 700, margin: \"0 0 4px\", color: \"#111\" }}>Colors</h2>",
|
|
1355
|
+
" <p style={{ fontSize: 13, color: \"#888\", margin: \"0 0 40px\" }}>Design tokens defined in CSS variables — grouped by role</p>",
|
|
1356
|
+
"",
|
|
1357
|
+
" {colorGroups.map(group => (",
|
|
1358
|
+
" <div key={group.key} style={{ marginBottom: 40 }}>",
|
|
1359
|
+
" <h3 style={{ fontSize: 14, fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.08em\", color: \"#6b7280\", margin: \"0 0 16px\", borderBottom: \"1px solid #e5e7eb\", paddingBottom: 8 }}>{group.label}</h3>",
|
|
1360
|
+
" <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fill, minmax(210px, 1fr))\", gap: 16 }}>",
|
|
1361
|
+
" {group.colors.map(({ name, hex, cssVar, description, usage }) => {",
|
|
1362
|
+
" const transparent = hex === 'transparent' || hex === 'oklch(1 0 0 / 0)' || hex.includes('0000000') || hex === '#0000';",
|
|
1363
|
+
" const light = isLight(hex.startsWith('#') ? hex : '#888888');",
|
|
1364
|
+
" return (",
|
|
1365
|
+
" <div key={name} style={{ background: \"#fff\", borderRadius: 12, border: \"1px solid #e5e7eb\", overflow: \"hidden\", boxShadow: \"0 1px 3px rgba(0,0,0,0.06)\" }}>",
|
|
1366
|
+
" {/* Swatch */}",
|
|
1367
|
+
" <div style={{ height: 72, background: transparent ? 'repeating-linear-gradient(45deg,#e5e7eb,#e5e7eb 4px,#fff 4px,#fff 10px)' : hex, position: \"relative\", flexShrink: 0 }}>",
|
|
1368
|
+
" {usage && usage.total > 0 && (",
|
|
1369
|
+
" <span style={{ position: \"absolute\", top: 8, right: 8, fontSize: 10, fontWeight: 700, padding: \"2px 7px\", borderRadius: 99, background: light ? \"rgba(0,0,0,0.18)\" : \"rgba(255,255,255,0.25)\", color: light ? \"#fff\" : \"#fff\", backdropFilter: \"blur(2px)\" }}>",
|
|
1370
|
+
" ×{usage.total}",
|
|
1371
|
+
" </span>",
|
|
1372
|
+
" )}",
|
|
1373
|
+
" </div>",
|
|
1374
|
+
" {/* Info */}",
|
|
1375
|
+
" <div style={{ padding: \"12px 14px\" }}>",
|
|
1376
|
+
" <div style={{ fontSize: 12, fontWeight: 700, color: \"#111\", marginBottom: 2 }}>{name}</div>",
|
|
1377
|
+
" <code style={{ fontSize: 10, color: \"#6b7280\", display: \"block\", marginBottom: 2 }}>{cssVar}</code>",
|
|
1378
|
+
" <code style={{ fontSize: 10, color: \"#9ca3af\", display: \"block\", marginBottom: description ? 6 : 0 }}>{hex.length > 28 ? hex.slice(0,28)+'…' : hex}</code>",
|
|
1379
|
+
" {description && <p style={{ margin: \"0 0 8px\", fontSize: 11, color: \"#6b7280\", lineHeight: 1.4 }}>{description}</p>}",
|
|
1380
|
+
" {usage && usage.total > 0 && (",
|
|
1381
|
+
" <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\", marginBottom: 6 }}>",
|
|
1382
|
+
" {usage.bg > 0 && <span style={{ fontSize: 10, padding: \"1px 6px\", background: \"#dbeafe\", color: \"#1e40af\", borderRadius: 4 }}>bg ×{usage.bg}</span>}",
|
|
1383
|
+
" {usage.text > 0 && <span style={{ fontSize: 10, padding: \"1px 6px\", background: \"#d1fae5\", color: \"#065f46\", borderRadius: 4 }}>text ×{usage.text}</span>}",
|
|
1384
|
+
" {usage.border > 0 && <span style={{ fontSize: 10, padding: \"1px 6px\", background: \"#fef9c3\", color: \"#854d0e\", borderRadius: 4 }}>border ×{usage.border}</span>}",
|
|
1385
|
+
" {usage.total - usage.bg - usage.text - usage.border > 0 && <span style={{ fontSize: 10, padding: \"1px 6px\", background: \"#f3e8ff\", color: \"#7e22ce\", borderRadius: 4 }}>other ×{usage.total - usage.bg - usage.text - usage.border}</span>}",
|
|
1386
|
+
" </div>",
|
|
1387
|
+
" )}",
|
|
1388
|
+
" {usage && usage.topFiles && usage.topFiles.length > 0 && (",
|
|
1389
|
+
" <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>",
|
|
1390
|
+
" {usage.topFiles.map((f: string) => (",
|
|
1391
|
+
" <span key={f} style={{ fontSize: 10, padding: \"1px 6px\", background: \"#f0f9ff\", color: \"#0369a1\", borderRadius: 3, border: \"1px solid #bae6fd\", fontFamily: \"monospace\" }}>{f}</span>",
|
|
1392
|
+
" ))}",
|
|
1393
|
+
" </div>",
|
|
1394
|
+
" )}",
|
|
1395
|
+
" {(!usage || usage.total === 0) && (",
|
|
1396
|
+
" <span style={{ fontSize: 10, color: \"#d1d5db\" }}>Not found in source</span>",
|
|
1397
|
+
" )}",
|
|
1398
|
+
" </div>",
|
|
1399
|
+
" </div>",
|
|
1400
|
+
" );",
|
|
1401
|
+
" })}",
|
|
1281
1402
|
" </div>",
|
|
1282
1403
|
" </div>",
|
|
1283
1404
|
" ))}",
|
|
1405
|
+
"",
|
|
1406
|
+
" {arbitraryColors.length > 0 && (",
|
|
1407
|
+
" <div>",
|
|
1408
|
+
" <h3 style={{ fontSize: 14, fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.08em\", color: \"#6b7280\", margin: \"0 0 16px\", borderBottom: \"1px solid #e5e7eb\", paddingBottom: 8 }}>Arbitrary Colors</h3>",
|
|
1409
|
+
" <p style={{ fontSize: 12, color: \"#9ca3af\", marginBottom: 16, marginTop: -8 }}>One-off hex values used via Tailwind arbitrary values or inline styles in this project</p>",
|
|
1410
|
+
" <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 8 }}>",
|
|
1411
|
+
" {arbitraryColors.map(({ name, hex, usage }) => (",
|
|
1412
|
+
" <div key={name} title={name + ' — ' + hex} style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 4, width: 56 }}>",
|
|
1413
|
+
" <div style={{ width: 40, height: 40, borderRadius: 8, background: hex, border: \"1px solid #e5e7eb\", flexShrink: 0 }} />",
|
|
1414
|
+
" <span style={{ fontSize: 9, color: \"#9ca3af\", textAlign: \"center\", wordBreak: \"break-all\" as any, lineHeight: 1.2 }}>{hex.length > 9 ? hex.slice(0,9)+'…' : hex}</span>",
|
|
1415
|
+
" {usage && usage.total > 0 && <span style={{ fontSize: 9, color: \"#6b7280\" }}>×{usage.total}</span>}",
|
|
1416
|
+
" </div>",
|
|
1417
|
+
" ))}",
|
|
1418
|
+
" </div>",
|
|
1419
|
+
" </div>",
|
|
1420
|
+
" )}",
|
|
1284
1421
|
" </div>",
|
|
1285
1422
|
" ),",
|
|
1286
1423
|
"};",
|
|
1287
1424
|
].join("\n");
|
|
1288
|
-
|
|
1289
|
-
|
|
1425
|
+
|
|
1426
|
+
fs.writeFileSync(path.join(foundationsDir, "Colors.stories.tsx"), colorsContent, "utf-8");
|
|
1427
|
+
console.log("[VDS] Wrote " + path.relative(PROJECT_ROOT, path.join(foundationsDir, "Colors.stories.tsx")));
|
|
1428
|
+
}
|
|
1290
1429
|
|
|
1291
1430
|
{
|
|
1292
1431
|
const typo = foundations?.typography || {};
|
|
@@ -1353,24 +1492,35 @@ function writeFoundationsStories(foundations) {
|
|
|
1353
1492
|
" ) : (",
|
|
1354
1493
|
" <div style={{ display: \"flex\", flexDirection: \"column\", gap: 0, marginBottom: 48, border: \"1px solid #e5e7eb\", borderRadius: 10, overflow: \"hidden\" }}>",
|
|
1355
1494
|
" {typeScale.map(({ step, size, px, lineHeight }, i) => {",
|
|
1356
|
-
" const
|
|
1357
|
-
" const
|
|
1358
|
-
" const
|
|
1495
|
+
" const usage = usedTextSizes.find(u => u.token === `text-${step}`);",
|
|
1496
|
+
" const usageCount = usage?.count;",
|
|
1497
|
+
" const topFiles = usage?.topFiles || [];",
|
|
1359
1498
|
" return (",
|
|
1360
|
-
" <div key={step} style={{ display: \"flex\",
|
|
1361
|
-
" <div style={{
|
|
1362
|
-
" <div style={{
|
|
1363
|
-
" <
|
|
1364
|
-
"
|
|
1499
|
+
" <div key={step} style={{ display: \"flex\", flexDirection: \"column\", padding: \"14px 20px\", background: i % 2 === 0 ? \"#fff\" : \"#f9fafb\", borderTop: i === 0 ? \"none\" : \"1px solid #f0f0f0\" }}>",
|
|
1500
|
+
" <div style={{ display: \"flex\", alignItems: \"center\", gap: 20 }}>",
|
|
1501
|
+
" <div style={{ width: 140, flexShrink: 0 }}>",
|
|
1502
|
+
" <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>",
|
|
1503
|
+
" <code style={{ fontSize: 12, fontWeight: 600, color: \"var(--color-primary, #6366f1)\", background: \"color-mix(in srgb, var(--color-primary, #6366f1) 12%, white)\", padding: \"2px 7px\", borderRadius: 4 }}>text-{step}</code>",
|
|
1504
|
+
" {usageCount && <span style={{ fontSize: 11, color: \"#9ca3af\" }}>×{usageCount}</span>}",
|
|
1505
|
+
" </div>",
|
|
1506
|
+
" <div style={{ fontSize: 11, color: \"#9ca3af\", marginTop: 4 }}>",
|
|
1507
|
+
" {size}{px && px !== size ? ` · ${px}` : \"\"}",
|
|
1508
|
+
" {lineHeight ? <span style={{ marginLeft: 8 }}>lh {lineHeight}</span> : null}",
|
|
1509
|
+
" </div>",
|
|
1365
1510
|
" </div>",
|
|
1366
|
-
" <div style={{ fontSize:
|
|
1367
|
-
"
|
|
1368
|
-
" {lineHeight ? <span style={{ marginLeft: 8 }}>lh {lineHeight}</span> : null}",
|
|
1511
|
+
" <div style={{ fontSize: size, fontFamily: sansFamily, color: \"#111\", lineHeight: lineHeight || 1.5, overflow: \"hidden\", whiteSpace: \"nowrap\", textOverflow: \"ellipsis\", flex: 1 }}>",
|
|
1512
|
+
" The quick brown fox jumps over the lazy dog",
|
|
1369
1513
|
" </div>",
|
|
1370
1514
|
" </div>",
|
|
1371
|
-
"
|
|
1372
|
-
"
|
|
1373
|
-
"
|
|
1515
|
+
" {topFiles.length > 0 && (",
|
|
1516
|
+
" <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 5, marginTop: 8, paddingLeft: 0 }}>",
|
|
1517
|
+
" {topFiles.map((name: string) => (",
|
|
1518
|
+
" <span key={name} style={{ fontSize: 10, background: \"#f0f9ff\", color: \"#0369a1\", padding: \"2px 8px\", borderRadius: 3, border: \"1px solid #bae6fd\", fontFamily: \"monospace\" }}>",
|
|
1519
|
+
" {name}",
|
|
1520
|
+
" </span>",
|
|
1521
|
+
" ))}",
|
|
1522
|
+
" </div>",
|
|
1523
|
+
" )}",
|
|
1374
1524
|
" </div>",
|
|
1375
1525
|
" );",
|
|
1376
1526
|
" })}",
|
|
@@ -1607,7 +1757,7 @@ function writeFoundationsStories(foundations) {
|
|
|
1607
1757
|
" {spacingTokens.map(({ token, label, barWidth }) => (",
|
|
1608
1758
|
" <div key={token} style={{ display: \"flex\", alignItems: \"center\", gap: 10, minHeight: 24 }}>",
|
|
1609
1759
|
" <span style={{ width: 40, fontSize: 11, color: \"#9ca3af\", textAlign: \"right\", flexShrink: 0, fontVariantNumeric: \"tabular-nums\" }}>{token}</span>",
|
|
1610
|
-
" <div style={{ width: Math.max(barWidth, 2), height: 16, background: barWidth === 0 ? \"transparent\" : \"
|
|
1760
|
+
" <div style={{ width: Math.max(barWidth, 2), height: 16, background: barWidth === 0 ? \"transparent\" : \"var(--color-primary, #6366f1)\", opacity: barWidth === 0 ? 1 : 0.85, borderRadius: 3, flexShrink: 0, border: barWidth === 0 ? \"1px dashed #555\" : \"none\", boxSizing: \"border-box\" as any }} />",
|
|
1611
1761
|
" <code style={{ fontSize: 11, color: \"#6b7280\" }}>{label}</code>",
|
|
1612
1762
|
" </div>",
|
|
1613
1763
|
" ))}",
|
|
@@ -1744,7 +1894,7 @@ function writeFoundationsStories(foundations) {
|
|
|
1744
1894
|
" <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, maxWidth: 380 }}>",
|
|
1745
1895
|
" {zIndexTokens.map(({ token, value, label }) => (",
|
|
1746
1896
|
" <div key={token} style={{ display: \"flex\", alignItems: \"center\", gap: 12, padding: \"8px 14px\", background: \"#fff\", borderRadius: 8, border: \"1px solid #e5e7eb\" }}>",
|
|
1747
|
-
" <span style={{ width: 36, fontSize: 15, fontWeight: 700, color: \"#6366f1\", textAlign: \"right\", flexShrink: 0, fontVariantNumeric: \"tabular-nums\" }}>{value}</span>",
|
|
1897
|
+
" <span style={{ width: 36, fontSize: 15, fontWeight: 700, color: \"var(--color-primary, #6366f1)\", textAlign: \"right\", flexShrink: 0, fontVariantNumeric: \"tabular-nums\" }}>{value}</span>",
|
|
1748
1898
|
" <div>",
|
|
1749
1899
|
" <span style={{ fontSize: 12, fontWeight: 600 }}>{token}</span>",
|
|
1750
1900
|
" {label ? <span style={{ fontSize: 11, color: \"#9ca3af\", marginLeft: 8 }}>{label}</span> : null}",
|
|
@@ -1756,7 +1906,7 @@ function writeFoundationsStories(foundations) {
|
|
|
1756
1906
|
" <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, maxWidth: 380 }}>",
|
|
1757
1907
|
" {usedZIndex.map(({ token, count }) => (",
|
|
1758
1908
|
" <div key={token} style={{ display: \"flex\", alignItems: \"center\", gap: 12, padding: \"8px 14px\", background: \"#fff\", borderRadius: 8, border: \"1px solid #e5e7eb\" }}>",
|
|
1759
|
-
" <span style={{ width: 36, fontSize: 15, fontWeight: 700, color: \"#6366f1\", textAlign: \"right\", flexShrink: 0 }}>{token.replace('z-','')}</span>",
|
|
1909
|
+
" <span style={{ width: 36, fontSize: 15, fontWeight: 700, color: \"var(--color-primary, #6366f1)\", textAlign: \"right\", flexShrink: 0 }}>{token.replace('z-','')}</span>",
|
|
1760
1910
|
" <div>",
|
|
1761
1911
|
" <span style={{ fontSize: 12, fontWeight: 600 }}>{token}</span>",
|
|
1762
1912
|
" {zSemantics[token] ? <span style={{ fontSize: 11, color: \"#9ca3af\", marginLeft: 8 }}>{zSemantics[token]}</span> : null}",
|
|
@@ -1837,7 +1987,7 @@ function writeFoundationsStories(foundations) {
|
|
|
1837
1987
|
" <div style={{",
|
|
1838
1988
|
" width: isFull ? 64 : 72,",
|
|
1839
1989
|
" height: isFull ? 64 : 56,",
|
|
1840
|
-
" background: \"
|
|
1990
|
+
" background: \"var(--color-primary, #6366f1)\",",
|
|
1841
1991
|
" borderRadius: isFull ? \"50%\" : value === \"0px\" || value === \"0\" ? 0 : value,",
|
|
1842
1992
|
" flexShrink: 0,",
|
|
1843
1993
|
" }} />",
|
|
@@ -1907,7 +2057,7 @@ function writeFoundationsStories(foundations) {
|
|
|
1907
2057
|
" position: \"absolute\",",
|
|
1908
2058
|
" top: 4, left: active ? 172 : 4,",
|
|
1909
2059
|
" width: 44, height: 24,",
|
|
1910
|
-
" background: \"
|
|
2060
|
+
" background: \"var(--color-primary, #6366f1)\",",
|
|
1911
2061
|
" borderRadius: 6,",
|
|
1912
2062
|
" transition: `left ${value} cubic-bezier(0.4,0,0.2,1)`,",
|
|
1913
2063
|
" }} />",
|