@kbach/react 0.5.26 → 0.5.27
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/dist/vite-plugin.js +89 -37
- package/dist/vite-plugin.mjs +89 -37
- package/package.json +1 -1
- package/dist/index.d.mts +0 -304
- package/dist/index.d.ts +0 -304
- package/dist/jsx-dev-runtime.d.mts +0 -19
- package/dist/jsx-dev-runtime.d.ts +0 -19
- package/dist/jsx-runtime.d.mts +0 -17
- package/dist/jsx-runtime.d.ts +0 -17
- package/dist/types-CV5vXnSH.d.mts +0 -70
- package/dist/types-CV5vXnSH.d.ts +0 -70
- package/dist/vite-plugin-client.d.mts +0 -8
- package/dist/vite-plugin-client.d.ts +0 -8
- package/dist/vite-plugin.d.mts +0 -22
- package/dist/vite-plugin.d.ts +0 -22
package/dist/vite-plugin.js
CHANGED
|
@@ -3352,14 +3352,89 @@ var VIRTUAL_ID = "virtual:kbach/styles.css";
|
|
|
3352
3352
|
var RESOLVED_ID = "\0virtual:kbach/styles.css";
|
|
3353
3353
|
var KBACH_START = "/* kbach:start */";
|
|
3354
3354
|
var KBACH_END = "/* kbach:end */";
|
|
3355
|
+
var GROUPS = [
|
|
3356
|
+
["Layout", /^(flex(?!-\d|-auto|-none|-initial|-1)|flex-(col|row|wrap|nowrap)|grid|block|inline|hidden|table|contents|overflow|items-|justify-|self-|place-|grow|shrink|float-|clear-|static|fixed|absolute|relative|sticky|z-|top-|right-|bottom-|left-|inset|aspect)/],
|
|
3357
|
+
["Sizing", /^(w-|h-|min-w-|max-w-|min-h-|max-h-|size-|flex-1|flex-auto|flex-none|flex-initial|basis-)/],
|
|
3358
|
+
["Spacing", /^(p-|px-|py-|pt-|pb-|pl-|pr-|m-|mx-|my-|mt-|mb-|ml-|mr-|gap-|space-)/],
|
|
3359
|
+
["Typography", /^(text-(xs|sm|base|lg|\dxl)|font-|leading-|tracking-|uppercase|lowercase|capitalize|normal-case|italic|not-italic|underline|overline|line-through|no-underline|truncate|whitespace-|text-(left|center|right|justify|start|end)|list-|align-|line-clamp)/],
|
|
3360
|
+
["Colors", /^(bg-|text-|color-|fill-|stroke-|caret-|accent-)/],
|
|
3361
|
+
["Borders", /^(border|rounded|ring|outline|divide)/],
|
|
3362
|
+
["Effects", /^(shadow|opacity|blur|brightness|contrast|grayscale|transition|duration|ease|delay|animate|scale|rotate|translate|transform|cursor|pointer|select-)/]
|
|
3363
|
+
];
|
|
3364
|
+
var GROUP_ORDER = ["Layout", "Sizing", "Spacing", "Typography", "Colors", "Borders", "Effects", "Utilities", "Dark Mode", "Responsive"];
|
|
3365
|
+
function classifyToken(token) {
|
|
3366
|
+
if (/^dark:/.test(token)) return "Dark Mode";
|
|
3367
|
+
if (/^(sm|md|lg|xl|2xl):/.test(token)) return "Responsive";
|
|
3368
|
+
const base = token.replace(/^(hover|focus|active|group-hover|peer-hover):/, "");
|
|
3369
|
+
for (const [label, re] of GROUPS) {
|
|
3370
|
+
if (re.test(base)) return label;
|
|
3371
|
+
}
|
|
3372
|
+
return "Utilities";
|
|
3373
|
+
}
|
|
3374
|
+
function buildColorVarMap(theme, usedCSS) {
|
|
3375
|
+
const map = /* @__PURE__ */ new Map();
|
|
3376
|
+
for (const [name, shades] of Object.entries(theme.colors ?? {})) {
|
|
3377
|
+
const entries = typeof shades === "string" ? [[name, shades]] : Object.entries(shades).map(([s, v]) => [`${name}-${s}`, v]);
|
|
3378
|
+
for (const [fullName, val] of entries) {
|
|
3379
|
+
if (typeof val === "string" && /^#[0-9a-fA-F]{3,8}$/.test(val) && usedCSS.includes(val)) {
|
|
3380
|
+
map.set(val, `--color-${fullName}`);
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
return map;
|
|
3385
|
+
}
|
|
3386
|
+
function formatKbachCSS(tokenCSS, theme) {
|
|
3387
|
+
const allRaw = [...tokenCSS.values()].filter(Boolean).join("\n");
|
|
3388
|
+
const colorVars = buildColorVarMap(theme, allRaw);
|
|
3389
|
+
function applyVars(css) {
|
|
3390
|
+
for (const [val, varName] of colorVars) {
|
|
3391
|
+
css = css.replaceAll(val, `var(${varName})`);
|
|
3392
|
+
}
|
|
3393
|
+
return css;
|
|
3394
|
+
}
|
|
3395
|
+
const groups = new Map(GROUP_ORDER.map((g) => [g, []]));
|
|
3396
|
+
for (const [token, css] of tokenCSS) {
|
|
3397
|
+
if (!css) continue;
|
|
3398
|
+
const label = classifyToken(token);
|
|
3399
|
+
if (!groups.has(label)) groups.set(label, []);
|
|
3400
|
+
groups.get(label).push(applyVars(css));
|
|
3401
|
+
}
|
|
3402
|
+
const out = ["/* Generated by Kbach \u2014 do not edit */"];
|
|
3403
|
+
if (colorVars.size > 0) {
|
|
3404
|
+
out.push("\n:root {");
|
|
3405
|
+
for (const [val, varName] of colorVars) {
|
|
3406
|
+
out.push(` ${varName}: ${val};`);
|
|
3407
|
+
}
|
|
3408
|
+
out.push("}");
|
|
3409
|
+
}
|
|
3410
|
+
const globalCSS = buildThemeGlobal(theme);
|
|
3411
|
+
if (globalCSS) {
|
|
3412
|
+
out.push(`
|
|
3413
|
+
/* Global */
|
|
3414
|
+
${globalCSS}`);
|
|
3415
|
+
}
|
|
3416
|
+
for (const label of GROUP_ORDER) {
|
|
3417
|
+
const items = groups.get(label) ?? [];
|
|
3418
|
+
if (!items.length) continue;
|
|
3419
|
+
out.push(`
|
|
3420
|
+
/* ${label} */`);
|
|
3421
|
+
out.push(items.join("\n"));
|
|
3422
|
+
}
|
|
3423
|
+
return out.join("\n");
|
|
3424
|
+
}
|
|
3425
|
+
function buildThemeGlobal(theme) {
|
|
3426
|
+
const ff = theme.fontFamily;
|
|
3427
|
+
if (!ff?.sans || ff.sans === "System") return "";
|
|
3428
|
+
const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
|
|
3429
|
+
return `body { font-family: ${family}; }`;
|
|
3430
|
+
}
|
|
3355
3431
|
function findMainCSSFile(root) {
|
|
3356
|
-
const
|
|
3432
|
+
for (const c of [
|
|
3357
3433
|
(0, import_path.join)(root, "app", "app.css"),
|
|
3358
3434
|
(0, import_path.join)(root, "src", "index.css"),
|
|
3359
3435
|
(0, import_path.join)(root, "src", "app.css"),
|
|
3360
3436
|
(0, import_path.join)(root, "app", "index.css")
|
|
3361
|
-
]
|
|
3362
|
-
for (const c of candidates) {
|
|
3437
|
+
]) {
|
|
3363
3438
|
if ((0, import_fs.existsSync)(c)) return c;
|
|
3364
3439
|
}
|
|
3365
3440
|
return null;
|
|
@@ -3393,11 +3468,8 @@ function scanDir(dir, onFile) {
|
|
|
3393
3468
|
const full = (0, import_path.join)(dir, entry);
|
|
3394
3469
|
try {
|
|
3395
3470
|
const st = (0, import_fs.statSync)(full);
|
|
3396
|
-
if (st.isDirectory())
|
|
3397
|
-
|
|
3398
|
-
} else if (/\.(tsx?|jsx?)$/.test(entry)) {
|
|
3399
|
-
onFile((0, import_fs.readFileSync)(full, "utf-8"));
|
|
3400
|
-
}
|
|
3471
|
+
if (st.isDirectory()) scanDir(full, onFile);
|
|
3472
|
+
else if (/\.(tsx?|jsx?)$/.test(entry)) onFile((0, import_fs.readFileSync)(full, "utf-8"));
|
|
3401
3473
|
} catch {
|
|
3402
3474
|
}
|
|
3403
3475
|
}
|
|
@@ -3414,12 +3486,6 @@ function extractClassStrings(code) {
|
|
|
3414
3486
|
}
|
|
3415
3487
|
return found;
|
|
3416
3488
|
}
|
|
3417
|
-
function buildGlobalCSS(theme) {
|
|
3418
|
-
const ff = theme.fontFamily;
|
|
3419
|
-
if (!ff?.sans || ff.sans === "System") return "";
|
|
3420
|
-
const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
|
|
3421
|
-
return `body { font-family: ${family}; }`;
|
|
3422
|
-
}
|
|
3423
3489
|
function kbach(userConfig) {
|
|
3424
3490
|
const cfg = buildConfig(userConfig ?? {});
|
|
3425
3491
|
const screens = toNumericScreens(cfg.theme.screens ?? {});
|
|
@@ -3433,21 +3499,13 @@ function kbach(userConfig) {
|
|
|
3433
3499
|
}
|
|
3434
3500
|
function extractFromCode(code) {
|
|
3435
3501
|
let added = false;
|
|
3436
|
-
for (const cls of extractClassStrings(code))
|
|
3437
|
-
for (const token of cls.split(/\s+/).filter(Boolean))
|
|
3502
|
+
for (const cls of extractClassStrings(code))
|
|
3503
|
+
for (const token of cls.split(/\s+/).filter(Boolean))
|
|
3438
3504
|
if (processToken(token)) added = true;
|
|
3439
|
-
}
|
|
3440
|
-
}
|
|
3441
3505
|
return added;
|
|
3442
3506
|
}
|
|
3443
|
-
function
|
|
3444
|
-
|
|
3445
|
-
const global = buildGlobalCSS(cfg.theme);
|
|
3446
|
-
if (global) parts.push(global);
|
|
3447
|
-
for (const css of tokenCSS.values()) {
|
|
3448
|
-
if (css) parts.push(css);
|
|
3449
|
-
}
|
|
3450
|
-
return parts.join("\n");
|
|
3507
|
+
function getFormattedCSS() {
|
|
3508
|
+
return formatKbachCSS(tokenCSS, cfg.theme);
|
|
3451
3509
|
}
|
|
3452
3510
|
return {
|
|
3453
3511
|
name: "kbach",
|
|
@@ -3456,33 +3514,27 @@ function kbach(userConfig) {
|
|
|
3456
3514
|
root = resolved.root;
|
|
3457
3515
|
},
|
|
3458
3516
|
buildStart() {
|
|
3459
|
-
for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
|
|
3517
|
+
for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
|
|
3460
3518
|
scanDir((0, import_path.join)(root, dir), (code) => extractFromCode(code));
|
|
3461
|
-
}
|
|
3462
3519
|
mainCSSFile = findMainCSSFile(root);
|
|
3463
|
-
if (mainCSSFile) writeKbachToFile(mainCSSFile,
|
|
3520
|
+
if (mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
|
|
3464
3521
|
},
|
|
3465
3522
|
transform(code, id) {
|
|
3466
3523
|
const cleanId = id.split("?")[0];
|
|
3467
|
-
if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
|
|
3524
|
+
if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
|
|
3468
3525
|
extractFromCode(code);
|
|
3469
|
-
}
|
|
3470
3526
|
},
|
|
3471
|
-
// ── Virtual module (opt-in explicit import) ───────────────────────────────
|
|
3472
3527
|
resolveId(id) {
|
|
3473
3528
|
if (id === VIRTUAL_ID) return RESOLVED_ID;
|
|
3474
3529
|
},
|
|
3475
3530
|
load(id) {
|
|
3476
|
-
if (id === RESOLVED_ID) return
|
|
3531
|
+
if (id === RESOLVED_ID) return getFormattedCSS();
|
|
3477
3532
|
},
|
|
3478
|
-
// ── HMR: write updated CSS to file when new classes are found ────────────
|
|
3479
|
-
// Vite's own file watcher detects the change and hot-reloads the CSS —
|
|
3480
|
-
// no manual invalidation needed.
|
|
3481
3533
|
handleHotUpdate({ file }) {
|
|
3482
3534
|
if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
|
|
3483
3535
|
try {
|
|
3484
3536
|
const added = extractFromCode((0, import_fs.readFileSync)(file, "utf-8"));
|
|
3485
|
-
if (added && mainCSSFile) writeKbachToFile(mainCSSFile,
|
|
3537
|
+
if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
|
|
3486
3538
|
} catch {
|
|
3487
3539
|
}
|
|
3488
3540
|
}
|
package/dist/vite-plugin.mjs
CHANGED
|
@@ -10,14 +10,89 @@ var VIRTUAL_ID = "virtual:kbach/styles.css";
|
|
|
10
10
|
var RESOLVED_ID = "\0virtual:kbach/styles.css";
|
|
11
11
|
var KBACH_START = "/* kbach:start */";
|
|
12
12
|
var KBACH_END = "/* kbach:end */";
|
|
13
|
+
var GROUPS = [
|
|
14
|
+
["Layout", /^(flex(?!-\d|-auto|-none|-initial|-1)|flex-(col|row|wrap|nowrap)|grid|block|inline|hidden|table|contents|overflow|items-|justify-|self-|place-|grow|shrink|float-|clear-|static|fixed|absolute|relative|sticky|z-|top-|right-|bottom-|left-|inset|aspect)/],
|
|
15
|
+
["Sizing", /^(w-|h-|min-w-|max-w-|min-h-|max-h-|size-|flex-1|flex-auto|flex-none|flex-initial|basis-)/],
|
|
16
|
+
["Spacing", /^(p-|px-|py-|pt-|pb-|pl-|pr-|m-|mx-|my-|mt-|mb-|ml-|mr-|gap-|space-)/],
|
|
17
|
+
["Typography", /^(text-(xs|sm|base|lg|\dxl)|font-|leading-|tracking-|uppercase|lowercase|capitalize|normal-case|italic|not-italic|underline|overline|line-through|no-underline|truncate|whitespace-|text-(left|center|right|justify|start|end)|list-|align-|line-clamp)/],
|
|
18
|
+
["Colors", /^(bg-|text-|color-|fill-|stroke-|caret-|accent-)/],
|
|
19
|
+
["Borders", /^(border|rounded|ring|outline|divide)/],
|
|
20
|
+
["Effects", /^(shadow|opacity|blur|brightness|contrast|grayscale|transition|duration|ease|delay|animate|scale|rotate|translate|transform|cursor|pointer|select-)/]
|
|
21
|
+
];
|
|
22
|
+
var GROUP_ORDER = ["Layout", "Sizing", "Spacing", "Typography", "Colors", "Borders", "Effects", "Utilities", "Dark Mode", "Responsive"];
|
|
23
|
+
function classifyToken(token) {
|
|
24
|
+
if (/^dark:/.test(token)) return "Dark Mode";
|
|
25
|
+
if (/^(sm|md|lg|xl|2xl):/.test(token)) return "Responsive";
|
|
26
|
+
const base = token.replace(/^(hover|focus|active|group-hover|peer-hover):/, "");
|
|
27
|
+
for (const [label, re] of GROUPS) {
|
|
28
|
+
if (re.test(base)) return label;
|
|
29
|
+
}
|
|
30
|
+
return "Utilities";
|
|
31
|
+
}
|
|
32
|
+
function buildColorVarMap(theme, usedCSS) {
|
|
33
|
+
const map = /* @__PURE__ */ new Map();
|
|
34
|
+
for (const [name, shades] of Object.entries(theme.colors ?? {})) {
|
|
35
|
+
const entries = typeof shades === "string" ? [[name, shades]] : Object.entries(shades).map(([s, v]) => [`${name}-${s}`, v]);
|
|
36
|
+
for (const [fullName, val] of entries) {
|
|
37
|
+
if (typeof val === "string" && /^#[0-9a-fA-F]{3,8}$/.test(val) && usedCSS.includes(val)) {
|
|
38
|
+
map.set(val, `--color-${fullName}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return map;
|
|
43
|
+
}
|
|
44
|
+
function formatKbachCSS(tokenCSS, theme) {
|
|
45
|
+
const allRaw = [...tokenCSS.values()].filter(Boolean).join("\n");
|
|
46
|
+
const colorVars = buildColorVarMap(theme, allRaw);
|
|
47
|
+
function applyVars(css) {
|
|
48
|
+
for (const [val, varName] of colorVars) {
|
|
49
|
+
css = css.replaceAll(val, `var(${varName})`);
|
|
50
|
+
}
|
|
51
|
+
return css;
|
|
52
|
+
}
|
|
53
|
+
const groups = new Map(GROUP_ORDER.map((g) => [g, []]));
|
|
54
|
+
for (const [token, css] of tokenCSS) {
|
|
55
|
+
if (!css) continue;
|
|
56
|
+
const label = classifyToken(token);
|
|
57
|
+
if (!groups.has(label)) groups.set(label, []);
|
|
58
|
+
groups.get(label).push(applyVars(css));
|
|
59
|
+
}
|
|
60
|
+
const out = ["/* Generated by Kbach \u2014 do not edit */"];
|
|
61
|
+
if (colorVars.size > 0) {
|
|
62
|
+
out.push("\n:root {");
|
|
63
|
+
for (const [val, varName] of colorVars) {
|
|
64
|
+
out.push(` ${varName}: ${val};`);
|
|
65
|
+
}
|
|
66
|
+
out.push("}");
|
|
67
|
+
}
|
|
68
|
+
const globalCSS = buildThemeGlobal(theme);
|
|
69
|
+
if (globalCSS) {
|
|
70
|
+
out.push(`
|
|
71
|
+
/* Global */
|
|
72
|
+
${globalCSS}`);
|
|
73
|
+
}
|
|
74
|
+
for (const label of GROUP_ORDER) {
|
|
75
|
+
const items = groups.get(label) ?? [];
|
|
76
|
+
if (!items.length) continue;
|
|
77
|
+
out.push(`
|
|
78
|
+
/* ${label} */`);
|
|
79
|
+
out.push(items.join("\n"));
|
|
80
|
+
}
|
|
81
|
+
return out.join("\n");
|
|
82
|
+
}
|
|
83
|
+
function buildThemeGlobal(theme) {
|
|
84
|
+
const ff = theme.fontFamily;
|
|
85
|
+
if (!ff?.sans || ff.sans === "System") return "";
|
|
86
|
+
const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
|
|
87
|
+
return `body { font-family: ${family}; }`;
|
|
88
|
+
}
|
|
13
89
|
function findMainCSSFile(root) {
|
|
14
|
-
const
|
|
90
|
+
for (const c of [
|
|
15
91
|
join(root, "app", "app.css"),
|
|
16
92
|
join(root, "src", "index.css"),
|
|
17
93
|
join(root, "src", "app.css"),
|
|
18
94
|
join(root, "app", "index.css")
|
|
19
|
-
]
|
|
20
|
-
for (const c of candidates) {
|
|
95
|
+
]) {
|
|
21
96
|
if (existsSync(c)) return c;
|
|
22
97
|
}
|
|
23
98
|
return null;
|
|
@@ -51,11 +126,8 @@ function scanDir(dir, onFile) {
|
|
|
51
126
|
const full = join(dir, entry);
|
|
52
127
|
try {
|
|
53
128
|
const st = statSync(full);
|
|
54
|
-
if (st.isDirectory())
|
|
55
|
-
|
|
56
|
-
} else if (/\.(tsx?|jsx?)$/.test(entry)) {
|
|
57
|
-
onFile(readFileSync(full, "utf-8"));
|
|
58
|
-
}
|
|
129
|
+
if (st.isDirectory()) scanDir(full, onFile);
|
|
130
|
+
else if (/\.(tsx?|jsx?)$/.test(entry)) onFile(readFileSync(full, "utf-8"));
|
|
59
131
|
} catch {
|
|
60
132
|
}
|
|
61
133
|
}
|
|
@@ -72,12 +144,6 @@ function extractClassStrings(code) {
|
|
|
72
144
|
}
|
|
73
145
|
return found;
|
|
74
146
|
}
|
|
75
|
-
function buildGlobalCSS(theme) {
|
|
76
|
-
const ff = theme.fontFamily;
|
|
77
|
-
if (!ff?.sans || ff.sans === "System") return "";
|
|
78
|
-
const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
|
|
79
|
-
return `body { font-family: ${family}; }`;
|
|
80
|
-
}
|
|
81
147
|
function kbach(userConfig) {
|
|
82
148
|
const cfg = buildConfig(userConfig ?? {});
|
|
83
149
|
const screens = toNumericScreens(cfg.theme.screens ?? {});
|
|
@@ -91,21 +157,13 @@ function kbach(userConfig) {
|
|
|
91
157
|
}
|
|
92
158
|
function extractFromCode(code) {
|
|
93
159
|
let added = false;
|
|
94
|
-
for (const cls of extractClassStrings(code))
|
|
95
|
-
for (const token of cls.split(/\s+/).filter(Boolean))
|
|
160
|
+
for (const cls of extractClassStrings(code))
|
|
161
|
+
for (const token of cls.split(/\s+/).filter(Boolean))
|
|
96
162
|
if (processToken(token)) added = true;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
163
|
return added;
|
|
100
164
|
}
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
const global = buildGlobalCSS(cfg.theme);
|
|
104
|
-
if (global) parts.push(global);
|
|
105
|
-
for (const css of tokenCSS.values()) {
|
|
106
|
-
if (css) parts.push(css);
|
|
107
|
-
}
|
|
108
|
-
return parts.join("\n");
|
|
165
|
+
function getFormattedCSS() {
|
|
166
|
+
return formatKbachCSS(tokenCSS, cfg.theme);
|
|
109
167
|
}
|
|
110
168
|
return {
|
|
111
169
|
name: "kbach",
|
|
@@ -114,33 +172,27 @@ function kbach(userConfig) {
|
|
|
114
172
|
root = resolved.root;
|
|
115
173
|
},
|
|
116
174
|
buildStart() {
|
|
117
|
-
for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
|
|
175
|
+
for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
|
|
118
176
|
scanDir(join(root, dir), (code) => extractFromCode(code));
|
|
119
|
-
}
|
|
120
177
|
mainCSSFile = findMainCSSFile(root);
|
|
121
|
-
if (mainCSSFile) writeKbachToFile(mainCSSFile,
|
|
178
|
+
if (mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
|
|
122
179
|
},
|
|
123
180
|
transform(code, id) {
|
|
124
181
|
const cleanId = id.split("?")[0];
|
|
125
|
-
if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
|
|
182
|
+
if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
|
|
126
183
|
extractFromCode(code);
|
|
127
|
-
}
|
|
128
184
|
},
|
|
129
|
-
// ── Virtual module (opt-in explicit import) ───────────────────────────────
|
|
130
185
|
resolveId(id) {
|
|
131
186
|
if (id === VIRTUAL_ID) return RESOLVED_ID;
|
|
132
187
|
},
|
|
133
188
|
load(id) {
|
|
134
|
-
if (id === RESOLVED_ID) return
|
|
189
|
+
if (id === RESOLVED_ID) return getFormattedCSS();
|
|
135
190
|
},
|
|
136
|
-
// ── HMR: write updated CSS to file when new classes are found ────────────
|
|
137
|
-
// Vite's own file watcher detects the change and hot-reloads the CSS —
|
|
138
|
-
// no manual invalidation needed.
|
|
139
191
|
handleHotUpdate({ file }) {
|
|
140
192
|
if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
|
|
141
193
|
try {
|
|
142
194
|
const added = extractFromCode(readFileSync(file, "utf-8"));
|
|
143
|
-
if (added && mainCSSFile) writeKbachToFile(mainCSSFile,
|
|
195
|
+
if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
|
|
144
196
|
} catch {
|
|
145
197
|
}
|
|
146
198
|
}
|
package/package.json
CHANGED
package/dist/index.d.mts
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import React__default, { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
|
|
3
|
-
import { T as ThemeColors, a as ThemeConfig, P as ParsedClass, R as ResolvedStyle, S as StyleValue, F as FrameworkConfig, b as ResolvedConfig, c as ThemeMode } from './types-CV5vXnSH.mjs';
|
|
4
|
-
export { d as PluginAPI } from './types-CV5vXnSH.mjs';
|
|
5
|
-
|
|
6
|
-
declare const defaultColors: ThemeColors;
|
|
7
|
-
declare const defaultTheme: ThemeConfig;
|
|
8
|
-
|
|
9
|
-
declare function parseClass(className: string): ParsedClass | null;
|
|
10
|
-
/** Parse a space-separated class string into individual ParsedClass objects. */
|
|
11
|
-
declare function parseClasses(classString: string): ParsedClass[];
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Resolve a class string to a ResolvedStyle object.
|
|
15
|
-
*
|
|
16
|
-
* The result groups styles by modifier key:
|
|
17
|
-
* - 'base' → always-applied styles
|
|
18
|
-
* - 'dark' → dark-mode styles
|
|
19
|
-
* - 'hover' → hover styles
|
|
20
|
-
* - 'dark:hover' → combined dark + hover
|
|
21
|
-
* - etc.
|
|
22
|
-
*
|
|
23
|
-
* Results are cached — repeated calls with the same string are O(1).
|
|
24
|
-
*/
|
|
25
|
-
declare function resolve(classString: string, theme: ThemeConfig, darkMode?: 'attribute' | 'class' | 'media'): ResolvedStyle;
|
|
26
|
-
/**
|
|
27
|
-
* Flatten a ResolvedStyle into a single StyleValue for the given runtime state.
|
|
28
|
-
* Used by useStyles() and styled().
|
|
29
|
-
*
|
|
30
|
-
* @param resolved Output of resolve()
|
|
31
|
-
* @param isDark Whether dark mode is currently active
|
|
32
|
-
* @param state Interaction state flags
|
|
33
|
-
* @param breakpoints Active breakpoint names (sm, md, lg, xl, 2xl). On web,
|
|
34
|
-
* pass an empty Set — CSS @media rules handle responsive.
|
|
35
|
-
*/
|
|
36
|
-
declare function flatten(resolved: ResolvedStyle, isDark: boolean, state?: {
|
|
37
|
-
hover?: boolean;
|
|
38
|
-
focus?: boolean;
|
|
39
|
-
pressed?: boolean;
|
|
40
|
-
active?: boolean;
|
|
41
|
-
disabled?: boolean;
|
|
42
|
-
checked?: boolean;
|
|
43
|
-
visited?: boolean;
|
|
44
|
-
placeholder?: boolean;
|
|
45
|
-
}, breakpoints?: Set<string>): StyleValue;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Load, merge, and cache the resolved config.
|
|
49
|
-
* Call resetConfig() to force a reload (e.g. in tests or after live update).
|
|
50
|
-
*/
|
|
51
|
-
declare function getConfig(): ResolvedConfig;
|
|
52
|
-
declare function buildConfig(userConfig: FrameworkConfig): ResolvedConfig;
|
|
53
|
-
declare function updateConfig(userConfig: FrameworkConfig): void;
|
|
54
|
-
/**
|
|
55
|
-
* Like updateConfig, but only calls it when the config object reference has
|
|
56
|
-
* actually changed. Used by the Babel-injected IIFE so that:
|
|
57
|
-
* - multiple files with kbach classes don't re-run the update on every load
|
|
58
|
-
* - Fast Refresh DOES re-run when kbach.config.js changes (new module → new object)
|
|
59
|
-
*/
|
|
60
|
-
declare function initConfig(userConfig: FrameworkConfig): void;
|
|
61
|
-
|
|
62
|
-
interface ThemeContextValue {
|
|
63
|
-
/** The user-selected mode ('light' | 'dark' | 'system') */
|
|
64
|
-
mode: ThemeMode;
|
|
65
|
-
/** The effective resolved mode (never 'system') */
|
|
66
|
-
resolvedMode: 'light' | 'dark';
|
|
67
|
-
/** Convenience boolean */
|
|
68
|
-
isDark: boolean;
|
|
69
|
-
/** Change the theme mode programmatically */
|
|
70
|
-
setMode: (mode: ThemeMode) => void;
|
|
71
|
-
/** Toggle between light and dark (ignores system) */
|
|
72
|
-
toggle: () => void;
|
|
73
|
-
/** The fully resolved framework config (theme values, darkMode strategy, etc.) */
|
|
74
|
-
config: ResolvedConfig;
|
|
75
|
-
}
|
|
76
|
-
declare const ThemeContext: React.Context<ThemeContextValue | null>;
|
|
77
|
-
declare function useTheme(): ThemeContextValue;
|
|
78
|
-
declare function useIsDark(): boolean;
|
|
79
|
-
|
|
80
|
-
interface ColorScale {
|
|
81
|
-
/** `colors.blue[6]` → raw hex string */
|
|
82
|
-
readonly [shade: number]: string;
|
|
83
|
-
/** `colors.blue['6/50']` → shade 6 at 50% opacity */
|
|
84
|
-
readonly [key: string]: string;
|
|
85
|
-
}
|
|
86
|
-
interface ColorsAPI {
|
|
87
|
-
/**
|
|
88
|
-
* Pass any CSS color through, optionally applying an opacity (0–100).
|
|
89
|
-
* - `colors.alpha('#3b82f6', 50)` → `'rgba(59,130,246,0.5)'`
|
|
90
|
-
* - `colors.alpha('rgb(0,0,0)', 10)` → `'rgba(0,0,0,0.1)'`
|
|
91
|
-
* - `colors.alpha('rgba(0,0,0,0.5)')` → `'rgba(0,0,0,0.5)'` (passthrough)
|
|
92
|
-
*/
|
|
93
|
-
readonly alpha: (color: string, opacity?: number) => string;
|
|
94
|
-
[color: string]: any;
|
|
95
|
-
}
|
|
96
|
-
declare function wrapColors(rawColors: ThemeColors): ColorsAPI;
|
|
97
|
-
declare function useColors(): ColorsAPI;
|
|
98
|
-
|
|
99
|
-
interface ThemeProviderProps {
|
|
100
|
-
children: ReactNode;
|
|
101
|
-
/** Initial mode. Falls back to persisted value, then 'system'. */
|
|
102
|
-
defaultMode?: ThemeMode;
|
|
103
|
-
/**
|
|
104
|
-
* System color scheme for native `defaultMode="system"`.
|
|
105
|
-
*
|
|
106
|
-
* Pass the value of `useColorScheme()` from `react-native`. When importing
|
|
107
|
-
* `ThemeProvider` from `@kbach/native` this is handled automatically.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```tsx
|
|
111
|
-
* import { useColorScheme } from 'react-native';
|
|
112
|
-
* const colorScheme = useColorScheme();
|
|
113
|
-
* <ThemeProvider defaultMode="system" colorScheme={colorScheme}>…</ThemeProvider>
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
colorScheme?: 'light' | 'dark' | null;
|
|
117
|
-
/**
|
|
118
|
-
* Current window/screen width in pixels for responsive breakpoints.
|
|
119
|
-
* On web this is read from `window.innerWidth` automatically.
|
|
120
|
-
* When importing `ThemeProvider` from `@kbach/native` this is provided
|
|
121
|
-
* automatically from `useWindowDimensions()`.
|
|
122
|
-
*/
|
|
123
|
-
windowWidth?: number;
|
|
124
|
-
/** Override the config (useful for per-tree config). Defaults to global getConfig(). */
|
|
125
|
-
config?: FrameworkConfig;
|
|
126
|
-
/** Disable persistence to localStorage */
|
|
127
|
-
disablePersistence?: boolean;
|
|
128
|
-
}
|
|
129
|
-
declare function ThemeProvider({ children, defaultMode, colorScheme, windowWidth: windowWidthProp, config: configOverride, disablePersistence, }: ThemeProviderProps): React__default.JSX.Element;
|
|
130
|
-
|
|
131
|
-
type ToggleVariant = 'button' | 'switch' | 'icon-button';
|
|
132
|
-
interface ThemeToggleProps {
|
|
133
|
-
/** Visual variant. Default: 'button' */
|
|
134
|
-
variant?: ToggleVariant;
|
|
135
|
-
/** Override label text (button variant) */
|
|
136
|
-
label?: string;
|
|
137
|
-
/** Custom light-mode label */
|
|
138
|
-
lightLabel?: string;
|
|
139
|
-
/** Custom dark-mode label */
|
|
140
|
-
darkLabel?: string;
|
|
141
|
-
/** Show system mode option */
|
|
142
|
-
includeSystem?: boolean;
|
|
143
|
-
/** Custom styles applied to the root container */
|
|
144
|
-
style?: object;
|
|
145
|
-
/** Custom styles for the label text */
|
|
146
|
-
labelStyle?: object;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Drop-in theme toggle. Works on web and React Native.
|
|
150
|
-
*
|
|
151
|
-
* ```tsx
|
|
152
|
-
* <ThemeToggle />
|
|
153
|
-
* <ThemeToggle variant="switch" />
|
|
154
|
-
* <ThemeToggle variant="icon-button" lightLabel="☀️" darkLabel="🌙" />
|
|
155
|
-
* ```
|
|
156
|
-
*/
|
|
157
|
-
declare function ThemeToggle({ variant, label, lightLabel, darkLabel, includeSystem, style, labelStyle, }: ThemeToggleProps): React__default.JSX.Element;
|
|
158
|
-
|
|
159
|
-
interface StyledProps {
|
|
160
|
-
/** Additional utility classes applied on top of the base classes */
|
|
161
|
-
kb?: string;
|
|
162
|
-
/** Merged with resolved kb styles; applied last */
|
|
163
|
-
style?: StyleValue | StyleValue[];
|
|
164
|
-
}
|
|
165
|
-
type OmittedKeys = 'style';
|
|
166
|
-
/**
|
|
167
|
-
* Create a styled component from any React / React Native component.
|
|
168
|
-
*
|
|
169
|
-
* ```tsx
|
|
170
|
-
* const Card = styled(View, 'bg-white dark:bg-gray-800 rounded-xl p-4 shadow-md');
|
|
171
|
-
* const Button = styled(TouchableOpacity, 'bg-blue-500 pressed:bg-blue-700 dark:bg-blue-600 rounded-lg p-3');
|
|
172
|
-
*
|
|
173
|
-
* // Use it:
|
|
174
|
-
* <Card kb="mt-4">...</Card>
|
|
175
|
-
* <Button onPress={handlePress} kb="w-full" />
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
declare function styled<T extends ComponentType<any>>(Component: T, baseClasses?: string): ForwardRefExoticComponent<Omit<React__default.ComponentPropsWithRef<T>, OmittedKeys> & StyledProps>;
|
|
179
|
-
|
|
180
|
-
interface InteractionState {
|
|
181
|
-
hover?: boolean;
|
|
182
|
-
focus?: boolean;
|
|
183
|
-
/** Maps to 'pressed' and 'active' modifiers */
|
|
184
|
-
pressed?: boolean;
|
|
185
|
-
active?: boolean;
|
|
186
|
-
disabled?: boolean;
|
|
187
|
-
checked?: boolean;
|
|
188
|
-
visited?: boolean;
|
|
189
|
-
placeholder?: boolean;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Resolve a utility class string to a style object for the current theme + state.
|
|
193
|
-
*
|
|
194
|
-
* ```tsx
|
|
195
|
-
* // Basic usage
|
|
196
|
-
* const styles = useStyles('bg-white dark:bg-gray-900 p-4');
|
|
197
|
-
*
|
|
198
|
-
* // With interaction state
|
|
199
|
-
* const [pressed, setPressed] = useState(false);
|
|
200
|
-
* const styles = useStyles('bg-blue-500 pressed:bg-blue-700', { pressed });
|
|
201
|
-
*
|
|
202
|
-
* // Multiple class strings (merged left-to-right)
|
|
203
|
-
* const styles = useStyles(['bg-white p-4', 'dark:bg-gray-900 rounded-xl']);
|
|
204
|
-
* ```
|
|
205
|
-
*/
|
|
206
|
-
declare function useStyles(classString: string | string[], state?: InteractionState): StyleValue;
|
|
207
|
-
/**
|
|
208
|
-
* Returns the full ResolvedStyle bucket map (base, dark, hover, …).
|
|
209
|
-
* Useful when you need to apply styles selectively or pass them to Animated.
|
|
210
|
-
*/
|
|
211
|
-
declare function useResolvedStyle(classString: string | string[]): ResolvedStyle;
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Subscribe to the global dark-mode store with React's concurrent-safe
|
|
215
|
-
* useSyncExternalStore so that any component using className/kb re-renders
|
|
216
|
-
* immediately when the theme changes — without needing ThemeContext.
|
|
217
|
-
*/
|
|
218
|
-
declare function useGlobalDarkMode(): boolean;
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Returns the name of the currently active breakpoint — the largest breakpoint
|
|
222
|
-
* whose min-width the window satisfies, or `'xs'` when below all breakpoints.
|
|
223
|
-
*
|
|
224
|
-
* ```ts
|
|
225
|
-
* const bp = useBreakpoint(); // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
226
|
-
* ```
|
|
227
|
-
*/
|
|
228
|
-
declare function useBreakpoint(): string;
|
|
229
|
-
/**
|
|
230
|
-
* Returns a record of boolean flags for each breakpoint — `true` when the
|
|
231
|
-
* window width satisfies that breakpoint's min-width threshold.
|
|
232
|
-
*
|
|
233
|
-
* ```ts
|
|
234
|
-
* const { sm, md, lg } = useResponsive();
|
|
235
|
-
* const padding = lg ? 32 : sm ? 16 : 8;
|
|
236
|
-
* ```
|
|
237
|
-
*/
|
|
238
|
-
declare function useResponsive(): Record<string, boolean>;
|
|
239
|
-
|
|
240
|
-
interface InteractiveWrapperProps {
|
|
241
|
-
/** The real component to render (View, TouchableOpacity, div, a third-party button…) */
|
|
242
|
-
Component: React__default.ComponentType<any> | string;
|
|
243
|
-
/** Pre-resolved style buckets from resolve() */
|
|
244
|
-
resolvedStyle: ResolvedStyle;
|
|
245
|
-
/** On web: original class string so CSS pseudo-rules still fire */
|
|
246
|
-
className?: string;
|
|
247
|
-
/** Extra style prop passed by the user */
|
|
248
|
-
style?: StyleValue | StyleValue[];
|
|
249
|
-
children?: React__default.ReactNode;
|
|
250
|
-
onPressIn?: (...args: any[]) => void;
|
|
251
|
-
onPressOut?: (...args: any[]) => void;
|
|
252
|
-
onPointerDown?: (...args: any[]) => void;
|
|
253
|
-
onPointerUp?: (...args: any[]) => void;
|
|
254
|
-
onPointerLeave?: (...args: any[]) => void;
|
|
255
|
-
onMouseEnter?: (...args: any[]) => void;
|
|
256
|
-
onMouseLeave?: (...args: any[]) => void;
|
|
257
|
-
onFocus?: (...args: any[]) => void;
|
|
258
|
-
onBlur?: (...args: any[]) => void;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Thin wrapper rendered automatically by the JSX runtime whenever a className/kb
|
|
262
|
-
* string contains interactive modifiers (hover:, pressed:, focus:, active:, …).
|
|
263
|
-
*
|
|
264
|
-
* Manages interaction state locally and flattens the correct style bucket on
|
|
265
|
-
* every render. The wrapped component sees a plain `style` prop — it never
|
|
266
|
-
* knows it was wrapped.
|
|
267
|
-
*
|
|
268
|
-
* Refs are forwarded so the host component's imperative API still works.
|
|
269
|
-
*/
|
|
270
|
-
declare const InteractiveWrapper: React__default.ForwardRefExoticComponent<InteractiveWrapperProps & React__default.RefAttributes<unknown>>;
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Resolve a utility class string outside of a React component.
|
|
274
|
-
*
|
|
275
|
-
* On **native** — returns a StyleValue (style object) for the given mode.
|
|
276
|
-
* On **web** — injects CSS and returns the original class string (use as className).
|
|
277
|
-
*
|
|
278
|
-
* ```ts
|
|
279
|
-
* // Inside a component use useStyles() instead.
|
|
280
|
-
* // kb() is useful for StyleSheet.create() calls and static values.
|
|
281
|
-
*
|
|
282
|
-
* const styles = StyleSheet.create({
|
|
283
|
-
* container: kb('flex-1 bg-white p-4') as any,
|
|
284
|
-
* });
|
|
285
|
-
*
|
|
286
|
-
* // Web: use as className
|
|
287
|
-
* <div className={kb('bg-white dark:bg-gray-900 p-4') as string} />
|
|
288
|
-
* ```
|
|
289
|
-
*
|
|
290
|
-
* @param classString Space-separated utility classes
|
|
291
|
-
* @param isDark Whether dark mode is active (default: false)
|
|
292
|
-
*/
|
|
293
|
-
declare function kb(classString: string, isDark?: boolean): StyleValue | string;
|
|
294
|
-
/**
|
|
295
|
-
* Conditionally join class names. Falsy values are ignored.
|
|
296
|
-
*
|
|
297
|
-
* ```ts
|
|
298
|
-
* cx('bg-white p-4', isActive && 'border-2 border-blue-500', undefined)
|
|
299
|
-
* // → 'bg-white p-4 border-2 border-blue-500'
|
|
300
|
-
* ```
|
|
301
|
-
*/
|
|
302
|
-
declare function cx(...classes: Array<string | false | null | undefined>): string;
|
|
303
|
-
|
|
304
|
-
export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeToggle, type ThemeToggleProps, type ToggleVariant, buildConfig, cx, defaultColors, defaultTheme, flatten, getConfig, initConfig, kb, parseClass, parseClasses, resolve, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
|
package/dist/index.d.ts
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import React__default, { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
|
|
3
|
-
import { T as ThemeColors, a as ThemeConfig, P as ParsedClass, R as ResolvedStyle, S as StyleValue, F as FrameworkConfig, b as ResolvedConfig, c as ThemeMode } from './types-CV5vXnSH.js';
|
|
4
|
-
export { d as PluginAPI } from './types-CV5vXnSH.js';
|
|
5
|
-
|
|
6
|
-
declare const defaultColors: ThemeColors;
|
|
7
|
-
declare const defaultTheme: ThemeConfig;
|
|
8
|
-
|
|
9
|
-
declare function parseClass(className: string): ParsedClass | null;
|
|
10
|
-
/** Parse a space-separated class string into individual ParsedClass objects. */
|
|
11
|
-
declare function parseClasses(classString: string): ParsedClass[];
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Resolve a class string to a ResolvedStyle object.
|
|
15
|
-
*
|
|
16
|
-
* The result groups styles by modifier key:
|
|
17
|
-
* - 'base' → always-applied styles
|
|
18
|
-
* - 'dark' → dark-mode styles
|
|
19
|
-
* - 'hover' → hover styles
|
|
20
|
-
* - 'dark:hover' → combined dark + hover
|
|
21
|
-
* - etc.
|
|
22
|
-
*
|
|
23
|
-
* Results are cached — repeated calls with the same string are O(1).
|
|
24
|
-
*/
|
|
25
|
-
declare function resolve(classString: string, theme: ThemeConfig, darkMode?: 'attribute' | 'class' | 'media'): ResolvedStyle;
|
|
26
|
-
/**
|
|
27
|
-
* Flatten a ResolvedStyle into a single StyleValue for the given runtime state.
|
|
28
|
-
* Used by useStyles() and styled().
|
|
29
|
-
*
|
|
30
|
-
* @param resolved Output of resolve()
|
|
31
|
-
* @param isDark Whether dark mode is currently active
|
|
32
|
-
* @param state Interaction state flags
|
|
33
|
-
* @param breakpoints Active breakpoint names (sm, md, lg, xl, 2xl). On web,
|
|
34
|
-
* pass an empty Set — CSS @media rules handle responsive.
|
|
35
|
-
*/
|
|
36
|
-
declare function flatten(resolved: ResolvedStyle, isDark: boolean, state?: {
|
|
37
|
-
hover?: boolean;
|
|
38
|
-
focus?: boolean;
|
|
39
|
-
pressed?: boolean;
|
|
40
|
-
active?: boolean;
|
|
41
|
-
disabled?: boolean;
|
|
42
|
-
checked?: boolean;
|
|
43
|
-
visited?: boolean;
|
|
44
|
-
placeholder?: boolean;
|
|
45
|
-
}, breakpoints?: Set<string>): StyleValue;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Load, merge, and cache the resolved config.
|
|
49
|
-
* Call resetConfig() to force a reload (e.g. in tests or after live update).
|
|
50
|
-
*/
|
|
51
|
-
declare function getConfig(): ResolvedConfig;
|
|
52
|
-
declare function buildConfig(userConfig: FrameworkConfig): ResolvedConfig;
|
|
53
|
-
declare function updateConfig(userConfig: FrameworkConfig): void;
|
|
54
|
-
/**
|
|
55
|
-
* Like updateConfig, but only calls it when the config object reference has
|
|
56
|
-
* actually changed. Used by the Babel-injected IIFE so that:
|
|
57
|
-
* - multiple files with kbach classes don't re-run the update on every load
|
|
58
|
-
* - Fast Refresh DOES re-run when kbach.config.js changes (new module → new object)
|
|
59
|
-
*/
|
|
60
|
-
declare function initConfig(userConfig: FrameworkConfig): void;
|
|
61
|
-
|
|
62
|
-
interface ThemeContextValue {
|
|
63
|
-
/** The user-selected mode ('light' | 'dark' | 'system') */
|
|
64
|
-
mode: ThemeMode;
|
|
65
|
-
/** The effective resolved mode (never 'system') */
|
|
66
|
-
resolvedMode: 'light' | 'dark';
|
|
67
|
-
/** Convenience boolean */
|
|
68
|
-
isDark: boolean;
|
|
69
|
-
/** Change the theme mode programmatically */
|
|
70
|
-
setMode: (mode: ThemeMode) => void;
|
|
71
|
-
/** Toggle between light and dark (ignores system) */
|
|
72
|
-
toggle: () => void;
|
|
73
|
-
/** The fully resolved framework config (theme values, darkMode strategy, etc.) */
|
|
74
|
-
config: ResolvedConfig;
|
|
75
|
-
}
|
|
76
|
-
declare const ThemeContext: React.Context<ThemeContextValue | null>;
|
|
77
|
-
declare function useTheme(): ThemeContextValue;
|
|
78
|
-
declare function useIsDark(): boolean;
|
|
79
|
-
|
|
80
|
-
interface ColorScale {
|
|
81
|
-
/** `colors.blue[6]` → raw hex string */
|
|
82
|
-
readonly [shade: number]: string;
|
|
83
|
-
/** `colors.blue['6/50']` → shade 6 at 50% opacity */
|
|
84
|
-
readonly [key: string]: string;
|
|
85
|
-
}
|
|
86
|
-
interface ColorsAPI {
|
|
87
|
-
/**
|
|
88
|
-
* Pass any CSS color through, optionally applying an opacity (0–100).
|
|
89
|
-
* - `colors.alpha('#3b82f6', 50)` → `'rgba(59,130,246,0.5)'`
|
|
90
|
-
* - `colors.alpha('rgb(0,0,0)', 10)` → `'rgba(0,0,0,0.1)'`
|
|
91
|
-
* - `colors.alpha('rgba(0,0,0,0.5)')` → `'rgba(0,0,0,0.5)'` (passthrough)
|
|
92
|
-
*/
|
|
93
|
-
readonly alpha: (color: string, opacity?: number) => string;
|
|
94
|
-
[color: string]: any;
|
|
95
|
-
}
|
|
96
|
-
declare function wrapColors(rawColors: ThemeColors): ColorsAPI;
|
|
97
|
-
declare function useColors(): ColorsAPI;
|
|
98
|
-
|
|
99
|
-
interface ThemeProviderProps {
|
|
100
|
-
children: ReactNode;
|
|
101
|
-
/** Initial mode. Falls back to persisted value, then 'system'. */
|
|
102
|
-
defaultMode?: ThemeMode;
|
|
103
|
-
/**
|
|
104
|
-
* System color scheme for native `defaultMode="system"`.
|
|
105
|
-
*
|
|
106
|
-
* Pass the value of `useColorScheme()` from `react-native`. When importing
|
|
107
|
-
* `ThemeProvider` from `@kbach/native` this is handled automatically.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```tsx
|
|
111
|
-
* import { useColorScheme } from 'react-native';
|
|
112
|
-
* const colorScheme = useColorScheme();
|
|
113
|
-
* <ThemeProvider defaultMode="system" colorScheme={colorScheme}>…</ThemeProvider>
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
colorScheme?: 'light' | 'dark' | null;
|
|
117
|
-
/**
|
|
118
|
-
* Current window/screen width in pixels for responsive breakpoints.
|
|
119
|
-
* On web this is read from `window.innerWidth` automatically.
|
|
120
|
-
* When importing `ThemeProvider` from `@kbach/native` this is provided
|
|
121
|
-
* automatically from `useWindowDimensions()`.
|
|
122
|
-
*/
|
|
123
|
-
windowWidth?: number;
|
|
124
|
-
/** Override the config (useful for per-tree config). Defaults to global getConfig(). */
|
|
125
|
-
config?: FrameworkConfig;
|
|
126
|
-
/** Disable persistence to localStorage */
|
|
127
|
-
disablePersistence?: boolean;
|
|
128
|
-
}
|
|
129
|
-
declare function ThemeProvider({ children, defaultMode, colorScheme, windowWidth: windowWidthProp, config: configOverride, disablePersistence, }: ThemeProviderProps): React__default.JSX.Element;
|
|
130
|
-
|
|
131
|
-
type ToggleVariant = 'button' | 'switch' | 'icon-button';
|
|
132
|
-
interface ThemeToggleProps {
|
|
133
|
-
/** Visual variant. Default: 'button' */
|
|
134
|
-
variant?: ToggleVariant;
|
|
135
|
-
/** Override label text (button variant) */
|
|
136
|
-
label?: string;
|
|
137
|
-
/** Custom light-mode label */
|
|
138
|
-
lightLabel?: string;
|
|
139
|
-
/** Custom dark-mode label */
|
|
140
|
-
darkLabel?: string;
|
|
141
|
-
/** Show system mode option */
|
|
142
|
-
includeSystem?: boolean;
|
|
143
|
-
/** Custom styles applied to the root container */
|
|
144
|
-
style?: object;
|
|
145
|
-
/** Custom styles for the label text */
|
|
146
|
-
labelStyle?: object;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Drop-in theme toggle. Works on web and React Native.
|
|
150
|
-
*
|
|
151
|
-
* ```tsx
|
|
152
|
-
* <ThemeToggle />
|
|
153
|
-
* <ThemeToggle variant="switch" />
|
|
154
|
-
* <ThemeToggle variant="icon-button" lightLabel="☀️" darkLabel="🌙" />
|
|
155
|
-
* ```
|
|
156
|
-
*/
|
|
157
|
-
declare function ThemeToggle({ variant, label, lightLabel, darkLabel, includeSystem, style, labelStyle, }: ThemeToggleProps): React__default.JSX.Element;
|
|
158
|
-
|
|
159
|
-
interface StyledProps {
|
|
160
|
-
/** Additional utility classes applied on top of the base classes */
|
|
161
|
-
kb?: string;
|
|
162
|
-
/** Merged with resolved kb styles; applied last */
|
|
163
|
-
style?: StyleValue | StyleValue[];
|
|
164
|
-
}
|
|
165
|
-
type OmittedKeys = 'style';
|
|
166
|
-
/**
|
|
167
|
-
* Create a styled component from any React / React Native component.
|
|
168
|
-
*
|
|
169
|
-
* ```tsx
|
|
170
|
-
* const Card = styled(View, 'bg-white dark:bg-gray-800 rounded-xl p-4 shadow-md');
|
|
171
|
-
* const Button = styled(TouchableOpacity, 'bg-blue-500 pressed:bg-blue-700 dark:bg-blue-600 rounded-lg p-3');
|
|
172
|
-
*
|
|
173
|
-
* // Use it:
|
|
174
|
-
* <Card kb="mt-4">...</Card>
|
|
175
|
-
* <Button onPress={handlePress} kb="w-full" />
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
declare function styled<T extends ComponentType<any>>(Component: T, baseClasses?: string): ForwardRefExoticComponent<Omit<React__default.ComponentPropsWithRef<T>, OmittedKeys> & StyledProps>;
|
|
179
|
-
|
|
180
|
-
interface InteractionState {
|
|
181
|
-
hover?: boolean;
|
|
182
|
-
focus?: boolean;
|
|
183
|
-
/** Maps to 'pressed' and 'active' modifiers */
|
|
184
|
-
pressed?: boolean;
|
|
185
|
-
active?: boolean;
|
|
186
|
-
disabled?: boolean;
|
|
187
|
-
checked?: boolean;
|
|
188
|
-
visited?: boolean;
|
|
189
|
-
placeholder?: boolean;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Resolve a utility class string to a style object for the current theme + state.
|
|
193
|
-
*
|
|
194
|
-
* ```tsx
|
|
195
|
-
* // Basic usage
|
|
196
|
-
* const styles = useStyles('bg-white dark:bg-gray-900 p-4');
|
|
197
|
-
*
|
|
198
|
-
* // With interaction state
|
|
199
|
-
* const [pressed, setPressed] = useState(false);
|
|
200
|
-
* const styles = useStyles('bg-blue-500 pressed:bg-blue-700', { pressed });
|
|
201
|
-
*
|
|
202
|
-
* // Multiple class strings (merged left-to-right)
|
|
203
|
-
* const styles = useStyles(['bg-white p-4', 'dark:bg-gray-900 rounded-xl']);
|
|
204
|
-
* ```
|
|
205
|
-
*/
|
|
206
|
-
declare function useStyles(classString: string | string[], state?: InteractionState): StyleValue;
|
|
207
|
-
/**
|
|
208
|
-
* Returns the full ResolvedStyle bucket map (base, dark, hover, …).
|
|
209
|
-
* Useful when you need to apply styles selectively or pass them to Animated.
|
|
210
|
-
*/
|
|
211
|
-
declare function useResolvedStyle(classString: string | string[]): ResolvedStyle;
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Subscribe to the global dark-mode store with React's concurrent-safe
|
|
215
|
-
* useSyncExternalStore so that any component using className/kb re-renders
|
|
216
|
-
* immediately when the theme changes — without needing ThemeContext.
|
|
217
|
-
*/
|
|
218
|
-
declare function useGlobalDarkMode(): boolean;
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Returns the name of the currently active breakpoint — the largest breakpoint
|
|
222
|
-
* whose min-width the window satisfies, or `'xs'` when below all breakpoints.
|
|
223
|
-
*
|
|
224
|
-
* ```ts
|
|
225
|
-
* const bp = useBreakpoint(); // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
226
|
-
* ```
|
|
227
|
-
*/
|
|
228
|
-
declare function useBreakpoint(): string;
|
|
229
|
-
/**
|
|
230
|
-
* Returns a record of boolean flags for each breakpoint — `true` when the
|
|
231
|
-
* window width satisfies that breakpoint's min-width threshold.
|
|
232
|
-
*
|
|
233
|
-
* ```ts
|
|
234
|
-
* const { sm, md, lg } = useResponsive();
|
|
235
|
-
* const padding = lg ? 32 : sm ? 16 : 8;
|
|
236
|
-
* ```
|
|
237
|
-
*/
|
|
238
|
-
declare function useResponsive(): Record<string, boolean>;
|
|
239
|
-
|
|
240
|
-
interface InteractiveWrapperProps {
|
|
241
|
-
/** The real component to render (View, TouchableOpacity, div, a third-party button…) */
|
|
242
|
-
Component: React__default.ComponentType<any> | string;
|
|
243
|
-
/** Pre-resolved style buckets from resolve() */
|
|
244
|
-
resolvedStyle: ResolvedStyle;
|
|
245
|
-
/** On web: original class string so CSS pseudo-rules still fire */
|
|
246
|
-
className?: string;
|
|
247
|
-
/** Extra style prop passed by the user */
|
|
248
|
-
style?: StyleValue | StyleValue[];
|
|
249
|
-
children?: React__default.ReactNode;
|
|
250
|
-
onPressIn?: (...args: any[]) => void;
|
|
251
|
-
onPressOut?: (...args: any[]) => void;
|
|
252
|
-
onPointerDown?: (...args: any[]) => void;
|
|
253
|
-
onPointerUp?: (...args: any[]) => void;
|
|
254
|
-
onPointerLeave?: (...args: any[]) => void;
|
|
255
|
-
onMouseEnter?: (...args: any[]) => void;
|
|
256
|
-
onMouseLeave?: (...args: any[]) => void;
|
|
257
|
-
onFocus?: (...args: any[]) => void;
|
|
258
|
-
onBlur?: (...args: any[]) => void;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Thin wrapper rendered automatically by the JSX runtime whenever a className/kb
|
|
262
|
-
* string contains interactive modifiers (hover:, pressed:, focus:, active:, …).
|
|
263
|
-
*
|
|
264
|
-
* Manages interaction state locally and flattens the correct style bucket on
|
|
265
|
-
* every render. The wrapped component sees a plain `style` prop — it never
|
|
266
|
-
* knows it was wrapped.
|
|
267
|
-
*
|
|
268
|
-
* Refs are forwarded so the host component's imperative API still works.
|
|
269
|
-
*/
|
|
270
|
-
declare const InteractiveWrapper: React__default.ForwardRefExoticComponent<InteractiveWrapperProps & React__default.RefAttributes<unknown>>;
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Resolve a utility class string outside of a React component.
|
|
274
|
-
*
|
|
275
|
-
* On **native** — returns a StyleValue (style object) for the given mode.
|
|
276
|
-
* On **web** — injects CSS and returns the original class string (use as className).
|
|
277
|
-
*
|
|
278
|
-
* ```ts
|
|
279
|
-
* // Inside a component use useStyles() instead.
|
|
280
|
-
* // kb() is useful for StyleSheet.create() calls and static values.
|
|
281
|
-
*
|
|
282
|
-
* const styles = StyleSheet.create({
|
|
283
|
-
* container: kb('flex-1 bg-white p-4') as any,
|
|
284
|
-
* });
|
|
285
|
-
*
|
|
286
|
-
* // Web: use as className
|
|
287
|
-
* <div className={kb('bg-white dark:bg-gray-900 p-4') as string} />
|
|
288
|
-
* ```
|
|
289
|
-
*
|
|
290
|
-
* @param classString Space-separated utility classes
|
|
291
|
-
* @param isDark Whether dark mode is active (default: false)
|
|
292
|
-
*/
|
|
293
|
-
declare function kb(classString: string, isDark?: boolean): StyleValue | string;
|
|
294
|
-
/**
|
|
295
|
-
* Conditionally join class names. Falsy values are ignored.
|
|
296
|
-
*
|
|
297
|
-
* ```ts
|
|
298
|
-
* cx('bg-white p-4', isActive && 'border-2 border-blue-500', undefined)
|
|
299
|
-
* // → 'bg-white p-4 border-2 border-blue-500'
|
|
300
|
-
* ```
|
|
301
|
-
*/
|
|
302
|
-
declare function cx(...classes: Array<string | false | null | undefined>): string;
|
|
303
|
-
|
|
304
|
-
export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeToggle, type ThemeToggleProps, type ToggleVariant, buildConfig, cx, defaultColors, defaultTheme, flatten, getConfig, initConfig, kb, parseClass, parseClasses, resolve, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
2
|
-
export { Fragment } from 'react';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @kbach/react/jsx-dev-runtime
|
|
6
|
-
*
|
|
7
|
-
* Development variant of the custom JSX runtime.
|
|
8
|
-
* Babel uses jsxDEV (instead of jsx/jsxs) in dev builds.
|
|
9
|
-
* We forward isStaticChildren so React's dev-mode key-warning suppression
|
|
10
|
-
* works correctly for compile-time static child arrays.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
declare function jsxDEV(type: unknown, props: Record<string, unknown> | null, key?: string, isStaticChildren?: boolean, _source?: {
|
|
14
|
-
fileName: string;
|
|
15
|
-
lineNumber: number;
|
|
16
|
-
columnNumber: number;
|
|
17
|
-
}, _self?: unknown): ReactElement;
|
|
18
|
-
|
|
19
|
-
export { jsxDEV };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
2
|
-
export { Fragment } from 'react';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @kbach/react/jsx-dev-runtime
|
|
6
|
-
*
|
|
7
|
-
* Development variant of the custom JSX runtime.
|
|
8
|
-
* Babel uses jsxDEV (instead of jsx/jsxs) in dev builds.
|
|
9
|
-
* We forward isStaticChildren so React's dev-mode key-warning suppression
|
|
10
|
-
* works correctly for compile-time static child arrays.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
declare function jsxDEV(type: unknown, props: Record<string, unknown> | null, key?: string, isStaticChildren?: boolean, _source?: {
|
|
14
|
-
fileName: string;
|
|
15
|
-
lineNumber: number;
|
|
16
|
-
columnNumber: number;
|
|
17
|
-
}, _self?: unknown): ReactElement;
|
|
18
|
-
|
|
19
|
-
export { jsxDEV };
|
package/dist/jsx-runtime.d.mts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
2
|
-
export { Fragment, JSX } from 'react';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @kbach/react/jsx-runtime
|
|
6
|
-
*
|
|
7
|
-
* Drop-in replacement for react/jsx-runtime.
|
|
8
|
-
* Intercepts `className` and `kb` props on EVERY JSX element — React Native
|
|
9
|
-
* built-ins, HTML elements on web, and any third-party library component.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/** jsx() — elements with 0–1 child or dynamic key. */
|
|
13
|
-
declare function jsx(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
|
|
14
|
-
/** jsxs() — elements with 2+ static children. Children array is compile-time stable. */
|
|
15
|
-
declare function jsxs(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
|
|
16
|
-
|
|
17
|
-
export { jsx, jsxs };
|
package/dist/jsx-runtime.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
2
|
-
export { Fragment, JSX } from 'react';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @kbach/react/jsx-runtime
|
|
6
|
-
*
|
|
7
|
-
* Drop-in replacement for react/jsx-runtime.
|
|
8
|
-
* Intercepts `className` and `kb` props on EVERY JSX element — React Native
|
|
9
|
-
* built-ins, HTML elements on web, and any third-party library component.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/** jsx() — elements with 0–1 child or dynamic key. */
|
|
13
|
-
declare function jsx(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
|
|
14
|
-
/** jsxs() — elements with 2+ static children. Children array is compile-time stable. */
|
|
15
|
-
declare function jsxs(type: unknown, props: Record<string, unknown> | null, key?: string): ReactElement;
|
|
16
|
-
|
|
17
|
-
export { jsx, jsxs };
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
type ThemeMode = 'light' | 'dark' | 'system';
|
|
2
|
-
interface StyleValue {
|
|
3
|
-
[key: string]: string | number | undefined | null | StyleValue | unknown[];
|
|
4
|
-
}
|
|
5
|
-
interface ParsedClass {
|
|
6
|
-
/** The original class string, e.g. "dark:hover:bg-[#fff]" */
|
|
7
|
-
original: string;
|
|
8
|
-
/** Up to 3 modifier prefixes, e.g. ['dark', 'hover'] */
|
|
9
|
-
modifiers: string[];
|
|
10
|
-
/** Whether a leading `-` was present for negative values */
|
|
11
|
-
negative: boolean;
|
|
12
|
-
/** Whether a leading `!` was present — applies !important to all CSS declarations */
|
|
13
|
-
important: boolean;
|
|
14
|
-
/** The utility name, e.g. 'bg', 'p', 'text' */
|
|
15
|
-
utility: string;
|
|
16
|
-
/** The resolved value, e.g. 'white', '#fff', '4' */
|
|
17
|
-
value: string;
|
|
18
|
-
/** Whether the value was specified with bracket notation [value] */
|
|
19
|
-
isArbitrary: boolean;
|
|
20
|
-
}
|
|
21
|
-
interface ResolvedStyle {
|
|
22
|
-
/** Base styles applied unconditionally */
|
|
23
|
-
base?: StyleValue;
|
|
24
|
-
/** Styles keyed by modifier or modifier combo, e.g. 'dark', 'hover', 'dark:hover' */
|
|
25
|
-
[modifierKey: string]: StyleValue | undefined;
|
|
26
|
-
}
|
|
27
|
-
type ColorShades = Record<string, string>;
|
|
28
|
-
type ThemeColors = Record<string, string | ColorShades>;
|
|
29
|
-
type ThemeSpacing = Record<string, number | string>;
|
|
30
|
-
interface ThemeConfig {
|
|
31
|
-
colors: ThemeColors;
|
|
32
|
-
spacing: ThemeSpacing;
|
|
33
|
-
fontSize: Record<string, number | string>;
|
|
34
|
-
fontFamily: Record<string, string | string[]>;
|
|
35
|
-
fontWeight: Record<string, string | number>;
|
|
36
|
-
borderRadius: Record<string, number | string>;
|
|
37
|
-
borderWidth: Record<string, number>;
|
|
38
|
-
opacity: Record<string, number>;
|
|
39
|
-
lineHeight: Record<string, number | string>;
|
|
40
|
-
letterSpacing: Record<string, number | string>;
|
|
41
|
-
zIndex: Record<string, number | string>;
|
|
42
|
-
flex: Record<string, number>;
|
|
43
|
-
shadow: Record<string, StyleValue>;
|
|
44
|
-
screens: Record<string, string | number>;
|
|
45
|
-
[key: string]: unknown;
|
|
46
|
-
}
|
|
47
|
-
type DarkMode = 'attribute' | 'class' | 'media';
|
|
48
|
-
interface PluginAPI {
|
|
49
|
-
addUtility(name: string, styles: StyleValue): void;
|
|
50
|
-
addVariant(name: string, selector: string): void;
|
|
51
|
-
theme(path: string, defaultValue?: unknown): unknown;
|
|
52
|
-
e(className: string): string;
|
|
53
|
-
}
|
|
54
|
-
interface FrameworkConfig {
|
|
55
|
-
darkMode?: DarkMode;
|
|
56
|
-
theme?: Partial<ThemeConfig>;
|
|
57
|
-
/** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
|
|
58
|
-
extend?: {
|
|
59
|
-
theme?: Partial<ThemeConfig>;
|
|
60
|
-
} & Partial<ThemeConfig>;
|
|
61
|
-
plugins?: Array<(api: PluginAPI) => void>;
|
|
62
|
-
content?: string[];
|
|
63
|
-
}
|
|
64
|
-
interface ResolvedConfig {
|
|
65
|
-
darkMode: DarkMode;
|
|
66
|
-
theme: ThemeConfig;
|
|
67
|
-
plugins: Array<(api: PluginAPI) => void>;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export type { FrameworkConfig as F, ParsedClass as P, ResolvedStyle as R, StyleValue as S, ThemeColors as T, ThemeConfig as a, ResolvedConfig as b, ThemeMode as c, PluginAPI as d };
|
package/dist/types-CV5vXnSH.d.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
type ThemeMode = 'light' | 'dark' | 'system';
|
|
2
|
-
interface StyleValue {
|
|
3
|
-
[key: string]: string | number | undefined | null | StyleValue | unknown[];
|
|
4
|
-
}
|
|
5
|
-
interface ParsedClass {
|
|
6
|
-
/** The original class string, e.g. "dark:hover:bg-[#fff]" */
|
|
7
|
-
original: string;
|
|
8
|
-
/** Up to 3 modifier prefixes, e.g. ['dark', 'hover'] */
|
|
9
|
-
modifiers: string[];
|
|
10
|
-
/** Whether a leading `-` was present for negative values */
|
|
11
|
-
negative: boolean;
|
|
12
|
-
/** Whether a leading `!` was present — applies !important to all CSS declarations */
|
|
13
|
-
important: boolean;
|
|
14
|
-
/** The utility name, e.g. 'bg', 'p', 'text' */
|
|
15
|
-
utility: string;
|
|
16
|
-
/** The resolved value, e.g. 'white', '#fff', '4' */
|
|
17
|
-
value: string;
|
|
18
|
-
/** Whether the value was specified with bracket notation [value] */
|
|
19
|
-
isArbitrary: boolean;
|
|
20
|
-
}
|
|
21
|
-
interface ResolvedStyle {
|
|
22
|
-
/** Base styles applied unconditionally */
|
|
23
|
-
base?: StyleValue;
|
|
24
|
-
/** Styles keyed by modifier or modifier combo, e.g. 'dark', 'hover', 'dark:hover' */
|
|
25
|
-
[modifierKey: string]: StyleValue | undefined;
|
|
26
|
-
}
|
|
27
|
-
type ColorShades = Record<string, string>;
|
|
28
|
-
type ThemeColors = Record<string, string | ColorShades>;
|
|
29
|
-
type ThemeSpacing = Record<string, number | string>;
|
|
30
|
-
interface ThemeConfig {
|
|
31
|
-
colors: ThemeColors;
|
|
32
|
-
spacing: ThemeSpacing;
|
|
33
|
-
fontSize: Record<string, number | string>;
|
|
34
|
-
fontFamily: Record<string, string | string[]>;
|
|
35
|
-
fontWeight: Record<string, string | number>;
|
|
36
|
-
borderRadius: Record<string, number | string>;
|
|
37
|
-
borderWidth: Record<string, number>;
|
|
38
|
-
opacity: Record<string, number>;
|
|
39
|
-
lineHeight: Record<string, number | string>;
|
|
40
|
-
letterSpacing: Record<string, number | string>;
|
|
41
|
-
zIndex: Record<string, number | string>;
|
|
42
|
-
flex: Record<string, number>;
|
|
43
|
-
shadow: Record<string, StyleValue>;
|
|
44
|
-
screens: Record<string, string | number>;
|
|
45
|
-
[key: string]: unknown;
|
|
46
|
-
}
|
|
47
|
-
type DarkMode = 'attribute' | 'class' | 'media';
|
|
48
|
-
interface PluginAPI {
|
|
49
|
-
addUtility(name: string, styles: StyleValue): void;
|
|
50
|
-
addVariant(name: string, selector: string): void;
|
|
51
|
-
theme(path: string, defaultValue?: unknown): unknown;
|
|
52
|
-
e(className: string): string;
|
|
53
|
-
}
|
|
54
|
-
interface FrameworkConfig {
|
|
55
|
-
darkMode?: DarkMode;
|
|
56
|
-
theme?: Partial<ThemeConfig>;
|
|
57
|
-
/** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
|
|
58
|
-
extend?: {
|
|
59
|
-
theme?: Partial<ThemeConfig>;
|
|
60
|
-
} & Partial<ThemeConfig>;
|
|
61
|
-
plugins?: Array<(api: PluginAPI) => void>;
|
|
62
|
-
content?: string[];
|
|
63
|
-
}
|
|
64
|
-
interface ResolvedConfig {
|
|
65
|
-
darkMode: DarkMode;
|
|
66
|
-
theme: ThemeConfig;
|
|
67
|
-
plugins: Array<(api: PluginAPI) => void>;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export type { FrameworkConfig as F, ParsedClass as P, ResolvedStyle as R, StyleValue as S, ThemeColors as T, ThemeConfig as a, ResolvedConfig as b, ThemeMode as c, PluginAPI as d };
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// TypeScript declarations for the Kbach Vite plugin virtual module.
|
|
2
|
-
// Add this to your tsconfig "types" array or via a triple-slash reference:
|
|
3
|
-
// /// <reference types="@kbach/react/vite/client" />
|
|
4
|
-
|
|
5
|
-
declare module 'virtual:kbach/styles.css' {
|
|
6
|
-
const css: string;
|
|
7
|
-
export default css;
|
|
8
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// TypeScript declarations for the Kbach Vite plugin virtual module.
|
|
2
|
-
// Add this to your tsconfig "types" array or via a triple-slash reference:
|
|
3
|
-
// /// <reference types="@kbach/react/vite/client" />
|
|
4
|
-
|
|
5
|
-
declare module 'virtual:kbach/styles.css' {
|
|
6
|
-
const css: string;
|
|
7
|
-
export default css;
|
|
8
|
-
}
|
package/dist/vite-plugin.d.mts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'vite';
|
|
2
|
-
import { F as FrameworkConfig } from './types-CV5vXnSH.mjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @kbach/react/vite
|
|
6
|
-
*
|
|
7
|
-
* Vite plugin — scans source files for Kbach className/kb props and generates CSS.
|
|
8
|
-
* Zero setup: just add kbach() to your plugins array.
|
|
9
|
-
* Only generates CSS for classes you actually use (like Tailwind).
|
|
10
|
-
*
|
|
11
|
-
* How it works (same as Tailwind):
|
|
12
|
-
* 1. Scans your source files at startup for className/kb props
|
|
13
|
-
* 2. Generates CSS rules for only those classes
|
|
14
|
-
* 3. Appends them to your imported CSS file (e.g. app.css) via Vite's transform
|
|
15
|
-
* 4. Vite serves the CSS through its normal pipeline → <link rel="stylesheet">
|
|
16
|
-
* 5. When you add a new class in dev, the CSS file is hot-reloaded
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
declare const VIRTUAL_ID = "virtual:kbach/styles.css";
|
|
20
|
-
declare function kbach(userConfig?: FrameworkConfig): Plugin;
|
|
21
|
-
|
|
22
|
-
export { VIRTUAL_ID, kbach };
|
package/dist/vite-plugin.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'vite';
|
|
2
|
-
import { F as FrameworkConfig } from './types-CV5vXnSH.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @kbach/react/vite
|
|
6
|
-
*
|
|
7
|
-
* Vite plugin — scans source files for Kbach className/kb props and generates CSS.
|
|
8
|
-
* Zero setup: just add kbach() to your plugins array.
|
|
9
|
-
* Only generates CSS for classes you actually use (like Tailwind).
|
|
10
|
-
*
|
|
11
|
-
* How it works (same as Tailwind):
|
|
12
|
-
* 1. Scans your source files at startup for className/kb props
|
|
13
|
-
* 2. Generates CSS rules for only those classes
|
|
14
|
-
* 3. Appends them to your imported CSS file (e.g. app.css) via Vite's transform
|
|
15
|
-
* 4. Vite serves the CSS through its normal pipeline → <link rel="stylesheet">
|
|
16
|
-
* 5. When you add a new class in dev, the CSS file is hot-reloaded
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
declare const VIRTUAL_ID = "virtual:kbach/styles.css";
|
|
20
|
-
declare function kbach(userConfig?: FrameworkConfig): Plugin;
|
|
21
|
-
|
|
22
|
-
export { VIRTUAL_ID, kbach };
|