@kbach/react 0.5.37 → 0.5.40
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/README.md +173 -98
- package/dist/{chunk-VZHNEDUW.mjs → chunk-6NHHYHNV.mjs} +36 -55
- package/dist/{chunk-36QDTNAQ.mjs → chunk-EYPBYQSB.mjs} +16 -10
- package/dist/{chunk-J2I5YSC5.mjs → chunk-IZ3W6G3V.mjs} +411 -1008
- package/dist/index.d.mts +10 -20
- package/dist/index.d.ts +10 -20
- package/dist/index.js +445 -1038
- package/dist/index.mjs +40 -22
- package/dist/jsx-dev-runtime.d.mts +6 -4
- package/dist/jsx-dev-runtime.d.ts +6 -4
- package/dist/jsx-dev-runtime.js +444 -1062
- package/dist/jsx-dev-runtime.mjs +10 -5
- package/dist/jsx-runtime.d.mts +2 -3
- package/dist/jsx-runtime.d.ts +2 -3
- package/dist/jsx-runtime.js +442 -1060
- package/dist/jsx-runtime.mjs +5 -3
- package/dist/types-D-24rbXu.d.mts +126 -0
- package/dist/types-D-24rbXu.d.ts +126 -0
- package/dist/vite-plugin.d.mts +1 -1
- package/dist/vite-plugin.d.ts +1 -1
- package/dist/vite-plugin.js +301 -841
- package/dist/vite-plugin.mjs +76 -25
- package/package.json +4 -2
- package/types.d.ts +1 -0
- package/dist/types-CV5vXnSH.d.mts +0 -70
- package/dist/types-CV5vXnSH.d.ts +0 -70
package/dist/vite-plugin.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
generateClassCSS,
|
|
4
4
|
setCSSGenMode,
|
|
5
5
|
splitClassTokens
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IZ3W6G3V.mjs";
|
|
7
7
|
|
|
8
8
|
// src/vite-plugin.ts
|
|
9
9
|
import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from "fs";
|
|
@@ -31,12 +31,18 @@ function classifyToken(token) {
|
|
|
31
31
|
return "Utilities";
|
|
32
32
|
}
|
|
33
33
|
function buildColorVarMap(theme, usedCSS) {
|
|
34
|
+
const usedHexValues = /* @__PURE__ */ new Set();
|
|
35
|
+
const hexRe = /#[0-9a-fA-F]{3,8}\b/g;
|
|
36
|
+
let hm;
|
|
37
|
+
while ((hm = hexRe.exec(usedCSS)) !== null) usedHexValues.add(hm[0].toLowerCase());
|
|
34
38
|
const map = /* @__PURE__ */ new Map();
|
|
35
39
|
for (const [name, shades] of Object.entries(theme.colors ?? {})) {
|
|
36
40
|
const entries = typeof shades === "string" ? [[name, shades]] : Object.entries(shades).map(([s, v]) => [`${name}-${s}`, v]);
|
|
37
41
|
for (const [fullName, val] of entries) {
|
|
38
|
-
if (typeof val === "string" && /^#[0-9a-fA-F]{3,8}$/.test(val)
|
|
39
|
-
|
|
42
|
+
if (typeof val === "string" && /^#[0-9a-fA-F]{3,8}$/.test(val)) {
|
|
43
|
+
if (usedHexValues.has(val.toLowerCase())) {
|
|
44
|
+
map.set(val, `--color-${fullName}`);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
}
|
|
@@ -116,6 +122,37 @@ function toNumericScreens(screens) {
|
|
|
116
122
|
}
|
|
117
123
|
return out;
|
|
118
124
|
}
|
|
125
|
+
function extractClassStrings(code) {
|
|
126
|
+
const found = /* @__PURE__ */ new Set();
|
|
127
|
+
const simpleRe = /(?:className|kb)=["']([^"']+)["']/g;
|
|
128
|
+
let m;
|
|
129
|
+
while ((m = simpleRe.exec(code)) !== null) pushTokens(m[1], found);
|
|
130
|
+
const exprLiteralRe = /(?:className|kb)=\{["'`]([^"'`}]+)["'`]\}/g;
|
|
131
|
+
while ((m = exprLiteralRe.exec(code)) !== null) pushTokens(m[1], found);
|
|
132
|
+
const ternaryBlockRe = /(?:className|kb)=\{([^}]{1,500})\}/g;
|
|
133
|
+
while ((m = ternaryBlockRe.exec(code)) !== null) {
|
|
134
|
+
const block = m[1];
|
|
135
|
+
const innerStrings = block.match(/["'`]([^"'`]{1,300})["'`]/g) ?? [];
|
|
136
|
+
for (const s of innerStrings) pushTokens(s.slice(1, -1), found);
|
|
137
|
+
}
|
|
138
|
+
const clsxRe = /(?:clsx|cn|classnames)\(([^)]{1,1000})\)/g;
|
|
139
|
+
while ((m = clsxRe.exec(code)) !== null) {
|
|
140
|
+
const block = m[1];
|
|
141
|
+
const innerStrings = block.match(/["'`]([^"'`]{1,300})["'`]/g) ?? [];
|
|
142
|
+
for (const s of innerStrings) pushTokens(s.slice(1, -1), found);
|
|
143
|
+
}
|
|
144
|
+
const templateRe = /`([^`]{1,2000})`/g;
|
|
145
|
+
while ((m = templateRe.exec(code)) !== null) {
|
|
146
|
+
const staticParts = m[1].replace(/\$\{[^}]*\}/g, " ");
|
|
147
|
+
pushTokens(staticParts, found);
|
|
148
|
+
}
|
|
149
|
+
return [...found];
|
|
150
|
+
}
|
|
151
|
+
function pushTokens(str, into) {
|
|
152
|
+
for (const tok of splitClassTokens(str)) {
|
|
153
|
+
if (tok) into.add(tok);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
119
156
|
function scanDir(dir, onFile) {
|
|
120
157
|
try {
|
|
121
158
|
for (const entry of readdirSync(dir)) {
|
|
@@ -124,41 +161,49 @@ function scanDir(dir, onFile) {
|
|
|
124
161
|
try {
|
|
125
162
|
const st = statSync(full);
|
|
126
163
|
if (st.isDirectory()) scanDir(full, onFile);
|
|
127
|
-
else if (/\.(tsx?|jsx?)$/.test(entry)) onFile(readFileSync(full, "utf-8"));
|
|
164
|
+
else if (/\.(tsx?|jsx?)$/.test(entry)) onFile(full, readFileSync(full, "utf-8"));
|
|
128
165
|
} catch {
|
|
129
166
|
}
|
|
130
167
|
}
|
|
131
168
|
} catch {
|
|
132
169
|
}
|
|
133
170
|
}
|
|
134
|
-
function extractClassStrings(code) {
|
|
135
|
-
const found = [];
|
|
136
|
-
const re = /(?:className|kb)=(?:["']([^"']+)["']|\{["']([^"']+)["']\})/g;
|
|
137
|
-
let m;
|
|
138
|
-
while ((m = re.exec(code)) !== null) {
|
|
139
|
-
const val = m[1] ?? m[2];
|
|
140
|
-
if (val) found.push(val);
|
|
141
|
-
}
|
|
142
|
-
return found;
|
|
143
|
-
}
|
|
144
171
|
function kbach(userConfig) {
|
|
145
172
|
const cfg = buildConfig(userConfig ?? {});
|
|
146
173
|
const screens = toNumericScreens(cfg.theme.screens ?? {});
|
|
147
174
|
let root = process.cwd();
|
|
148
175
|
let mainCSSFile = null;
|
|
149
|
-
|
|
150
|
-
|
|
176
|
+
const fileTokens = /* @__PURE__ */ new Map();
|
|
177
|
+
const tokenCSS = /* @__PURE__ */ new Map();
|
|
178
|
+
function processFile(filePath, code) {
|
|
179
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
180
|
+
for (const cls of extractClassStrings(code)) {
|
|
181
|
+
for (const tok of splitClassTokens(cls)) {
|
|
182
|
+
tokens.add(tok);
|
|
183
|
+
if (!tokenCSS.has(tok)) {
|
|
184
|
+
tokenCSS.set(tok, generateClassCSS(tok, cfg.theme, cfg.darkMode, screens));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
fileTokens.set(filePath, tokens);
|
|
189
|
+
}
|
|
190
|
+
function buildTokenCSSView() {
|
|
191
|
+
const active = /* @__PURE__ */ new Set();
|
|
192
|
+
for (const tokens of fileTokens.values()) for (const t of tokens) active.add(t);
|
|
193
|
+
const view = /* @__PURE__ */ new Map();
|
|
194
|
+
for (const tok of active) {
|
|
195
|
+
const css = tokenCSS.get(tok);
|
|
196
|
+
if (css !== void 0) view.set(tok, css);
|
|
197
|
+
}
|
|
198
|
+
return view;
|
|
199
|
+
}
|
|
200
|
+
function initialScan() {
|
|
151
201
|
for (const dir of ["src", "app", "pages", "components", "views", "layouts"]) {
|
|
152
|
-
scanDir(join(root, dir),
|
|
153
|
-
for (const cls of extractClassStrings(code))
|
|
154
|
-
for (const token of splitClassTokens(cls))
|
|
155
|
-
if (!tokenCSS.has(token)) {
|
|
156
|
-
const css = generateClassCSS(token, cfg.theme, cfg.darkMode, screens);
|
|
157
|
-
tokenCSS.set(token, css);
|
|
158
|
-
}
|
|
159
|
-
});
|
|
202
|
+
scanDir(join(root, dir), processFile);
|
|
160
203
|
}
|
|
161
|
-
|
|
204
|
+
}
|
|
205
|
+
function generateCSS() {
|
|
206
|
+
return formatKbachCSS(buildTokenCSSView(), cfg.theme);
|
|
162
207
|
}
|
|
163
208
|
return {
|
|
164
209
|
name: "kbach",
|
|
@@ -168,10 +213,16 @@ function kbach(userConfig) {
|
|
|
168
213
|
},
|
|
169
214
|
buildStart() {
|
|
170
215
|
mainCSSFile = findMainCSSFile(root);
|
|
216
|
+
initialScan();
|
|
171
217
|
if (mainCSSFile) writeKbachToFile(mainCSSFile, generateCSS());
|
|
172
218
|
},
|
|
173
219
|
handleHotUpdate({ file }) {
|
|
174
220
|
if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
|
|
221
|
+
try {
|
|
222
|
+
processFile(file, readFileSync(file, "utf-8"));
|
|
223
|
+
} catch {
|
|
224
|
+
fileTokens.delete(file);
|
|
225
|
+
}
|
|
175
226
|
if (mainCSSFile) writeKbachToFile(mainCSSFile, generateCSS());
|
|
176
227
|
}
|
|
177
228
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kbach/react",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.40",
|
|
4
4
|
"description": "React / React Native components and hooks for the Kbach framework",
|
|
5
5
|
"source": "./src/index.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -72,6 +72,8 @@
|
|
|
72
72
|
"files": [
|
|
73
73
|
"dist",
|
|
74
74
|
"scripts",
|
|
75
|
-
"
|
|
75
|
+
"types.d.ts",
|
|
76
|
+
"kbach-react.md",
|
|
77
|
+
"README.md"
|
|
76
78
|
]
|
|
77
79
|
}
|
package/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference path="./src/kbach-env.d.ts" />
|
|
@@ -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 };
|