@eduardoalvarez/arrecife 0.3.0 → 0.5.0

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +121 -1
  3. package/dist/brand/index.cjs +29 -10
  4. package/dist/brand/index.d.cts +9 -1
  5. package/dist/brand/index.d.ts +9 -1
  6. package/dist/brand/index.js +4 -2
  7. package/dist/chart/index.cjs +287 -0
  8. package/dist/chart/index.d.cts +127 -0
  9. package/dist/chart/index.d.ts +127 -0
  10. package/dist/chart/index.js +103 -0
  11. package/dist/chunk-KPZNNMV5.js +83 -0
  12. package/dist/chunk-MLKGABMK.js +7 -0
  13. package/dist/chunk-NHS7ETKJ.js +27 -0
  14. package/dist/{chunk-I7GYZD2A.js → chunk-TSPJOM6K.js} +5 -7
  15. package/dist/chunk-UOWIDFCB.js +81 -0
  16. package/dist/{chunk-VSMW2CT4.js → chunk-VPT32GPG.js} +2 -1
  17. package/dist/{chunk-ND45OQOC.js → chunk-YZ2SDOVZ.js} +29 -35
  18. package/dist/chunk-ZEOQKRQ7.js +19 -0
  19. package/dist/form/index.cjs +301 -0
  20. package/dist/form/index.d.cts +86 -0
  21. package/dist/form/index.d.ts +86 -0
  22. package/dist/form/index.js +84 -0
  23. package/dist/index.cjs +1094 -293
  24. package/dist/index.d.cts +452 -37
  25. package/dist/index.d.ts +452 -37
  26. package/dist/index.js +963 -373
  27. package/dist/label-DuTvJGxD.d.cts +14 -0
  28. package/dist/label-DuTvJGxD.d.ts +14 -0
  29. package/dist/og/index.js +2 -1
  30. package/dist/shiki/index.js +2 -1
  31. package/dist/tema/index.cjs +94 -0
  32. package/dist/tema/index.d.cts +110 -0
  33. package/dist/tema/index.d.ts +110 -0
  34. package/dist/tema/index.js +2 -0
  35. package/dist/tokens/index.cjs +6 -0
  36. package/dist/tokens/index.d.cts +33 -1
  37. package/dist/tokens/index.d.ts +33 -1
  38. package/dist/tokens/index.js +3 -2
  39. package/dist/tokens/theme.css +43 -0
  40. package/llms.txt +351 -44
  41. package/package.json +31 -2
package/llms.txt CHANGED
@@ -99,32 +99,83 @@ escribe con el nombre de la tabla.
99
99
 
100
100
  ## Qué importar de dónde
101
101
 
102
- `exports` tiene cinco subrutas y la elección importa: tres de ellas **no
103
- arrastran React**, y por eso pueden consumirse desde un worker, un
104
- `astro.config.mjs`, un script de build o un generador con Satori.
105
-
106
- | Subruta | Arrastra React | Para qué |
107
- | --- | --- | --- |
108
- | `@eduardoalvarez/arrecife` | sí | Componentes, primitivos, marca, `cn`. Reexporta tokens |
109
- | `@eduardoalvarez/arrecife/tokens` | **no** | El objeto `tokens` en JS. Satori, Astro, scripts |
110
- | `@eduardoalvarez/arrecife/tokens/theme.css` | — | El `@theme` de Tailwind v4 |
111
- | `@eduardoalvarez/arrecife/og` | **no** | Las plantillas de Open Graph para Satori |
112
- | `@eduardoalvarez/arrecife/shiki` | **no** | El tema de resaltado de sintaxis |
113
- | `@eduardoalvarez/arrecife/brand` | sí | Logo, isotipo y mascota como componentes |
114
- | `@eduardoalvarez/arrecife/assets/*` | — | Los PNG de la marca |
102
+ La elección importa, y por dos motivos distintos. Cuatro subrutas **no arrastran
103
+ React**, así que pueden consumirse desde un worker, un `astro.config.mjs`, un
104
+ script de build o un generador con Satori. Otras dos piden una **dependencia de
105
+ pares opcional** que solo instala quien las use.
106
+
107
+ | Subruta | Arrastra React | Pide además | Para qué |
108
+ | --- | --- | --- | --- |
109
+ | `@eduardoalvarez/arrecife` | sí | — | Componentes, primitivos, marca, `cn`. Reexporta tokens y tema |
110
+ | `@eduardoalvarez/arrecife/tokens` | **no** | — | El objeto `tokens` en JS. Satori, Astro, scripts |
111
+ | `@eduardoalvarez/arrecife/tokens/theme.css` | — | — | El `@theme` de Tailwind v4 |
112
+ | `@eduardoalvarez/arrecife/tema` | **no** | — | `scriptTema` para el `<head>`, y leer o cambiar el modo |
113
+ | `@eduardoalvarez/arrecife/og` | **no** | — | Las plantillas de Open Graph para Satori |
114
+ | `@eduardoalvarez/arrecife/shiki` | **no** | — | El tema de resaltado de sintaxis |
115
+ | `@eduardoalvarez/arrecife/brand` | sí | — | Logo, isotipo y mascota como componentes |
116
+ | `@eduardoalvarez/arrecife/form` | sí | `react-hook-form` | La capa de formulario: etiquetas, errores y `aria-*` |
117
+ | `@eduardoalvarez/arrecife/chart` | sí | `recharts` | El chasis de las gráficas y la paleta de series |
118
+ | `@eduardoalvarez/arrecife/assets/*` | — | — | Los PNG de la marca |
115
119
 
116
120
  Importar la raíz desde un script de build para sacar un token es el error que las
117
121
  subrutas existen para evitar: arrastra React entero a un worker que no lo monta.
118
122
 
123
+ `./form` y `./chart` están fuera de la raíz por el motivo simétrico: si colgaran
124
+ del índice principal, los proyectos que no dibujan gráficas ni usan React Hook
125
+ Form tendrían que instalar esas dependencias igualmente para que su bundler
126
+ resolviera un import que nunca ejecutan.
127
+
119
128
  ```ts
120
129
  // Bien, en un generador de OG o en astro.config.mjs
121
130
  import { tokens } from '@eduardoalvarez/arrecife/tokens';
122
131
  import { arrecife } from '@eduardoalvarez/arrecife/shiki';
123
132
 
133
+ // Bien, en el <head> de un Astro que no monta React
134
+ import { scriptTema } from '@eduardoalvarez/arrecife/tema';
135
+
124
136
  // Mal: monta React donde no hace falta
125
137
  import { tokens } from '@eduardoalvarez/arrecife';
126
138
  ```
127
139
 
140
+ ### El tema, y el parpadeo de la primera pintura
141
+
142
+ `ThemeToggle` es el botón; lo difícil está en `./tema`. Sin `scriptTema` inline en
143
+ el `<head>`, la primera pintura sale con el modo por defecto y el elegido entra
144
+ un frame después: en un sitio oscuro que el usuario dejó en claro, eso es un
145
+ fogonazo blanco en cada carga.
146
+
147
+ ```astro
148
+ ---
149
+ import { scriptTema } from '@eduardoalvarez/arrecife/tema';
150
+ ---
151
+ <head>
152
+ <script is:inline set:html={scriptTema} />
153
+ </head>
154
+ ```
155
+
156
+ Tiene que ir INLINE. Un `<script src>`, aunque sea síncrono, se descarga, y el
157
+ parpadeo vuelve. El script reengancha en `astro:after-swap` porque las
158
+ transiciones de vista reemplazan el `<html>` entero.
159
+
160
+ ### Los iconos de redes van agrupados
161
+
162
+ ```tsx
163
+ // ❌ no existe
164
+ import { GitHub } from '@eduardoalvarez/arrecife';
165
+
166
+ // ✅
167
+ import { social } from '@eduardoalvarez/arrecife';
168
+ <social.GitHub />
169
+ ```
170
+
171
+ Los ocho: `GitHub`, `LinkedIn`, `X`, `Instagram`, `Discord`, `YouTube`, `Rss`,
172
+ `Correo`. Van bajo namespace porque uno se llama `X` y sueltos colisiona.
173
+
174
+ Los glifos internos —`Close`, `ChevronDown`, `Sol`— **no se exportan** y no van a
175
+ exportarse: son el juego mínimo de los primitivos. Un componente que necesita un
176
+ icono lo recibe por prop (`Stat` tiene `icon`, cada `Red` de `Footer` tiene el
177
+ suyo). No pidas que se publiquen: pasa el tuyo.
178
+
128
179
  ## Tokens
129
180
 
130
181
  La fuente es un objeto de TypeScript y la salida CSS se genera de él, así que el
@@ -260,7 +311,76 @@ primitiva de Radix se resumen en la línea `Extiende`, y son los de siempre.
260
311
 
261
312
  ## Primitivos
262
313
 
263
- Se importan de `@eduardoalvarez/arrecife`. 100 exportaciones.
314
+ Se importan de `@eduardoalvarez/arrecife`. 110 exportaciones.
315
+
316
+ ### Accordion, AccordionItem, AccordionTrigger, AccordionContent
317
+
318
+ Fuente: `src/primitives/accordion.tsx`
319
+
320
+ **Accordion**
321
+ El plegable. Lo pedían dos proyectos: el FAQ del portafolio y el temario de cursos, que es literalmente una lista de secciones que se abren.
322
+
323
+ - Extiende: `ComponentPropsWithoutRef<typeof AccordionPrimitive.Root>`
324
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
325
+
326
+ **AccordionItem**
327
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
328
+
329
+ **AccordionTrigger**
330
+ El disparador es el encabezado, así que va DENTRO de un `<h3>`: Radix envuelve el botón en `AccordionPrimitive.Header`, que renderiza el elemento que se le pida. Sin eso, un lector de pantalla ve una lista de botones sueltos y pierde la estructura de la página, que es justo lo que un FAQ necesita conservar.
331
+
332
+ - Extiende: `ComponentPropsWithoutRef< typeof AccordionPrimitive.Trigger >`
333
+
334
+ | prop | tipo | req. | defecto | qué hace |
335
+ | --- | --- | --- | --- | --- |
336
+ | `headingLevel` | `4 \| 2 \| 3` | | `3` | Nivel del encabezado que envuelve al disparador. |
337
+
338
+ **AccordionContent**
339
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
340
+
341
+ ### AlertDialogOverlay, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogCancel, AlertDialogAction, AlertDialog, AlertDialogTrigger
342
+
343
+ Fuente: `src/primitives/alert-dialog.tsx`
344
+
345
+ **AlertDialogOverlay**
346
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
347
+
348
+ **AlertDialogContent**
349
+ Sin entrada animada, igual que `Dialog`: aparece donde va a quedarse.
350
+
351
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
352
+
353
+ **AlertDialogHeader**
354
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
355
+
356
+ **AlertDialogFooter**
357
+ Cancelar a la IZQUIERDA de confirmar en escritorio y ABAJO en móvil, que es lo que da `flex-col-reverse`: el orden del DOM pone cancelar primero —es donde va el foco— y en columna el dedo lo encuentra donde toca sin cambiar la tabulación.
358
+
359
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
360
+
361
+ **AlertDialogTitle**
362
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
363
+
364
+ **AlertDialogDescription**
365
+ Lo que se pierde, dicho entero. Es lo que el rol `alertdialog` hace que se anuncie de entrada, así que aquí no va «esta acción no se puede deshacer» suelto: va qué se borra y qué se lleva por delante.
366
+
367
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
368
+
369
+ **AlertDialogCancel**
370
+ El que se lleva el foco al abrir.
371
+
372
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
373
+
374
+ **AlertDialogAction**
375
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
376
+
377
+ **AlertDialog**
378
+ La confirmación destructiva. NO es un `Dialog` con otro texto, y por eso está en su propio archivo y sobre su propia primitiva de Radix.
379
+
380
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
381
+
382
+ **AlertDialogTrigger**
383
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
264
384
 
265
385
  ### Alert
266
386
 
@@ -277,7 +397,7 @@ El aviso lleva el color en el fondo, no solo en el borde.
277
397
  | `title` | `ReactNode` | | | |
278
398
  | `variant` | `"accent" \| "success" \| "warning" \| "error"` | | `accent` | |
279
399
 
280
- ### Avatar, AvatarImage, AvatarFallback
400
+ ### Avatar, AvatarImage, AvatarFallback, AvatarUpload
281
401
 
282
402
  Fuente: `src/primitives/avatar.tsx`
283
403
 
@@ -298,6 +418,21 @@ Iniciales mientras la imagen carga, o cuando no hay imagen.
298
418
 
299
419
  - Sin props propios: pasa los del elemento o la primitiva que envuelve.
300
420
 
421
+ **AvatarUpload**
422
+ El avatar que se puede cambiar. `Avatar` muestra; este además deja elegir.
423
+
424
+ - Extiende: `Omit<ComponentPropsWithoutRef<'div'>, 'onSelect' \| 'children'> & VariantProps<typeof avatar>`
425
+
426
+ | prop | tipo | req. | defecto | qué hace |
427
+ | --- | --- | --- | --- | --- |
428
+ | `accept` | `string` | | `image/*` | Qué acepta el diálogo del sistema. |
429
+ | `disabled` | `boolean \| undefined` | | `false` | |
430
+ | `fallback` | `ReactNode` | | | Iniciales mientras no hay imagen. |
431
+ | `label` | `string` | | `Cambiar la foto` | Nombre accesible del control. Es lo único que lo nombra: no hay texto visible. |
432
+ | `onSelectFile` | `(archivo: File) => void` | | | Se dispara con el archivo elegido. La subida la hace el proyecto. |
433
+ | `size` | `"sm" \| "md" \| "lg" \| "xl"` | | | |
434
+ | `src` | `string` | | | La imagen actual, ya subida. La previsualización local la gana mientras dure. |
435
+
301
436
  ### Badge, CategoryBadge, MetricBadge
302
437
 
303
438
  Fuente: `src/primitives/badge.tsx`
@@ -736,33 +871,18 @@ Fuente: `src/primitives/textarea.tsx`
736
871
  | --- | --- | --- | --- | --- |
737
872
  | `invalid` | `boolean` | | `false` | |
738
873
 
739
- ### ToastViewport, Toast, ToastTitle, ToastDescription, ToastProvider, ToastAction
874
+ ### Toaster
740
875
 
741
- Fuente: `src/primitives/toast.tsx`
742
-
743
- **ToastViewport**
744
- - Sin props propios: pasa los del elemento o la primitiva que envuelve.
876
+ Fuente: `src/primitives/toaster.tsx`
745
877
 
746
- **Toast**
747
- Sin deslizamiento de entrada: el aviso aparece donde va a quedarse.
878
+ Va UNA vez, lo más arriba posible del árbol. Dos `Toaster` montados pintan cada aviso dos veces: la lista es del módulo, no de la instancia.
748
879
 
749
- - Extiende: `ComponentPropsWithoutRef<typeof ToastPrimitive.Root> & VariantProps<typeof toast>`
880
+ - Extiende: `{ /** Cuánto dura un aviso que no dice lo contrario. */ duration?: number; /** * Nombre del landmark que Radix crea para la región de avisos. Se traduce * porque lo lee un lector de pantalla, y el default de Radix está en inglés. */ label?: string; }`
750
881
 
751
882
  | prop | tipo | req. | defecto | qué hace |
752
883
  | --- | --- | --- | --- | --- |
753
- | `variant` | `"success" \| "error" \| "neutral"` | | `neutral` | |
754
-
755
- **ToastTitle**
756
- - Sin props propios: pasa los del elemento o la primitiva que envuelve.
757
-
758
- **ToastDescription**
759
- - Sin props propios: pasa los del elemento o la primitiva que envuelve.
760
-
761
- **ToastProvider**
762
- - Sin props propios: pasa los del elemento o la primitiva que envuelve.
763
-
764
- **ToastAction**
765
- - Sin props propios: pasa los del elemento o la primitiva que envuelve.
884
+ | `duration` | `number` | | `5000` | Cuánto dura un aviso que no dice lo contrario. |
885
+ | `label` | `string` | | `Avisos` | Nombre del landmark que Radix crea para la región de avisos. Se traduce porque lo lee un lector de pantalla, y el default de Radix está en inglés. |
766
886
 
767
887
  ### TooltipContent, TooltipProvider, Tooltip, TooltipTrigger
768
888
 
@@ -788,15 +908,15 @@ Fuente: `src/primitives/typography.tsx`
788
908
 
789
909
  | prop | tipo | req. | defecto | qué hace |
790
910
  | --- | --- | --- | --- | --- |
791
- | `as` | `"caption" \| "dd" \| "dt" \| "em" \| "figcaption" \| "h1" \| "h2" \| "h3" \| "h4" \| "legend" \| "li" \| "p" \| "span" \| "strong"` | | | Etiqueta HTML. Por defecto, la que corresponde a la escala. |
911
+ | `as` | `"h2" \| "h3" \| "li" \| "p" \| "span" \| "caption" \| "dd" \| "dt" \| "em" \| "figcaption" \| "h1" \| "h4" \| "legend" \| "strong"` | | | Etiqueta HTML. Por defecto, la que corresponde a la escala. |
792
912
  | `asChild` | `boolean` | | `false` | Renderiza el hijo en vez de crear un elemento, para envolver un enlace. |
793
913
  | `measure` | `boolean` | | | Corta la línea a 68ch. Activo por defecto en `body`, que es la única escala pensada para leerse en párrafos largos. |
794
914
  | `tone` | `"accent" \| "success" \| "warning" \| "error" \| "warm" \| "primary" \| "secondary" \| "muted"` | | `primary` | |
795
- | `variant` | `"display" \| "body" \| "h1" \| "h2" \| "h3" \| "label" \| "meta" \| "stat" \| "lead" \| "ui" \| "tag" \| "chip" \| "eyebrow"` | | `body` | |
915
+ | `variant` | `"display" \| "h2" \| "h3" \| "label" \| "body" \| "h1" \| "meta" \| "stat" \| "lead" \| "ui" \| "tag" \| "chip" \| "eyebrow"` | | `body` | |
796
916
 
797
917
  ## Componentes
798
918
 
799
- Se importan de `@eduardoalvarez/arrecife`. 21 exportaciones.
919
+ Se importan de `@eduardoalvarez/arrecife`. 24 exportaciones.
800
920
 
801
921
  ### ArticleCard
802
922
 
@@ -812,6 +932,7 @@ La línea de metadatos va en `meta` y no en `eyebrow`: `18 ago 2026 · 8 min de
812
932
  | `date` | `ReactNode` | | | Fecha ya formateada por el proyecto: la librería no impone locale. |
813
933
  | `dateTime` | `string` | | | Valor de `datetime` del `<time>`, en ISO. |
814
934
  | `excerpt` | `ReactNode` | | | Entradilla. Se corta a dos líneas para que la rejilla no se desalinee. |
935
+ | `headingLevel` | `2 \| 3` | | `3` | Nivel del titular. `h3` por defecto: una tarjeta suelta en una rejilla no gana el nivel que su posición no le da. |
815
936
  | `readingMinutes` | `number` | | | |
816
937
  | `tags` | `readonly string[]` | | | |
817
938
  | `title` | `ReactNode` | sí | | |
@@ -916,6 +1037,24 @@ La regla más importante de la mascota, por fin como código.
916
1037
  | `expresion` | `"annoyed" \| "confused" \| "hearts" \| "laughing" \| "shades" \| "waiting" \| "wink"` | sí | | La cara. Obligatoria: sin ella esto es un párrafo centrado. |
917
1038
  | `title` | `ReactNode` | sí | | |
918
1039
 
1040
+ ### EventCalendar
1041
+
1042
+ Fuente: `src/components/event-calendar/index.tsx`
1043
+
1044
+ - Extiende: `Omit<ComponentPropsWithoutRef<'div'>, 'onSelect' \| 'children'>`
1045
+
1046
+ | prop | tipo | req. | defecto | qué hace |
1047
+ | --- | --- | --- | --- | --- |
1048
+ | `emptyMessage` | `ReactNode` | | `Nada en este día.` | Texto del panel cuando el día elegido no tiene nada. |
1049
+ | `events` | `readonly EventoCalendario[]` | sí | | |
1050
+ | `formatDay` | `(dia: Date) => string` | | `(dia) => format(dia, "EEEE d de MMMM", { locale: es })` | Encabezado del panel. Por defecto, `es` de date-fns, como `Calendar`. |
1051
+ | `formatTime` | `(fecha: Date) => string` | | `(fecha) => format(fecha, HH:mm, { locale: es })` | |
1052
+ | `onCreateEvent` | `(evento: Omit<EventoCalendario, "id">) => void` | | | Sin él, la agenda es de solo lectura y no se pinta el formulario. |
1053
+ | `onDeleteEvent` | `(id: string) => void` | | | |
1054
+ | `onSelectDay` | `(dia: Date) => void` | | | |
1055
+ | `onUpdateEvent` | `(evento: EventoCalendario) => void` | | | |
1056
+ | `selected` | `Date` | | | Día seleccionado, si el proyecto lo controla. Sin él, empieza en hoy. |
1057
+
919
1058
  ### Footer, FooterLink
920
1059
 
921
1060
  Fuente: `src/components/footer/index.tsx`
@@ -925,6 +1064,7 @@ Fuente: `src/components/footer/index.tsx`
925
1064
 
926
1065
  | prop | tipo | req. | defecto | qué hace |
927
1066
  | --- | --- | --- | --- | --- |
1067
+ | `brand` | `ReactNode` | | | La fila de marca: la aleta y el wordmark, arriba del todo. |
928
1068
  | `social` | `readonly Red[]` | | | |
929
1069
  | `year` | `number` | | `new Date().getFullYear()` | Año de la firma. |
930
1070
 
@@ -951,6 +1091,7 @@ UNO por sitio. Es la única pieza del sistema que se gasta como el botón de con
951
1091
  | `eyebrow` | `ReactNode` | | | Mono, versalitas, en acento. |
952
1092
  | `pose` | `"desk" \| "laptop-coffee" \| "peek" \| "surf"` | | | La pose de Tiburoncín. Sin ella el hero es un panel con texto. |
953
1093
  | `title` | `ReactNode` | sí | | |
1094
+ | `variant` | `"cabecera" \| "centrado"` | | `cabecera` | `cabecera` sangra la pose por la esquina; `centrado` la pone arriba y centra el texto, para una página que es solo esto. |
954
1095
 
955
1096
  ### LinkRow
956
1097
 
@@ -1006,7 +1147,11 @@ Fuente: `src/components/newsletter-form/index.tsx`
1006
1147
  | `errorMessage` | `ReactNode` | | `No se pudo suscribir ese correo. Revísalo y vuelve a intentar.` | |
1007
1148
  | `expresion` | `"annoyed" \| "confused" \| "hearts" \| "laughing" \| "shades" \| "waiting" \| "wink"` | | | |
1008
1149
  | `fieldLabel` | `string` | | `Correo electrónico` | |
1009
- | `onSubmitEmail` | `(email: string) => void` | | | Se dispara con el correo ya leído del campo. |
1150
+ | `nameField` | `boolean` | | `false` | Añade el campo de nombre delante del correo. |
1151
+ | `nameInputProps` | `Omit<InputProps, "id" \| "disabled" \| "name">` | | | Lo que el proyecto necesite colgar del campo de nombre: `minLength`, `maxLength`, `pattern`. La librería no impone ninguna de las tres. |
1152
+ | `nameLabel` | `string` | | `Nombre` | |
1153
+ | `namePlaceholder` | `string` | | `Cómo te llamas` | |
1154
+ | `onSubmitEmail` | `(email: string, name?: string \| undefined) => void` | | | Se dispara con el correo ya leído del campo, y con el nombre si el campo está puesto. |
1010
1155
  | `placeholder` | `string` | | `tu@correo.dev` | |
1011
1156
  | `state` | `"error" \| "reposo" \| "enviando" \| "exito"` | | `reposo` | |
1012
1157
  | `submitLabel` | `string` | | `Suscribirme` | |
@@ -1024,12 +1169,26 @@ Una sola cabecera en dos escalas, no dos componentes.
1024
1169
  | prop | tipo | req. | defecto | qué hace |
1025
1170
  | --- | --- | --- | --- | --- |
1026
1171
  | `action` | `ReactNode` | | | Ranura para las llamadas a la acción. Si aquí va un botón de conversión, es el único de la pantalla. |
1027
- | `as` | `"h1" \| "h2"` | | `h1` | Nivel del titular. `h1` salvo que la página ya tenga uno. |
1172
+ | `as` | `"h2" \| "h1"` | | `h1` | Nivel del titular. `h1` salvo que la página ya tenga uno. |
1028
1173
  | `description` | `ReactNode` | | | |
1029
1174
  | `eyebrow` | `ReactNode` | | | Mono, versalitas, en acento. Es la sección a la que pertenece la página. |
1030
1175
  | `size` | `"display" \| "page"` | | `page` | |
1031
1176
  | `title` | `ReactNode` | sí | | |
1032
1177
 
1178
+ ### ScrollingProgressBar
1179
+
1180
+ Fuente: `src/components/scrolling-progress-bar/index.tsx`
1181
+
1182
+ Cuánto llevas leído. NO es `Progress` con otro nombre.
1183
+
1184
+ - Extiende: `Omit<ComponentPropsWithoutRef<'div'>, 'children'>`
1185
+
1186
+ | prop | tipo | req. | defecto | qué hace |
1187
+ | --- | --- | --- | --- | --- |
1188
+ | `sticky` | `boolean` | | `true` | Pega la barra al borde superior de la ventana. |
1189
+ | `target` | `RefObject<HTMLElement \| null>` | | | El elemento que se mide. Sin él, el documento entero. |
1190
+ | `tone` | `"accent" \| "warm"` | | `accent` | Arena en vez de bioluz, para igualar el progreso de curso. |
1191
+
1033
1192
  ### SidebarItem, SidebarNav
1034
1193
 
1035
1194
  Fuente: `src/components/sidebar-nav/index.tsx`
@@ -1063,6 +1222,8 @@ Una métrica grande: el número en la escala `stat` y su nombre debajo.
1063
1222
 
1064
1223
  | prop | tipo | req. | defecto | qué hace |
1065
1224
  | --- | --- | --- | --- | --- |
1225
+ | `description` | `ReactNode` | | | La bajada: el matiz que el número solo no da. «12 aplicaciones» no dice si son muchas, y aquí es donde se dice. |
1226
+ | `icon` | `ReactNode` | | | Glifo al lado del título, a 1em. Hereda `currentColor`, así que sigue al tono del título y no hay que teñirlo aparte. |
1066
1227
  | `label` | `ReactNode` | sí | | Qué se está contando. Va en mono versalitas. |
1067
1228
  | `progress` | `number` | | | Con `progress`, la métrica se lee como avance y añade la barra. |
1068
1229
  | `tone` | `"neutral" \| "alerta"` | | `neutral` | `alerta` solo cuando el número ES el problema. |
@@ -1079,11 +1240,27 @@ Fuente: `src/components/talk-card/index.tsx`
1079
1240
  | `asChild` | `boolean \| undefined` | | | Renderiza el hijo en vez de un `<a>`. Es como se enchufa el `Link` de Next o de Astro sin que la librería dependa de ningún enrutador. |
1080
1241
  | `date` | `ReactNode` | | | |
1081
1242
  | `dateTime` | `string` | | | |
1243
+ | `description` | `ReactNode` | | | De qué iba la charla. Se corta a dos líneas, igual que el `excerpt` de `ArticleCard`, para que la rejilla no se desalinee. |
1082
1244
  | `event` | `ReactNode` | sí | | Dónde se dio: la conferencia, el meetup, el equipo. |
1083
1245
  | `location` | `ReactNode` | | | |
1084
1246
  | `status` | `ReactNode` | | | Etiqueta corta de estado: «con vídeo», «próxima», «solo audio». |
1085
1247
  | `title` | `ReactNode` | sí | | |
1086
1248
 
1249
+ ### ThemeToggle
1250
+
1251
+ Fuente: `src/components/theme-toggle/index.tsx`
1252
+
1253
+ El control que faltaba. La librería definía todo el sistema de temas y no exponía lo que lo cambia, así que dos proyectos lo reimplementaban.
1254
+
1255
+ - Extiende: `Omit<ComponentPropsWithoutRef<'button'>, 'onClick'>`
1256
+
1257
+ | prop | tipo | req. | defecto | qué hace |
1258
+ | --- | --- | --- | --- | --- |
1259
+ | `label` | `string` | | `Cambiar de tema` | Nombre accesible. El botón no tiene texto visible, así que es lo único que lo nombra. |
1260
+ | `onThemeChange` | `(tema: Tema) => void` | | | Se dispara con el tema que quedó puesto, por si el proyecto quiere anotarlo. |
1261
+ | `size` | `"sm" \| "md" \| "lg" \| "icon"` | | `icon` | |
1262
+ | `variant` | `"primary" \| "conversion" \| "secondary" \| "tertiary"` | | `secondary` | |
1263
+
1087
1264
  ### TableOfContents
1088
1265
 
1089
1266
  Fuente: `src/components/toc/index.tsx`
@@ -1123,6 +1300,7 @@ El wordmark sale de `naming.wordmark`, no de una cadena escrita a mano, y siempr
1123
1300
  | prop | tipo | req. | defecto | qué hace |
1124
1301
  | --- | --- | --- | --- | --- |
1125
1302
  | `basePath` | `string` | | `RUTA_ASSETS` | |
1303
+ | `conLema` | `boolean \| undefined` | | `false` | Añade el lema bajo el wordmark, separado de la aleta por una divisoria. |
1126
1304
  | `sobre` | `"oscuro" \| "claro"` | | `oscuro` | |
1127
1305
  | `soloIsotipo` | `boolean \| undefined` | | `false` | Oculta el wordmark y deja solo la aleta, para barras muy estrechas. |
1128
1306
 
@@ -1152,6 +1330,100 @@ La cabeza de Tiburoncín, con expresión.
1152
1330
  | `basePath` | `string` | | `RUTA_ASSETS` | |
1153
1331
  | `expresion` | `"annoyed" \| "confused" \| "hearts" \| "laughing" \| "shades" \| "waiting" \| "wink"` | sí | | |
1154
1332
 
1333
+ ## Formularios
1334
+
1335
+ Se importan de `@eduardoalvarez/arrecife/form` · pide `react-hook-form`. 7 exportaciones.
1336
+
1337
+ ### FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage, Form
1338
+
1339
+ Fuente: `src/form/index.tsx`
1340
+
1341
+ **FormField**
1342
+ Un campo controlado. Envuelve el `Controller` de RHF y además publica el nombre en contexto, que es de donde lo leen la etiqueta y el mensaje sin que haya que repetirlo tres veces.
1343
+
1344
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1345
+
1346
+ **FormItem**
1347
+ La caja del campo: etiqueta, control, ayuda y mensaje, en columna.
1348
+
1349
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1350
+
1351
+ **FormLabel**
1352
+ La etiqueta NO se tiñe de rojo cuando el campo falla.
1353
+
1354
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1355
+
1356
+ **FormControl**
1357
+ Envuelve al control y le cablea los atributos: el `id` que la etiqueta apunta, el `aria-describedby` con la ayuda y el mensaje, y el `aria-invalid`.
1358
+
1359
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1360
+
1361
+ **FormDescription**
1362
+ La ayuda del campo. Se anuncia siempre, haya error o no.
1363
+
1364
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1365
+
1366
+ **FormMessage**
1367
+ El mensaje de validación. Sin error no renderiza nada: un hueco reservado para el fallo desplaza el resto del formulario cada vez que aparece.
1368
+
1369
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1370
+
1371
+ **Form**
1372
+ La capa que ata los controles a un formulario con validación y mensajes.
1373
+
1374
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1375
+
1376
+ ## Gráficas
1377
+
1378
+ Se importan de `@eduardoalvarez/arrecife/chart` · pide `recharts`. 5 exportaciones.
1379
+
1380
+ ### ChartContainer, ChartTooltip, ChartLegend, ChartTooltipContent, ChartLegendContent
1381
+
1382
+ Fuente: `src/chart/index.tsx`
1383
+
1384
+ **ChartContainer**
1385
+ Envuelve la gráfica en un `<figure>` con nombre accesible y le da a Recharts el alto concreto que necesita para medirse.
1386
+
1387
+ - Extiende: `Omit<ComponentPropsWithoutRef<'figure'>, 'title'>`
1388
+
1389
+ | prop | tipo | req. | defecto | qué hace |
1390
+ | --- | --- | --- | --- | --- |
1391
+ | `height` | `number` | | `320` | Alto en píxeles. Recharts necesita uno concreto para medir. |
1392
+ | `label` | `string` | sí | | Qué muestra la gráfica, en una frase. Obligatorio, como el `label` de `Progress`: un `<svg>` de barras sin nombre accesible no es «una gráfica sin etiqueta», es una región vacía. |
1393
+ | `summary` | `ReactNode` | | | Lo que la gráfica dice, en palabras. Va en un `figcaption` oculto visualmente. |
1394
+
1395
+ **ChartTooltip**
1396
+ El `Tooltip` de Recharts con los defectos del sistema: sin animación y con el cursor teñido de `surfaceRaised`.
1397
+
1398
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1399
+
1400
+ **ChartLegend**
1401
+ - Sin props propios: pasa los del elemento o la primitiva que envuelve.
1402
+
1403
+ **ChartTooltipContent**
1404
+ La caja del tooltip. Es una tarjeta del sistema —`surface`, borde de control, sombra estándar— y no la caja blanca de Recharts, que en modo oscuro es un rectángulo blanco encima de un panel oscuro.
1405
+
1406
+ - Extiende: `{ active?: boolean \| undefined; payload?: readonly ChartPayloadItem[] \| undefined; label?: ReactNode; /** Formatea el valor. Sin ella se imprime tal cual: la librería no impone locale. */ formatter?: ((valor: unknown, item: ChartPayloadItem) => ReactNode) \| undefined; /** Oculta el encabezado, para una gráfica de una sola categoría. */ hideLabel?: boolean; className?: string; }`
1407
+
1408
+ | prop | tipo | req. | defecto | qué hace |
1409
+ | --- | --- | --- | --- | --- |
1410
+ | `active` | `boolean \| undefined` | | | |
1411
+ | `className` | `string` | | | |
1412
+ | `formatter` | `(valor: unknown, item: ChartPayloadItem) => ReactNode` | | | Formatea el valor. Sin ella se imprime tal cual: la librería no impone locale. |
1413
+ | `hideLabel` | `boolean` | | `false` | Oculta el encabezado, para una gráfica de una sola categoría. |
1414
+ | `label` | `ReactNode` | | | |
1415
+ | `payload` | `readonly ChartPayloadItem[]` | | | |
1416
+
1417
+ **ChartLegendContent**
1418
+ La leyenda con la misma marca cuadrada del tooltip y la escala `label`.
1419
+
1420
+ - Extiende: `{ payload?: readonly ChartPayloadItem[] \| undefined; className?: string; }`
1421
+
1422
+ | prop | tipo | req. | defecto | qué hace |
1423
+ | --- | --- | --- | --- | --- |
1424
+ | `className` | `string` | | | |
1425
+ | `payload` | `readonly ChartPayloadItem[]` | | | |
1426
+
1155
1427
  ## Exportaciones que no son componentes
1156
1428
 
1157
1429
  La raíz reexporta todo lo de `./tokens` y `./brand` por conveniencia. Cada uno
@@ -1173,15 +1445,16 @@ no monta React, esa subruta es la que hay que importar.
1173
1445
  | `motion` | `{ readonly duration: "150ms"; readonly easing: "ease-out"; readonly properties: "color, background-color, border-color, fill, stroke"; }` | 150ms ease-out — solo color y borde. El sistema no anima posición ni escala: los estados se comunican con borde y color, no con movimiento. |
1174
1446
  | `naming` | `{ readonly wordmark: "Eduardo Álvarez"; readonly mascot: "Tiburoncín"; readonly domain: "eduardoalvarez.dev"; }` | El wordmark siempre dice «Eduardo Álvarez». La mascota se llama Tiburoncín y nunca aparece escrita dentro del logo. |
1175
1447
  | `radius` | `{ readonly chip: 6; readonly control: 10; readonly card: 14; readonly panel: 16; readonly pill: 999; }` | |
1448
+ | `series` | `{ readonly dark: readonly ["#35D6C0", "#F2A65A", "#3E7CB1", "#71919C"]; readonly light: readonly ["#0D7C6F", "#A65B27", "#3E7CB1", "#626A75"]; }` | La paleta de series de las gráficas. CUATRO, por el mismo motivo que la de sintaxis: el sistema se comunica con color y borde, no con ruido cromático. |
1176
1449
  | `shadow` | `{ readonly standard: "0 1px 2px rgba(0, 0, 0, 0.35)"; }` | Un solo nivel. No hay escala de elevación. |
1177
1450
  | `sintaxis` | `{ fondo, identificador, literal, palabraClave, comentario, invalido }` | La paleta del resaltado de sintaxis. |
1178
1451
  | `size` | `{ readonly nav: 64; readonly content: 760; readonly wide: 1180; }` | |
1179
1452
  | `spacing` | `{ readonly stepXs: 8; readonly stepSm: 12; readonly stepMd: 16; readonly stepLg: 26; readonly stepXl: 40; readonly section: 96; }` | El ritmo de página. Los cinco escalones llevan `step` en el nombre, y no es decoración: es la corrección de un bug que no dio la cara en ningún sitio. |
1180
1453
  | `tagline` | `{ largo, corto, en }` | |
1181
- | `tokens` | `{ colors, brand, fonts, typeScale, limits, radius, control, spacing, size, gradient, sintaxis, shadow, motion, tagline, naming }` | Todos los tokens en un solo objeto, para plantillas Satori y generadores. |
1454
+ | `tokens` | `{ colors, brand, fonts, typeScale, limits, radius, control, spacing, size, gradient, sintaxis, series, shadow, motion, tagline, naming }` | Todos los tokens en un solo objeto, para plantillas Satori y generadores. |
1182
1455
  | `typeScale` | `{ display, stat, h1, h2, h3, body, lead, ui, label, tag, chip, meta, eyebrow }` | |
1183
1456
 
1184
- Tipos (12): `BrandToken`, `ColorMode`, `ColorToken`, `ControlToken`, `FontToken`, `GradientToken`, `RadiusToken`, `SintaxisToken`, `SizeToken`, `SpacingToken`, `Tokens`, `TypeScaleToken`.
1457
+ Tipos (13): `BrandToken`, `ColorMode`, `ColorToken`, `ControlToken`, `FontToken`, `GradientToken`, `RadiusToken`, `SeriesToken`, `SintaxisToken`, `SizeToken`, `SpacingToken`, `Tokens`, `TypeScaleToken`.
1185
1458
 
1186
1459
  ### `@eduardoalvarez/arrecife/brand`
1187
1460
 
@@ -1205,6 +1478,38 @@ Tipos (8): `Aleta`, `Cara`, `CaraDeMascotaProps`, `Fondo`, `IsotipoProps`, `Logo
1205
1478
 
1206
1479
  Tipos (1): `TemaShiki`.
1207
1480
 
1481
+ ### `@eduardoalvarez/arrecife/chart`
1482
+
1483
+ | export | tipo | qué es |
1484
+ | --- | --- | --- |
1485
+ | `colorDeSerie` | `(indice: number): string` | El color de la serie `indice`, como custom property. |
1486
+ | `COLORES_DE_SERIE` | `string[]` | Las cuatro, en orden, para pasárselas de golpe a un `Pie` con `Cell`. |
1487
+
1488
+ Tipos (4): `ChartContainerProps`, `ChartLegendContentProps`, `ChartPayloadItem`, `ChartTooltipContentProps`.
1489
+
1490
+ ### `@eduardoalvarez/arrecife/tema`
1491
+
1492
+ | export | tipo | qué es |
1493
+ | --- | --- | --- |
1494
+ | `alternarTema` | `(): Tema` | Cambia al contrario y devuelve el que quedó. |
1495
+ | `aplicarTema` | `(tema: Tema, persistir?: boolean): void` | Pone el tema en el `<html>` y lo persiste. |
1496
+ | `escucharTema` | `(alCambiar: (tema: Tema) => void): () => void` | Se suscribe a los cambios de tema y devuelve la función que cancela. |
1497
+ | `scriptTema` | `string` | El script que va INLINE en el `<head>`, antes de cualquier hoja de estilo. |
1498
+ | `TEMA_ATRIBUTO` | `"data-theme"` | El atributo que leen los bloques `[data-theme]` de `theme.css`. |
1499
+ | `TEMA_CLAVE` | `"arrecife-tema"` | La clave de `localStorage`. |
1500
+ | `TEMA_EVENTO` | `"arrecife:tema"` | El evento que se emite cuando el tema cambia. |
1501
+ | `temaActual` | `(): Tema` | El tema que hay puesto ahora mismo, leído del DOM. |
1502
+ | `temaGuardado` | `(): Tema \| null` | La preferencia guardada, si la hay. `null` significa «nadie ha elegido», que no es lo mismo que «eligió oscuro»: sin elección manda el sistema. |
1503
+ | `temaPreferido` | `(): Tema` | El tema que corresponde: lo elegido, y si no hay elección, lo que pida el sistema. Sin `prefers-color-scheme` declarado, oscuro, que es el primario. |
1504
+
1505
+ Tipos (1): `Tema`.
1506
+
1507
+ ### `@eduardoalvarez/arrecife/form`
1508
+
1509
+ | export | tipo | qué es |
1510
+ | --- | --- | --- |
1511
+ | `useFormField` | `(): { invalid: boolean; isDirty: boolean; isTouched: boolean; isValidating: boolean; error?: FieldError; name: string; id: string; idDescripcion: string; idMensaje: string; }` | Lo que necesita cualquier pieza del campo: el nombre, los tres ids y el estado de validación. |
1512
+
1208
1513
  ### `@eduardoalvarez/arrecife/og`
1209
1514
 
1210
1515
  | export | tipo | qué es |
@@ -1232,8 +1537,10 @@ Tipos (6): `DatosArticulo`, `DatosBase`, `DatosCharla`, `DatosCurso`, `DatosDefe
1232
1537
  | `social` | `typeof import("src/lib/social")` | |
1233
1538
  | `SUPERFICIE_TARJETA` | `"rounded-card border-hairline bg-surface border"` | El contenedor de superficie del sistema, y la única definición de lo que es una tarjeta: `surface`, borde `hairline`, radio de tarjeta. |
1234
1539
  | `textVariants` | `(props?: (ConfigVariants<{ variant: { display: string; stat: string; h1: string; h2: string; h3: string; body: string; lead: string; ui: string; label: string; tag: string; chip: string; meta: string; eyebrow: string; }; tone: { ...; }; }> & ClassProp) \| undefined): string` | |
1540
+ | `toast` | `(mensaje: ReactNode, opciones?: ToastOptions \| undefined): string` | Lanza un aviso. Devuelve su id, que es lo que hay que guardar para cerrarlo a mano —el caso de «guardando…» que se reemplaza cuando termina la petición. |
1541
+ | `useTema` | `(): Tema` | El tema puesto ahora mismo, para un proyecto que necesite ramificar en React —un logo distinto por modo, una imagen que no tiene versión clara—. |
1235
1542
 
1236
- Tipos (51): `AlertProps`, `ArticleCardProps`, `AudioPlayerMode`, `AudioPlayerProps`, `AuthorCardProps`, `AvatarProps`, `BadgeProps`, `BlockquoteProps`, `BreadcrumbProps`, `ButtonProps`, `CalendarProps`, `CategoryBadgeProps`, `CheckboxProps`, `CodeBlockProps`, `CodeProps`, `CourseCardProps`, `DateFieldProps`, `EmptyStateProps`, `Entrada`, `FooterLinkProps`, `FooterProps`, `HeroProps`, `InputProps`, `LabelProps`, `LinkRowProps`, `MetricBadgeProps`, `Migaja`, `NavItemProps`, `NavProps`, `NewsletterFormProps`, `NewsletterState`, `PageHeaderProps`, `PaginationLinkProps`, `PopoverContentProps`, `ProgressProps`, `RadioGroupItemProps`, `RadioGroupProps`, `Red`, `SeparatorProps`, `SheetContentProps`, `SidebarItemProps`, `SidebarNavProps`, `SkeletonProps`, `StatProps`, `SwitchProps`, `TableOfContentsProps`, `TabsProps`, `TalkCardProps`, `TextProps`, `TextareaProps`, `ToastProps`.
1543
+ Tipos (60): `AccordionProps`, `AccordionTriggerProps`, `AlertProps`, `ArticleCardProps`, `AudioPlayerMode`, `AudioPlayerProps`, `AuthorCardProps`, `AvatarProps`, `AvatarUploadProps`, `BadgeProps`, `BlockquoteProps`, `BreadcrumbProps`, `ButtonProps`, `CalendarProps`, `CategoryBadgeProps`, `CheckboxProps`, `CodeBlockProps`, `CodeProps`, `CourseCardProps`, `DateFieldProps`, `EmptyStateProps`, `Entrada`, `EventCalendarProps`, `EventoCalendario`, `FooterLinkProps`, `FooterProps`, `HeroProps`, `InputProps`, `LabelProps`, `LinkRowProps`, `MetricBadgeProps`, `Migaja`, `NavItemProps`, `NavProps`, `NewsletterFormProps`, `NewsletterState`, `PageHeaderProps`, `PaginationLinkProps`, `PopoverContentProps`, `ProgressProps`, `RadioGroupItemProps`, `RadioGroupProps`, `Red`, `ScrollingProgressBarProps`, `SeparatorProps`, `SheetContentProps`, `SidebarItemProps`, `SidebarNavProps`, `SkeletonProps`, `StatProps`, `SwitchProps`, `TableOfContentsProps`, `TabsProps`, `TalkCardProps`, `TextProps`, `TextareaProps`, `ThemeToggleProps`, `ToastOptions`, `ToastVariant`, `ToasterProps`.
1237
1544
 
1238
1545
  # Dónde mirar si esto no basta
1239
1546
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eduardoalvarez/arrecife",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Librería de componentes de la identidad visual de Eduardo Álvarez",
5
5
  "license": "MIT",
6
6
  "author": "Eduardo Esteban Álvarez Castañeda <soy@eduardoalvarez.dev>",
@@ -30,6 +30,11 @@
30
30
  "require": "./dist/tokens/index.cjs"
31
31
  },
32
32
  "./tokens/theme.css": "./dist/tokens/theme.css",
33
+ "./tema": {
34
+ "types": "./dist/tema/index.d.ts",
35
+ "import": "./dist/tema/index.js",
36
+ "require": "./dist/tema/index.cjs"
37
+ },
33
38
  "./brand": {
34
39
  "types": "./dist/brand/index.d.ts",
35
40
  "import": "./dist/brand/index.js",
@@ -45,6 +50,16 @@
45
50
  "import": "./dist/shiki/index.js",
46
51
  "require": "./dist/shiki/index.cjs"
47
52
  },
53
+ "./form": {
54
+ "types": "./dist/form/index.d.ts",
55
+ "import": "./dist/form/index.js",
56
+ "require": "./dist/form/index.cjs"
57
+ },
58
+ "./chart": {
59
+ "types": "./dist/chart/index.d.ts",
60
+ "import": "./dist/chart/index.js",
61
+ "require": "./dist/chart/index.cjs"
62
+ },
48
63
  "./llms.txt": "./llms.txt",
49
64
  "./assets/*": "./assets/*",
50
65
  "./package.json": "./package.json"
@@ -74,7 +89,17 @@
74
89
  },
75
90
  "peerDependencies": {
76
91
  "react": "^19.0.0",
77
- "react-dom": "^19.0.0"
92
+ "react-dom": "^19.0.0",
93
+ "react-hook-form": "^7.0.0",
94
+ "recharts": "^3.0.0"
95
+ },
96
+ "peerDependenciesMeta": {
97
+ "react-hook-form": {
98
+ "optional": true
99
+ },
100
+ "recharts": {
101
+ "optional": true
102
+ }
78
103
  },
79
104
  "devDependencies": {
80
105
  "@eslint/js": "^10.0.1",
@@ -94,6 +119,8 @@
94
119
  "playwright": "^1.62.1",
95
120
  "react": "^19.2.0",
96
121
  "react-dom": "^19.2.0",
122
+ "react-hook-form": "^7.87.0",
123
+ "recharts": "^3.10.1",
97
124
  "storybook": "^10.5.10",
98
125
  "storybook-addon-pseudo-states": "^10.5.10",
99
126
  "tailwindcss": "^4.3.3",
@@ -111,6 +138,8 @@
111
138
  "access": "public"
112
139
  },
113
140
  "dependencies": {
141
+ "@radix-ui/react-accordion": "^1.2.20",
142
+ "@radix-ui/react-alert-dialog": "^1.1.23",
114
143
  "@radix-ui/react-avatar": "^1.2.6",
115
144
  "@radix-ui/react-checkbox": "^1.3.11",
116
145
  "@radix-ui/react-dialog": "^1.1.23",