quickit-ui 0.1.17 → 0.1.20
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 +169 -3
- package/dist/quickit-ui.css +1 -1
- package/dist/quickit-ui.d.ts +106 -0
- package/dist/quickit-ui.js +2925 -1979
- 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,17 +186,28 @@ 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");
|
|
76
205
|
const linkFocusRing = useQuickitFocusRing("link");
|
|
77
206
|
const checkboxFocusRing = useQuickitFocusRing("checkbox");
|
|
78
207
|
const radioFocusRing = useQuickitFocusRing("radio");
|
|
208
|
+
const pressEffect = useQuickitPressEffect();
|
|
209
|
+
const buttonRipple = useQuickitRipple("button");
|
|
210
|
+
const linkRipple = useQuickitRipple("link");
|
|
79
211
|
|
|
80
212
|
return (
|
|
81
213
|
<div>
|
|
@@ -83,6 +215,9 @@ function Toolbar() {
|
|
|
83
215
|
<span>link focus: {String(linkFocusRing)}</span>
|
|
84
216
|
<span>checkbox focus: {String(checkboxFocusRing)}</span>
|
|
85
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>
|
|
86
221
|
</div>
|
|
87
222
|
);
|
|
88
223
|
}
|
|
@@ -102,6 +237,7 @@ import {
|
|
|
102
237
|
export function LoginOptions() {
|
|
103
238
|
return (
|
|
104
239
|
<QuickitProvider
|
|
240
|
+
pressEffect="ripple"
|
|
105
241
|
focusRing={{ disabledComponents: ["link", "checkbox", "radio"] }}
|
|
106
242
|
>
|
|
107
243
|
<div className="flex flex-wrap items-center gap-4">
|
|
@@ -186,6 +322,33 @@ import {
|
|
|
186
322
|
} from "quickit-ui";
|
|
187
323
|
```
|
|
188
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
|
+
|
|
189
352
|
## Ejemplos
|
|
190
353
|
|
|
191
354
|
### Button
|
|
@@ -212,6 +375,9 @@ Notas rápidas de `Button`:
|
|
|
212
375
|
|
|
213
376
|
- `shape="square"` y `shape="circle"` están pensados para icon buttons.
|
|
214
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}`.
|
|
215
381
|
- Si quieres esa animación en un icon button, usa `activeMotion={true}`.
|
|
216
382
|
|
|
217
383
|
```jsx
|