@kbach/react 0.5.25 → 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.
@@ -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 candidates = [
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
- scanDir(full, onFile);
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,18 +3486,11 @@ 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 ?? {});
3426
3492
  const tokenCSS = /* @__PURE__ */ new Map();
3427
3493
  let root = process.cwd();
3428
- let server = null;
3429
3494
  let mainCSSFile = null;
3430
3495
  function processToken(token) {
3431
3496
  if (tokenCSS.has(token)) return false;
@@ -3434,21 +3499,13 @@ function kbach(userConfig) {
3434
3499
  }
3435
3500
  function extractFromCode(code) {
3436
3501
  let added = false;
3437
- for (const cls of extractClassStrings(code)) {
3438
- 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))
3439
3504
  if (processToken(token)) added = true;
3440
- }
3441
- }
3442
3505
  return added;
3443
3506
  }
3444
- function getAllCSS() {
3445
- const parts = [];
3446
- const global = buildGlobalCSS(cfg.theme);
3447
- if (global) parts.push(global);
3448
- for (const css of tokenCSS.values()) {
3449
- if (css) parts.push(css);
3450
- }
3451
- return parts.join("\n");
3507
+ function getFormattedCSS() {
3508
+ return formatKbachCSS(tokenCSS, cfg.theme);
3452
3509
  }
3453
3510
  return {
3454
3511
  name: "kbach",
@@ -3456,37 +3513,28 @@ function kbach(userConfig) {
3456
3513
  configResolved(resolved) {
3457
3514
  root = resolved.root;
3458
3515
  },
3459
- configureServer(s) {
3460
- server = s;
3461
- },
3462
3516
  buildStart() {
3463
- for (const dir of ["src", "app", "pages", "components", "views", "layouts"]) {
3517
+ for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
3464
3518
  scanDir((0, import_path.join)(root, dir), (code) => extractFromCode(code));
3465
- }
3466
3519
  mainCSSFile = findMainCSSFile(root);
3467
- if (mainCSSFile) writeKbachToFile(mainCSSFile, getAllCSS());
3520
+ if (mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
3468
3521
  },
3469
3522
  transform(code, id) {
3470
3523
  const cleanId = id.split("?")[0];
3471
- if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules")) {
3524
+ if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
3472
3525
  extractFromCode(code);
3473
- }
3474
3526
  },
3475
- // ── Virtual module (opt-in explicit import) ───────────────────────────────
3476
3527
  resolveId(id) {
3477
3528
  if (id === VIRTUAL_ID) return RESOLVED_ID;
3478
3529
  },
3479
3530
  load(id) {
3480
- if (id === RESOLVED_ID) return getAllCSS();
3531
+ if (id === RESOLVED_ID) return getFormattedCSS();
3481
3532
  },
3482
- // ── HMR: write updated CSS to file when new classes are found ────────────
3483
- // Vite's own file watcher detects the change and hot-reloads the CSS —
3484
- // no manual invalidation needed.
3485
3533
  handleHotUpdate({ file }) {
3486
3534
  if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
3487
3535
  try {
3488
3536
  const added = extractFromCode((0, import_fs.readFileSync)(file, "utf-8"));
3489
- if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getAllCSS());
3537
+ if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
3490
3538
  } catch {
3491
3539
  }
3492
3540
  }
@@ -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 candidates = [
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
- scanDir(full, onFile);
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,18 +144,11 @@ 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 ?? {});
84
150
  const tokenCSS = /* @__PURE__ */ new Map();
85
151
  let root = process.cwd();
86
- let server = null;
87
152
  let mainCSSFile = null;
88
153
  function processToken(token) {
89
154
  if (tokenCSS.has(token)) return false;
@@ -92,21 +157,13 @@ function kbach(userConfig) {
92
157
  }
93
158
  function extractFromCode(code) {
94
159
  let added = false;
95
- for (const cls of extractClassStrings(code)) {
96
- 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))
97
162
  if (processToken(token)) added = true;
98
- }
99
- }
100
163
  return added;
101
164
  }
102
- function getAllCSS() {
103
- const parts = [];
104
- const global = buildGlobalCSS(cfg.theme);
105
- if (global) parts.push(global);
106
- for (const css of tokenCSS.values()) {
107
- if (css) parts.push(css);
108
- }
109
- return parts.join("\n");
165
+ function getFormattedCSS() {
166
+ return formatKbachCSS(tokenCSS, cfg.theme);
110
167
  }
111
168
  return {
112
169
  name: "kbach",
@@ -114,37 +171,28 @@ function kbach(userConfig) {
114
171
  configResolved(resolved) {
115
172
  root = resolved.root;
116
173
  },
117
- configureServer(s) {
118
- server = s;
119
- },
120
174
  buildStart() {
121
- for (const dir of ["src", "app", "pages", "components", "views", "layouts"]) {
175
+ for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
122
176
  scanDir(join(root, dir), (code) => extractFromCode(code));
123
- }
124
177
  mainCSSFile = findMainCSSFile(root);
125
- if (mainCSSFile) writeKbachToFile(mainCSSFile, getAllCSS());
178
+ if (mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
126
179
  },
127
180
  transform(code, id) {
128
181
  const cleanId = id.split("?")[0];
129
- if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules")) {
182
+ if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
130
183
  extractFromCode(code);
131
- }
132
184
  },
133
- // ── Virtual module (opt-in explicit import) ───────────────────────────────
134
185
  resolveId(id) {
135
186
  if (id === VIRTUAL_ID) return RESOLVED_ID;
136
187
  },
137
188
  load(id) {
138
- if (id === RESOLVED_ID) return getAllCSS();
189
+ if (id === RESOLVED_ID) return getFormattedCSS();
139
190
  },
140
- // ── HMR: write updated CSS to file when new classes are found ────────────
141
- // Vite's own file watcher detects the change and hot-reloads the CSS —
142
- // no manual invalidation needed.
143
191
  handleHotUpdate({ file }) {
144
192
  if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
145
193
  try {
146
194
  const added = extractFromCode(readFileSync(file, "utf-8"));
147
- if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getAllCSS());
195
+ if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
148
196
  } catch {
149
197
  }
150
198
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react",
3
- "version": "0.5.25",
3
+ "version": "0.5.27",
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",
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 };
@@ -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,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 };
@@ -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
- }
@@ -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 };
@@ -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 };