@kbach/react 1.0.0-beta.5 → 1.0.0-beta.7
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 +136 -7
- package/dist/chunk-P4CQSYIL.mjs +1340 -0
- package/dist/postcss-plugin.d.mts +36 -0
- package/dist/postcss-plugin.d.ts +36 -0
- package/dist/postcss-plugin.js +1119 -0
- package/dist/postcss-plugin.mjs +79 -0
- package/dist/vite-plugin.d.mts +52 -5
- package/dist/vite-plugin.d.ts +52 -5
- package/dist/vite-plugin.js +326 -309
- package/dist/vite-plugin.mjs +12 -1320
- package/package.json +12 -1
package/README.md
CHANGED
|
@@ -32,14 +32,11 @@ export default defineConfig({
|
|
|
32
32
|
|
|
33
33
|
```tsx
|
|
34
34
|
// main.tsx
|
|
35
|
-
import { initKbach } from '@kbach/react';
|
|
36
35
|
import { createRoot } from 'react-dom/client';
|
|
37
36
|
import App from './App';
|
|
38
37
|
import './kbach.css';
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
createRoot(document.getElementById('root')!).render(<App />);
|
|
42
|
-
});
|
|
39
|
+
createRoot(document.getElementById('root')!).render(<App />);
|
|
43
40
|
```
|
|
44
41
|
|
|
45
42
|
```tsx
|
|
@@ -48,6 +45,134 @@ initKbach().then(() => {
|
|
|
48
45
|
</div>
|
|
49
46
|
```
|
|
50
47
|
|
|
48
|
+
That's the whole setup — the Vite plugin config plus a `kbach.css` with the
|
|
49
|
+
two marker comments. No `initKbach()`/async step before your first render:
|
|
50
|
+
`className` here is a plain string prop, resolved entirely by the CSS
|
|
51
|
+
`@kbach/react/vite` already generated at build time, same as any other
|
|
52
|
+
static stylesheet — nothing here calls into the WASM engine at render time,
|
|
53
|
+
so there's nothing to await.
|
|
54
|
+
|
|
55
|
+
`initKbach()` (still exported from `@kbach/react`) is only needed for two
|
|
56
|
+
opt-in features that genuinely do call into the Rust/WASM engine at
|
|
57
|
+
runtime: the dynamic [`kb()`](#dynamic-classes) function, and the optional
|
|
58
|
+
`@kbach/react/jsx-runtime` (a `jsxImportSource` override that intercepts
|
|
59
|
+
*every* element's `className` automatically instead of relying on the
|
|
60
|
+
static build). If you use either, `await initKbach()` once before your
|
|
61
|
+
first render, same as before.
|
|
62
|
+
|
|
63
|
+
## React Router
|
|
64
|
+
|
|
65
|
+
React Router is a client-side routing library with no build-tool coupling
|
|
66
|
+
of its own, so it layers on top of the exact same Vite + `kbach.css` setup
|
|
67
|
+
either way — but which "either way" depends on which of React Router's two
|
|
68
|
+
genuinely different modes you're using.
|
|
69
|
+
|
|
70
|
+
**Library mode** (you call `createRoot` yourself — `createBrowserRouter` +
|
|
71
|
+
`<RouterProvider>`, or the classic `<BrowserRouter>` component): needs
|
|
72
|
+
nothing beyond the Quick Start above.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
// main.tsx
|
|
76
|
+
import { createRoot } from 'react-dom/client';
|
|
77
|
+
import { RouterProvider, createBrowserRouter } from 'react-router';
|
|
78
|
+
import './kbach.css';
|
|
79
|
+
import Home from './routes/home';
|
|
80
|
+
import About from './routes/about';
|
|
81
|
+
|
|
82
|
+
const router = createBrowserRouter([
|
|
83
|
+
{ path: '/', Component: Home },
|
|
84
|
+
{ path: '/about', Component: About },
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
createRoot(document.getElementById('root')!).render(<RouterProvider router={router} />);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Framework mode** (`npx create-react-router@latest` — file-based routing
|
|
91
|
+
under `app/`, its own Vite plugin, SSR by default): two things differ from
|
|
92
|
+
the Quick Start, both because this mode owns your project's structure and
|
|
93
|
+
render lifecycle, not you:
|
|
94
|
+
|
|
95
|
+
1. Its convention is `app/`, not `src/` — pass `cssFile` so the plugin
|
|
96
|
+
writes to `app/kbach.css` instead of the (here, nonexistent) default:
|
|
97
|
+
```ts
|
|
98
|
+
// vite.config.ts
|
|
99
|
+
import { reactRouter } from '@react-router/dev/vite';
|
|
100
|
+
import { kbach } from '@kbach/react/vite';
|
|
101
|
+
import { defineConfig } from 'vite';
|
|
102
|
+
|
|
103
|
+
export default defineConfig({
|
|
104
|
+
plugins: [kbach({ cssFile: 'app/kbach.css' }), reactRouter()],
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
2. **Don't call `createRoot` yourself in `app/root.tsx`** — the framework's
|
|
108
|
+
own generated client/server entry points already do this; `root.tsx`
|
|
109
|
+
only ever *exports* a `Layout`/default component. Adding your own
|
|
110
|
+
`createRoot(...).render(...)` at that file's top level runs during SSR
|
|
111
|
+
too, where `document` doesn't exist, and crashes the build immediately.
|
|
112
|
+
`app/root.tsx` needs only:
|
|
113
|
+
```tsx
|
|
114
|
+
import './kbach.css';
|
|
115
|
+
export default function App() {
|
|
116
|
+
return <Outlet />;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Either mode: every route's own components use `className` exactly like any
|
|
121
|
+
other component — routing has no effect on how Kbach resolves classes,
|
|
122
|
+
since resolution already happened at build time, before routing even
|
|
123
|
+
enters the picture.
|
|
124
|
+
|
|
125
|
+
## Next.js
|
|
126
|
+
|
|
127
|
+
Next.js uses webpack/Turbopack, not Vite, so `@kbach/react/vite` doesn't
|
|
128
|
+
apply — use `@kbach/react/postcss` instead, which does the exact same
|
|
129
|
+
build-time class-string scanning and CSS generation (they share the same
|
|
130
|
+
underlying engine), just wired into PostCSS, which both of Next.js's
|
|
131
|
+
bundlers already run for you with zero extra config.
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
// postcss.config.js
|
|
135
|
+
module.exports = {
|
|
136
|
+
plugins: {
|
|
137
|
+
'@kbach/react/postcss': {},
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```css
|
|
143
|
+
/* app/globals.css (App Router) or styles/globals.css (Pages Router) */
|
|
144
|
+
/* kbach:start */
|
|
145
|
+
/* kbach:end */
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
// app/layout.tsx
|
|
150
|
+
import './globals.css';
|
|
151
|
+
|
|
152
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
153
|
+
return (
|
|
154
|
+
<html lang="en">
|
|
155
|
+
<body>{children}</body>
|
|
156
|
+
</html>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Plain `className="..."` strings on Server Components work with zero extra
|
|
162
|
+
setup — the CSS already exists at build time, same as any other static
|
|
163
|
+
stylesheet. Hook-based exports (`useTheme`, `useColors`, `<ThemeProvider>`)
|
|
164
|
+
already carry their own `'use client'` directive, so importing them into a
|
|
165
|
+
Client Component just works; importing one into a Server Component is a
|
|
166
|
+
compile-time error the same way importing `useState` into one would be —
|
|
167
|
+
that's React's own rule, not a Kbach limitation.
|
|
168
|
+
|
|
169
|
+
`root`/`theme`/`config`/`include`/`safelist` options all match
|
|
170
|
+
`@kbach/react/vite`'s exactly (see `KbachPluginOptions`, above) — `root`
|
|
171
|
+
additionally defaults to `process.cwd()` rather than a bundler-resolved
|
|
172
|
+
project root, since PostCSS has no equivalent to Vite's own resolved
|
|
173
|
+
`root` to read; pass it explicitly if your `postcss.config.js` doesn't
|
|
174
|
+
live at your project root (e.g. a monorepo app).
|
|
175
|
+
|
|
51
176
|
## Dark mode
|
|
52
177
|
|
|
53
178
|
```tsx
|
|
@@ -77,16 +202,20 @@ setTheme({
|
|
|
77
202
|
## Dynamic classes
|
|
78
203
|
|
|
79
204
|
Classes that appear literally in your source are resolved at build time.
|
|
80
|
-
For classes assembled from truly dynamic data, use `kb()
|
|
205
|
+
For classes assembled from truly dynamic data, use `kb()` — this is the
|
|
206
|
+
one thing in this package that genuinely calls into the WASM engine at
|
|
207
|
+
runtime, so `await initKbach()` once at startup before the first `kb()`
|
|
208
|
+
call (or before rendering, if you can't guarantee it runs first otherwise):
|
|
81
209
|
|
|
82
210
|
```ts
|
|
83
|
-
import { kb } from '@kbach/react';
|
|
211
|
+
import { initKbach, kb } from '@kbach/react';
|
|
84
212
|
|
|
213
|
+
await initKbach();
|
|
85
214
|
const className = kb(`bg-${userColor}-6`);
|
|
86
215
|
```
|
|
87
216
|
|
|
88
217
|
Prefer a `safelist` entry in the plugin config when the possible values are
|
|
89
|
-
known ahead of time — keeps everything static.
|
|
218
|
+
known ahead of time — keeps everything static, no `initKbach()` needed.
|
|
90
219
|
|
|
91
220
|
## Reading colors as values
|
|
92
221
|
|