quickit-ui 0.1.16 → 0.1.19
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 +209 -4
- package/dist/quickit-ui.css +1 -1
- package/dist/quickit-ui.d.ts +106 -0
- package/dist/quickit-ui.js +2935 -1989
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,17 @@ Importa los estilos una sola vez:
|
|
|
14
14
|
import "quickit-ui/styles.css";
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
Si tu app también usa utilidades propias de Tailwind con `dark:`, declara esto en tu CSS global:
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
@import "tailwindcss";
|
|
21
|
+
@import "quickit-ui/styles.css";
|
|
22
|
+
|
|
23
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Eso hace que tu app y Quickit reaccionen a la misma clase `dark`.
|
|
27
|
+
|
|
17
28
|
## Uso rápido
|
|
18
29
|
|
|
19
30
|
```jsx
|
|
@@ -34,7 +45,7 @@ export default function App() {
|
|
|
34
45
|
|
|
35
46
|
## Tema
|
|
36
47
|
|
|
37
|
-
Quickit UI trabaja con `light` y `dark`.
|
|
48
|
+
Quickit UI trabaja con `light` y `dark`. Si ya gestionas el tema en tu app, `QuickitProvider` solo lo distribuye al resto de componentes.
|
|
38
49
|
|
|
39
50
|
```jsx
|
|
40
51
|
import "quickit-ui/styles.css";
|
|
@@ -49,12 +60,122 @@ export default function App() {
|
|
|
49
60
|
}
|
|
50
61
|
```
|
|
51
62
|
|
|
52
|
-
|
|
63
|
+
Si prefieres que Quickit gestione el toggle y la persistencia, usa `QuickitThemeProvider` con `useQuickitThemeController`:
|
|
64
|
+
|
|
65
|
+
```jsx
|
|
66
|
+
import "quickit-ui/styles.css";
|
|
67
|
+
import {
|
|
68
|
+
Button,
|
|
69
|
+
QuickitThemeProvider,
|
|
70
|
+
useQuickitThemeController,
|
|
71
|
+
} from "quickit-ui";
|
|
72
|
+
|
|
73
|
+
function ThemeControls() {
|
|
74
|
+
const { resolvedTheme, setTheme, systemTheme, theme, toggleTheme } =
|
|
75
|
+
useQuickitThemeController();
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className="space-y-4">
|
|
79
|
+
<p>
|
|
80
|
+
Preferencia: {theme}. Sistema: {systemTheme}. Tema activo: {resolvedTheme}
|
|
81
|
+
</p>
|
|
82
|
+
|
|
83
|
+
<div className="flex flex-wrap gap-3">
|
|
84
|
+
<Button onClick={() => setTheme("system")}>Sistema</Button>
|
|
85
|
+
<Button onClick={() => setTheme("light")}>Claro</Button>
|
|
86
|
+
<Button onClick={() => setTheme("dark")}>Oscuro</Button>
|
|
87
|
+
<Button color="brand" variant="outline" onClick={toggleTheme}>
|
|
88
|
+
Alternar desde {resolvedTheme}
|
|
89
|
+
</Button>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export default function App() {
|
|
96
|
+
return (
|
|
97
|
+
<QuickitThemeProvider
|
|
98
|
+
defaultTheme="system"
|
|
99
|
+
storageKey="ava-quickit-theme"
|
|
100
|
+
>
|
|
101
|
+
<ThemeControls />
|
|
102
|
+
</QuickitThemeProvider>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Notas:
|
|
108
|
+
|
|
109
|
+
- el storage key por defecto es `quickit-ui-theme`
|
|
110
|
+
- `defaultTheme` ahora soporta `system | light | dark`
|
|
111
|
+
- `QuickitThemeProvider` aplica la clase `dark` sobre `document.documentElement`
|
|
112
|
+
- puedes sobrescribir el storage key con `storageKey`
|
|
113
|
+
- `useQuickitThemeController()` expone `theme`, `resolvedTheme`, `systemTheme`, `setTheme` y `toggleTheme`
|
|
114
|
+
- `theme` es la preferencia persistida; `resolvedTheme` es el modo que Quickit está aplicando realmente
|
|
115
|
+
- si usas clases propias como `dark:bg-zinc-950`, añade `@custom-variant dark (&:where(.dark, .dark *));` a tu CSS global
|
|
116
|
+
|
|
117
|
+
Si tu layout propio también depende del tema:
|
|
118
|
+
|
|
119
|
+
```jsx
|
|
120
|
+
import { useQuickitThemeController } from "quickit-ui";
|
|
121
|
+
|
|
122
|
+
function Shell() {
|
|
123
|
+
const { theme, resolvedTheme } = useQuickitThemeController();
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<div className="bg-white text-zinc-950 dark:bg-zinc-950 dark:text-white">
|
|
127
|
+
<header className="border-b border-zinc-200 px-6 py-4 dark:border-zinc-800">
|
|
128
|
+
Preferencia: {theme}. Tema efectivo: {resolvedTheme}
|
|
129
|
+
</header>
|
|
130
|
+
<main className="p-6">
|
|
131
|
+
<Dashboard />
|
|
132
|
+
</main>
|
|
133
|
+
</div>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Patrón con `Switch`:
|
|
139
|
+
|
|
140
|
+
```jsx
|
|
141
|
+
import {
|
|
142
|
+
QuickitThemeProvider,
|
|
143
|
+
Switch,
|
|
144
|
+
Tooltip,
|
|
145
|
+
useQuickitThemeController,
|
|
146
|
+
} from "quickit-ui";
|
|
147
|
+
|
|
148
|
+
function ToggleTheme() {
|
|
149
|
+
const { resolvedTheme, theme, toggleTheme } = useQuickitThemeController();
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<Tooltip content="Alternar tema">
|
|
153
|
+
<Switch
|
|
154
|
+
color="brand"
|
|
155
|
+
checked={resolvedTheme === "dark"}
|
|
156
|
+
onCheckedChange={toggleTheme}
|
|
157
|
+
/>
|
|
158
|
+
</Tooltip>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function App() {
|
|
163
|
+
return (
|
|
164
|
+
<QuickitThemeProvider storageKey="ava-quickit-theme">
|
|
165
|
+
<ToggleTheme />
|
|
166
|
+
</QuickitThemeProvider>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
También puedes controlar el focus ring y el efecto de presión globalmente desde el provider:
|
|
53
172
|
|
|
54
173
|
```jsx
|
|
55
174
|
<QuickitProvider
|
|
56
175
|
theme="dark"
|
|
57
176
|
focusRing={{ disabledComponents: ["input", "textarea"] }}
|
|
177
|
+
pressEffect="ripple"
|
|
178
|
+
ripple={{ disabledComponents: ["link"] }}
|
|
58
179
|
>
|
|
59
180
|
<App />
|
|
60
181
|
</QuickitProvider>
|
|
@@ -65,16 +186,70 @@ Reglas:
|
|
|
65
186
|
- por defecto Quickit mantiene focus visible accesible en componentes interactivos
|
|
66
187
|
- `focusRing={false}` lo desactiva en toda la librería
|
|
67
188
|
- `focusRing={{ disabledComponents: [...] }}` lo desactiva solo en componentes específicos
|
|
189
|
+
- por defecto Quickit usa `pressEffect="transform"` en `Button` y en `Link` con `appearance="button"`
|
|
190
|
+
- `pressEffect="ripple"` cambia esa política global para usar ripple en lugar de transform
|
|
191
|
+
- `ripple={false}` lo desactiva en toda la librería cuando `pressEffect="ripple"`
|
|
192
|
+
- `ripple={{ disabledComponents: [...] }}` lo desactiva solo en botones o links cuando `pressEffect="ripple"`
|
|
68
193
|
|
|
69
194
|
Si necesitas leer esa decisión desde tu app o desde wrappers propios:
|
|
70
195
|
|
|
71
196
|
```jsx
|
|
72
|
-
import {
|
|
197
|
+
import {
|
|
198
|
+
useQuickitFocusRing,
|
|
199
|
+
useQuickitPressEffect,
|
|
200
|
+
useQuickitRipple,
|
|
201
|
+
} from "quickit-ui";
|
|
73
202
|
|
|
74
203
|
function Toolbar() {
|
|
75
204
|
const buttonFocusRing = useQuickitFocusRing("button");
|
|
205
|
+
const linkFocusRing = useQuickitFocusRing("link");
|
|
206
|
+
const checkboxFocusRing = useQuickitFocusRing("checkbox");
|
|
207
|
+
const radioFocusRing = useQuickitFocusRing("radio");
|
|
208
|
+
const pressEffect = useQuickitPressEffect();
|
|
209
|
+
const buttonRipple = useQuickitRipple("button");
|
|
210
|
+
const linkRipple = useQuickitRipple("link");
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<div>
|
|
214
|
+
<span>button focus: {String(buttonFocusRing)}</span>
|
|
215
|
+
<span>link focus: {String(linkFocusRing)}</span>
|
|
216
|
+
<span>checkbox focus: {String(checkboxFocusRing)}</span>
|
|
217
|
+
<span>radio focus: {String(radioFocusRing)}</span>
|
|
218
|
+
<span>pressEffect: {pressEffect}</span>
|
|
219
|
+
<span>button ripple: {String(buttonRipple)}</span>
|
|
220
|
+
<span>link ripple: {String(linkRipple)}</span>
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Caso real:
|
|
76
227
|
|
|
77
|
-
|
|
228
|
+
```jsx
|
|
229
|
+
import {
|
|
230
|
+
Button,
|
|
231
|
+
Checkbox,
|
|
232
|
+
Link,
|
|
233
|
+
QuickitProvider,
|
|
234
|
+
Radio,
|
|
235
|
+
} from "quickit-ui";
|
|
236
|
+
|
|
237
|
+
export function LoginOptions() {
|
|
238
|
+
return (
|
|
239
|
+
<QuickitProvider
|
|
240
|
+
pressEffect="ripple"
|
|
241
|
+
focusRing={{ disabledComponents: ["link", "checkbox", "radio"] }}
|
|
242
|
+
>
|
|
243
|
+
<div className="flex flex-wrap items-center gap-4">
|
|
244
|
+
<Link href="#">Ver términos</Link>
|
|
245
|
+
<Checkbox label="Recordarme" defaultChecked />
|
|
246
|
+
<Radio name="login-mode" label="Modo manual" defaultChecked />
|
|
247
|
+
<Button color="neutral" variant="outline">
|
|
248
|
+
Continuar
|
|
249
|
+
</Button>
|
|
250
|
+
</div>
|
|
251
|
+
</QuickitProvider>
|
|
252
|
+
);
|
|
78
253
|
}
|
|
79
254
|
```
|
|
80
255
|
|
|
@@ -147,6 +322,33 @@ import {
|
|
|
147
322
|
} from "quickit-ui";
|
|
148
323
|
```
|
|
149
324
|
|
|
325
|
+
## InputGroup
|
|
326
|
+
|
|
327
|
+
Usa `InputGroupAddon` para segmentos pasivos y `InputGroupAction` para segmentos interactivos.
|
|
328
|
+
`InputGroupAction` reutiliza `Button` y renderiza un `<button>` real, así que soporta `type`, `onClick`, `disabled`, foco y teclado.
|
|
329
|
+
|
|
330
|
+
```jsx
|
|
331
|
+
import {
|
|
332
|
+
Input,
|
|
333
|
+
InputGroup,
|
|
334
|
+
InputGroupAction,
|
|
335
|
+
} from "quickit-ui";
|
|
336
|
+
|
|
337
|
+
export function Filters() {
|
|
338
|
+
return (
|
|
339
|
+
<InputGroup attached>
|
|
340
|
+
<InputGroupAction variant="outline" onClick={() => console.log("todo")}>
|
|
341
|
+
Todo
|
|
342
|
+
</InputGroupAction>
|
|
343
|
+
<Input placeholder="Filtra por nombre o etiqueta" />
|
|
344
|
+
<InputGroupAction variant="outline" onClick={() => console.log("estado")}>
|
|
345
|
+
Estado
|
|
346
|
+
</InputGroupAction>
|
|
347
|
+
</InputGroup>
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
150
352
|
## Ejemplos
|
|
151
353
|
|
|
152
354
|
### Button
|
|
@@ -173,6 +375,9 @@ Notas rápidas de `Button`:
|
|
|
173
375
|
|
|
174
376
|
- `shape="square"` y `shape="circle"` están pensados para icon buttons.
|
|
175
377
|
- `shape="square"` y `shape="circle"` salen con `activeMotion` desactivado por defecto.
|
|
378
|
+
- `Button` y `Link` con `appearance="button"` usan `pressEffect="transform"` por defecto.
|
|
379
|
+
- Si quieres ripple, usa `pressEffect="ripple"` en esa instancia o en `QuickitProvider`.
|
|
380
|
+
- Cuando `pressEffect="ripple"`, puedes apagarlo con `ripple={false}`.
|
|
176
381
|
- Si quieres esa animación en un icon button, usa `activeMotion={true}`.
|
|
177
382
|
|
|
178
383
|
```jsx
|