@shibui-ui/ui 1.19.8 → 1.20.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.
package/README.md CHANGED
@@ -77,6 +77,1009 @@ import { LibButton } from '@shibui/ui/angular';
77
77
 
78
78
  Storybook desplegado en Firebase Hosting — disponible en cada PR vía CI/CD.
79
79
 
80
+
81
+ # Shibui UI — Components Registry
82
+ > Referencia de agente · `@shibui/ui` · Auto-uso en proyectos consumidores
83
+
84
+ Versión del registro: `1.0.0` — Sincronizado con `packages/shibui-ui/src/index.ts`
85
+
86
+ ## Cómo usar este fichero
87
+
88
+ Este fichero está pensado para que agentes Claude que trabajen en **proyectos que consumen** `@shibui/ui` (app-react, app-angular, app-svelte, proyectos externos) puedan conocer de un vistazo todos los componentes disponibles, su nombre de importación, tag HTML y variantes principales.
89
+
90
+ ### Notación de importación
91
+
92
+ ```ts
93
+ // Web Component estándar (Lit, Angular, Svelte, Vanilla)
94
+ import '@shibui/ui';
95
+ // → usa el tag HTML: <lib-button variant="primary">
96
+
97
+ // React wrapper (PascalCase)
98
+ import { LibButton } from '@shibui/ui/react';
99
+ // → usa JSX: <LibButton variant="primary" />
100
+
101
+ // Solo tokens CSS
102
+ import '@shibui/ui/tokens';
103
+ ```
104
+
105
+ ### Binding de props en React
106
+
107
+ ```tsx
108
+ // Props primitivas → attribute binding normal
109
+ <LibButton variant="primary" size="md" disabled />
110
+
111
+ // Props de array/objeto → property binding con punto en Lit nativo
112
+ // En React wrapper esto es automático:
113
+ <LibSidebar links={LINKS} />
114
+
115
+ // Eventos → prefijo onUiLib + PascalCase del nombre del evento
116
+ // ui-lib-click → onUiLibClick
117
+ // ui-lib-tab-change → onUiLibTabChange
118
+ <LibButton onUiLibClick={(e: CustomEvent) => console.log(e.detail)} />
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Tokens de diseño (CSS custom properties)
124
+
125
+ > Importar con `@shibui/ui/tokens` o `import '@shibui/ui/tokens'`
126
+
127
+ ### Colores primitivos
128
+ | Token | Valor | Uso |
129
+ |---|---|---|
130
+ | `--color-washi-50` | `#FAF7F4` | Fondo base claro |
131
+ | `--color-washi-900` | `#221C16` | Fondo inverse / texto |
132
+ | `--color-washi-950` | `#120E0A` | Fondo oscuro total |
133
+ | `--color-kaki-400` | `#D97234` | Acento cálido claro |
134
+ | `--color-kaki-500` | `#B85A1E` | Acento principal |
135
+ | `--color-celadon-400` | `#4E9482` | Acento jade / info |
136
+ | `--color-celadon-500` | `#357164` | Acento jade oscuro |
137
+
138
+ ### Tokens semánticos
139
+ | Token | Light | Dark |
140
+ |---|---|---|
141
+ | `--bg-base` | washi-50 | washi-950 |
142
+ | `--bg-surface` | washi-100 | washi-900 |
143
+ | `--bg-elevated` | #fff | washi-800 |
144
+ | `--text-primary` | washi-900 | washi-50 |
145
+ | `--text-secondary` | washi-600 | washi-400 |
146
+ | `--text-muted` | washi-400 | washi-600 |
147
+ | `--text-accent` | kaki-500 | kaki-300 |
148
+ | `--border-subtle` | washi-200 | washi-800 |
149
+ | `--border-default` | washi-300 | washi-700 |
150
+
151
+ ### Tipografía
152
+ | Token | Valor |
153
+ |---|---|
154
+ | `--lib-font-display` | `"Cormorant Garamond", serif` |
155
+ | `--lib-font-body` | `"Shippori Mincho", serif` |
156
+ | `--lib-font-mono` | `"DM Mono", monospace` |
157
+
158
+ ### Espaciado (base 4px)
159
+ | Token | Valor |
160
+ |---|---|
161
+ | `--lib-space-xs` | `0.25rem` (4px) |
162
+ | `--lib-space-sm` | `0.5rem` (8px) |
163
+ | `--lib-space-md` | `1rem` (16px) ★ estándar |
164
+ | `--lib-space-lg` | `1.5rem` (24px) |
165
+ | `--lib-space-xl` | `2rem` (32px) |
166
+
167
+ ### Escalas tipográficas
168
+ `--text-xs` (11px) · `--text-sm` (13px) · `--text-base` (15px) · `--text-md` (17px) · `--text-lg` (20px) · `--text-xl` (24px) · `--text-2xl` (32px) · `--text-3xl` (44px) · `--text-4xl` (60px) · `--text-5xl` (80px)
169
+
170
+ ---
171
+
172
+ ## Átomos
173
+
174
+ Elementos indivisibles, sin estado interno. Reciben datos vía props y emiten eventos custom.
175
+
176
+ ### `lib-accordion-item` · `LibAccordionItem`
177
+ Ítem individual colapsable.
178
+ ```tsx
179
+ <LibAccordionItem label="Pregunta aquí">
180
+ <p>Contenido del panel</p>
181
+ </LibAccordionItem>
182
+ ```
183
+ **Props:** `label: string`
184
+
185
+ ---
186
+
187
+ ### `lib-aspect-ratio` · `LibAspectRatio`
188
+ Contenedor que mantiene relación de aspecto fija.
189
+ ```tsx
190
+ <LibAspectRatio ratio="16/9">
191
+ <img src="..." />
192
+ </LibAspectRatio>
193
+ ```
194
+ **Props:** `ratio: string` (ej: `"16/9"`, `"1/1"`, `"4/3"`)
195
+
196
+ ---
197
+
198
+ ### `lib-avatar` · `LibAvatar`
199
+ Imagen de perfil con fallback a iniciales.
200
+ ```tsx
201
+ <LibAvatar name="Alejandro Borbalán" src="/profile.webp" size="md" shape="circle" />
202
+ ```
203
+ **Props:** `name?: string` · `src?: string` · `size?: 'sm'|'md'|'lg'|'xl'` · `shape?: 'circle'|'square'|'squircle'`
204
+
205
+ ---
206
+
207
+ ### `lib-background` · `LibBackground`
208
+ Contenedor con variantes de fondo visual.
209
+ ```tsx
210
+ <LibBackground variant="midnight">
211
+ {/* contenido */}
212
+ </LibBackground>
213
+ ```
214
+ **Props:** `variant: 'midnight'|'ash-grid'|'paper'|'dark'|...`
215
+
216
+ ---
217
+
218
+ ### `lib-badge` · `LibBadge`
219
+ Indicador visual pequeño para estado, notificaciones o etiquetas.
220
+ ```tsx
221
+ <LibBadge variant="accent" dot>12</LibBadge>
222
+ <LibBadge variant="success" pill>Activo</LibBadge>
223
+ ```
224
+ **Props:** `variant: 'default'|'accent'|'celadon'|'dark'|'error'|'success'|'warning'` · `dot?: boolean` · `pill?: boolean`
225
+
226
+ ---
227
+
228
+ ### `lib-bento-item` · `LibBentoItem`
229
+ Celda para composiciones bento grid.
230
+ **Props:** `span?: number` · `variant?: string`
231
+
232
+ ---
233
+
234
+ ### `lib-burger-button` · `LibBurger`
235
+ Botón hamburguesa con variantes de animación.
236
+ ```tsx
237
+ <LibBurger variant="kintsugi" />
238
+ ```
239
+ **Props:** `variant: 'ink'|'kanji'|'washi'|'framed'|'kintsugi'|'glitch'` · `open?: boolean`
240
+ **Eventos:** `onUiLibBurgerToggle`
241
+
242
+ ---
243
+
244
+ ### `lib-button` · `LibButton`
245
+ Elemento interactivo base.
246
+ ```tsx
247
+ <LibButton variant="primary" size="md" disabled={false}>
248
+ Texto del botón
249
+ </LibButton>
250
+ ```
251
+ **Props:** `variant: 'default'|'primary'|'secondary'|'ghost'|'accent'|'danger'` · `size: 'sm'|'md'|'lg'|'xl'` · `disabled?: boolean` · `loading?: boolean`
252
+ **Slots:** `prefix` · `suffix`
253
+ **Eventos:** `onUiLibClick`
254
+
255
+ ---
256
+
257
+ ### `lib-card` · `LibCard`
258
+ Contenedor para agrupar contenido relacionado.
259
+ ```tsx
260
+ <LibCard variant="kintsugi" kanji="渋">
261
+ <span slot="tag">01</span>
262
+ <h3 slot="title">Título</h3>
263
+ <p>Descripción del contenido</p>
264
+ <span slot="footer">Categoría</span>
265
+ </LibCard>
266
+ ```
267
+ **Props:** `variant: 'default'|'inverse'|'accent'|'featured'|'kintsugi'|'glitch'|'celadon'|'washi'` · `kanji?: string` · `clickable?: boolean`
268
+ **Slots:** `tag` · `title` · `footer` · `default`
269
+ **Eventos:** `onUiLibCardClick` (cuando `clickable`)
270
+
271
+ ---
272
+
273
+ ### `lib-card-grid` · `LibComponentGrid`
274
+ Grid de cards auto-responsivo.
275
+ ```tsx
276
+ <LibComponentGrid style={{ '--cg-cols': 'repeat(3, 1fr)' }}>
277
+ <LibCard>...</LibCard>
278
+ </LibComponentGrid>
279
+ ```
280
+ **CSS vars:** `--cg-cols` · `--cg-gap`
281
+
282
+ ---
283
+
284
+ ### `lib-checkbox` · `LibCheckbox`
285
+ Control de selección binaria.
286
+ ```tsx
287
+ <LibCheckbox
288
+ variant="kaki"
289
+ label="Acepto los términos"
290
+ sublabel="Texto secundario"
291
+ checked={value}
292
+ onChange={(e: CustomEvent) => setValue(e.detail.checked)}
293
+ />
294
+ ```
295
+ **Props:** `variant: 'default'|'kaki'|'error'` · `label?: string` · `sublabel?: string` · `checked?: boolean` · `disabled?: boolean` · `indeterminate?: boolean`
296
+ **Eventos:** `onUiLibCheckboxChange` → `detail: { checked: boolean }`
297
+
298
+ ---
299
+
300
+ ### `lib-close-button` · `LibCloseButton`
301
+ Botón de cierre semántico.
302
+ ```tsx
303
+ <LibCloseButton libClose={(e: CustomEvent) => handleClose()} />
304
+ ```
305
+ **Eventos:** `onLibClose`
306
+
307
+ ---
308
+
309
+ ### `lib-code-block` · `LibCodeBlock`
310
+ Bloque de código con clipboard y variante ghost.
311
+ ```tsx
312
+ <LibCodeBlock language="typescript" variant="default">
313
+ {`const x = 'shibui';`}
314
+ </LibCodeBlock>
315
+ ```
316
+ **Props:** `language?: string` · `variant?: 'default'|'ghost'`
317
+
318
+ ---
319
+
320
+ ### `lib-color-scale` · `LibColorScale`
321
+ Muestra interactiva de escala de color con hover-expand.
322
+ **Props:** `colors: Array<{token: string, value: string, step: string}>`
323
+
324
+ ---
325
+
326
+ ### `lib-content-pillar` · `LibContentPillar`
327
+ Bloque de contenido editorial con kanji decorativo.
328
+ **Slots:** `eyebrow` · `title` · `body`
329
+
330
+ ---
331
+
332
+ ### `lib-copy-button` · `LibCopyButton`
333
+ Botón para copiar al portapapeles.
334
+ ```tsx
335
+ <LibCopyButton value="texto a copiar" />
336
+ ```
337
+ **Props:** `value: string` · `label?: string`
338
+ **Eventos:** `onUiLibCopy`
339
+
340
+ ---
341
+
342
+ ### `lib-counter` · `LibCounter`
343
+ Contador animado con efecto digit-flip.
344
+ ```tsx
345
+ <LibCounter value={66} suffix="+" prefix="" tone="on-dark" play-on-visible />
346
+ ```
347
+ **Props:** `value: number` · `suffix?: string` · `prefix?: string` · `thousands?: string` · `size?: 'sm'|'md'|'lg'` · `tone?: 'default'|'on-dark'` · `play-on-visible?: boolean`
348
+
349
+ ---
350
+
351
+ ### `lib-display-heading` · `LibDisplayHeading`
352
+ Heading editorial con Cormorant Garamond.
353
+ **Props:** `level?: 1|2|3|4` · `size?: string` · `accent?: string`
354
+
355
+ ---
356
+
357
+ ### `lib-divider` · `LibDivider`
358
+ Separador visual entre secciones.
359
+ ```tsx
360
+ <LibDivider orientation="horizontal" style-variant="hairline">
361
+ texto opcional
362
+ </LibDivider>
363
+ ```
364
+ **Props:** `orientation?: 'horizontal'|'vertical'` · `style-variant?: 'default'|'hairline'|'strong'`
365
+
366
+ ---
367
+
368
+ ### `lib-eyebrow` · `LibEyebrow`
369
+ Etiqueta eyebrow con tracking wide para secciones.
370
+ ```tsx
371
+ <LibEyebrow color="kaki" size="sm">Design Tokens · v1.0</LibEyebrow>
372
+ ```
373
+ **Props:** `color?: 'default'|'kaki'|'dark'|'celadon'` · `size?: 'sm'|'md'`
374
+
375
+ ---
376
+
377
+ ### `lib-glass-card` · `LibGlassCard`
378
+ Card con efecto glassmorphism (Efecto Agua).
379
+ ```tsx
380
+ <LibGlassCard variant="water">Contenido</LibGlassCard>
381
+ ```
382
+ **Props:** `variant?: 'paper'|'water'|'kaki'` · `intensity?: 'low'|'md'|'high'`
383
+
384
+ ---
385
+
386
+ ### `lib-icon` · `LibIcon`
387
+ Símbolo visual — wrapper de Phosphor Icons.
388
+ ```tsx
389
+ <LibIcon name="heart" size="md" variant="primary" />
390
+ ```
391
+ **Props:** `name: string` · `size?: 'sm'|'md'|'lg'|'xl'|number` · `variant?: 'default'|'primary'|'success'|'danger'|'warning'`
392
+
393
+ Iconos disponibles (nombres clave): `arrow-down/up/left/right` · `home` · `copy` · `save` · `edit` · `download` · `upload` · `share` · `link` · `bell` · `mail` · `phone` · `lock` · `unlock` · `shield` · `key` · `github` · `linkedin` · `twitter` · `trash` · `book` · `flask` · `chart-line` · `chart-pie` · `business` · `location` · `compass` · `globe` · `time` · `timer` · `health` · `sun` · `moon` · `coffee` · `gift` · `trophy` · `award` · `idea` · `more` · `menu` · `x` · `x-circle` · `play` · `pause` · `camera` · `image` · `folder` · `file`
394
+
395
+ ---
396
+
397
+ ### `lib-kbd` · `LibKbd`
398
+ Representación de tecla de teclado.
399
+ ```tsx
400
+ <LibKbd>⌘K</LibKbd>
401
+ ```
402
+
403
+ ---
404
+
405
+ ### `lib-label` · `LibLabel`
406
+ Etiqueta de texto para inputs.
407
+ ```tsx
408
+ <LibLabel required>Email</LibLabel>
409
+ ```
410
+ **Props:** `required?: boolean` · `for?: string`
411
+
412
+ ---
413
+
414
+ ### `lib-liquid-button` · `LibLiquidButton`
415
+ Botón con efecto líquido interactivo.
416
+ **Props:** `variant?: string` · `label?: string`
417
+
418
+ ---
419
+
420
+ ### `lib-magnetic` · `LibMagnetic`
421
+ Efecto magnético de atracción al cursor sobre su contenido.
422
+ ```tsx
423
+ <LibMagnetic strength={0.3}>
424
+ <LibButton>Hover me</LibButton>
425
+ </LibMagnetic>
426
+ ```
427
+ **Props:** `strength?: number`
428
+
429
+ ---
430
+
431
+ ### `lib-progress` · `LibProgress`
432
+ Barra de progreso lineal.
433
+ ```tsx
434
+ <LibProgress value={75} max={100} variant="kaki" />
435
+ ```
436
+ **Props:** `value: number` · `max?: number` · `variant?: 'default'|'kaki'|'celadon'`
437
+
438
+ ---
439
+
440
+ ### `lib-progress-circle` · `LibProgressCircle`
441
+ Indicador de progreso circular.
442
+ **Props:** `value: number` · `max?: number` · `size?: 'sm'|'md'|'lg'`
443
+
444
+ ---
445
+
446
+ ### `lib-quote` · `LibQuote`
447
+ Blockquote editorial.
448
+ **Slots:** `default` · `cite`
449
+
450
+ ---
451
+
452
+ ### `lib-radio` · `LibRadio`
453
+ Control de selección única para grupos.
454
+ ```tsx
455
+ <LibRadio name="group" value="a" checked={selected === 'a'} label="Opción A"
456
+ onChange={(e: CustomEvent) => setSelected(e.detail.value)} />
457
+ ```
458
+ **Props:** `name: string` · `value: string` · `checked?: boolean` · `disabled?: boolean` · `label?: string`
459
+ **Eventos:** `onUiLibRadioChange` → `detail: { value: string }`
460
+
461
+ ---
462
+
463
+ ### `lib-rating` · `LibRating`
464
+ Control de valoración por estrellas.
465
+ **Props:** `value?: number` · `max?: number` · `readonly?: boolean`
466
+ **Eventos:** `onUiLibRatingChange`
467
+
468
+ ---
469
+
470
+ ### `lib-reading-progress` · `LibReadingProgress`
471
+ Indicador de progreso de lectura.
472
+ **Props:** `variant?: 'bar'|'ring'|'dots'|'vertical'` · `target?: string`
473
+
474
+ ---
475
+
476
+ ### `lib-ripple` · `LibRipple`
477
+ Efecto ripple sobre elementos interactivos.
478
+ ```tsx
479
+ <LibRipple color="oklch(45% 0.05 45 / 0.3)" />
480
+ ```
481
+ **Props:** `color?: string`
482
+
483
+ ---
484
+
485
+ ### `lib-select-option` · `LibSelectOption`
486
+ Opción individual dentro de un select.
487
+ ```tsx
488
+ <LibSelectOption value="es" selected>España</LibSelectOption>
489
+ <LibSelectOption value="fr" disabled>Francia</LibSelectOption>
490
+ ```
491
+ **Props:** `value: string` · `selected?: boolean` · `disabled?: boolean`
492
+
493
+ ---
494
+
495
+ ### `lib-skeleton` · `LibSkeleton`
496
+ Placeholder de carga.
497
+ ```tsx
498
+ <LibSkeleton variant="text" width="60%" />
499
+ <LibSkeleton variant="avatar" size="md" />
500
+ ```
501
+ **Props:** `variant?: 'text'|'title'|'avatar'|'image'|'button'` · `width?: string` · `height?: string` · `size?: string` · `dark?: boolean`
502
+
503
+ ---
504
+
505
+ ### `lib-spacer` · `LibSpacer`
506
+ Espaciador utilitario para layouts.
507
+ **Props:** `size?: 'xs'|'sm'|'md'|'lg'|'xl'` · `axis?: 'x'|'y'`
508
+
509
+ ---
510
+
511
+ ### `lib-spinner` · `LibSpinner`
512
+ Indicador de carga.
513
+ ```tsx
514
+ <LibSpinner size="md" variant="kaki" />
515
+ ```
516
+ **Props:** `size?: 'sm'|'md'|'lg'` · `variant?: 'default'|'kaki'|'celadon'`
517
+
518
+ ---
519
+
520
+ ### `lib-spotlight-card` · `LibSpotlightCard`
521
+ Card con efecto spotlight reactivo al cursor (Kintsugi Digital).
522
+ **Props:** `variant?: 'kaki'|'water'|'white'`
523
+
524
+ ---
525
+
526
+ ### `lib-status-dot` · `LibStatusDot`
527
+ Pequeño indicador de color para estados.
528
+ ```tsx
529
+ <LibStatusDot status="success" />
530
+ ```
531
+ **Props:** `status: 'success'|'error'|'warning'|'info'|'default'` · `pulse?: boolean`
532
+
533
+ ---
534
+
535
+ ### `lib-step` · `LibStep`
536
+ Paso individual dentro de un stepper.
537
+ **Props:** `label: string` · `state?: 'pending'|'active'|'complete'|'error'`
538
+
539
+ ---
540
+
541
+ ### `lib-switch` · `LibSwitch`
542
+ Toggle control on/off.
543
+ ```tsx
544
+ <LibSwitch checked={value} label="Activar notificaciones"
545
+ onChange={(e: CustomEvent) => setValue(e.detail.checked)} />
546
+ ```
547
+ **Props:** `checked?: boolean` · `disabled?: boolean` · `label?: string`
548
+ **Eventos:** `onUiLibSwitchChange` → `detail: { checked: boolean }`
549
+
550
+ ---
551
+
552
+ ### `lib-text-glitch` · `LibTextGlitch`
553
+ Efecto de glitch tipográfico animado.
554
+ ```tsx
555
+ <LibTextGlitch text="shibui" />
556
+ ```
557
+ **Props:** `text: string` · `intensity?: 'low'|'md'|'high'`
558
+
559
+ ---
560
+
561
+ ### `lib-text-list` · `LibTextList`
562
+ Lista estilizada de elementos de texto.
563
+ **Props:** `items: string[]` · `variant?: string`
564
+
565
+ ---
566
+
567
+ ### `lib-tooltip` · `LibTooltip`
568
+ Información contextual al hover.
569
+ ```tsx
570
+ <LibTooltip content="Texto del tooltip" placement="top">
571
+ <LibButton>Hover</LibButton>
572
+ </LibTooltip>
573
+ ```
574
+ **Props:** `content: string` · `placement?: 'top'|'bottom'|'left'|'right'`
575
+
576
+ ---
577
+
578
+ ### `lib-visually-hidden` · `LibVisuallyHidden`
579
+ Elemento accesible oculto visualmente.
580
+ ```tsx
581
+ <LibVisuallyHidden>Texto para lectores de pantalla</LibVisuallyHidden>
582
+ ```
583
+
584
+ ---
585
+
586
+ ## Moléculas
587
+
588
+ Grupos funcionales de átomos con estado interno simple.
589
+
590
+ ### `lib-alert` · `LibAlert`
591
+ Alerta para mensajes informativos, de aviso, error o éxito.
592
+ ```tsx
593
+ <LibAlert variant="success" title="Guardado" dismissible>
594
+ Los cambios se han guardado correctamente.
595
+ </LibAlert>
596
+ ```
597
+ **Props:** `variant: 'default'|'info'|'success'|'warning'|'error'` · `title?: string` · `dismissible?: boolean`
598
+ **Eventos:** `onUiLibAlertDismiss`
599
+
600
+ ---
601
+
602
+ ### `lib-breadcrumb` · `LibBreadcrumb`
603
+ Navegación de migas de pan.
604
+ ```tsx
605
+ <LibBreadcrumb items={[
606
+ { label: 'Inicio', href: '/' },
607
+ { label: 'Componentes', href: '/componentes' },
608
+ { label: 'Button' }
609
+ ]} />
610
+ ```
611
+ **Props:** `items: Array<{ label: string, href?: string }>` · `separator?: string`
612
+
613
+ ---
614
+
615
+ ### `lib-button-group` · `LibButtonGroup`
616
+ Colección de botones relacionados agrupados.
617
+ ```tsx
618
+ <LibButtonGroup dark>
619
+ <LibButton variant="primary">CTA</LibButton>
620
+ <LibButton variant="ghost">Secundario</LibButton>
621
+ </LibButtonGroup>
622
+ ```
623
+ **Props:** `dark?: boolean` · `orientation?: 'horizontal'|'vertical'`
624
+
625
+ ---
626
+
627
+ ### `lib-checkbox-card` · `LibCheckboxCard`
628
+ Checkbox con tarjeta image picker.
629
+ **Props:** `checked?: boolean` · `label?: string` · `value?: string`
630
+ **Eventos:** `onUiLibCheckboxCardChange`
631
+
632
+ ---
633
+
634
+ ### `lib-chip` · `LibChip`
635
+ Etiqueta interactiva compacta para filtros.
636
+ ```tsx
637
+ <LibChip removable onUiLibChipRemove={(e) => handleRemove(e.detail.value)}>
638
+ React
639
+ </LibChip>
640
+ ```
641
+ **Props:** `removable?: boolean` · `selected?: boolean` · `disabled?: boolean`
642
+ **Eventos:** `onUiLibChipRemove` · `onUiLibChipClick`
643
+
644
+ ---
645
+
646
+ ### `lib-color-picker` · `LibColorPicker`
647
+ Selector de color.
648
+ **Props:** `value?: string` · `format?: 'hex'|'oklch'|'rgb'`
649
+ **Eventos:** `onUiLibColorChange`
650
+
651
+ ---
652
+
653
+ ### `lib-dropdown` · `LibDropdown`
654
+ Menú desplegable con opciones.
655
+ ```tsx
656
+ <LibDropdown trigger="click" placement="bottom-start">
657
+ <LibButton slot="trigger">Opciones</LibButton>
658
+ <LibSelectOption value="1">Editar</LibSelectOption>
659
+ <LibSelectOption value="2">Eliminar</LibSelectOption>
660
+ </LibDropdown>
661
+ ```
662
+ **Props:** `trigger?: 'click'|'hover'` · `placement?: string`
663
+ **Eventos:** `onUiLibDropdownSelect`
664
+
665
+ ---
666
+
667
+ ### `lib-empty-state` · `LibEmptyState`
668
+ Estado vacío con mensaje e ilustración.
669
+ ```tsx
670
+ <LibEmptyState
671
+ title="Sin resultados"
672
+ description="Prueba con otros términos de búsqueda."
673
+ icon="search"
674
+ />
675
+ ```
676
+ **Props:** `title: string` · `description?: string` · `icon?: string`
677
+ **Slots:** `action`
678
+
679
+ ---
680
+
681
+ ### `lib-file-uploader` · `LibFileUploader`
682
+ Control para subir ficheros.
683
+ **Props:** `accept?: string` · `multiple?: boolean` · `max-size?: number`
684
+ **Eventos:** `onUiLibFilesChange`
685
+
686
+ ---
687
+
688
+ ### `lib-header` · `LibHeader`
689
+ Header de navegación con múltiples variantes.
690
+ ```tsx
691
+ <LibHeader
692
+ variant="kintsugi"
693
+ logo-mark="渋"
694
+ brand-name="shibui"
695
+ links={NAV_LINKS}
696
+ actions={ACTIONS}
697
+ onUiLibHeaderLink={(e: CustomEvent) => navigate(e.detail.id)}
698
+ />
699
+ ```
700
+ **Props:** `variant: 'classic'|'dark'|'centered'|'transparent'|'kintsugi'|'glitch'|'mega'|'minimal'|'shrink'|'app-bar'` · `logo-mark?: string` · `brand-name?: string` · `brand-tagline?: string` · `logo-href?: string` · `version?: string` · `links?: NavLink[]` · `actions?: HeaderAction[]` · `show-search?: boolean` · `search-placeholder?: string`
701
+ **Eventos:** `onUiLibHeaderLink` → `detail: { id: string }` · `onUiLibHeaderAction`
702
+
703
+ ---
704
+
705
+ ### `lib-input` · `LibInput`
706
+ Campo de texto con slots prefix/suffix y validación.
707
+ ```tsx
708
+ <LibInput
709
+ label="Buscar"
710
+ placeholder="Escribe..."
711
+ required
712
+ error-message="Campo requerido"
713
+ >
714
+ <lib-icon slot="prefix" name="compass" size="sm" />
715
+ </LibInput>
716
+ ```
717
+ **Props:** `label?: string` · `placeholder?: string` · `type?: string` · `required?: boolean` · `disabled?: boolean` · `error?: boolean` · `error-message?: string` · `value?: string`
718
+ **Slots:** `prefix` · `suffix`
719
+ **Eventos:** `onUiLibInputChange` · `onUiLibInputInput`
720
+
721
+ ---
722
+
723
+ ### `lib-modal` · `LibModal`
724
+ Ventana overlay sobre la interfaz principal.
725
+ ```tsx
726
+ <LibModal
727
+ open
728
+ heading="Título del modal"
729
+ variant="default"
730
+ _animate="scale"
731
+ onUiLibModalClose={() => setOpen(false)}
732
+ >
733
+ <p>Contenido del modal</p>
734
+ <div slot="footer">
735
+ <LibButton variant="ghost" onUiLibClick={onClose}>Cancelar</LibButton>
736
+ <LibButton variant="primary" onUiLibClick={onConfirm}>Confirmar</LibButton>
737
+ </div>
738
+ </LibModal>
739
+ ```
740
+ **Props:** `open?: boolean` · `heading?: string` · `variant?: 'default'|'compact'` · `_animate?: 'scale'|'slide'|'fade'`
741
+ **Slots:** `default` · `footer`
742
+ **Eventos:** `onUiLibModalClose`
743
+
744
+ ---
745
+
746
+ ### `lib-multiselect` *(disponible como lib-select con multiple)*
747
+
748
+ ---
749
+
750
+ ### `lib-pagination` · `LibPagination`
751
+ Control de paginación.
752
+ ```tsx
753
+ <LibPagination
754
+ current={page}
755
+ total={10}
756
+ onUiLibPageChange={(e: CustomEvent) => setPage(e.detail.page)}
757
+ />
758
+ ```
759
+ **Props:** `current: number` · `total: number` · `siblings?: number`
760
+ **Eventos:** `onUiLibPageChange` → `detail: { page: number }`
761
+
762
+ ---
763
+
764
+ ### `lib-range-slider` · `LibRangeSlider`
765
+ Control deslizante para rango numérico.
766
+ **Props:** `min?: number` · `max?: number` · `value?: number` · `step?: number`
767
+ **Eventos:** `onUiLibRangeChange`
768
+
769
+ ---
770
+
771
+ ### `lib-segmented-control` · `LibSegmentedControl`
772
+ Selector de opciones mutuamente excluyentes.
773
+ ```tsx
774
+ <LibSegmentedControl
775
+ options={['Día', 'Semana', 'Mes']}
776
+ value={selected}
777
+ onUiLibSegmentChange={(e: CustomEvent) => setSelected(e.detail.value)}
778
+ />
779
+ ```
780
+ **Props:** `options: string[]` · `value?: string`
781
+ **Eventos:** `onUiLibSegmentChange`
782
+
783
+ ---
784
+
785
+ ### `lib-select` · `LibSelect`
786
+ Dropdown para selección única.
787
+ ```tsx
788
+ <LibSelect label="País" placeholder="Elige uno...">
789
+ <lib-select-option value="es">España</lib-select-option>
790
+ <lib-select-option value="fr">Francia</lib-select-option>
791
+ </LibSelect>
792
+ ```
793
+ **Props:** `label?: string` · `placeholder?: string` · `disabled?: boolean`
794
+ **Slots:** `lib-select-option`
795
+ **Eventos:** `onUiLibSelectChange` → `detail: { value: string }`
796
+
797
+ ---
798
+
799
+ ### `lib-tabs` · `LibTabs`
800
+ Navegación por pestañas.
801
+ ```tsx
802
+ <LibTabs
803
+ items={[
804
+ { id: 'tab1', label: 'General' },
805
+ { id: 'tab2', label: 'Avanzado' },
806
+ ]}
807
+ active="tab1"
808
+ variant="underline"
809
+ onUiLibTabChange={(e: CustomEvent) => setActive(e.detail.id)}
810
+ />
811
+ ```
812
+ **Props:** `items: TabItem[]` · `active?: string` · `variant?: 'underline'|'pill'|'card'|'outline'|'vertical'`
813
+ **Eventos:** `onUiLibTabChange` → `detail: { id: string, prev: string }`
814
+
815
+ ---
816
+
817
+ ### `lib-tree-select` · `LibTreeSelect`
818
+ Selector con estructura de árbol jerárquico.
819
+ **Props:** `items: TreeNode[]` · `value?: string`
820
+ **Eventos:** `onUiLibTreeSelect`
821
+
822
+ ---
823
+
824
+ ## Organismos
825
+
826
+ Secciones complejas y autónomas con lógica interna.
827
+
828
+ ### `lib-accordion` · `LibAccordion`
829
+ Contenido expandible por secciones.
830
+ ```tsx
831
+ <LibAccordion variant="default">
832
+ <lib-accordion-item label="Sección 1">Contenido 1</lib-accordion-item>
833
+ <lib-accordion-item label="Sección 2">Contenido 2</lib-accordion-item>
834
+ </LibAccordion>
835
+ ```
836
+ **Props:** `variant?: 'default'|'flush'|'separated'` · `allow-multiple?: boolean`
837
+
838
+ ---
839
+
840
+ ### `lib-bento-grid` · `LibBentoGrid`
841
+ Layout bento grid para composiciones complejas.
842
+ ```tsx
843
+ <LibBentoGrid columns={3}>
844
+ <lib-bento-item span={2}>...</lib-bento-item>
845
+ <lib-bento-item>...</lib-bento-item>
846
+ </LibBentoGrid>
847
+ ```
848
+ **Props:** `columns?: number` · `gap?: string`
849
+
850
+ ---
851
+
852
+ ### `lib-carousel` · `LibCarousel`
853
+ Visualización de contenido en formato carrusel.
854
+ **Props:** `autoplay?: boolean` · `interval?: number` · `loop?: boolean`
855
+ **Eventos:** `onUiLibCarouselChange`
856
+
857
+ ---
858
+
859
+ ### `lib-cursor-follower` · `LibCursorFollower`
860
+ Cursor personalizado que sigue al puntero.
861
+ **Props:** `variant?: string` · `color?: string`
862
+
863
+ ---
864
+
865
+ ### `lib-data-table` · `LibDataTable`
866
+ Tabla de datos con funcionalidades avanzadas.
867
+ ```tsx
868
+ <LibDataTable
869
+ columns={[
870
+ { key: 'name', label: 'Nombre', sortable: true },
871
+ { key: 'status', label: 'Estado' },
872
+ ]}
873
+ rows={DATA}
874
+ />
875
+ ```
876
+ **Props:** `columns: TableColumn[]` · `rows: Record<string, unknown>[]` · `loading?: boolean` · `sortable?: boolean`
877
+ **Eventos:** `onUiLibTableSort` · `onUiLibTableRowClick`
878
+
879
+ ---
880
+
881
+ ### `lib-dialog` · `LibDialog`
882
+ Ventana modal que requiere interacción explícita.
883
+ **Props:** `open?: boolean` · `heading?: string`
884
+ **Eventos:** `onUiLibDialogClose`
885
+
886
+ ---
887
+
888
+ ### `lib-drawer` · `LibDrawer`
889
+ Panel lateral deslizante.
890
+ ```tsx
891
+ <LibDrawer open={isOpen} placement="right" onUiLibDrawerClose={() => setOpen(false)}>
892
+ <p>Contenido del drawer</p>
893
+ </LibDrawer>
894
+ ```
895
+ **Props:** `open?: boolean` · `placement?: 'left'|'right'|'top'|'bottom'` · `size?: 'sm'|'md'|'lg'|'full'`
896
+ **Eventos:** `onUiLibDrawerClose`
897
+
898
+ ---
899
+
900
+ ### `lib-footer` · `LibFooter`
901
+ Footer con variantes editoriales.
902
+ ```tsx
903
+ <LibFooter
904
+ variant="dark"
905
+ brand-name="shibui"
906
+ brand-kanji="渋い"
907
+ columns={FOOTER_COLUMNS}
908
+ navLinks={NAV_LINKS}
909
+ />
910
+ ```
911
+ **Props:** `variant: 'social'|'accordion'|'kintsugi'|'glitch'|'dark'` · `brand-name?: string` · `brand-kanji?: string` · `brand-sub?: string` · `location?: string` · `version?: string` · `github-href?: string` · `linkedin-href?: string` · `email?: string` · `columns?: FooterColumn[]` · `navLinks?: FooterLink[]` · `legalLinks?: FooterLink[]`
912
+
913
+ ---
914
+
915
+ ### `lib-horizontal-scroll-section` · `LibHorizontalScrollSection`
916
+ Sección con scroll horizontal controlado.
917
+ **Props:** `speed?: number`
918
+
919
+ ---
920
+
921
+ ### `lib-parallax` · `LibParallaxContainer`
922
+ Contenedor con efecto parallax.
923
+ **Props:** `speed?: number` · `direction?: 'vertical'|'horizontal'`
924
+
925
+ ---
926
+
927
+ ### `lib-parallax-text-stack` · `LibParallaxTextStack`
928
+ Stack de texto con efecto parallax escalonado.
929
+ **Props:** `lines: string[]` · `speed?: number`
930
+
931
+ ---
932
+
933
+ ### `lib-sidebar` · `LibSidebar`
934
+ Panel de navegación lateral colapsable.
935
+ ```tsx
936
+ <LibSidebar
937
+ variant="kintsugi"
938
+ brand-name="shibui"
939
+ logo-mark="渋"
940
+ user-name="Alejandro"
941
+ user-role="Senior FE"
942
+ links={SIDEBAR_LINKS}
943
+ active-id="dashboard"
944
+ colapsed="true"
945
+ show-search="true"
946
+ onUiLibSidebarLink={(e: CustomEvent<{ id: string }>) => navigate(e.detail.id)}
947
+ />
948
+ ```
949
+ **Props:** `variant: 'dark'|'light'|'kintsugi'|'glitch'` · `brand-name?: string` · `logo-mark?: string` · `user-name?: string` · `user-role?: string` · `role?: string` · `links: SidebarLink[]` · `active-id?: string` · `colapsed?: string` · `show-search?: string`
950
+ **Eventos:** `onUiLibSidebarLink` → `detail: { id: string }`
951
+
952
+ ---
953
+
954
+ ### `lib-stagger-container` · `LibStaggerContainer`
955
+ Contenedor de animaciones stagger escalonadas.
956
+ **Props:** `delay?: number` · `stagger?: number`
957
+
958
+ ---
959
+
960
+ ### `lib-stepper` · `LibStepper`
961
+ Flujo de pasos secuenciales.
962
+ ```tsx
963
+ <LibStepper
964
+ steps={[
965
+ { label: 'Datos básicos', state: 'complete' },
966
+ { label: 'Configuración', state: 'active' },
967
+ { label: 'Confirmación', state: 'pending' },
968
+ ]}
969
+ current={1}
970
+ />
971
+ ```
972
+ **Props:** `steps: StepItem[]` · `current?: number` · `orientation?: 'horizontal'|'vertical'`
973
+ **Eventos:** `onUiLibStepperChange`
974
+
975
+ ---
976
+
977
+ ### `lib-timeline` · `LibTimeline`
978
+ Visualización cronológica de eventos.
979
+ ```tsx
980
+ <LibTimeline>
981
+ <lib-timeline-item date="2024" title="Inicio del proyecto">
982
+ Descripción del evento.
983
+ </lib-timeline-item>
984
+ </LibTimeline>
985
+ ```
986
+ **Props:** `orientation?: 'vertical'|'horizontal'`
987
+
988
+ ---
989
+
990
+ ### `lib-toast-manager` · `LibToastManager`
991
+ Gestor de notificaciones toast.
992
+ ```tsx
993
+ // Instanciar una vez en el root
994
+ <LibToastManager position="bottom-right" />
995
+
996
+ // Emitir desde cualquier punto
997
+ document.dispatchEvent(new CustomEvent('lib-toast', {
998
+ detail: { message: 'Guardado', variant: 'success' },
999
+ bubbles: true
1000
+ }));
1001
+ ```
1002
+ **Props:** `position?: 'top-right'|'top-left'|'bottom-right'|'bottom-left'|'top-center'|'bottom-center'` · `duration?: number`
1003
+
1004
+ ---
1005
+
1006
+ ## Interfaces y tipos exportados
1007
+
1008
+ ```ts
1009
+ import type {
1010
+ SidebarLink, // { id, label, icon, group?, badge?, disabled? }
1011
+ SidebarVariant, // 'dark' | 'light' | 'kintsugi' | 'glitch'
1012
+ SidebarSocial, // { href, icon, label }
1013
+ FooterVariant, // 'social' | 'accordion' | 'kintsugi' | 'glitch'
1014
+ FooterLink, // { label, href }
1015
+ FooterColumn, // { heading, links: FooterLink[] }
1016
+ FooterSocial, // { label, href, icon }
1017
+ LibSize, // 'sm' | 'md' | 'lg' | 'xl'
1018
+ LibVariant, // 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'accent'
1019
+ LibSemanticColor, // 'primary' | 'danger' | 'text' | 'inherit'
1020
+ UiClickEventDetail, // { originalEvent: Event, timestamp: number }
1021
+ } from '@shibui/ui';
1022
+ ```
1023
+
1024
+ ---
1025
+
1026
+ ## Patrones frecuentes
1027
+
1028
+ ### Array props en React wrapper
1029
+ ```tsx
1030
+ // CORRECTO — property binding automático en el wrapper
1031
+ <LibSidebar links={LINKS} />
1032
+
1033
+ // En Lit nativo (sin wrapper) usar punto explícito
1034
+ // <lib-sidebar .links=${LINKS}></lib-sidebar>
1035
+ ```
1036
+
1037
+ ### Eventos custom
1038
+ ```tsx
1039
+ // Todos los eventos siguen el patrón:
1040
+ // nombre-del-evento → onNombreDelEvento (camelCase con prefijo on)
1041
+ // ui-lib-click → onUiLibClick
1042
+ // ui-lib-tab-change → onUiLibTabChange
1043
+
1044
+ <LibTabs onUiLibTabChange={(e: CustomEvent<{ id: string }>) => {
1045
+ console.log(e.detail.id);
1046
+ }} />
1047
+ ```
1048
+
1049
+ ### Dark mode
1050
+ ```tsx
1051
+ // Añadir data-theme="dark" al elemento raíz
1052
+ document.documentElement.dataset.theme = 'dark';
1053
+
1054
+ // Los tokens semánticos se actualizan automáticamente:
1055
+ // --bg-base, --text-primary, --border-subtle, etc.
1056
+ ```
1057
+
1058
+ ### Tokens CSS en componentes React
1059
+ ```tsx
1060
+ // Los tokens NO están en :root por defecto en algunos entornos.
1061
+ // Importar explícitamente:
1062
+ import '@shibui/ui/tokens';
1063
+
1064
+ // O referenciar con fallback:
1065
+ style={{ color: 'var(--text-accent, #B85A1E)' }}
1066
+ ```
1067
+
1068
+ ---
1069
+
1070
+ ## Notas para agentes Claude
1071
+
1072
+ 1. **Siempre usar PascalCase** en ficheros `.tsx` (`LibButton`, no `lib-button`).
1073
+ 2. **Siempre importar desde `@shibui/ui/react`** en React — nunca el tag HTML directo.
1074
+ 3. **Eventos** siempre con tipo `CustomEvent` explícito — nunca `any`.
1075
+ 4. **Array props** se pasan directamente sin `.prop=` — el wrapper lo gestiona.
1076
+ 5. **Los tokens `--lib-*`** deben estar disponibles. Si no hay estilos, verificar que se importa `@shibui/ui/tokens`.
1077
+ 6. **`lib-text-glitch`** tiene un typo en el barrel (`text-glich`). Si hay error de importación, importar directamente desde la ruta del componente.
1078
+ 7. **No existe `lib-multiselect` como componente independiente** — usar `lib-select` con la prop `multiple`.
1079
+ 8. **`lib-modal`** necesita `open` booleano explícito para mostrarse. No tiene estado interno de visibilidad.
1080
+ 9. **`lib-toast-manager`** debe instanciarse una vez en el árbol. Los toasts se disparan vía `CustomEvent` global.
1081
+ 10. **El evento de cierre** de modal, drawer y dialog es siempre `onUiLib[Componente]Close`.
1082
+
80
1083
  ## 📄 Licencia
81
1084
 
82
- MIT
1085
+ MIT