@kbach/react 1.0.0-beta.27 → 1.0.0-beta.29
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/AGENTS.md +214 -162
- package/dist/{chunk-UP7MWEU5.mjs → chunk-6KXERZP3.mjs} +1 -1
- package/dist/{chunk-OVKVZA7B.mjs → chunk-FBYS4BI3.mjs} +76 -0
- package/dist/{chunk-DJKDEDPE.mjs → chunk-K6AUD64N.mjs} +70 -6
- package/dist/{chunk-KTRJZDVE.mjs → chunk-NHWKWY2T.mjs} +71 -17
- package/dist/{chunk-43FOLRQA.mjs → chunk-UK5S55DF.mjs} +9 -54
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +144 -55
- package/dist/index.mjs +5 -5
- package/dist/jsx-dev-runtime.js +141 -4
- package/dist/jsx-dev-runtime.mjs +3 -3
- package/dist/jsx-runtime.js +141 -4
- package/dist/jsx-runtime.mjs +3 -3
- package/dist/postcss-plugin.js +99 -21
- package/dist/postcss-plugin.mjs +8 -4
- package/dist/vite-plugin.d.mts +3 -1
- package/dist/vite-plugin.d.ts +3 -1
- package/dist/vite-plugin.js +125 -23
- package/dist/vite-plugin.mjs +5 -3
- package/package.json +2 -2
package/dist/vite-plugin.js
CHANGED
|
@@ -23,6 +23,7 @@ __export(vite_plugin_exports, {
|
|
|
23
23
|
CSS_SYNC_DEBOUNCE_MS: () => CSS_SYNC_DEBOUNCE_MS,
|
|
24
24
|
DEFAULT_SCAN_DIRS: () => DEFAULT_SCAN_DIRS,
|
|
25
25
|
findMainCSSFile: () => findMainCSSFile,
|
|
26
|
+
isConfigFile: () => isConfigFile,
|
|
26
27
|
kbach: () => kbach,
|
|
27
28
|
loadConfigFile: () => loadConfigFile,
|
|
28
29
|
resolveEffectiveTheme: () => resolveEffectiveTheme
|
|
@@ -269,6 +270,59 @@ function buildResetCSS(usedTags) {
|
|
|
269
270
|
return RESET_RULES.filter((r) => !r.tags || r.tags.some((t) => usedTags.has(t))).map((r) => r.css).join("\n");
|
|
270
271
|
}
|
|
271
272
|
|
|
273
|
+
// src/colorVariables.ts
|
|
274
|
+
function parseHexRgb(hex) {
|
|
275
|
+
const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
276
|
+
if (!m) return null;
|
|
277
|
+
let h = m[1];
|
|
278
|
+
if (h.length === 3) h = h.split("").map((c) => c + c).join("");
|
|
279
|
+
const n = parseInt(h, 16);
|
|
280
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
281
|
+
}
|
|
282
|
+
function wrapDarkDecls(strategy, decls) {
|
|
283
|
+
switch (strategy) {
|
|
284
|
+
case "class":
|
|
285
|
+
return `.dark { ${decls} }`;
|
|
286
|
+
case "media":
|
|
287
|
+
return `@media (prefers-color-scheme: dark) { :root { ${decls} } }`;
|
|
288
|
+
case "attribute":
|
|
289
|
+
default:
|
|
290
|
+
return `[data-theme="dark"] { ${decls} }`;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function modeAwareDecls(theme) {
|
|
294
|
+
const light = [];
|
|
295
|
+
const dark = [];
|
|
296
|
+
for (const [name, value] of Object.entries(theme.colors)) {
|
|
297
|
+
if (typeof value === "string") continue;
|
|
298
|
+
const l = parseHexRgb(value.light);
|
|
299
|
+
const d = parseHexRgb(value.dark);
|
|
300
|
+
if (!l || !d) continue;
|
|
301
|
+
light.push(`--kb-color-${name}: ${l.join(",")};`);
|
|
302
|
+
dark.push(`--kb-color-${name}: ${d.join(",")};`);
|
|
303
|
+
}
|
|
304
|
+
return { light, dark };
|
|
305
|
+
}
|
|
306
|
+
function colorVariablesCss(theme) {
|
|
307
|
+
const { light, dark } = modeAwareDecls(theme);
|
|
308
|
+
if (light.length === 0) return "";
|
|
309
|
+
return `:root { ${light.join(" ")} }
|
|
310
|
+
${wrapDarkDecls(theme.darkMode, dark.join(" "))}`;
|
|
311
|
+
}
|
|
312
|
+
function withColorVariables(theme) {
|
|
313
|
+
let changed = false;
|
|
314
|
+
const colors = {};
|
|
315
|
+
for (const [name, value] of Object.entries(theme.colors)) {
|
|
316
|
+
if (typeof value !== "string" && parseHexRgb(value.light) && parseHexRgb(value.dark)) {
|
|
317
|
+
colors[name] = `rgb(var(--kb-color-${name}))`;
|
|
318
|
+
changed = true;
|
|
319
|
+
} else {
|
|
320
|
+
colors[name] = value;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return changed ? { ...theme, colors } : theme;
|
|
324
|
+
}
|
|
325
|
+
|
|
272
326
|
// src/vite-plugin/format.ts
|
|
273
327
|
var KBACH_START = "/* kbach:start */";
|
|
274
328
|
var KBACH_END = "/* kbach:end */";
|
|
@@ -288,6 +342,8 @@ function formatKbachCSS(tokenRules, theme, usedTags) {
|
|
|
288
342
|
lines.push("", ":root {", ` --kb-dark-mode: ${theme.darkMode};`);
|
|
289
343
|
for (const [varName, val] of declarations) lines.push(` ${varName}: ${val};`);
|
|
290
344
|
lines.push("}");
|
|
345
|
+
const colorVars = colorVariablesCss(theme);
|
|
346
|
+
if (colorVars) lines.push("", prettifyCSS(colorVars));
|
|
291
347
|
lines.push("", prettifyCSS(text));
|
|
292
348
|
return lines.join("\n");
|
|
293
349
|
}
|
|
@@ -694,16 +750,6 @@ function detectDarkModeStrategyFromDom() {
|
|
|
694
750
|
setTheme({ ...activeTheme, darkMode: raw });
|
|
695
751
|
}
|
|
696
752
|
|
|
697
|
-
// src/colorVariables.ts
|
|
698
|
-
function parseHexRgb(hex) {
|
|
699
|
-
const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
700
|
-
if (!m) return null;
|
|
701
|
-
let h = m[1];
|
|
702
|
-
if (h.length === 3) h = h.split("").map((c) => c + c).join("");
|
|
703
|
-
const n = parseInt(h, 16);
|
|
704
|
-
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
705
|
-
}
|
|
706
|
-
|
|
707
753
|
// src/darkModeStore.ts
|
|
708
754
|
var STORAGE_KEY = "kbach-theme";
|
|
709
755
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -768,7 +814,13 @@ function applyOpacityToHex(hex, opacityText) {
|
|
|
768
814
|
return `rgba(${rgb.join(",")},${clamped})`;
|
|
769
815
|
}
|
|
770
816
|
function resolveColorEntry(value, lookup) {
|
|
771
|
-
if (typeof value !== "string")
|
|
817
|
+
if (typeof value !== "string") {
|
|
818
|
+
const side = (v, mode2) => {
|
|
819
|
+
const r = resolveColorEntry(v, lookup);
|
|
820
|
+
return typeof r === "string" ? r : r[mode2];
|
|
821
|
+
};
|
|
822
|
+
return { light: side(value.light, "light"), dark: side(value.dark, "dark") };
|
|
823
|
+
}
|
|
772
824
|
const slash = value.indexOf("/");
|
|
773
825
|
const name = slash === -1 ? value : value.slice(0, slash);
|
|
774
826
|
const opacity = slash === -1 ? void 0 : value.slice(slash + 1);
|
|
@@ -835,6 +887,9 @@ var import_node = require("@kbach/core-engine/node");
|
|
|
835
887
|
function generateCssForToken(token, themeJson) {
|
|
836
888
|
return JSON.parse((0, import_node.generate_css)(token, themeJson));
|
|
837
889
|
}
|
|
890
|
+
function suggestClassForToken(token, themeJson) {
|
|
891
|
+
return (0, import_node.suggest_class)(token, themeJson) || null;
|
|
892
|
+
}
|
|
838
893
|
|
|
839
894
|
// src/vite-plugin/scan.ts
|
|
840
895
|
var import_fs = require("fs");
|
|
@@ -1094,17 +1149,18 @@ function isMarkerClass(base) {
|
|
|
1094
1149
|
if (slashIdx === -1) return false;
|
|
1095
1150
|
return MARKER_CLASSES.has(base.slice(0, slashIdx)) && slashIdx < base.length - 1;
|
|
1096
1151
|
}
|
|
1097
|
-
|
|
1152
|
+
var TAILWIND_SHADE = /-(?:50|[1-9]00|950)(?:\/|$)/;
|
|
1153
|
+
function warnIfUnknownClass(token, filePath, code, isResolvable, projectCssClasses, warnedTokens, suggest) {
|
|
1098
1154
|
if (isResolvable || warnedTokens.has(token)) return;
|
|
1099
1155
|
const base = stripModifierPrefix(token);
|
|
1100
1156
|
if (!base || projectCssClasses.has(base) || isMarkerClass(base)) return;
|
|
1101
1157
|
warnedTokens.add(token);
|
|
1102
1158
|
const pos = findLineCol(code, token);
|
|
1103
1159
|
const location = pos ? `${blue(filePath)}${green(`:${pos.line}:${pos.column}`)}` : blue(filePath);
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
${
|
|
1107
|
-
);
|
|
1160
|
+
const suggestion = suggest?.(token) ?? null;
|
|
1161
|
+
const hint = suggestion ? `${gray("\u2014 did you mean")} ${highlight(suggestion)}${gray("?")}${TAILWIND_SHADE.test(token) ? gray(" Kbach color shades run 1\u201312, not 50\u2013950.") : ""}` : gray("\u2014 no Kbach utility or project CSS rule matches it. Typo?");
|
|
1162
|
+
console.warn(`${kbachTag()} ${gray("Unknown class")} ${highlight(token)} ${hint}
|
|
1163
|
+
${bold("at")} ${location}`);
|
|
1108
1164
|
}
|
|
1109
1165
|
|
|
1110
1166
|
// src/staticCss/engine.ts
|
|
@@ -1114,7 +1170,8 @@ function normPath(p) {
|
|
|
1114
1170
|
}
|
|
1115
1171
|
var SAFELIST_KEY = "\0kbach-safelist";
|
|
1116
1172
|
function createKbachStaticCssEngine(options) {
|
|
1117
|
-
const { root, theme,
|
|
1173
|
+
const { root, theme, includeDirs, safelist } = options;
|
|
1174
|
+
const themeJson = JSON.stringify(withColorVariables(theme));
|
|
1118
1175
|
const fileTokens = /* @__PURE__ */ new Map();
|
|
1119
1176
|
const tokenRules = /* @__PURE__ */ new Map();
|
|
1120
1177
|
const fileTags = /* @__PURE__ */ new Map();
|
|
@@ -1132,7 +1189,7 @@ function createKbachStaticCssEngine(options) {
|
|
|
1132
1189
|
tokens.add(tok);
|
|
1133
1190
|
const rules = resolveToken(tok);
|
|
1134
1191
|
if (process.env.NODE_ENV !== "production") {
|
|
1135
|
-
warnIfUnknownClass(tok, filePath, code, rules.length > 0, projectCssClasses, warnedTokens);
|
|
1192
|
+
warnIfUnknownClass(tok, filePath, code, rules.length > 0, projectCssClasses, warnedTokens, (t) => suggestClassForToken(t, themeJson));
|
|
1136
1193
|
}
|
|
1137
1194
|
}
|
|
1138
1195
|
fileTokens.set(normPath(filePath), tokens);
|
|
@@ -1217,13 +1274,27 @@ function isEsmRequireFailure(err) {
|
|
|
1217
1274
|
return err.code === "ERR_REQUIRE_ESM" || /is not defined in ES module scope/.test(err.message);
|
|
1218
1275
|
}
|
|
1219
1276
|
async function importConfigModule(path) {
|
|
1220
|
-
const
|
|
1277
|
+
const url = (0, import_url.pathToFileURL)(path).href;
|
|
1278
|
+
let mod;
|
|
1279
|
+
try {
|
|
1280
|
+
mod = await nativeImport(url + "?t=" + Date.now());
|
|
1281
|
+
} catch (err) {
|
|
1282
|
+
if (err.code !== "ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING") throw err;
|
|
1283
|
+
mod = await import(url);
|
|
1284
|
+
}
|
|
1221
1285
|
return mod.default ?? mod;
|
|
1222
1286
|
}
|
|
1287
|
+
var nativeImport = new Function("url", "return import(url)");
|
|
1223
1288
|
function requireConfigModule(root, path) {
|
|
1224
|
-
const
|
|
1289
|
+
const req = (0, import_module.createRequire)(root);
|
|
1290
|
+
delete req.cache[req.resolve(path)];
|
|
1291
|
+
const mod = req(path);
|
|
1225
1292
|
return mod.default ?? mod;
|
|
1226
1293
|
}
|
|
1294
|
+
function isConfigFile(root, file) {
|
|
1295
|
+
const norm = (p) => p.replace(/\\/g, "/").toLowerCase();
|
|
1296
|
+
return /^kbach\.config\.(c|m)?js$/.test((0, import_path4.basename)(file)) && norm((0, import_path4.dirname)(file)) === norm(root);
|
|
1297
|
+
}
|
|
1227
1298
|
async function loadConfigFile(root) {
|
|
1228
1299
|
const cjsPath = (0, import_path4.join)(root, "kbach.config.cjs");
|
|
1229
1300
|
if ((0, import_fs3.existsSync)(cjsPath)) return requireConfigModule(root, cjsPath);
|
|
@@ -1231,6 +1302,7 @@ async function loadConfigFile(root) {
|
|
|
1231
1302
|
if ((0, import_fs3.existsSync)(mjsPath)) return importConfigModule(mjsPath);
|
|
1232
1303
|
const jsPath = (0, import_path4.join)(root, "kbach.config.js");
|
|
1233
1304
|
if (!(0, import_fs3.existsSync)(jsPath)) return void 0;
|
|
1305
|
+
if (isEsmProject(root)) return importConfigModule(jsPath);
|
|
1234
1306
|
try {
|
|
1235
1307
|
return requireConfigModule(root, jsPath);
|
|
1236
1308
|
} catch (err) {
|
|
@@ -1238,6 +1310,13 @@ async function loadConfigFile(root) {
|
|
|
1238
1310
|
return importConfigModule(jsPath);
|
|
1239
1311
|
}
|
|
1240
1312
|
}
|
|
1313
|
+
function isEsmProject(root) {
|
|
1314
|
+
try {
|
|
1315
|
+
return JSON.parse((0, import_fs3.readFileSync)((0, import_path4.join)(root, "package.json"), "utf-8")).type === "module";
|
|
1316
|
+
} catch {
|
|
1317
|
+
return false;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1241
1320
|
async function resolveEffectiveTheme(root, options) {
|
|
1242
1321
|
if (options.theme) return options.theme;
|
|
1243
1322
|
if (options.config) return resolveKbachConfig(options.config);
|
|
@@ -1249,7 +1328,7 @@ function kbach(options = {}) {
|
|
|
1249
1328
|
const safelist = options.safelist ?? [];
|
|
1250
1329
|
let root = process.cwd();
|
|
1251
1330
|
let theme = defaultTheme;
|
|
1252
|
-
let engine = createKbachStaticCssEngine({ root, theme,
|
|
1331
|
+
let engine = createKbachStaticCssEngine({ root, theme, includeDirs, safelist });
|
|
1253
1332
|
let mainCSSFilePath = (0, import_path4.join)(root, "src", "kbach.css");
|
|
1254
1333
|
function mainCSSFile() {
|
|
1255
1334
|
return mainCSSFilePath;
|
|
@@ -1266,13 +1345,27 @@ function kbach(options = {}) {
|
|
|
1266
1345
|
syncMainCSSFile(server);
|
|
1267
1346
|
}, CSS_SYNC_DEBOUNCE_MS);
|
|
1268
1347
|
}
|
|
1348
|
+
async function reloadConfig(server) {
|
|
1349
|
+
if (options.theme || options.config) return;
|
|
1350
|
+
try {
|
|
1351
|
+
theme = await resolveEffectiveTheme(root, options);
|
|
1352
|
+
} catch (err) {
|
|
1353
|
+
console.warn(`${kbachTag()} Couldn't reload kbach.config: ${err.message}`);
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
engine = createKbachStaticCssEngine({ root, theme, includeDirs, safelist });
|
|
1357
|
+
engine.scanProjectCssSelectorsOnce();
|
|
1358
|
+
engine.initialScan();
|
|
1359
|
+
engine.processSafelist();
|
|
1360
|
+
syncMainCSSFile(server);
|
|
1361
|
+
}
|
|
1269
1362
|
return {
|
|
1270
1363
|
name: "kbach",
|
|
1271
1364
|
enforce: "pre",
|
|
1272
1365
|
async configResolved(resolved) {
|
|
1273
1366
|
root = resolved.root;
|
|
1274
1367
|
theme = await resolveEffectiveTheme(root, options);
|
|
1275
|
-
engine = createKbachStaticCssEngine({ root, theme,
|
|
1368
|
+
engine = createKbachStaticCssEngine({ root, theme, includeDirs, safelist });
|
|
1276
1369
|
mainCSSFilePath = findMainCSSFile(root, includeDirs, options.cssFile);
|
|
1277
1370
|
},
|
|
1278
1371
|
buildStart() {
|
|
@@ -1287,6 +1380,10 @@ function kbach(options = {}) {
|
|
|
1287
1380
|
configureServer(server) {
|
|
1288
1381
|
const onAddOrUnlink = (file, isUnlink) => {
|
|
1289
1382
|
if (file.includes("node_modules")) return;
|
|
1383
|
+
if (isConfigFile(root, file)) {
|
|
1384
|
+
void reloadConfig(server);
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1290
1387
|
if (!/\.(tsx?|jsx?)$/.test(file)) return;
|
|
1291
1388
|
if (isUnlink) {
|
|
1292
1389
|
engine.removeFile(file);
|
|
@@ -1302,8 +1399,12 @@ function kbach(options = {}) {
|
|
|
1302
1399
|
server.watcher.on("add", (file) => onAddOrUnlink(file, false));
|
|
1303
1400
|
server.watcher.on("unlink", (file) => onAddOrUnlink(file, true));
|
|
1304
1401
|
},
|
|
1305
|
-
handleHotUpdate({ file, server }) {
|
|
1402
|
+
async handleHotUpdate({ file, server }) {
|
|
1306
1403
|
if (file.includes("node_modules")) return;
|
|
1404
|
+
if (isConfigFile(root, file)) {
|
|
1405
|
+
await reloadConfig(server);
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1307
1408
|
if (!/\.(tsx?|jsx?)$/.test(file)) return;
|
|
1308
1409
|
try {
|
|
1309
1410
|
engine.processFile(file, readSourceFile(file));
|
|
@@ -1319,6 +1420,7 @@ function kbach(options = {}) {
|
|
|
1319
1420
|
CSS_SYNC_DEBOUNCE_MS,
|
|
1320
1421
|
DEFAULT_SCAN_DIRS,
|
|
1321
1422
|
findMainCSSFile,
|
|
1423
|
+
isConfigFile,
|
|
1322
1424
|
kbach,
|
|
1323
1425
|
loadConfigFile,
|
|
1324
1426
|
resolveEffectiveTheme
|
package/dist/vite-plugin.mjs
CHANGED
|
@@ -2,16 +2,18 @@ import {
|
|
|
2
2
|
CSS_SYNC_DEBOUNCE_MS,
|
|
3
3
|
DEFAULT_SCAN_DIRS,
|
|
4
4
|
findMainCSSFile,
|
|
5
|
+
isConfigFile,
|
|
5
6
|
kbach,
|
|
6
7
|
loadConfigFile,
|
|
7
8
|
resolveEffectiveTheme
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-NHWKWY2T.mjs";
|
|
10
|
+
import "./chunk-UK5S55DF.mjs";
|
|
11
|
+
import "./chunk-FBYS4BI3.mjs";
|
|
11
12
|
export {
|
|
12
13
|
CSS_SYNC_DEBOUNCE_MS,
|
|
13
14
|
DEFAULT_SCAN_DIRS,
|
|
14
15
|
findMainCSSFile,
|
|
16
|
+
isConfigFile,
|
|
15
17
|
kbach,
|
|
16
18
|
loadConfigFile,
|
|
17
19
|
resolveEffectiveTheme
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kbach/react",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.29",
|
|
4
4
|
"description": "A utility-first styling engine for React, powered by a Rust/WASM core: Tailwind CSS-compatible utility class names with Kbach's own color palette.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"generate:colors": "node ../core-engine/scripts/generate-palette.mjs src/generatedPalette.ts"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@kbach/core-engine": "1.0.0-beta.
|
|
77
|
+
"@kbach/core-engine": "1.0.0-beta.18"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@types/react": "^19.2.0",
|