@kbach/react 0.6.25 → 0.6.28

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 CHANGED
@@ -36,36 +36,13 @@ That's the only setting needed — Vite, Next.js, and React Router all read it.
36
36
 
37
37
  | Framework | Use |
38
38
  |---|---|
39
- | Next.js | **[Runtime setup](#runtime-setup)** — Static CSS doesn't apply (webpack/Turbopack, not Vite) |
39
+ | Vite, React Router library mode, CRA, other Vite-based | **[Static CSS setup](#static-css-setup)** (recommended) — zero runtime cost, catches typos at build time. [Runtime setup](#runtime-setup) is there if you'd rather skip the plugin for now. |
40
40
  | React Router, framework mode | **[Static CSS setup](#static-css-setup)** — and skip `@vitejs/plugin-react`, see note in that section |
41
- | Vite, React Router library mode, CRA, other | Either — Runtime is faster to try, Static CSS is zero-cost for production |
42
-
43
- ## Runtime setup
44
-
45
- Client-side CSS injection — works with any bundler (Vite, webpack, Turbopack, Metro-for-web, …), no build plugin. This is the whole setup:
46
-
47
- ```jsx
48
- import { ThemeProvider, KbachReset } from '@kbach/react';
49
-
50
- export default function Root() {
51
- return (
52
- <ThemeProvider defaultMode="system">
53
- <KbachReset />
54
- <App />
55
- </ThemeProvider>
56
- );
57
- }
58
- ```
59
-
60
- That's it — done. `<KbachReset />` renders the base reset (see [CSS resets](#css-resets)) as real markup instead of waiting on client JS — matters most for SSR, where it avoids a flash of unstyled browser defaults before hydration. `@kbach/react` ships its own `"use client"` directive, so this works in a Next.js Server Component tree with no wrapper needed — in Next.js, render it once in the root `layout.tsx`.
61
-
62
- Using a custom `kbach.config.js`? Pass it to `ThemeProvider` too — see [Wiring the config in](#wiring-the-config-in--required-for-both-setups).
63
-
64
- Don't also set up Static CSS below in the same app — pick one.
41
+ | Next.js | **[Runtime setup](#runtime-setup)** — Static CSS doesn't apply (webpack/Turbopack, not Vite) |
65
42
 
66
43
  ## Static CSS setup
67
44
 
68
- Vite only. A build-time plugin writes real CSS into a file you import at build time — nothing generated client-side, zero runtime cost. Three pieces, all required:
45
+ Vite only, and the recommended setup for any Vite-based app — a build-time plugin writes real CSS into a file you import at build time, so nothing is generated client-side and there's zero runtime cost. Three pieces, all required:
69
46
 
70
47
  **1. Add the plugin:**
71
48
 
@@ -90,6 +67,8 @@ export default defineConfig({ plugins: [kbach()] });
90
67
  import './kbach.css';
91
68
  ```
92
69
 
70
+ This import is what actually switches the app over to Static CSS — the plugin alone only generates the file; without importing it, runtime injection stays active and you get both at once.
71
+
93
72
  **3. Wrap your app — no `<KbachReset />` here, `kbach.css` already includes the reset:**
94
73
 
95
74
  ```jsx
@@ -100,7 +79,7 @@ export default function Root() {
100
79
  }
101
80
  ```
102
81
 
103
- Done. The plugin scans your source at build time and writes CSS between the markers — importing `kbach.css` auto-disables runtime injection, so there's no double-styling between this and the Runtime setup above. It also warns in the terminal (with a clickable `file:line`) for any class it doesn't recognize as a real utility or an existing CSS rule elsewhere in the project — usually a typo.
82
+ Done. The plugin scans your source at build time and writes CSS between the markers — importing `kbach.css` auto-disables runtime injection, so there's no double-styling between this and Runtime setup below. It also warns in the terminal (with a clickable `file:line`) for any class it doesn't recognize as a real utility or an existing CSS rule elsewhere in the project — usually a typo.
104
83
 
105
84
  Using a custom `kbach.config.js`? It needs to be wired in **twice** here — once to `kbach()` above (step 1) so the generated CSS reflects it, and once to `ThemeProvider` (step 3) so dark mode/`useColors()`/animations do too. See [Wiring the config in](#wiring-the-config-in--required-for-both-setups) — easy to only do one and have the other silently fall back to defaults.
106
85
 
@@ -117,6 +96,29 @@ export default defineConfig({ plugins: [kbach(), reactRouter()] });
117
96
 
118
97
  (React Router library mode — `createBrowserRouter`, no SSR — has no such conflict; set it up like any Vite + React app.)
119
98
 
99
+ ## Runtime setup
100
+
101
+ Client-side CSS injection — works with any bundler (Vite, webpack, Turbopack, Metro-for-web, …), no build plugin. The right choice for Next.js (Static CSS doesn't apply there), or if you'd rather not wire up a Vite plugin yet. This is the whole setup:
102
+
103
+ ```jsx
104
+ import { ThemeProvider, KbachReset } from '@kbach/react';
105
+
106
+ export default function Root() {
107
+ return (
108
+ <ThemeProvider defaultMode="system">
109
+ <KbachReset />
110
+ <App />
111
+ </ThemeProvider>
112
+ );
113
+ }
114
+ ```
115
+
116
+ That's it — done. `<KbachReset />` renders the base reset (see [CSS resets](#css-resets)) as real markup instead of waiting on client JS — matters most for SSR, where it avoids a flash of unstyled browser defaults before hydration. `@kbach/react` ships its own `"use client"` directive, so this works in a Next.js Server Component tree with no wrapper needed — in Next.js, render it once in the root `layout.tsx`.
117
+
118
+ Using a custom `kbach.config.js`? Pass it to `ThemeProvider` too — see [Wiring the config in](#wiring-the-config-in--required-for-both-setups).
119
+
120
+ Don't also set up Static CSS above in the same app — pick one.
121
+
120
122
  ## Dark mode
121
123
 
122
124
  `<ThemeProvider>` powers every `dark:` class — detects OS color scheme, persists the user's choice, re-renders on change.
@@ -218,6 +220,30 @@ colors.blue['6/50'] // 'rgba(59,130,246,0.5)'
218
220
  colors.alpha('#ff6b35', 60) // 'rgba(255,107,53,0.6)'
219
221
  ```
220
222
 
223
+ ### Typed theme tokens
224
+
225
+ `useColors()` and `useSpacing()` are typed against the built-in theme by default (`DefaultColorName`/`DefaultSpacingKey`), so TypeScript autocompletes real color/spacing names and flags a typo (`colors.blu`, `spacing.ful`) as an error — no setup needed if you're on the default theme.
226
+
227
+ ```ts
228
+ import { useSpacing } from '@kbach/react';
229
+
230
+ const spacing = useSpacing();
231
+ spacing[4] // 16
232
+ spacing.full // '100%'
233
+ spacing['1/2'] // '50%'
234
+ ```
235
+
236
+ A customized `kbach.config.js` isn't visible to TypeScript — it's a plain `.js` file loaded at runtime, not a statically-analyzed module — so a project with extra colors or spacing keys needs to widen the type parameter by hand:
237
+
238
+ ```ts
239
+ import { useColors, type DefaultColorName } from '@kbach/react';
240
+
241
+ const colors = useColors<DefaultColorName | 'brand'>();
242
+ colors.brand[6] // now type-checks
243
+ ```
244
+
245
+ This only affects the exported *types* — `useColors()`/`useSpacing()` called with no type argument behave exactly as before at runtime. If existing code was relying on a color/spacing name TypeScript couldn't previously catch (the old types had a blanket `[key: string]: any`), this may surface a new type error — the fix is the escape-hatch pattern above, not a code change.
246
+
221
247
  ## Modifiers
222
248
 
223
249
  Chain in any order: `<div className="dark:sm:hover:p-4" />`