quickit-ui 0.1.13 → 0.1.16

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 CHANGED
@@ -1,94 +1,106 @@
1
1
  # Quickit UI
2
2
 
3
- Quickit UI es una libreria de componentes para React pensada para construir interfaces consistentes, limpias y rapidas de integrar.
3
+ Quickit UI es una librería de componentes para React enfocada en interfaces consistentes, con una API semántica, tema `light` y `dark`, documentación local y soporte TypeScript vía `.d.ts`.
4
4
 
5
- Incluye componentes base como `Button`, `Input`, `Modal`, `Dropdown`, `Tabs`, `Tooltip`, `Avatar`, `Badge`, `Skeleton` y mas.
6
-
7
- ## Documentacion local
8
-
9
- La libreria incluye una documentacion local con ejemplos, API y fundamentos del sistema.
5
+ ## Instalación
10
6
 
11
7
  ```bash
12
- npm install
13
- npm run dev
14
- ```
15
-
16
- Para generar la version estatica de la documentacion:
17
-
18
- ```bash
19
- npm run build:docs
8
+ npm install quickit-ui react react-dom
20
9
  ```
21
10
 
22
- ## Instalacion
11
+ Importa los estilos una sola vez:
23
12
 
24
- Instala el paquete junto con sus dependencias peer:
25
-
26
- ```bash
27
- npm install quickit-ui react react-dom
13
+ ```jsx
14
+ import "quickit-ui/styles.css";
28
15
  ```
29
16
 
30
- ## Uso rapido
31
-
32
- Importa los estilos del paquete una sola vez y empieza a usar los componentes:
17
+ ## Uso rápido
33
18
 
34
19
  ```jsx
35
- import 'quickit-ui/styles.css'
36
- import { Button, Input, QuickitProvider } from 'quickit-ui'
20
+ import "quickit-ui/styles.css";
21
+ import { Button, Input, QuickitProvider } from "quickit-ui";
37
22
 
38
23
  export default function App() {
39
24
  return (
40
25
  <QuickitProvider theme="light">
41
26
  <main className="space-y-4 p-6">
42
- <Input placeholder="Correo electronico" />
43
- <Button color="neutral">Continuar</Button>
27
+ <Input color="neutral" placeholder="Correo electrónico" />
28
+ <Button color="brand">Continuar</Button>
44
29
  </main>
45
30
  </QuickitProvider>
46
- )
31
+ );
47
32
  }
48
33
  ```
49
34
 
50
35
  ## Tema
51
36
 
52
- Quickit UI soporta `light` y `dark` desde `QuickitProvider`.
37
+ Quickit UI trabaja con `light` y `dark`. El estado del tema vive en tu app; `QuickitProvider` solo lo distribuye al resto de componentes.
53
38
 
54
39
  ```jsx
55
- import 'quickit-ui/styles.css'
56
- import { Button, QuickitProvider } from 'quickit-ui'
40
+ import "quickit-ui/styles.css";
41
+ import { Button, QuickitProvider } from "quickit-ui";
57
42
 
58
43
  export default function App() {
59
44
  return (
60
45
  <QuickitProvider theme="dark">
61
- <Button>Guardar cambios</Button>
46
+ <Button color="neutral">Guardar cambios</Button>
62
47
  </QuickitProvider>
63
- )
48
+ );
64
49
  }
65
50
  ```
66
51
 
67
- ## Personalizar colores
52
+ También puedes controlar el focus ring globalmente desde el provider:
53
+
54
+ ```jsx
55
+ <QuickitProvider
56
+ theme="dark"
57
+ focusRing={{ disabledComponents: ["input", "textarea"] }}
58
+ >
59
+ <App />
60
+ </QuickitProvider>
61
+ ```
62
+
63
+ Reglas:
68
64
 
69
- La API de color es semántica: `neutral`, `primary`, `brand`, `success`, `danger`, `warning`, `info`, `light` y `dark`.
65
+ - por defecto Quickit mantiene focus visible accesible en componentes interactivos
66
+ - `focusRing={false}` lo desactiva en toda la librería
67
+ - `focusRing={{ disabledComponents: [...] }}` lo desactiva solo en componentes específicos
68
+
69
+ Si necesitas leer esa decisión desde tu app o desde wrappers propios:
70
+
71
+ ```jsx
72
+ import { useQuickitFocusRing } from "quickit-ui";
73
+
74
+ function Toolbar() {
75
+ const buttonFocusRing = useQuickitFocusRing("button");
76
+
77
+ return <span>button focus: {String(buttonFocusRing)}</span>;
78
+ }
79
+ ```
70
80
 
71
- La lógica recomendada es esta:
72
- - cada color semántico usa una familia Tailwind interna
73
- - si reemplazas esa familia, cambias ese color en toda la librería
74
- - `brand` existe precisamente para tu color de marca y consume `brand-*`
75
- - si quieres usar tu color de marca en otro slot, reemplaza la familia que consume ese slot semántico
76
- - si quieres un color nuevo solo en un caso puntual, usa `className`
77
- - si quieres soportar un nuevo valor como `color="gray"` o `color="clientA"` en toda la librería, eso requiere ampliar la API
81
+ ## Colores semánticos
78
82
 
79
- Mapa actual:
83
+ La API pública soporta:
80
84
 
81
85
  ```txt
82
- neutral -> neutral-*
83
- primary -> blue-*
84
- brand -> brand-*
85
- success -> emerald-*
86
- danger -> red-*
87
- warning -> amber-*
88
- info -> sky-*
86
+ neutral | slate | zinc | primary | brand | success | danger | warning | info | light | dark | black
89
87
  ```
90
88
 
91
- Ejemplo recomendado: si tu marca debe vivir en `brand`, reemplaza `brand-*`:
89
+ Criterio actual:
90
+
91
+ - `neutral` mantiene la base premium de la librería.
92
+ - `slate` y `zinc` exponen neutrales explícitos.
93
+ - `primary` usa `sky-*`.
94
+ - `brand` usa `brand-*`.
95
+ - `success` usa `emerald-*`.
96
+ - `danger` usa `rose-*`.
97
+ - `warning` usa `amber-*`.
98
+ - `info` usa `cyan-*`.
99
+ - `light` usa una escala clara basada en `stone-*`.
100
+ - `dark` es una variante oscura intermedia.
101
+ - `black` es la opción más densa y de mayor contraste.
102
+
103
+ Ejemplo recomendado para conectar tu marca:
92
104
 
93
105
  ```css
94
106
  @import "quickit-ui/styles.css";
@@ -103,55 +115,11 @@ Ejemplo recomendado: si tu marca debe vivir en `brand`, reemplaza `brand-*`:
103
115
  }
104
116
  ```
105
117
 
106
- Si prefieres que tu marca viva en `primary`, entonces reemplaza `blue-*`.
107
-
108
- Si quieres cambiar `neutral`, reemplaza `neutral-*`:
109
-
110
- ```css
111
- :root {
112
- --color-neutral-50: oklch(0.985 0.002 247);
113
- --color-neutral-100: oklch(0.97 0.004 247);
114
- --color-neutral-200: oklch(0.93 0.01 252);
115
- --color-neutral-300: oklch(0.87 0.018 253);
116
- --color-neutral-700: oklch(0.37 0.03 257);
117
- --color-neutral-800: oklch(0.28 0.028 260);
118
- --color-neutral-900: oklch(0.21 0.026 265);
119
- }
120
- ```
121
-
122
- También puedes reutilizar otro slot semántico como color de marca:
123
-
124
- ```css
125
- :root {
126
- /* color="info" */
127
- --color-sky-600: oklch(62% 0.19 330);
128
- --color-sky-700: oklch(55% 0.18 330);
129
- }
130
- ```
131
-
132
- Si creas una paleta nueva como `gray-*`, podrás usarla en clases Tailwind, pero no aparece sola en la API de Quickit:
133
-
134
- ```css
135
- @theme {
136
- --color-gray-50: oklch(0.984 0.003 247.858);
137
- --color-gray-100: oklch(0.968 0.007 247.896);
138
- --color-gray-200: oklch(0.929 0.013 255.508);
139
- --color-gray-300: oklch(0.869 0.022 252.894);
140
- --color-gray-400: oklch(0.704 0.04 256.788);
141
- --color-gray-500: oklch(0.554 0.046 257.417);
142
- --color-gray-600: oklch(0.446 0.043 257.281);
143
- --color-gray-700: oklch(0.372 0.044 257.287);
144
- --color-gray-800: oklch(0.279 0.041 260.031);
145
- --color-gray-900: oklch(0.208 0.042 265.755);
146
- --color-gray-950: oklch(0.129 0.042 264.695);
147
- }
148
- ```
118
+ Si quieres que `primary` use tu marca, reemplaza `sky-*`.
149
119
 
150
- Eso significa:
151
- - sí puedes usar `bg-gray-500`, `text-gray-700`, etc. en `className`
152
- - no puedes usar `color="gray"` a menos que la librería amplíe su mapa de colores
120
+ Si necesitas neutrales más explícitos y previsibles, usa `color="slate"` o `color="zinc"` en lugar de asumir que `neutral` es una escala plana.
153
121
 
154
- Si quieres un color nuevo puntual, puedes sobreescribir estilos con `className`:
122
+ Si necesitas un color puntual fuera de la API semántica, sobrescribe con `className`:
155
123
 
156
124
  ```jsx
157
125
  <Button
@@ -162,12 +130,29 @@ Si quieres un color nuevo puntual, puedes sobreescribir estilos con `className`:
162
130
  </Button>
163
131
  ```
164
132
 
165
- ## Ejemplos rapidos
133
+ ## Hooks y utilidades
134
+
135
+ Quickit también exporta hooks y utilidades para componer tu app o tu propia documentación:
136
+
137
+ ```jsx
138
+ import {
139
+ QUICKIT_BREAKPOINTS,
140
+ QUICKIT_BUTTON_SHAPES,
141
+ QUICKIT_CONTROL_SIZES,
142
+ QUICKIT_SEMANTIC_COLORS,
143
+ QuickitProvider,
144
+ useBreakpoint,
145
+ useMediaQuery,
146
+ useQuickitTheme,
147
+ } from "quickit-ui";
148
+ ```
149
+
150
+ ## Ejemplos
166
151
 
167
152
  ### Button
168
153
 
169
154
  ```jsx
170
- import { Button } from 'quickit-ui'
155
+ import { Button } from "quickit-ui";
171
156
 
172
157
  export function Actions() {
173
158
  return (
@@ -180,10 +165,32 @@ export function Actions() {
180
165
  Guardar
181
166
  </Button>
182
167
  </div>
183
- )
168
+ );
184
169
  }
185
170
  ```
186
171
 
172
+ Notas rápidas de `Button`:
173
+
174
+ - `shape="square"` y `shape="circle"` están pensados para icon buttons.
175
+ - `shape="square"` y `shape="circle"` salen con `activeMotion` desactivado por defecto.
176
+ - Si quieres esa animación en un icon button, usa `activeMotion={true}`.
177
+
178
+ ```jsx
179
+ <Button shape="square" variant="outline" color="neutral" aria-label="Buscar">
180
+ <SearchIcon />
181
+ </Button>
182
+
183
+ <Button
184
+ shape="square"
185
+ variant="outline"
186
+ color="neutral"
187
+ activeMotion
188
+ aria-label="Buscar con motion"
189
+ >
190
+ <SearchIcon />
191
+ </Button>
192
+ ```
193
+
187
194
  ### Formularios
188
195
 
189
196
  ```jsx
@@ -195,20 +202,21 @@ import {
195
202
  Label,
196
203
  Select,
197
204
  Textarea,
198
- } from 'quickit-ui'
205
+ } from "quickit-ui";
199
206
 
200
207
  export function ContactForm() {
201
208
  return (
202
209
  <div className="space-y-4">
203
210
  <FormControl>
204
211
  <Label htmlFor="name">Nombre</Label>
205
- <Input id="name" placeholder="Tu nombre" />
212
+ <Input id="name" color="neutral" placeholder="Tu nombre" />
206
213
  </FormControl>
207
214
 
208
215
  <FormControl>
209
216
  <Label htmlFor="topic">Tema</Label>
210
217
  <Select
211
218
  id="topic"
219
+ color="slate"
212
220
  defaultValue="support"
213
221
  onValueChange={(value) => console.log(value)}
214
222
  >
@@ -218,24 +226,44 @@ export function ContactForm() {
218
226
  <FormDescription>Selecciona el motivo de tu consulta.</FormDescription>
219
227
  </FormControl>
220
228
 
229
+ <FormControl>
230
+ <Label htmlFor="password">Contraseña</Label>
231
+ <Input
232
+ id="password"
233
+ type="password"
234
+ color="brand"
235
+ placeholder="••••••••"
236
+ />
237
+ </FormControl>
238
+
239
+ <FormControl>
240
+ <Label htmlFor="search">Buscar componente</Label>
241
+ <Input
242
+ id="search"
243
+ type="search"
244
+ color="neutral"
245
+ defaultValue="Modal"
246
+ />
247
+ </FormControl>
248
+
221
249
  <FormControl invalid>
222
250
  <Label htmlFor="message">Mensaje</Label>
223
- <Textarea id="message" placeholder="Escribe tu mensaje" />
251
+ <Textarea id="message" color="danger" placeholder="Escribe tu mensaje" />
224
252
  <FormMessage>Este campo es obligatorio.</FormMessage>
225
253
  </FormControl>
226
254
  </div>
227
- )
255
+ );
228
256
  }
229
257
  ```
230
258
 
231
- ### Navegacion
259
+ ### Navegación
232
260
 
233
261
  ```jsx
234
- import { Tabs, TabsContent, TabsList, TabsTrigger } from 'quickit-ui'
262
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "quickit-ui";
235
263
 
236
264
  export function SettingsTabs() {
237
265
  return (
238
- <Tabs defaultValue="general" activationMode="manual">
266
+ <Tabs defaultValue="general" activationMode="manual" color="brand">
239
267
  <TabsList>
240
268
  <TabsTrigger value="general">General</TabsTrigger>
241
269
  <TabsTrigger value="security">Seguridad</TabsTrigger>
@@ -244,7 +272,33 @@ export function SettingsTabs() {
244
272
  <TabsContent value="general">Contenido general</TabsContent>
245
273
  <TabsContent value="security">Contenido de seguridad</TabsContent>
246
274
  </Tabs>
247
- )
275
+ );
276
+ }
277
+ ```
278
+
279
+ ### Lógica declarativa
280
+
281
+ ```jsx
282
+ import { Default, For, Match, RenderSwitch, Show } from "quickit-ui";
283
+
284
+ export function States({ items, status, user }) {
285
+ return (
286
+ <>
287
+ <Show when={user} fallback={<p>Inicia sesión</p>}>
288
+ {(value) => <p>Hola, {value.name}</p>}
289
+ </Show>
290
+
291
+ <RenderSwitch value={status}>
292
+ <Match when="idle">Idle</Match>
293
+ <Match when="loading">Loading</Match>
294
+ <Default>Done</Default>
295
+ </RenderSwitch>
296
+
297
+ <For each={items} fallback={<p>Sin resultados</p>}>
298
+ {(item) => <div key={item.id}>{item.label}</div>}
299
+ </For>
300
+ </>
301
+ );
248
302
  }
249
303
  ```
250
304
 
@@ -264,13 +318,13 @@ import {
264
318
  ModalContent,
265
319
  ModalHeader,
266
320
  ModalTitle,
267
- } from 'quickit-ui'
321
+ } from "quickit-ui";
268
322
 
269
323
  export function OverlayExamples() {
270
324
  return (
271
325
  <div className="flex gap-4">
272
326
  <Dropdown>
273
- <DropdownTrigger>
327
+ <DropdownTrigger asChild>
274
328
  <Button color="neutral" variant="outline">
275
329
  Opciones
276
330
  </Button>
@@ -284,11 +338,13 @@ export function OverlayExamples() {
284
338
  </Dropdown>
285
339
 
286
340
  <Modal>
287
- <Button color="neutral">Abrir modal</Button>
341
+ <Modal.Trigger asChild>
342
+ <Button color="neutral">Abrir modal</Button>
343
+ </Modal.Trigger>
288
344
 
289
- <ModalContent>
345
+ <Modal.Content>
290
346
  <ModalHeader>
291
- <ModalTitle>Confirmar accion</ModalTitle>
347
+ <ModalTitle>Confirmar acción</ModalTitle>
292
348
  </ModalHeader>
293
349
 
294
350
  <ModalBody>Este cambio no se puede deshacer.</ModalBody>
@@ -299,17 +355,29 @@ export function OverlayExamples() {
299
355
  </ModalAction>
300
356
  <ModalAction color="danger">Eliminar</ModalAction>
301
357
  </ModalActions>
302
- </ModalContent>
358
+ </Modal.Content>
303
359
  </Modal>
304
360
  </div>
305
- )
361
+ );
306
362
  }
307
363
  ```
308
364
 
365
+ ## Identidad
366
+
367
+ Quickit incluye primitives y compuestos de identidad:
368
+
369
+ - `Avatar`
370
+ - `AvatarGroup`
371
+ - `AvatarPresence`
372
+ - `Initials`
373
+ - `UserChip`
374
+
309
375
  ## Componentes disponibles
310
376
 
311
377
  - `Accordion`
312
378
  - `Avatar`
379
+ - `AvatarGroup`
380
+ - `AvatarPresence`
313
381
  - `Badge`
314
382
  - `Breadcrumb`
315
383
  - `Button`
@@ -317,6 +385,9 @@ export function OverlayExamples() {
317
385
  - `Dropdown`
318
386
  - `EmptyState`
319
387
  - `FormControl`
388
+ - `FormDescription`
389
+ - `FormMessage`
390
+ - `Initials`
320
391
  - `Input`
321
392
  - `Label`
322
393
  - `Link`
@@ -330,6 +401,25 @@ export function OverlayExamples() {
330
401
  - `Tabs`
331
402
  - `Textarea`
332
403
  - `Tooltip`
404
+ - `UserChip`
405
+ - `Show`
406
+ - `RenderSwitch`
407
+ - `Match`
408
+ - `Default`
409
+ - `For`
410
+
411
+ ## Documentación local
412
+
413
+ ```bash
414
+ npm install
415
+ npm run dev
416
+ ```
417
+
418
+ Para generar la versión estática:
419
+
420
+ ```bash
421
+ npm run build:docs
422
+ ```
333
423
 
334
424
  ## Requisitos
335
425
 
@@ -337,26 +427,15 @@ export function OverlayExamples() {
337
427
  - `react-dom` `^19.0.0`
338
428
  - Node.js `18` o superior
339
429
 
340
- ## Exportaciones utiles
341
-
342
- El paquete exporta componentes, hooks y utilidades desde:
343
-
344
- ```jsx
345
- import {
346
- Button,
347
- Input,
348
- QuickitProvider,
349
- useQuickitTheme,
350
- } from 'quickit-ui'
351
- ```
352
-
353
- ## Scripts utiles
430
+ ## Scripts útiles
354
431
 
355
432
  - `npm run dev`: entorno local de desarrollo.
356
- - `npm run build`: build de la libreria para distribucion. El paquete publicado no incluye sourcemaps para reducir el peso en npm.
357
- - `npm run build:docs`: build estatico de la documentacion.
358
- - `npm run lint`: validacion con ESLint.
359
- - `npm run pack:check`: vista previa del paquete que se publicaria en npm.
433
+ - `npm run build`: build de la librería para distribución.
434
+ - `npm run build:docs`: build estático de la documentación.
435
+ - `npm run lint`: validación con ESLint.
436
+ - `npm run test`: pruebas runtime.
437
+ - `npm run test:types`: validación del consumo TypeScript.
438
+ - `npm run pack:check`: vista previa del paquete que se publicaría en npm.
360
439
 
361
440
  ## Licencia
362
441