vibe-design-system 2.3.0 → 2.4.0
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
|
@@ -452,32 +452,39 @@ function humanizeName(filePath) {
|
|
|
452
452
|
return base.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
|
|
455
|
+
// Priority order: first match in pattern wins
|
|
456
|
+
const COMPONENT_SUGGESTION_KEYWORDS_ORDERED = [
|
|
456
457
|
{ re: /\bcard\b/i, name: "Card" },
|
|
457
458
|
{ re: /\bsection\b/i, name: "Section" },
|
|
458
|
-
{ re: /\bitem\b/i, name: "Item" },
|
|
459
|
-
{ re: /\bbadge\b/i, name: "Badge" },
|
|
460
|
-
{ re: /\brow\b/i, name: "Row" },
|
|
461
459
|
{ re: /\bgrid\b/i, name: "Grid" },
|
|
462
460
|
{ re: /\bhero\b/i, name: "Hero" },
|
|
463
461
|
{ re: /\bcta\b/i, name: "Cta" },
|
|
464
|
-
{ re: /\
|
|
465
|
-
{ re: /\
|
|
466
|
-
{ re: /\
|
|
467
|
-
{ re: /\
|
|
468
|
-
{ re: /\
|
|
469
|
-
{ re: /\
|
|
470
|
-
{ re: /\
|
|
471
|
-
{ re: /\
|
|
462
|
+
{ re: /\bnav\b/i, name: "Nav" },
|
|
463
|
+
{ re: /\bfooter\b/i, name: "Footer" },
|
|
464
|
+
{ re: /\bheader\b/i, name: "Header" },
|
|
465
|
+
{ re: /\bform\b/i, name: "Form" },
|
|
466
|
+
{ re: /\bmodal\b/i, name: "Modal" },
|
|
467
|
+
{ re: /\bbadge\b/i, name: "Badge" },
|
|
468
|
+
{ re: /\bitem\b/i, name: "Item" },
|
|
469
|
+
{ re: /\brow\b/i, name: "Row" },
|
|
470
|
+
{ re: /\blist\b/i, name: "List" },
|
|
472
471
|
];
|
|
473
472
|
|
|
474
|
-
function suggestNameFromPattern(pattern
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
if (re.test(pattern)) parts.push(name);
|
|
473
|
+
function suggestNameFromPattern(pattern) {
|
|
474
|
+
for (const { re, name } of COMPONENT_SUGGESTION_KEYWORDS_ORDERED) {
|
|
475
|
+
if (re.test(pattern)) return name;
|
|
478
476
|
}
|
|
479
|
-
|
|
480
|
-
return "
|
|
477
|
+
const firstToken = pattern.split(/\s+/)[0] || "";
|
|
478
|
+
if (/^max-w|^mx-auto|^container$/i.test(firstToken)) return "Container";
|
|
479
|
+
if (/^flex\b/i.test(firstToken)) return "FlexRow";
|
|
480
|
+
if (/^grid\b/i.test(firstToken)) return "Grid";
|
|
481
|
+
if (firstToken.length > 0) {
|
|
482
|
+
const pascal = firstToken
|
|
483
|
+
.replace(/-([a-z0-9])/gi, (_, c) => c.toUpperCase())
|
|
484
|
+
.replace(/^(.)/, (_, c) => c.toUpperCase());
|
|
485
|
+
return pascal.replace(/[^a-zA-Z0-9]/g, "") || "Block";
|
|
486
|
+
}
|
|
487
|
+
return "Block";
|
|
481
488
|
}
|
|
482
489
|
|
|
483
490
|
/** Scan src/pages/*.tsx for repeated className clusters; return component suggestions. */
|
|
@@ -516,11 +523,9 @@ function extractComponentSuggestions() {
|
|
|
516
523
|
}
|
|
517
524
|
|
|
518
525
|
const suggestions = [];
|
|
519
|
-
let blockIndex = 0;
|
|
520
526
|
for (const [pattern, { count, files, snippet }] of byPattern.entries()) {
|
|
521
527
|
if (count < 2) continue;
|
|
522
|
-
const suggestedName = suggestNameFromPattern(pattern
|
|
523
|
-
if (suggestedName.startsWith("Block")) blockIndex += 1;
|
|
528
|
+
const suggestedName = suggestNameFromPattern(pattern);
|
|
524
529
|
suggestions.push({
|
|
525
530
|
suggestedName,
|
|
526
531
|
occurrences: count,
|
|
@@ -750,8 +755,6 @@ function extractFoundations() {
|
|
|
750
755
|
const radius = {};
|
|
751
756
|
if (cssRadiusVars.radius) radius.base = cssRadiusVars.radius;
|
|
752
757
|
if (Object.keys(borderRadiusScale).length > 0) radius.borderRadius = borderRadiusScale;
|
|
753
|
-
const foundationsColors = { ...colors };
|
|
754
|
-
if (Object.keys(colorsDark).length > 0) foundationsColors._dark = colorsDark;
|
|
755
758
|
|
|
756
759
|
// Fallback: if no typography tokens from config, extract from Google Fonts @import
|
|
757
760
|
if (Object.keys(typography).length === 0 || (!typography.body && !typography.bodyFontFamily)) {
|
|
@@ -777,19 +780,34 @@ function extractFoundations() {
|
|
|
777
780
|
}
|
|
778
781
|
|
|
779
782
|
// ── FALLBACK 1: Arbitrary Tailwind values ──────────────────
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
783
|
+
let allTsxFiles = [];
|
|
784
|
+
try {
|
|
785
|
+
const { globSync } = projectRequire("glob");
|
|
786
|
+
const ROOT = PROJECT_ROOT;
|
|
787
|
+
allTsxFiles = globSync("src/**/*.{tsx,jsx,ts,js}", {
|
|
788
|
+
cwd: ROOT,
|
|
789
|
+
absolute: true,
|
|
790
|
+
ignore: ["**/*.stories.*", "**/node_modules/**"],
|
|
791
|
+
});
|
|
792
|
+
} catch (_) {
|
|
793
|
+
function walkDir(dir, list) {
|
|
794
|
+
if (!fs.existsSync(dir)) return;
|
|
795
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
796
|
+
for (const e of entries) {
|
|
797
|
+
const full = path.join(dir, e.name);
|
|
798
|
+
if (e.isDirectory()) {
|
|
799
|
+
if (e.name !== "node_modules" && e.name !== "dist") walkDir(full, list);
|
|
800
|
+
} else if (/\.(tsx|jsx|ts|js)$/i.test(e.name) && !e.name.includes(".stories.")) {
|
|
801
|
+
list.push(full);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
walkDir(SRC_DIR, allTsxFiles);
|
|
806
|
+
}
|
|
789
807
|
|
|
790
808
|
const ARBITRARY_HEX = /(?:bg|text|border|ring|fill|stroke|from|to|via)-\[#([0-9a-fA-F]{3,8})\]/g;
|
|
791
809
|
const arbitraryColors = new Map();
|
|
792
|
-
for (const file of
|
|
810
|
+
for (const file of allTsxFiles) {
|
|
793
811
|
try {
|
|
794
812
|
const content = fs.readFileSync(file, "utf-8");
|
|
795
813
|
for (const match of content.matchAll(ARBITRARY_HEX)) {
|
|
@@ -813,18 +831,23 @@ function extractFoundations() {
|
|
|
813
831
|
const name = "arbitrary-" + hex.slice(1).toLowerCase();
|
|
814
832
|
colors[name] = { value: hex, source: "arbitrary-tailwind", frequency: count };
|
|
815
833
|
}
|
|
816
|
-
|
|
817
834
|
// ── FALLBACK 2: Google Fonts URL ──────────────────────────
|
|
818
835
|
const GFONTS_PATTERN = /family=([A-Za-z+]+)(?::.*?)?(?:&|$)/g;
|
|
819
|
-
const
|
|
820
|
-
(
|
|
821
|
-
f
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
836
|
+
const fontFileCandidates = [
|
|
837
|
+
...allTsxFiles.filter(
|
|
838
|
+
(f) =>
|
|
839
|
+
f.includes("layout.") ||
|
|
840
|
+
f.includes("_document.") ||
|
|
841
|
+
f.endsWith("index.css") ||
|
|
842
|
+
f.includes("globals.css")
|
|
843
|
+
),
|
|
844
|
+
path.join(PROJECT_ROOT, "index.html"),
|
|
845
|
+
path.join(PROJECT_ROOT, "src", "index.css"),
|
|
846
|
+
path.join(PROJECT_ROOT, "src", "globals.css"),
|
|
847
|
+
path.join(PROJECT_ROOT, "src", "App.css"),
|
|
848
|
+
path.join(PROJECT_ROOT, "app", "globals.css"),
|
|
849
|
+
].filter((p) => fs.existsSync(p));
|
|
850
|
+
for (const file of fontFileCandidates) {
|
|
828
851
|
try {
|
|
829
852
|
const content = fs.readFileSync(file, "utf-8");
|
|
830
853
|
if (!content.includes("fonts.googleapis.com")) continue;
|
|
@@ -839,6 +862,9 @@ function extractFoundations() {
|
|
|
839
862
|
} catch (_) {}
|
|
840
863
|
}
|
|
841
864
|
|
|
865
|
+
const foundationsColors = { ...colors };
|
|
866
|
+
if (Object.keys(colorsDark).length > 0) foundationsColors._dark = colorsDark;
|
|
867
|
+
|
|
842
868
|
const twTheme = getTailwindTheme();
|
|
843
869
|
const normalizeThemeObj = (obj) => {
|
|
844
870
|
if (!obj || typeof obj !== "object") return {};
|
|
@@ -831,7 +831,7 @@ function writeChangelogStory(changelog) {
|
|
|
831
831
|
" render: () => (",
|
|
832
832
|
" <div style={{ fontFamily: \"monospace\", padding: 24 }}>",
|
|
833
833
|
" <h2>CHANGELOG</h2>",
|
|
834
|
-
" {changelog.length === 0 ? <p>No changes recorded yet
|
|
834
|
+
" {changelog.length === 0 ? <p>No changes recorded yet.</p> : changelog.map((entry) => (",
|
|
835
835
|
" <div key={entry.version}>",
|
|
836
836
|
" <h3>v{entry.version} — {entry.date}</h3>",
|
|
837
837
|
" {entry.changes.map((c, i) => <div key={i}>{c.type}: {c.name ?? c.key ?? \"\"}</div>)}",
|