@kbach/react 0.1.0 → 0.1.1
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 +253 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# @kbach/react
|
|
2
|
+
|
|
3
|
+
Tailwind-like utility classes for **React (web)**. Same class names as Tailwind, zero stylesheet required — classes are converted to inline styles at render time via a custom JSX runtime.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
/** @jsxImportSource @kbach/react */
|
|
7
|
+
|
|
8
|
+
<div className="bg-white dark:bg-gray-10 p-4 rounded-xl shadow" />
|
|
9
|
+
<div className="bg-blue-7 hover:bg-blue-8 dark:bg-indigo-6 rounded-lg px-6 py-3" />
|
|
10
|
+
<div className="bg-[#6366f1] p-[14px] rounded-[20px]" />
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @kbach/react
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
### 1. Configure the JSX runtime
|
|
22
|
+
|
|
23
|
+
**tsconfig.json** (applies to every file in the project)
|
|
24
|
+
|
|
25
|
+
```jsonc
|
|
26
|
+
{
|
|
27
|
+
"compilerOptions": {
|
|
28
|
+
"jsx": "react-jsx",
|
|
29
|
+
"jsxImportSource": "@kbach/react"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Vite**
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
// vite.config.ts
|
|
38
|
+
import { defineConfig } from 'vite';
|
|
39
|
+
import react from '@vitejs/plugin-react';
|
|
40
|
+
|
|
41
|
+
export default defineConfig({
|
|
42
|
+
plugins: [react({ jsxImportSource: '@kbach/react' })],
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Babel**
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
// babel.config.js
|
|
50
|
+
module.exports = {
|
|
51
|
+
presets: [
|
|
52
|
+
['@babel/preset-react', { runtime: 'automatic', importSource: '@kbach/react' }],
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Per-file pragma** (no config change required)
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
/** @jsxImportSource @kbach/react */
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. Wrap your app
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { ThemeProvider } from '@kbach/react';
|
|
67
|
+
|
|
68
|
+
export default function Root() {
|
|
69
|
+
return (
|
|
70
|
+
<ThemeProvider defaultMode="system">
|
|
71
|
+
<App />
|
|
72
|
+
</ThemeProvider>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API
|
|
78
|
+
|
|
79
|
+
### `className` prop
|
|
80
|
+
|
|
81
|
+
Works on any HTML element or React component once the JSX runtime is configured.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
<div className="bg-white dark:bg-gray-10 p-4 rounded-xl" />
|
|
85
|
+
<p className="text-gray-10 dark:text-white text-lg font-bold" />
|
|
86
|
+
<button className="bg-blue-7 hover:bg-blue-8 pressed:bg-blue-8 rounded-lg px-4 py-2" />
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `styled(Component, classes)`
|
|
90
|
+
|
|
91
|
+
Pre-style any component. Returns a new component that merges the base classes with any `className` or `tw` prop passed at use time.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { styled } from '@kbach/react';
|
|
95
|
+
|
|
96
|
+
const Card = styled('div', 'bg-white dark:bg-gray-9 rounded-2xl p-6 shadow');
|
|
97
|
+
const Title = styled('h2', 'text-2xl font-bold text-gray-10 dark:text-white');
|
|
98
|
+
const Button = styled(
|
|
99
|
+
'button',
|
|
100
|
+
'bg-blue-7 hover:bg-blue-8 dark:bg-indigo-6 rounded-xl px-6 py-3'
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
// Pass extra classes at use time
|
|
104
|
+
<Card tw="mt-4 mb-2">
|
|
105
|
+
<Title tw="text-3xl">Hello</Title>
|
|
106
|
+
</Card>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### `useStyles(classes)`
|
|
110
|
+
|
|
111
|
+
Resolve classes to a style object inside a component.
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { useStyles } from '@kbach/react';
|
|
115
|
+
|
|
116
|
+
function Badge() {
|
|
117
|
+
const style = useStyles('bg-blue-6 dark:bg-indigo-6 px-3 py-1 rounded-full');
|
|
118
|
+
return <span style={style}>New</span>;
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### `tw(classes)`
|
|
123
|
+
|
|
124
|
+
Resolve classes outside a component (static contexts).
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { tw } from '@kbach/react';
|
|
128
|
+
|
|
129
|
+
const cardStyle = tw('bg-white p-4 rounded-xl') as React.CSSProperties;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `cx(...classes)`
|
|
133
|
+
|
|
134
|
+
Conditionally join class strings. Falsy values are ignored.
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { cx } from '@kbach/react';
|
|
138
|
+
|
|
139
|
+
<div className={cx(
|
|
140
|
+
'p-4 rounded-xl',
|
|
141
|
+
isSelected && 'border-2 border-blue-6',
|
|
142
|
+
isDisabled && 'opacity-50',
|
|
143
|
+
)} />
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `useTheme()`
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { useTheme } from '@kbach/react';
|
|
150
|
+
|
|
151
|
+
const { mode, resolvedMode, isDark, setMode, toggle } = useTheme();
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
| Value | Type | Description |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `mode` | `'light' \| 'dark' \| 'system'` | User-selected mode |
|
|
157
|
+
| `resolvedMode` | `'light' \| 'dark'` | Resolved after system lookup |
|
|
158
|
+
| `isDark` | `boolean` | Shorthand for `resolvedMode === 'dark'` |
|
|
159
|
+
| `setMode(mode)` | `fn` | Set mode explicitly |
|
|
160
|
+
| `toggle()` | `fn` | Toggle between light and dark |
|
|
161
|
+
|
|
162
|
+
### `ThemeToggle`
|
|
163
|
+
|
|
164
|
+
Drop-in toggle component.
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
<ThemeToggle /> // button (default)
|
|
168
|
+
<ThemeToggle variant="switch" /> // toggle switch
|
|
169
|
+
<ThemeToggle variant="icon-button" /> // icon button
|
|
170
|
+
<ThemeToggle variant="button" includeSystem /> // three-way selector
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Modifiers
|
|
174
|
+
|
|
175
|
+
Up to **3 modifiers** can be chained in any order.
|
|
176
|
+
|
|
177
|
+
| Modifier | Trigger |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `dark:` | Dark mode active |
|
|
180
|
+
| `light:` | Light mode active |
|
|
181
|
+
| `hover:` | Mouse hover |
|
|
182
|
+
| `pressed:` | Click / touch |
|
|
183
|
+
| `focus:` | Element focused |
|
|
184
|
+
| `active:` | Element active |
|
|
185
|
+
| `disabled:` | Element disabled |
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
<div className="dark:hover:bg-gray-9" />
|
|
189
|
+
<button className="dark:pressed:bg-indigo-8" />
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Arbitrary values
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
<div className="bg-[#6366f1]" />
|
|
196
|
+
<div className="p-[14px]" />
|
|
197
|
+
<div className="text-[18px]" />
|
|
198
|
+
<div className="bg-[rgba(99,102,241,0.15)]" />
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Color with opacity
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<div className="bg-blue-6/50" /> {/* 50% opacity */}
|
|
205
|
+
<div className="bg-gray-10/75" /> {/* 75% opacity */}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Color scale
|
|
209
|
+
|
|
210
|
+
Colors use an 11-shade scale where **1 is lightest** and **11 is darkest**.
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
bg-gray-1 (near white) → bg-gray-6 (mid) → bg-gray-11 (near black)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Available families: `slate` `gray` `zinc` `neutral` `stone` `red` `orange` `amber` `yellow` `lime` `green` `emerald` `teal` `cyan` `sky` `blue` `indigo` `violet` `purple` `fuchsia` `pink` `rose`
|
|
217
|
+
|
|
218
|
+
## Configuration
|
|
219
|
+
|
|
220
|
+
```js
|
|
221
|
+
// kbach.config.js
|
|
222
|
+
module.exports = {
|
|
223
|
+
darkMode: 'attribute', // 'attribute' | 'class' | 'media'
|
|
224
|
+
|
|
225
|
+
theme: {
|
|
226
|
+
colors: {
|
|
227
|
+
brand: { 1: '#eff6ff', 6: '#3b82f6', 10: '#1e3a5f' },
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
extend: {
|
|
232
|
+
theme: {
|
|
233
|
+
colors: { brand: { 6: '#6366f1' } },
|
|
234
|
+
spacing: { 18: '72px' },
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
plugins: [
|
|
239
|
+
({ addUtility, theme }) => {
|
|
240
|
+
addUtility('border-brand', {
|
|
241
|
+
borderColor: theme('colors.brand.6'),
|
|
242
|
+
borderWidth: 2,
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
};
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
import { updateConfig } from '@kbach/react';
|
|
251
|
+
|
|
252
|
+
updateConfig({ extend: { theme: { colors: { brand: { 6: '#6366f1' } } } } });
|
|
253
|
+
```
|