@kbach/react 0.5.33 → 0.5.35
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 +13 -1
- package/dist/{chunk-VZD4672I.mjs → chunk-65BTN2UR.mjs} +2 -2
- package/dist/{chunk-X6FH5QTD.mjs → chunk-VRYE5CAE.mjs} +1 -1
- package/dist/{chunk-SOBLKZGE.mjs → chunk-YU55J6F6.mjs} +477 -437
- package/dist/index.js +472 -437
- package/dist/index.mjs +2 -2
- package/dist/jsx-dev-runtime.js +472 -437
- package/dist/jsx-dev-runtime.mjs +3 -3
- package/dist/jsx-runtime.js +472 -437
- package/dist/jsx-runtime.mjs +3 -3
- package/dist/vite-plugin.js +489 -450
- package/dist/vite-plugin.mjs +6 -3
- package/kbach-react.md +778 -0
- package/package.json +2 -2
- package/KBACH.md +0 -952
package/kbach-react.md
ADDED
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
# Kbach React — Complete AI Reference
|
|
2
|
+
|
|
3
|
+
Kbach is a Tailwind-like utility CSS framework for React (web). Classes are written as `className` strings and resolved at render time through a custom JSX runtime. On web, stateful and structural CSS rules are injected into the page so they work with the browser cascade. A Vite plugin generates a physical `app.css` file for static CSS delivery.
|
|
4
|
+
|
|
5
|
+
Package: `@kbach/react`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
### tsconfig.json
|
|
12
|
+
```json
|
|
13
|
+
{ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "@kbach/react" } }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### vite.config.ts
|
|
17
|
+
```ts
|
|
18
|
+
import { defineConfig } from 'vite';
|
|
19
|
+
import react from '@vitejs/plugin-react';
|
|
20
|
+
import { kbach } from '@kbach/react/vite';
|
|
21
|
+
|
|
22
|
+
export default defineConfig({
|
|
23
|
+
plugins: [
|
|
24
|
+
react({ jsxImportSource: '@kbach/react' }),
|
|
25
|
+
kbach(), // generates / updates app.css on every HMR event
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Babel (non-Vite)
|
|
31
|
+
```js
|
|
32
|
+
module.exports = {
|
|
33
|
+
presets: [['@babel/preset-react', { runtime: 'automatic', importSource: '@kbach/react' }]],
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Per-file (no config needed)
|
|
38
|
+
```jsx
|
|
39
|
+
/** @jsxImportSource @kbach/react */
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Wrap app
|
|
43
|
+
```jsx
|
|
44
|
+
import { ThemeProvider } from '@kbach/react';
|
|
45
|
+
<ThemeProvider defaultMode="system"><App /></ThemeProvider>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Vite Plugin
|
|
51
|
+
|
|
52
|
+
The `kbach()` Vite plugin scans your source files and writes generated CSS between `/* kbach:start */` / `/* kbach:end */` markers in your main CSS file (`app/app.css`, `src/index.css`, etc.).
|
|
53
|
+
|
|
54
|
+
- Runs on `buildStart` (initial load) and on every HMR file change
|
|
55
|
+
- Stateless: rescans all files fresh every time — removed classes are immediately evicted
|
|
56
|
+
- Output is grouped by category with CSS custom properties for theme colors
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// vite.config.ts
|
|
60
|
+
import { kbach } from '@kbach/react/vite';
|
|
61
|
+
|
|
62
|
+
kbach({
|
|
63
|
+
darkMode: 'attribute',
|
|
64
|
+
theme: {
|
|
65
|
+
colors: { brand: { 6: '#6366f1' } },
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Generated output format:
|
|
71
|
+
```css
|
|
72
|
+
/* kbach:start */
|
|
73
|
+
/* Generated by Kbach — do not edit */
|
|
74
|
+
|
|
75
|
+
:root {
|
|
76
|
+
--color-blue-6: #3b82f6;
|
|
77
|
+
--color-gray-10: #111827;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Layout */
|
|
81
|
+
.flex { display: flex }
|
|
82
|
+
.items-center { align-items: center }
|
|
83
|
+
|
|
84
|
+
/* Sizing */
|
|
85
|
+
.w-full { width: 100% }
|
|
86
|
+
.w-\[200px\] { width: 200px }
|
|
87
|
+
|
|
88
|
+
/* Dark Mode */
|
|
89
|
+
[data-theme="dark"] .dark\:bg-gray-10 { background-color: var(--color-gray-10) }
|
|
90
|
+
/* kbach:end */
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Core API
|
|
96
|
+
|
|
97
|
+
### className prop
|
|
98
|
+
Works on any element once the JSX runtime is active.
|
|
99
|
+
```jsx
|
|
100
|
+
<div className="bg-white dark:bg-gray-10 p-4 rounded-xl shadow" />
|
|
101
|
+
<p className="text-gray-10 text-lg font-bold" />
|
|
102
|
+
<button className="bg-blue-7 hover:bg-blue-8 rounded-lg px-4 py-2" />
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### styled(Component, baseClasses)
|
|
106
|
+
Pre-style a component. Returns a new component that accepts a `kb` prop for extra classes. Forwards the full class string as `className` so CSS rules (group-hover:, before:, print:) match the element.
|
|
107
|
+
```jsx
|
|
108
|
+
import { styled } from '@kbach/react';
|
|
109
|
+
|
|
110
|
+
const Card = styled('div', 'bg-white dark:bg-gray-9 rounded-2xl p-6 shadow');
|
|
111
|
+
const Button = styled('button', 'bg-blue-7 hover:bg-blue-8 rounded-xl px-6 py-3');
|
|
112
|
+
|
|
113
|
+
<Card kb="mt-4"> // merges mt-4 with base classes
|
|
114
|
+
<Button kb="w-full" /> // merges w-full with base classes
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### useStyles(classes)
|
|
118
|
+
Resolve classes to a style object inside a component.
|
|
119
|
+
```jsx
|
|
120
|
+
import { useStyles } from '@kbach/react';
|
|
121
|
+
const style = useStyles('bg-blue-6 px-3 py-1 rounded-full');
|
|
122
|
+
return <span style={style}>Badge</span>;
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### kb(classes)
|
|
126
|
+
Resolve outside a component (static contexts).
|
|
127
|
+
```js
|
|
128
|
+
import { kb } from '@kbach/react';
|
|
129
|
+
const cardStyle = kb('bg-white p-4 rounded-xl') as React.CSSProperties;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### cx(...classes)
|
|
133
|
+
Conditionally join class strings. Falsy values ignored.
|
|
134
|
+
```jsx
|
|
135
|
+
import { cx } from '@kbach/react';
|
|
136
|
+
<div className={cx('p-4', isActive && 'border-2 border-blue-6', isDisabled && 'opacity-50')} />
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### useTheme()
|
|
140
|
+
```ts
|
|
141
|
+
const { mode, resolvedMode, isDark, setMode, toggle, config } = useTheme();
|
|
142
|
+
// mode: 'light' | 'dark' | 'system'
|
|
143
|
+
// resolvedMode: 'light' | 'dark'
|
|
144
|
+
// isDark: boolean
|
|
145
|
+
// setMode(mode): void
|
|
146
|
+
// toggle(): void
|
|
147
|
+
// config: ResolvedConfig
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### useIsDark()
|
|
151
|
+
```ts
|
|
152
|
+
const isDark = useIsDark(); // boolean
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### useColors()
|
|
156
|
+
Returns a proxy over the active theme's color palette.
|
|
157
|
+
```ts
|
|
158
|
+
const colors = useColors();
|
|
159
|
+
colors.blue[6] // '#3b82f6'
|
|
160
|
+
colors.blue['6/50'] // 'rgba(59,130,246,0.5)'
|
|
161
|
+
colors.white // '#ffffff'
|
|
162
|
+
colors['white/20'] // 'rgba(255,255,255,0.2)'
|
|
163
|
+
colors.alpha('#ff6b35', 60) // 'rgba(255,107,53,0.6)'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### ThemeToggle
|
|
167
|
+
```jsx
|
|
168
|
+
<ThemeToggle /> // button (default)
|
|
169
|
+
<ThemeToggle variant="switch" /> // toggle switch
|
|
170
|
+
<ThemeToggle variant="icon-button" /> // icon button
|
|
171
|
+
<ThemeToggle variant="button" includeSystem /> // three-way light/dark/system
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Modifier System
|
|
177
|
+
|
|
178
|
+
Up to 3 modifiers can be chained in any order before the utility name.
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
dark:hover:bg-blue-8
|
|
182
|
+
sm:dark:text-lg
|
|
183
|
+
motion-reduce:transition-none
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Theme modifiers
|
|
187
|
+
| Modifier | Condition |
|
|
188
|
+
|---|---|
|
|
189
|
+
| `dark:` | Dark mode active |
|
|
190
|
+
| `light:` | Light mode active |
|
|
191
|
+
| `not-dark:` | Light mode active (alias) |
|
|
192
|
+
| `not-light:` | Dark mode active (alias) |
|
|
193
|
+
|
|
194
|
+
Dark mode strategy set in `ThemeProvider` or config:
|
|
195
|
+
- `'attribute'` (default) — `[data-theme="dark"]` on a wrapper element
|
|
196
|
+
- `'class'` — `.dark` class on a wrapper element
|
|
197
|
+
- `'media'` — `@media (prefers-color-scheme: dark)`
|
|
198
|
+
|
|
199
|
+
### Interaction modifiers
|
|
200
|
+
| Modifier | Triggers on |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `hover:` | Mouse hover |
|
|
203
|
+
| `focus:` | Element focused |
|
|
204
|
+
| `focus-within:` | Focus anywhere inside element |
|
|
205
|
+
| `focus-visible:` | Keyboard focus ring |
|
|
206
|
+
| `active:` | Active state |
|
|
207
|
+
| `pressed:` | Click / touch pressed |
|
|
208
|
+
| `visited:` | Visited link |
|
|
209
|
+
| `disabled:` | Disabled element |
|
|
210
|
+
| `checked:` | Checkbox / radio checked |
|
|
211
|
+
| `placeholder:` | Input placeholder text |
|
|
212
|
+
|
|
213
|
+
Negated: `not-hover:`, `not-focus:`, `not-active:`, `not-pressed:`, `not-visited:`, `not-disabled:`, `not-checked:`
|
|
214
|
+
|
|
215
|
+
### Structural modifiers
|
|
216
|
+
| Modifier | Pseudo-class |
|
|
217
|
+
|---|---|
|
|
218
|
+
| `first:` | `:first-child` |
|
|
219
|
+
| `last:` | `:last-child` |
|
|
220
|
+
| `odd:` | `:nth-child(odd)` |
|
|
221
|
+
| `even:` | `:nth-child(even)` |
|
|
222
|
+
| `only:` | `:only-child` |
|
|
223
|
+
|
|
224
|
+
### Responsive modifiers
|
|
225
|
+
| Modifier | Min-width |
|
|
226
|
+
|---|---|
|
|
227
|
+
| `sm:` | 576 px |
|
|
228
|
+
| `md:` | 768 px |
|
|
229
|
+
| `lg:` | 1024 px |
|
|
230
|
+
| `xl:` | 1280 px |
|
|
231
|
+
| `2xl:` | 1536 px |
|
|
232
|
+
|
|
233
|
+
Responsive styles are handled via `@media (min-width)` CSS rules — no JS breakpoint tracking.
|
|
234
|
+
|
|
235
|
+
### Group / peer modifiers
|
|
236
|
+
Mark a parent with `group`, then use `group-hover:` etc. on children.
|
|
237
|
+
|
|
238
|
+
```jsx
|
|
239
|
+
<div className="group">
|
|
240
|
+
<span className="opacity-0 group-hover:opacity-100 transition" />
|
|
241
|
+
</div>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
| Modifier | Fires when |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `group-hover:` | Ancestor `.group` is hovered |
|
|
247
|
+
| `group-focus:` | Ancestor `.group` is focused |
|
|
248
|
+
| `peer-hover:` | Previous sibling `.peer` is hovered |
|
|
249
|
+
| `peer-focus:` | Previous sibling `.peer` is focused |
|
|
250
|
+
|
|
251
|
+
### Pseudo-element modifiers
|
|
252
|
+
```jsx
|
|
253
|
+
<div className="before:content-['*'] before:text-red-6 relative" />
|
|
254
|
+
<p className="first-letter:text-4xl first-letter:font-bold" />
|
|
255
|
+
<p className="selection:bg-blue-3" />
|
|
256
|
+
<input className="placeholder:text-gray-5" />
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
| Modifier | CSS selector |
|
|
260
|
+
|---|---|
|
|
261
|
+
| `before:` | `::before` |
|
|
262
|
+
| `after:` | `::after` |
|
|
263
|
+
| `selection:` | `::selection` |
|
|
264
|
+
| `first-letter:` | `::first-letter` |
|
|
265
|
+
| `first-line:` | `::first-line` |
|
|
266
|
+
| `marker:` | `::marker` |
|
|
267
|
+
| `placeholder:` | `::placeholder` |
|
|
268
|
+
|
|
269
|
+
### Print modifier
|
|
270
|
+
```jsx
|
|
271
|
+
<div className="print:hidden" />
|
|
272
|
+
<div className="print:text-black print:bg-white" />
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Orientation modifiers
|
|
276
|
+
| Modifier | Media query |
|
|
277
|
+
|---|---|
|
|
278
|
+
| `landscape:` | `@media (orientation: landscape)` |
|
|
279
|
+
| `portrait:` | `@media (orientation: portrait)` |
|
|
280
|
+
|
|
281
|
+
### Accessibility modifiers
|
|
282
|
+
| Modifier | Media query |
|
|
283
|
+
|---|---|
|
|
284
|
+
| `motion-reduce:` | `@media (prefers-reduced-motion: reduce)` |
|
|
285
|
+
| `motion-safe:` | `@media (prefers-reduced-motion: no-preference)` |
|
|
286
|
+
| `contrast-more:` | `@media (prefers-contrast: more)` |
|
|
287
|
+
| `contrast-less:` | `@media (prefers-contrast: less)` |
|
|
288
|
+
|
|
289
|
+
### Directionality modifiers
|
|
290
|
+
| Modifier | CSS selector scope |
|
|
291
|
+
|---|---|
|
|
292
|
+
| `rtl:` | `[dir="rtl"] .cls` |
|
|
293
|
+
| `ltr:` | `[dir="ltr"] .cls` |
|
|
294
|
+
|
|
295
|
+
### Important modifier
|
|
296
|
+
Prefix any class with `!` to add `!important` to every CSS declaration.
|
|
297
|
+
```jsx
|
|
298
|
+
<div className="!p-0 !m-0 !bg-transparent" />
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Arbitrary Values
|
|
304
|
+
|
|
305
|
+
Wrap any value in `[]` to use it directly.
|
|
306
|
+
```jsx
|
|
307
|
+
<div className="bg-[#6366f1]" />
|
|
308
|
+
<div className="p-[14px]" />
|
|
309
|
+
<div className="w-[calc(100%-2rem)]" />
|
|
310
|
+
<div className="text-[18px]" />
|
|
311
|
+
<div className="rounded-[20px]" />
|
|
312
|
+
<div className="bg-[rgba(99,102,241,0.15)]" />
|
|
313
|
+
<div className="grid-cols-[1fr_2fr_1fr]" />
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Negative Values
|
|
319
|
+
```jsx
|
|
320
|
+
<div className="-mt-4" /> // marginTop: -16
|
|
321
|
+
<div className="-mx-2" /> // marginHorizontal: -8
|
|
322
|
+
<div className="-translate-x-2" />
|
|
323
|
+
<div className="-mt-[10px]" /> // marginTop: -10px
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Color with Opacity
|
|
329
|
+
```jsx
|
|
330
|
+
<div className="bg-blue-6/50" /> // 50% opacity
|
|
331
|
+
<div className="text-gray-10/75" /> // 75% opacity
|
|
332
|
+
<div className="bg-black/[0.15]" /> // arbitrary opacity
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Color System
|
|
338
|
+
|
|
339
|
+
### 12-shade scale
|
|
340
|
+
1 = lightest, 12 = darkest.
|
|
341
|
+
|
|
342
|
+
```
|
|
343
|
+
shade 1 2 3 4 5 6 7 8 9 10 11 12
|
|
344
|
+
─────────────────────────────────────────────
|
|
345
|
+
light dark
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Usage: `bg-blue-6`, `text-gray-10`, `border-red-4/50`
|
|
349
|
+
|
|
350
|
+
### Color families (22 total)
|
|
351
|
+
Grays: `slate`, `gray`, `zinc`, `neutral`, `stone`
|
|
352
|
+
Colors: `red`, `orange`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`, `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `fuchsia`, `pink`, `rose`
|
|
353
|
+
Special: `transparent`, `current` (currentColor), `black`, `white`
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## Utility Reference
|
|
358
|
+
|
|
359
|
+
### Background
|
|
360
|
+
```
|
|
361
|
+
bg-{color} backgroundColor
|
|
362
|
+
bg-{color}/{opacity} backgroundColor with alpha
|
|
363
|
+
bg-transparent
|
|
364
|
+
bg-clip-border/padding/content/text
|
|
365
|
+
bg-gradient-to-{dir} linear gradient (t, tr, r, br, b, bl, l, tl)
|
|
366
|
+
use with: from-{color}, via-{color}, to-{color}
|
|
367
|
+
bg-none/auto/cover/contain
|
|
368
|
+
bg-center/top/bottom/left/right/left-top/…
|
|
369
|
+
bg-repeat/no-repeat/repeat-x/repeat-y
|
|
370
|
+
bg-fixed/local/scroll
|
|
371
|
+
bg-blend-{mode} normal, multiply, screen, overlay, darken, lighten, …
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Text
|
|
375
|
+
```
|
|
376
|
+
text-{size} xs(12) sm(14) base(16) lg(18) xl(20) 2xl(24) 3xl(30) 4xl(36) 5xl(48) 6xl(60) 7xl(72) 8xl(96) 9xl(128)
|
|
377
|
+
text-{color}
|
|
378
|
+
text-left/right/center/justify/start/end
|
|
379
|
+
text-wrap/nowrap/balance/pretty
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Font
|
|
383
|
+
```
|
|
384
|
+
font-thin/extralight/light/normal/medium/semibold/bold/extrabold/black
|
|
385
|
+
font-{family} sans, mono, serif, or custom
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Text decoration
|
|
389
|
+
```
|
|
390
|
+
underline / overline / line-through / no-underline
|
|
391
|
+
decoration-{color}
|
|
392
|
+
decoration-solid/dashed/dotted/double/wavy
|
|
393
|
+
decoration-0/1/2/4/8/auto/from-font
|
|
394
|
+
underline-offset-0/1/2/4/8/auto
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Text transform
|
|
398
|
+
```
|
|
399
|
+
uppercase / lowercase / capitalize / normal-case
|
|
400
|
+
italic / not-italic
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Text overflow
|
|
404
|
+
```
|
|
405
|
+
truncate
|
|
406
|
+
overflow-ellipsis
|
|
407
|
+
line-clamp-{n} n = 1–20
|
|
408
|
+
line-clamp-none
|
|
409
|
+
whitespace-normal/nowrap/pre/pre-wrap/pre-line
|
|
410
|
+
break-normal/words/all
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Typography misc
|
|
414
|
+
```
|
|
415
|
+
leading-none/tight/snug/normal/relaxed/loose (+ numeric 3–10)
|
|
416
|
+
tracking-tighter/tight/normal/wide/wider/widest
|
|
417
|
+
antialiased / subpixel-antialiased
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Spacing — Padding
|
|
421
|
+
```
|
|
422
|
+
p-{n} px-{n} py-{n} pt-{n} pr-{n} pb-{n} pl-{n}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Spacing — Margin
|
|
426
|
+
```
|
|
427
|
+
m-{n} mx-{n} my-{n} mt-{n} mr-{n} mb-{n} ml-{n}
|
|
428
|
+
mx-auto (centers element)
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Spacing scale (1 unit = 4px):
|
|
432
|
+
`px(1) 0 0.5(2) 1(4) 1.5(6) 2(8) 2.5(10) 3(12) 3.5(14) 4(16) 5(20) 6(24) 7(28) 8(32) 9(36) 10(40) 11(44) 12(48) 14(56) 16(64) 20(80) 24(96) 28(112) 32(128) 36(144) 40(160) 44(176) 48(192) 52(208) 56(224) 60(240) 64(256) 72(288) 80(320) 96(384) auto full(100%) 1/2 1/3 2/3 1/4 3/4 screen(100vh) min max fit`
|
|
433
|
+
|
|
434
|
+
### Sizing
|
|
435
|
+
```
|
|
436
|
+
w-{n} h-{n} size-{n} min-w-{n} min-h-{n} max-w-{n} max-h-{n}
|
|
437
|
+
|
|
438
|
+
Named max-w: none xs(320) sm(384) md(448) lg(512) xl(576) 2xl(672) 3xl(768)
|
|
439
|
+
4xl(896) 5xl(1024) 6xl(1152) 7xl(1280) prose(65ch)
|
|
440
|
+
|
|
441
|
+
Screen: w-screen(100vw) h-screen(100vh)
|
|
442
|
+
min-w-screen max-w-screen min-h-screen max-h-screen
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Display
|
|
446
|
+
```
|
|
447
|
+
block / inline / inline-block / flex / inline-flex
|
|
448
|
+
grid / inline-grid / hidden / contents / flow-root / table
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Flex
|
|
452
|
+
```
|
|
453
|
+
flex-row/col/row-reverse/col-reverse
|
|
454
|
+
flex-wrap/nowrap/wrap-reverse
|
|
455
|
+
flex-1 / flex-auto / flex-initial / flex-none
|
|
456
|
+
flex-grow/grow-0 flex-shrink/shrink-0
|
|
457
|
+
basis-{n}
|
|
458
|
+
items-start/end/center/baseline/stretch
|
|
459
|
+
justify-start/end/center/between/around/evenly
|
|
460
|
+
justify-items-start/end/center/stretch
|
|
461
|
+
justify-self-start/end/center/auto
|
|
462
|
+
self-start/end/center/auto/stretch/baseline
|
|
463
|
+
content-start/end/center/between/around/evenly/stretch
|
|
464
|
+
order-{n}
|
|
465
|
+
gap-{n} gap-x-{n} gap-y-{n}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Grid
|
|
469
|
+
```
|
|
470
|
+
grid-cols-{n} repeat(n, minmax(0, 1fr)) n = 1–12
|
|
471
|
+
grid-rows-{n}
|
|
472
|
+
grid-flow-row/col/dense/row-dense/col-dense
|
|
473
|
+
auto-cols-auto/min/max/fr
|
|
474
|
+
auto-rows-auto/min/max/fr
|
|
475
|
+
col-span-{n} / col-span-full
|
|
476
|
+
col-start-{n}/auto col-end-{n}/auto
|
|
477
|
+
row-span-{n} / row-span-full
|
|
478
|
+
row-start-{n}/auto row-end-{n}/auto
|
|
479
|
+
place-items-start/end/center/stretch
|
|
480
|
+
place-content-start/end/center/between/around/evenly/stretch
|
|
481
|
+
place-self-start/end/center/auto/stretch
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Position
|
|
485
|
+
```
|
|
486
|
+
static / relative / absolute / fixed / sticky
|
|
487
|
+
inset-{n} inset-x-{n} inset-y-{n}
|
|
488
|
+
top-{n} right-{n} bottom-{n} left-{n}
|
|
489
|
+
z-0/10/20/30/40/50/auto
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Overflow
|
|
493
|
+
```
|
|
494
|
+
overflow-hidden/visible/scroll/auto/clip
|
|
495
|
+
overflow-x-hidden/visible/scroll/auto/clip
|
|
496
|
+
overflow-y-hidden/visible/scroll/auto/clip
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Border
|
|
500
|
+
```
|
|
501
|
+
border / border-{n} borderWidth: 0 1 2 4 8
|
|
502
|
+
border-t/r/b/l
|
|
503
|
+
border-{color}
|
|
504
|
+
border-solid/dashed/dotted/none
|
|
505
|
+
border-collapse / border-separate
|
|
506
|
+
rounded / rounded-none/sm/md/lg/xl/2xl/3xl/full
|
|
507
|
+
rounded-t/r/b/l rounded-tl/tr/bl/br
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Shadow
|
|
511
|
+
```
|
|
512
|
+
shadow-sm / shadow / shadow-md / shadow-lg / shadow-xl / shadow-2xl / shadow-none
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Opacity
|
|
516
|
+
```
|
|
517
|
+
opacity-0/5/10/15/20/25/30/40/50/60/70/75/80/90/95/100
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### Ring
|
|
521
|
+
```
|
|
522
|
+
ring / ring-{n}(0 1 2 4 8)
|
|
523
|
+
ring-{color}
|
|
524
|
+
ring-inset
|
|
525
|
+
ring-offset-{n}(0 1 2 4 8)
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Outline
|
|
529
|
+
```
|
|
530
|
+
outline-none / outline / outline-{n}(0 1 2 4 8)
|
|
531
|
+
outline-{color}
|
|
532
|
+
outline-offset-{n}(0 1 2 4 8)
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### Transforms
|
|
536
|
+
```
|
|
537
|
+
scale-{n} scale-x-{n} scale-y-{n}
|
|
538
|
+
rotate-{n}
|
|
539
|
+
translate-x-{n} translate-y-{n}
|
|
540
|
+
skew-x-{n} skew-y-{n}
|
|
541
|
+
origin-center/top/top-right/right/bottom-right/bottom/bottom-left/left/top-left
|
|
542
|
+
perspective-{n}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Filters
|
|
546
|
+
```
|
|
547
|
+
blur-{sm/md/lg/xl/2xl/3xl}
|
|
548
|
+
brightness-{n} contrast-{n}
|
|
549
|
+
grayscale / grayscale-0
|
|
550
|
+
hue-rotate-{n}
|
|
551
|
+
invert / invert-0
|
|
552
|
+
saturate-{n}
|
|
553
|
+
sepia / sepia-0
|
|
554
|
+
drop-shadow-{sm/md/lg/xl/2xl/none}
|
|
555
|
+
|
|
556
|
+
backdrop-blur-{n} backdrop-brightness-{n} backdrop-contrast-{n}
|
|
557
|
+
backdrop-grayscale backdrop-hue-rotate-{n} backdrop-invert
|
|
558
|
+
backdrop-opacity-{n} backdrop-saturate-{n} backdrop-sepia
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Animation & Transition
|
|
562
|
+
```
|
|
563
|
+
animate-spin / animate-ping / animate-pulse / animate-bounce / animate-none
|
|
564
|
+
transition / transition-all/none/colors/opacity/shadow/transform
|
|
565
|
+
duration-75/100/150/200/300/500/700/1000
|
|
566
|
+
delay-75/100/150/200/300/500/700/1000
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Cursor
|
|
570
|
+
```
|
|
571
|
+
cursor-auto/default/pointer/wait/text/move/not-allowed
|
|
572
|
+
cursor-grab/grabbing/zoom-in/zoom-out/crosshair/help/none
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Pointer events / User select
|
|
576
|
+
```
|
|
577
|
+
pointer-events-none / pointer-events-auto
|
|
578
|
+
select-none / select-text / select-all / select-auto
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### Touch action
|
|
582
|
+
```
|
|
583
|
+
touch-auto / touch-none / touch-pan-x / touch-pan-y
|
|
584
|
+
touch-pan-left / touch-pan-right / touch-pan-up / touch-pan-down
|
|
585
|
+
touch-pinch-zoom / touch-manipulation
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### Scroll
|
|
589
|
+
```
|
|
590
|
+
scroll-smooth / scroll-auto
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Float & Clear
|
|
594
|
+
```
|
|
595
|
+
float-left / float-right / float-start / float-end / float-none
|
|
596
|
+
clear-left / clear-right / clear-both / clear-start / clear-end / clear-none
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Vertical align
|
|
600
|
+
```
|
|
601
|
+
align-baseline / align-top / align-middle / align-bottom
|
|
602
|
+
align-text-top / align-text-bottom / align-sub / align-super
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### Visibility
|
|
606
|
+
```
|
|
607
|
+
visible / invisible
|
|
608
|
+
sr-only / not-sr-only
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Lists
|
|
612
|
+
```
|
|
613
|
+
list-none / list-disc / list-decimal
|
|
614
|
+
list-inside / list-outside
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Misc
|
|
618
|
+
```
|
|
619
|
+
appearance-none
|
|
620
|
+
resize / resize-none / resize-x / resize-y
|
|
621
|
+
box-border / box-content
|
|
622
|
+
object-contain/cover/fill/none/scale-down
|
|
623
|
+
object-center/top/bottom/left/right/…
|
|
624
|
+
aspect-auto / aspect-square / aspect-video / aspect-[4/3]
|
|
625
|
+
columns-{n} / columns-auto / columns-{size}
|
|
626
|
+
caret-{color} / caret-auto / caret-transparent
|
|
627
|
+
accent-{color} / accent-auto
|
|
628
|
+
mix-blend-{mode}
|
|
629
|
+
bg-blend-{mode}
|
|
630
|
+
will-change-auto/scroll/contents/transform
|
|
631
|
+
divide-x-{n} / divide-y-{n} / divide-{color} / divide-solid/dashed/dotted
|
|
632
|
+
space-x-{n} / space-y-{n}
|
|
633
|
+
group / peer (standalone marker classes)
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## Theme Configuration
|
|
639
|
+
|
|
640
|
+
### kbach.config.js (project root)
|
|
641
|
+
```js
|
|
642
|
+
module.exports = {
|
|
643
|
+
darkMode: 'attribute', // 'attribute' | 'class' | 'media'
|
|
644
|
+
|
|
645
|
+
theme: {
|
|
646
|
+
colors: {
|
|
647
|
+
brand: { 1: '#eff6ff', 6: '#3b82f6', 10: '#1e3a8a' },
|
|
648
|
+
},
|
|
649
|
+
},
|
|
650
|
+
|
|
651
|
+
extend: {
|
|
652
|
+
theme: {
|
|
653
|
+
colors: { brand: { 6: '#6366f1' } },
|
|
654
|
+
spacing: { 18: 72, 22: 88 },
|
|
655
|
+
fontSize: { '10xl': 160 },
|
|
656
|
+
fontFamily: {
|
|
657
|
+
sans: 'Inter, sans-serif',
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
|
|
662
|
+
plugins: [
|
|
663
|
+
({ addUtility, theme }) => {
|
|
664
|
+
addUtility('border-brand', {
|
|
665
|
+
borderColor: theme('colors.brand.6'),
|
|
666
|
+
borderWidth: 2,
|
|
667
|
+
});
|
|
668
|
+
},
|
|
669
|
+
],
|
|
670
|
+
};
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
**Global default font (web):** Setting `fontFamily.sans` to anything other than `'System'` auto-injects `body { font-family: <font> }`.
|
|
674
|
+
|
|
675
|
+
### Runtime update
|
|
676
|
+
```js
|
|
677
|
+
import { updateConfig, clearCache } from '@kbach/react';
|
|
678
|
+
updateConfig({ extend: { theme: { colors: { brand: { 6: '#6366f1' } } } } });
|
|
679
|
+
clearCache(); // always call after updateConfig()
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
### Default theme values
|
|
683
|
+
```
|
|
684
|
+
spacing: 1 unit = 4px
|
|
685
|
+
fontSize: xs(12)–9xl(128)
|
|
686
|
+
borderRadius: none(0) sm(2) DEFAULT(4) md(6) lg(8) xl(12) 2xl(16) 3xl(24) full(9999)
|
|
687
|
+
borderWidth: DEFAULT(1) 0 2 4 8
|
|
688
|
+
opacity: 0 5 10 15 20 25 30 40 50 60 70 75 80 90 95 100
|
|
689
|
+
lineHeight: none(1) tight(1.25) snug(1.375) normal(1.5) relaxed(1.625) loose(2)
|
|
690
|
+
letterSpacing:tighter(-0.8) tight(-0.4) normal(0) wide(0.4) wider(0.8) widest(1.6)
|
|
691
|
+
zIndex: auto 0 10 20 30 40 50
|
|
692
|
+
screens: sm(576) md(768) lg(1024) xl(1280) 2xl(1536)
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
## Common Patterns
|
|
698
|
+
|
|
699
|
+
### Dark mode card
|
|
700
|
+
```jsx
|
|
701
|
+
<div className="bg-white dark:bg-gray-9 rounded-2xl p-6 shadow-md">
|
|
702
|
+
<h2 className="text-2xl font-bold text-gray-10 dark:text-white">Title</h2>
|
|
703
|
+
<p className="text-gray-6 dark:text-gray-4 mt-2">Body text</p>
|
|
704
|
+
</div>
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### Interactive button
|
|
708
|
+
```jsx
|
|
709
|
+
<button className="bg-blue-7 hover:bg-blue-8 active:bg-blue-9 disabled:opacity-50 disabled:cursor-not-allowed text-white font-semibold px-6 py-3 rounded-xl transition" />
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Responsive layout
|
|
713
|
+
```jsx
|
|
714
|
+
<div className="flex flex-col md:flex-row gap-4">
|
|
715
|
+
<aside className="w-full md:w-64 lg:w-80">…</aside>
|
|
716
|
+
<main className="flex-1">…</main>
|
|
717
|
+
</div>
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
### Responsive grid
|
|
721
|
+
```jsx
|
|
722
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
|
723
|
+
{items.map(item => <Card key={item.id} />)}
|
|
724
|
+
</div>
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### Group hover reveal
|
|
728
|
+
```jsx
|
|
729
|
+
<div className="group relative overflow-hidden rounded-xl">
|
|
730
|
+
<img src="…" className="transition group-hover:scale-105" />
|
|
731
|
+
<div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition flex items-center justify-center">
|
|
732
|
+
<span className="text-white font-bold">View</span>
|
|
733
|
+
</div>
|
|
734
|
+
</div>
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### Before/after pseudo-elements
|
|
738
|
+
```jsx
|
|
739
|
+
<div className="relative before:absolute before:inset-0 before:bg-blue-6/10 before:rounded-xl" />
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Input with caret and focus ring
|
|
743
|
+
```jsx
|
|
744
|
+
<input className="caret-blue-6 focus:ring-2 focus:ring-blue-5 focus:outline-none border border-gray-4 rounded-lg px-4 py-2" />
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
### Print-specific styles
|
|
748
|
+
```jsx
|
|
749
|
+
<nav className="print:hidden" />
|
|
750
|
+
<article className="print:text-black print:bg-white print:shadow-none" />
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
### Reduced-motion safe animation
|
|
754
|
+
```jsx
|
|
755
|
+
<div className="motion-safe:animate-spin motion-reduce:opacity-75" />
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### RTL-aware spacing
|
|
759
|
+
```jsx
|
|
760
|
+
<div className="ltr:pl-4 rtl:pr-4 ltr:text-left rtl:text-right" />
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
### Contrast accessibility
|
|
764
|
+
```jsx
|
|
765
|
+
<button className="bg-blue-6 contrast-more:bg-blue-9 contrast-more:border-2 text-white">
|
|
766
|
+
Submit
|
|
767
|
+
</button>
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
## Caching
|
|
773
|
+
|
|
774
|
+
The resolver uses an LRU cache (10,000 entries). Cleared automatically on `updateConfig()`. Manually:
|
|
775
|
+
```js
|
|
776
|
+
import { clearCache } from '@kbach/react';
|
|
777
|
+
clearCache();
|
|
778
|
+
```
|