@adamosuiteservices/ui 1.2.5 → 1.3.5
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/dist/accordion-rounded.cjs +1 -1
- package/dist/accordion-rounded.js +1 -1
- package/dist/accordion.cjs +1 -1
- package/dist/accordion.js +1 -1
- package/dist/avatar.cjs +1 -1
- package/dist/avatar.js +1 -1
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/breadcrumb.cjs +1 -0
- package/dist/breadcrumb.js +105 -0
- package/dist/{button-C1n6snOY.js → button-2GdKenQI.js} +1 -1
- package/dist/{button-BV-_FVKZ.cjs → button-DEQVHMrX.cjs} +1 -1
- package/dist/button-group.cjs +1 -1
- package/dist/button-group.js +2 -2
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/calendar.cjs +1 -1
- package/dist/calendar.js +1 -1
- package/dist/{checkbox-BrmXPKTn.js → checkbox-Dr487kAg.js} +3 -3
- package/dist/{checkbox-Lq-HvSgc.cjs → checkbox-YWAnswaW.cjs} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/collapsible.cjs +1 -1
- package/dist/collapsible.js +1 -1
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.js +6 -6
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +11 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.d.ts +26 -0
- package/dist/components/ui/breadcrumb/index.d.ts +1 -0
- package/dist/components/ui/dialog/dialog.d.ts +2 -1
- package/dist/context-menu.cjs +1 -1
- package/dist/context-menu.js +2 -2
- package/dist/custom-layered-styles.css +1 -1
- package/dist/dialog.cjs +1 -1
- package/dist/dialog.js +33 -19
- package/dist/dropdown-menu.cjs +1 -1
- package/dist/dropdown-menu.js +3 -3
- package/dist/ellipsis-CryjZKZn.js +15 -0
- package/dist/ellipsis-Ct9VTDOG.cjs +6 -0
- package/dist/field.cjs +1 -1
- package/dist/field.js +2 -2
- package/dist/hover-card.cjs +1 -1
- package/dist/hover-card.js +6 -6
- package/dist/{index-CAOY367Y.js → index-B0M7VOwp.js} +2 -2
- package/dist/{index-B-ZRqW0J.js → index-BBoIAjAs.js} +3 -3
- package/dist/{index-gO_QEiaK.cjs → index-BDs8lUfq.cjs} +1 -1
- package/dist/index-BFyr34mw.cjs +5 -0
- package/dist/index-BMWt1NBG.js +79 -0
- package/dist/{index-yR-v1A4G.js → index-BX9hz-JD.js} +1 -1
- package/dist/{index-BGiGvaq8.cjs → index-BcGMAmWE.cjs} +1 -1
- package/dist/{index-IKJMQref.cjs → index-Bd0gQB0k.cjs} +1 -1
- package/dist/{index-VIUqZjyP.cjs → index-BeWgla7c.cjs} +1 -1
- package/dist/{index-EUea2gfp.js → index-BpWB3aFK.js} +1 -1
- package/dist/index-BvLQnI56.js +59 -0
- package/dist/{index-CwUFT-GQ.js → index-C0YiLSjW.js} +4 -4
- package/dist/{index-o0sNTcKe.js → index-CBjZooac.js} +2 -2
- package/dist/{index-DnS_sBBe.cjs → index-COuvjZLM.cjs} +1 -1
- package/dist/index-CTjlbbt9.cjs +1 -0
- package/dist/index-CUWMxxKG.js +97 -0
- package/dist/{index-C329e3yQ.js → index-CZZ3llmi.js} +2 -2
- package/dist/index-CjyiloO7.cjs +1 -0
- package/dist/{index-D3wSWKST.cjs → index-Cmx9M9cZ.cjs} +1 -1
- package/dist/index-CocSS1YK.cjs +1 -0
- package/dist/index-CzRiuk60.cjs +1 -0
- package/dist/index-DFPDUUq7.js +658 -0
- package/dist/{index-D3S7dBDI.cjs → index-DIwmXz1u.cjs} +1 -1
- package/dist/index-DLcqcWxM.js +29 -0
- package/dist/index-DMLQL2aG.js +286 -0
- package/dist/{index-DXQ-7kNJ.cjs → index-DMs8RL3E.cjs} +1 -1
- package/dist/{index-Ce3QBKyj.cjs → index-Dbj9vHNq.cjs} +1 -1
- package/dist/{index-BRLtxFFr.cjs → index-DmGzwG2z.cjs} +1 -1
- package/dist/{index-P1sVIHE3.js → index-PYkEXTqJ.js} +1 -1
- package/dist/{index-DulPG3F9.js → index-Se4vRnIO.js} +3 -3
- package/dist/index-_XxjJPRD.cjs +1 -0
- package/dist/{index-B-cHTKrs.js → index-yWvyIlmA.js} +4 -4
- package/dist/input-group.cjs +1 -1
- package/dist/input-group.js +1 -1
- package/dist/{label-Cne2J57f.cjs → label-BjXORCBM.cjs} +1 -1
- package/dist/{label-Ky8qBEC3.js → label-CmwGvhy1.js} +1 -1
- package/dist/label.cjs +1 -1
- package/dist/label.js +1 -1
- package/dist/pagination.cjs +1 -6
- package/dist/pagination.js +58 -69
- package/dist/popover-3rIoNCXs.js +306 -0
- package/dist/popover-FCKBtFo-.cjs +1 -0
- package/dist/popover.cjs +1 -1
- package/dist/popover.js +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +5 -5
- package/dist/select.cjs +2 -2
- package/dist/select.js +585 -542
- package/dist/{separator-CGnu_jIu.cjs → separator-BaZqZZ9R.cjs} +1 -1
- package/dist/{separator-BH73A90k.js → separator-DR7lQjv9.js} +1 -1
- package/dist/separator.cjs +1 -1
- package/dist/separator.js +1 -1
- package/dist/{sheet-CcxnJ6LH.cjs → sheet-CU-sFSaJ.cjs} +1 -1
- package/dist/{sheet-_DVpQIVF.js → sheet-UZWAbdXr.js} +1 -1
- package/dist/sheet.cjs +1 -1
- package/dist/sheet.js +1 -1
- package/dist/sidebar.cjs +1 -1
- package/dist/sidebar.js +4 -4
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +3 -3
- package/dist/styles.css +1 -1
- package/dist/switch.cjs +1 -1
- package/dist/switch.js +2 -2
- package/dist/tabs-underline.cjs +1 -1
- package/dist/tabs-underline.js +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.js +1 -1
- package/dist/toaster.cjs +1 -1
- package/dist/toaster.js +1 -1
- package/dist/toggle.cjs +1 -1
- package/dist/toggle.js +1 -1
- package/dist/tooltip.cjs +1 -1
- package/dist/tooltip.js +114 -108
- package/dist/typography.cjs +1 -1
- package/dist/typography.js +1 -1
- package/docs/AI-GUIDE.md +321 -0
- package/docs/components/layout/sidebar.md +330 -0
- package/docs/components/layout/toaster.md +436 -0
- package/docs/components/ui/accordion-rounded.md +583 -0
- package/docs/components/ui/accordion.md +267 -0
- package/docs/components/ui/alert.md +671 -0
- package/docs/components/ui/avatar.md +588 -0
- package/docs/components/ui/badge.md +1024 -0
- package/docs/components/ui/breadcrumb.md +614 -0
- package/docs/components/ui/button-group.md +1002 -0
- package/docs/components/ui/button.md +1078 -0
- package/docs/components/ui/calendar.md +1159 -0
- package/docs/components/ui/card.md +1265 -0
- package/docs/components/ui/checkbox.md +292 -0
- package/docs/components/ui/collapsible.md +320 -0
- package/docs/components/ui/combobox.md +328 -0
- package/docs/components/ui/command.md +454 -0
- package/docs/components/ui/context-menu.md +540 -0
- package/docs/components/ui/dialog.md +628 -0
- package/docs/components/ui/dropdown-menu.md +731 -0
- package/docs/components/ui/field.md +706 -0
- package/docs/components/ui/hover-card.md +446 -0
- package/docs/components/ui/input-group.md +509 -0
- package/docs/components/ui/input.md +362 -0
- package/docs/components/ui/kbd.md +434 -0
- package/docs/components/ui/label.md +359 -0
- package/docs/components/ui/pagination.md +650 -0
- package/docs/components/ui/popover.md +536 -0
- package/docs/components/ui/progress.md +182 -0
- package/docs/components/ui/radio-group.md +311 -0
- package/docs/components/ui/select.md +352 -0
- package/docs/components/ui/separator.md +214 -0
- package/docs/components/ui/sheet.md +142 -0
- package/docs/components/ui/skeleton.md +140 -0
- package/docs/components/ui/slider.md +341 -0
- package/docs/components/ui/spinner.md +170 -0
- package/docs/components/ui/switch.md +402 -0
- package/docs/components/ui/table.md +183 -0
- package/docs/components/ui/tabs-underline.md +106 -0
- package/docs/components/ui/tabs.md +122 -0
- package/docs/components/ui/textarea.md +243 -0
- package/docs/components/ui/toggle.md +243 -0
- package/docs/components/ui/tooltip.md +320 -0
- package/docs/components/ui/typography.md +191 -0
- package/package.json +11 -5
- package/dist/index-6oTEokEx.js +0 -82
- package/dist/index-B-NyefE0.js +0 -243
- package/dist/index-BKbK2GzY.cjs +0 -1
- package/dist/index-BMitW9UR.cjs +0 -1
- package/dist/index-BpvjJ_T6.cjs +0 -5
- package/dist/index-C5wjudc-.js +0 -36
- package/dist/index-CezwiPd_.js +0 -615
- package/dist/index-D02K8KOB.js +0 -54
- package/dist/index-D7hQvndv.cjs +0 -1
- package/dist/index-DQvx1rG_.cjs +0 -1
- package/dist/popover-BjdTqaB8.cjs +0 -1
- package/dist/popover-EnVfE0YA.js +0 -263
|
@@ -0,0 +1,1024 @@
|
|
|
1
|
+
# Badge Component
|
|
2
|
+
|
|
3
|
+
## Descripción
|
|
4
|
+
|
|
5
|
+
Componente compacto para **etiquetar, categorizar y resaltar información**. Ofrece 13 variantes semánticas (incluyendo versiones "medium" suaves), 2 tamaños, iconos auto-dimensionados, soporte para links clickeables, y estilos especiales para números. Ideal para estados, notificaciones, etiquetas de producto, roles de usuario y contadores.
|
|
6
|
+
|
|
7
|
+
## Características
|
|
8
|
+
|
|
9
|
+
- ✅ 13 variantes: default (2), waiting (2), secondary, success (2), warning (2), destructive (2), muted, outline
|
|
10
|
+
- ✅ Versiones "medium" con fondos suaves y colores vibrantes
|
|
11
|
+
- ✅ 2 tamaños: default (compact) y lg (large)
|
|
12
|
+
- ✅ Iconos auto-dimensionados (12px default, 16px large)
|
|
13
|
+
- ✅ Prop `asChild` para badges clickeables (links)
|
|
14
|
+
- ✅ Hover automático cuando es link (`[a&]:hover`)
|
|
15
|
+
- ✅ Focus ring accesible con aria-invalid support
|
|
16
|
+
- ✅ Width auto-ajustable (`w-fit`)
|
|
17
|
+
- ✅ Estilos especiales para números circulares
|
|
18
|
+
- ✅ Dark mode completo en todas las variantes
|
|
19
|
+
|
|
20
|
+
## Importación
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { Badge } from "@adamosuiteservices/ui/badge";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Uso Básico
|
|
27
|
+
|
|
28
|
+
### Badge Simple
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<Badge>Badge</Badge>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Con Icono
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { CheckIcon } from "lucide-react";
|
|
38
|
+
|
|
39
|
+
<Badge>
|
|
40
|
+
<CheckIcon />
|
|
41
|
+
Verified
|
|
42
|
+
</Badge>;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Nota**: Los iconos se auto-dimensionan a 12px (default) o 16px (lg).
|
|
46
|
+
|
|
47
|
+
### Como Link Clickeable
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<Badge asChild>
|
|
51
|
+
<a href="/profile">View Profile</a>
|
|
52
|
+
</Badge>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Comportamiento**: El badge se renderiza como `<a>` con estilos de hover automáticos.
|
|
56
|
+
|
|
57
|
+
## Variantes
|
|
58
|
+
|
|
59
|
+
### default (Primary)
|
|
60
|
+
|
|
61
|
+
Badge sólido con colores primarios de la marca.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<Badge variant="default">Default</Badge>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Estilos**:
|
|
68
|
+
|
|
69
|
+
- Fondo: `bg-primary`
|
|
70
|
+
- Texto: `text-primary-foreground`
|
|
71
|
+
- Border: Transparente
|
|
72
|
+
- Hover (link): `bg-primary/90`
|
|
73
|
+
- Uso: Badges principales, featured, new, popular
|
|
74
|
+
|
|
75
|
+
### default-medium
|
|
76
|
+
|
|
77
|
+
Versión suave con fondo claro y icono en color primario.
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
<Badge variant="default-medium">Default Medium</Badge>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Estilos**:
|
|
84
|
+
|
|
85
|
+
- Fondo: `bg-primary-50` (muy claro)
|
|
86
|
+
- Texto: `text-neutral-600`
|
|
87
|
+
- Icono: `text-primary` (color vibrante)
|
|
88
|
+
- Hover (link): `bg-primary-100`
|
|
89
|
+
- Dark mode: `bg-primary-200`, `text-primary-800`
|
|
90
|
+
- Uso: Estados informativos suaves, categorías
|
|
91
|
+
|
|
92
|
+
### waiting
|
|
93
|
+
|
|
94
|
+
Badge para estados pendientes o en espera.
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
<Badge variant="waiting">Waiting</Badge>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Estilos**:
|
|
101
|
+
|
|
102
|
+
- Fondo: `bg-waiting` (color de espera)
|
|
103
|
+
- Texto: `text-waiting-foreground`
|
|
104
|
+
- Hover (link): `bg-waiting/90`
|
|
105
|
+
- Uso: Pendiente, en revisión, en proceso
|
|
106
|
+
|
|
107
|
+
### waiting-medium
|
|
108
|
+
|
|
109
|
+
Versión suave del badge waiting.
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
<Badge variant="waiting-medium">Waiting Medium</Badge>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Estilos**:
|
|
116
|
+
|
|
117
|
+
- Fondo: `bg-waiting-50`
|
|
118
|
+
- Texto: `text-neutral-600`
|
|
119
|
+
- Icono: `text-waiting`
|
|
120
|
+
- Dark mode: `bg-waiting-200`, `text-waiting-800`
|
|
121
|
+
- Uso: Estados de espera sutiles
|
|
122
|
+
|
|
123
|
+
### secondary
|
|
124
|
+
|
|
125
|
+
Badge con colores secundarios.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Estilos**:
|
|
132
|
+
|
|
133
|
+
- Fondo: `bg-secondary`
|
|
134
|
+
- Texto: `text-secondary-foreground`
|
|
135
|
+
- Hover (link): `bg-secondary/90`
|
|
136
|
+
- Uso: Información adicional, etiquetas genéricas
|
|
137
|
+
|
|
138
|
+
### success
|
|
139
|
+
|
|
140
|
+
Badge verde sólido para estados exitosos.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
<Badge variant="success">Success</Badge>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Estilos**:
|
|
147
|
+
|
|
148
|
+
- Fondo: `bg-success` (verde)
|
|
149
|
+
- Texto: `text-white`
|
|
150
|
+
- Hover (link): `bg-success/90`
|
|
151
|
+
- Focus ring: `ring-success/20`
|
|
152
|
+
- Dark mode: `bg-success/60`
|
|
153
|
+
- Uso: Completado, aprobado, activo, disponible
|
|
154
|
+
|
|
155
|
+
### success-medium
|
|
156
|
+
|
|
157
|
+
Versión suave del badge success.
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
<Badge variant="success-medium">Success Medium</Badge>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Estilos**:
|
|
164
|
+
|
|
165
|
+
- Fondo: `bg-success-50` (verde muy claro)
|
|
166
|
+
- Texto: `text-neutral-600`
|
|
167
|
+
- Icono: `text-success` (verde vibrante)
|
|
168
|
+
- Hover (link): `bg-success-100`
|
|
169
|
+
- Dark mode: `bg-success-200`, `text-success-800`
|
|
170
|
+
- Uso: Estados positivos sutiles, confirmaciones
|
|
171
|
+
|
|
172
|
+
### warning
|
|
173
|
+
|
|
174
|
+
Badge naranja/amarillo sólido para advertencias.
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
<Badge variant="warning">Warning</Badge>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Estilos**:
|
|
181
|
+
|
|
182
|
+
- Fondo: `bg-warning` (naranja/amarillo)
|
|
183
|
+
- Texto: `text-white`
|
|
184
|
+
- Hover (link): `bg-warning/90`
|
|
185
|
+
- Focus ring: `ring-warning/20`
|
|
186
|
+
- Dark mode: `bg-warning/60`
|
|
187
|
+
- Uso: Advertencia, atención requerida, casi lleno
|
|
188
|
+
|
|
189
|
+
### warning-medium
|
|
190
|
+
|
|
191
|
+
Versión suave del badge warning.
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
<Badge variant="warning-medium">Warning Medium</Badge>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Estilos**:
|
|
198
|
+
|
|
199
|
+
- Fondo: `bg-warning-50` (naranja muy claro)
|
|
200
|
+
- Texto: `text-neutral-600`
|
|
201
|
+
- Icono: `text-warning`
|
|
202
|
+
- Dark mode: `bg-warning-200`, `text-warning-800`
|
|
203
|
+
- Uso: Advertencias sutiles, precauciones
|
|
204
|
+
|
|
205
|
+
### destructive
|
|
206
|
+
|
|
207
|
+
Badge rojo sólido para errores y estados negativos.
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Estilos**:
|
|
214
|
+
|
|
215
|
+
- Fondo: `bg-destructive` (rojo)
|
|
216
|
+
- Texto: `text-white`
|
|
217
|
+
- Hover (link): `bg-destructive/90`
|
|
218
|
+
- Focus ring: `ring-destructive/20`
|
|
219
|
+
- Dark mode: `bg-destructive/60`
|
|
220
|
+
- Uso: Error, inactivo, cancelado, rechazado
|
|
221
|
+
|
|
222
|
+
### destructive-medium
|
|
223
|
+
|
|
224
|
+
Versión suave del badge destructive.
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
<Badge variant="destructive-medium">Destructive Medium</Badge>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Estilos**:
|
|
231
|
+
|
|
232
|
+
- Fondo: `bg-destructive-50` (rojo muy claro)
|
|
233
|
+
- Texto: `text-neutral-600`
|
|
234
|
+
- Icono: `text-destructive` (rojo vibrante)
|
|
235
|
+
- Dark mode: `bg-destructive-200`, `text-destructive-800`
|
|
236
|
+
- Uso: Errores sutiles, estados negativos
|
|
237
|
+
|
|
238
|
+
### muted
|
|
239
|
+
|
|
240
|
+
Badge con colores apagados para bajo énfasis.
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
<Badge variant="muted">Muted</Badge>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Estilos**:
|
|
247
|
+
|
|
248
|
+
- Fondo: `bg-muted`
|
|
249
|
+
- Texto: `text-muted-foreground`
|
|
250
|
+
- Hover (link): `bg-muted/90`
|
|
251
|
+
- Dark mode: `bg-muted/60`
|
|
252
|
+
- Uso: Información secundaria, disabled, draft
|
|
253
|
+
|
|
254
|
+
### outline
|
|
255
|
+
|
|
256
|
+
Badge con borde y fondo transparente.
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
<Badge variant="outline">Outline</Badge>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Estilos**:
|
|
263
|
+
|
|
264
|
+
- Fondo: Transparente
|
|
265
|
+
- Texto: `text-foreground`
|
|
266
|
+
- Border: Visible
|
|
267
|
+
- Hover (link): `bg-accent`
|
|
268
|
+
- Uso: Tags, categorías, filtros, etiquetas neutrales
|
|
269
|
+
|
|
270
|
+
## Tamaños
|
|
271
|
+
|
|
272
|
+
### default (Compact)
|
|
273
|
+
|
|
274
|
+
Tamaño compacto para uso general.
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
<Badge>Compact Badge</Badge>
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Dimensiones**:
|
|
281
|
+
|
|
282
|
+
- Padding horizontal: `px-2` (8px)
|
|
283
|
+
- Padding vertical: `py-0.5` (2px)
|
|
284
|
+
- Texto: `text-xs` (12px)
|
|
285
|
+
- Iconos: `size-3` (12x12px)
|
|
286
|
+
- Gap: `gap-1` (4px)
|
|
287
|
+
|
|
288
|
+
### lg (Large)
|
|
289
|
+
|
|
290
|
+
Tamaño grande para mayor visibilidad.
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
<Badge size="lg">Large Badge</Badge>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Dimensiones**:
|
|
297
|
+
|
|
298
|
+
- Padding horizontal: `px-2` (8px)
|
|
299
|
+
- Padding vertical: `py-1` (4px)
|
|
300
|
+
- Texto: `text-sm` (14px)
|
|
301
|
+
- Iconos: `size-4` (16x16px)
|
|
302
|
+
- Gap: `gap-2` (8px)
|
|
303
|
+
|
|
304
|
+
## Props
|
|
305
|
+
|
|
306
|
+
| Prop | Tipo | Default | Descripción |
|
|
307
|
+
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------ |
|
|
308
|
+
| variant | `"default" \| "default-medium" \| "waiting" \| "waiting-medium" \| "secondary" \| "success" \| "success-medium" \| "warning" \| "warning-medium" \| "destructive" \| "destructive-medium" \| "muted" \| "outline"` | `"default"` | Variante visual del badge |
|
|
309
|
+
| size | `"default" \| "lg"` | `"default"` | Tamaño del badge |
|
|
310
|
+
| asChild | `boolean` | `false` | Renderiza el hijo en lugar de un `<span>`. Usa Radix UI Slot |
|
|
311
|
+
| className | `string` | - | Clases CSS adicionales |
|
|
312
|
+
| children | `ReactNode` | - | Contenido del badge (texto, iconos, números) |
|
|
313
|
+
| ...props | `HTMLAttributes<HTMLSpanElement>` | - | Todas las props nativas de `<span>` |
|
|
314
|
+
|
|
315
|
+
**Nota sobre asChild**: Útil para badges clickeables con links `<a>`.
|
|
316
|
+
|
|
317
|
+
## Estilos Base Automáticos
|
|
318
|
+
|
|
319
|
+
Todos los badges tienen estos estilos aplicados:
|
|
320
|
+
|
|
321
|
+
```css
|
|
322
|
+
inline-flex /* Display flex inline */
|
|
323
|
+
items-center /* Alinea verticalmente */
|
|
324
|
+
justify-center /* Centra horizontalmente */
|
|
325
|
+
rounded-md /* Border radius medium */
|
|
326
|
+
border /* Border (transparente en la mayoría) */
|
|
327
|
+
w-fit /* Ancho auto-ajustable */
|
|
328
|
+
whitespace-nowrap /* No rompe líneas */
|
|
329
|
+
shrink-0 /* No se encoge en flex/grid */
|
|
330
|
+
overflow-hidden /* Oculta overflow */
|
|
331
|
+
transition-[color,box-shadow] /* Transiciones suaves */
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Iconos Auto-dimensionados
|
|
335
|
+
|
|
336
|
+
```css
|
|
337
|
+
[&>svg]:size-3 /* SVG → 12x12px (default) */
|
|
338
|
+
[&>svg]:size-4 /* SVG → 16x16px (size="lg") */
|
|
339
|
+
[&>svg]:pointer-events-none /* Iconos no capturan clicks */
|
|
340
|
+
gap-1 /* 4px entre elementos (default) */
|
|
341
|
+
gap-2 /* 8px entre elementos (lg) */
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Hover Automático en Links
|
|
345
|
+
|
|
346
|
+
```css
|
|
347
|
+
[a&]:hover:bg-primary/90 /* Solo si el badge es un <a> */
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Beneficio**: El hover solo se aplica cuando usas `asChild` con `<a>`.
|
|
351
|
+
|
|
352
|
+
## Patrones Avanzados
|
|
353
|
+
|
|
354
|
+
### Badges de Estado
|
|
355
|
+
|
|
356
|
+
Para indicadores de estado del sistema.
|
|
357
|
+
|
|
358
|
+
```tsx
|
|
359
|
+
import { CheckIcon, XIcon, AlertCircleIcon, ZapIcon } from "lucide-react";
|
|
360
|
+
|
|
361
|
+
<div className="flex gap-2">
|
|
362
|
+
<Badge variant="success">
|
|
363
|
+
<CheckIcon />
|
|
364
|
+
Active
|
|
365
|
+
</Badge>
|
|
366
|
+
<Badge variant="secondary">
|
|
367
|
+
<ZapIcon />
|
|
368
|
+
Pending
|
|
369
|
+
</Badge>
|
|
370
|
+
<Badge variant="warning-medium">
|
|
371
|
+
<AlertCircleIcon />
|
|
372
|
+
Warning
|
|
373
|
+
</Badge>
|
|
374
|
+
<Badge variant="destructive">
|
|
375
|
+
<XIcon />
|
|
376
|
+
Inactive
|
|
377
|
+
</Badge>
|
|
378
|
+
</div>;
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Badges Numéricos (Circulares)
|
|
382
|
+
|
|
383
|
+
Para notificaciones y contadores.
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
{/* Small circular badges */}
|
|
387
|
+
<Badge className="h-5 min-w-5 rounded-full px-1 font-mono tabular-nums">
|
|
388
|
+
8
|
|
389
|
+
</Badge>
|
|
390
|
+
|
|
391
|
+
<Badge
|
|
392
|
+
variant="destructive"
|
|
393
|
+
className="h-5 min-w-5 rounded-full px-1 font-mono tabular-nums"
|
|
394
|
+
>
|
|
395
|
+
99
|
|
396
|
+
</Badge>
|
|
397
|
+
|
|
398
|
+
<Badge
|
|
399
|
+
variant="outline"
|
|
400
|
+
className="h-5 min-w-5 rounded-full px-1 font-mono tabular-nums"
|
|
401
|
+
>
|
|
402
|
+
20+
|
|
403
|
+
</Badge>
|
|
404
|
+
|
|
405
|
+
{/* Larger circular badge */}
|
|
406
|
+
<Badge
|
|
407
|
+
variant="secondary"
|
|
408
|
+
className="h-6 min-w-6 rounded-full px-1.5 font-mono tabular-nums"
|
|
409
|
+
>
|
|
410
|
+
1.2K
|
|
411
|
+
</Badge>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Clases importantes**:
|
|
415
|
+
|
|
416
|
+
- `rounded-full`: Circular
|
|
417
|
+
- `min-w-5`: Ancho mínimo para mantener forma circular
|
|
418
|
+
- `font-mono`: Fuente monoespaciada para números
|
|
419
|
+
- `tabular-nums`: Números alineados
|
|
420
|
+
|
|
421
|
+
### Badges con Notificaciones (Posicionados)
|
|
422
|
+
|
|
423
|
+
Para iconos con contadores.
|
|
424
|
+
|
|
425
|
+
```tsx
|
|
426
|
+
import { BellIcon, HeartIcon, GiftIcon } from "lucide-react";
|
|
427
|
+
import { Button } from "@adamosuiteservices/ui/button";
|
|
428
|
+
|
|
429
|
+
<div className="flex gap-6 items-center">
|
|
430
|
+
{/* Con contador */}
|
|
431
|
+
<div className="relative">
|
|
432
|
+
<Button variant="outline" size="icon">
|
|
433
|
+
<BellIcon />
|
|
434
|
+
</Button>
|
|
435
|
+
<Badge
|
|
436
|
+
variant="destructive"
|
|
437
|
+
className="absolute -top-2 -right-2 h-5 min-w-5 rounded-full px-1 font-mono tabular-nums"
|
|
438
|
+
>
|
|
439
|
+
3
|
|
440
|
+
</Badge>
|
|
441
|
+
</div>
|
|
442
|
+
|
|
443
|
+
{/* Con número más grande */}
|
|
444
|
+
<div className="relative">
|
|
445
|
+
<Button variant="outline" size="icon">
|
|
446
|
+
<HeartIcon />
|
|
447
|
+
</Button>
|
|
448
|
+
<Badge
|
|
449
|
+
variant="default"
|
|
450
|
+
className="absolute -top-2 -right-2 h-5 min-w-5 rounded-full px-1 font-mono tabular-nums"
|
|
451
|
+
>
|
|
452
|
+
12
|
|
453
|
+
</Badge>
|
|
454
|
+
</div>
|
|
455
|
+
|
|
456
|
+
{/* Solo indicador (sin número) */}
|
|
457
|
+
<div className="relative">
|
|
458
|
+
<Button variant="outline" size="icon">
|
|
459
|
+
<GiftIcon />
|
|
460
|
+
</Button>
|
|
461
|
+
<Badge
|
|
462
|
+
variant="secondary"
|
|
463
|
+
className="absolute -top-2 -right-2 h-4 min-w-4 rounded-full px-0.5 text-xs"
|
|
464
|
+
>
|
|
465
|
+
•
|
|
466
|
+
</Badge>
|
|
467
|
+
</div>
|
|
468
|
+
</div>;
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Roles de Usuario
|
|
472
|
+
|
|
473
|
+
Para permisos y niveles.
|
|
474
|
+
|
|
475
|
+
```tsx
|
|
476
|
+
import { CrownIcon, ShieldIcon, BadgeCheckIcon } from "lucide-react";
|
|
477
|
+
|
|
478
|
+
<div className="flex gap-2">
|
|
479
|
+
<Badge variant="default">
|
|
480
|
+
<CrownIcon />
|
|
481
|
+
Admin
|
|
482
|
+
</Badge>
|
|
483
|
+
<Badge variant="secondary">
|
|
484
|
+
<ShieldIcon />
|
|
485
|
+
Moderator
|
|
486
|
+
</Badge>
|
|
487
|
+
<Badge variant="default-medium">
|
|
488
|
+
<BadgeCheckIcon />
|
|
489
|
+
Verified
|
|
490
|
+
</Badge>
|
|
491
|
+
<Badge variant="outline">Member</Badge>
|
|
492
|
+
</div>;
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Badges de Producto (E-commerce)
|
|
496
|
+
|
|
497
|
+
Para etiquetas promocionales.
|
|
498
|
+
|
|
499
|
+
```tsx
|
|
500
|
+
import { GiftIcon, StarIcon } from "lucide-react";
|
|
501
|
+
|
|
502
|
+
<div className="space-y-4">
|
|
503
|
+
{/* Badges básicos */}
|
|
504
|
+
<div className="flex gap-2">
|
|
505
|
+
<Badge variant="destructive">Sale</Badge>
|
|
506
|
+
<Badge variant="default">New</Badge>
|
|
507
|
+
<Badge variant="secondary">Bestseller</Badge>
|
|
508
|
+
<Badge variant="outline">Limited</Badge>
|
|
509
|
+
</div>
|
|
510
|
+
|
|
511
|
+
{/* Badges personalizados */}
|
|
512
|
+
<div className="flex gap-2">
|
|
513
|
+
<Badge className="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
|
|
514
|
+
Free Shipping
|
|
515
|
+
</Badge>
|
|
516
|
+
<Badge className="bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200">
|
|
517
|
+
<StarIcon />
|
|
518
|
+
Premium
|
|
519
|
+
</Badge>
|
|
520
|
+
<Badge className="bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">
|
|
521
|
+
<GiftIcon />
|
|
522
|
+
Bundle Deal
|
|
523
|
+
</Badge>
|
|
524
|
+
</div>
|
|
525
|
+
</div>;
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Badges con Avatares
|
|
529
|
+
|
|
530
|
+
Para menciones y tags de usuario.
|
|
531
|
+
|
|
532
|
+
```tsx
|
|
533
|
+
import {
|
|
534
|
+
Avatar,
|
|
535
|
+
AvatarImage,
|
|
536
|
+
AvatarFallback,
|
|
537
|
+
} from "@adamosuiteservices/ui/avatar";
|
|
538
|
+
import { BadgeCheckIcon } from "lucide-react";
|
|
539
|
+
|
|
540
|
+
<div className="flex gap-4 items-center">
|
|
541
|
+
<div className="flex items-center gap-2">
|
|
542
|
+
<Avatar className="size-6">
|
|
543
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
544
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
545
|
+
</Avatar>
|
|
546
|
+
<Badge variant="secondary">shadcn</Badge>
|
|
547
|
+
</div>
|
|
548
|
+
|
|
549
|
+
<div className="flex items-center gap-2">
|
|
550
|
+
<Avatar className="size-6">
|
|
551
|
+
<AvatarFallback>ML</AvatarFallback>
|
|
552
|
+
</Avatar>
|
|
553
|
+
<Badge variant="default">
|
|
554
|
+
<BadgeCheckIcon />
|
|
555
|
+
maxleiter
|
|
556
|
+
</Badge>
|
|
557
|
+
</div>
|
|
558
|
+
</div>;
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Badges de Precio
|
|
562
|
+
|
|
563
|
+
Para información de precios y promociones.
|
|
564
|
+
|
|
565
|
+
```tsx
|
|
566
|
+
import { DollarSignIcon, TrendingUpIcon } from "lucide-react";
|
|
567
|
+
|
|
568
|
+
<div className="flex gap-2">
|
|
569
|
+
<Badge variant="secondary">
|
|
570
|
+
<DollarSignIcon />
|
|
571
|
+
$9.99
|
|
572
|
+
</Badge>
|
|
573
|
+
<Badge variant="destructive" className="animate-pulse">
|
|
574
|
+
50% OFF
|
|
575
|
+
</Badge>
|
|
576
|
+
<Badge variant="default">
|
|
577
|
+
<TrendingUpIcon />
|
|
578
|
+
Best Value
|
|
579
|
+
</Badge>
|
|
580
|
+
<Badge variant="outline">Free Trial</Badge>
|
|
581
|
+
</div>;
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Colores Personalizados
|
|
585
|
+
|
|
586
|
+
Para casos especiales de branding.
|
|
587
|
+
|
|
588
|
+
```tsx
|
|
589
|
+
import {
|
|
590
|
+
BadgeCheckIcon,
|
|
591
|
+
CheckIcon,
|
|
592
|
+
StarIcon,
|
|
593
|
+
TrendingUpIcon,
|
|
594
|
+
} from "lucide-react";
|
|
595
|
+
|
|
596
|
+
<div className="flex gap-2">
|
|
597
|
+
<Badge className="bg-blue-500 text-white dark:bg-blue-600">
|
|
598
|
+
<BadgeCheckIcon />
|
|
599
|
+
Verified
|
|
600
|
+
</Badge>
|
|
601
|
+
<Badge className="bg-green-500 text-white dark:bg-green-600">
|
|
602
|
+
<CheckIcon />
|
|
603
|
+
Success
|
|
604
|
+
</Badge>
|
|
605
|
+
<Badge className="bg-purple-500 text-white dark:bg-purple-600">
|
|
606
|
+
<StarIcon />
|
|
607
|
+
Premium
|
|
608
|
+
</Badge>
|
|
609
|
+
<Badge className="bg-orange-500 text-white dark:bg-orange-600">
|
|
610
|
+
<TrendingUpIcon />
|
|
611
|
+
Trending
|
|
612
|
+
</Badge>
|
|
613
|
+
</div>;
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### Badges Clickeables
|
|
617
|
+
|
|
618
|
+
Para navegación y filtros.
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
{
|
|
622
|
+
/* Badge como link */
|
|
623
|
+
}
|
|
624
|
+
<Badge asChild>
|
|
625
|
+
<a href="/category/react">React</a>
|
|
626
|
+
</Badge>;
|
|
627
|
+
|
|
628
|
+
{
|
|
629
|
+
/* Badge como botón */
|
|
630
|
+
}
|
|
631
|
+
<Badge asChild>
|
|
632
|
+
<button onClick={handleClick}>
|
|
633
|
+
<XIcon />
|
|
634
|
+
Remove
|
|
635
|
+
</button>
|
|
636
|
+
</Badge>;
|
|
637
|
+
|
|
638
|
+
{
|
|
639
|
+
/* Badge interactivo con estado */
|
|
640
|
+
}
|
|
641
|
+
<Badge asChild variant={isActive ? "default" : "outline"}>
|
|
642
|
+
<button onClick={() => setIsActive(!isActive)}>
|
|
643
|
+
{isActive ? "Active" : "Inactive"}
|
|
644
|
+
</button>
|
|
645
|
+
</Badge>;
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
## Casos de Uso Comunes
|
|
649
|
+
|
|
650
|
+
### Indicadores de Estado
|
|
651
|
+
|
|
652
|
+
```tsx
|
|
653
|
+
// Estados del sistema
|
|
654
|
+
<Badge variant="success">Online</Badge>
|
|
655
|
+
<Badge variant="warning">Maintenance</Badge>
|
|
656
|
+
<Badge variant="destructive">Offline</Badge>
|
|
657
|
+
<Badge variant="muted">Draft</Badge>
|
|
658
|
+
|
|
659
|
+
// Estados de pedido
|
|
660
|
+
<Badge variant="waiting">Pending</Badge>
|
|
661
|
+
<Badge variant="default">Processing</Badge>
|
|
662
|
+
<Badge variant="success">Completed</Badge>
|
|
663
|
+
<Badge variant="destructive">Cancelled</Badge>
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### Tags y Categorías
|
|
667
|
+
|
|
668
|
+
```tsx
|
|
669
|
+
<div className="flex gap-2 flex-wrap">
|
|
670
|
+
<Badge variant="outline">React</Badge>
|
|
671
|
+
<Badge variant="outline">TypeScript</Badge>
|
|
672
|
+
<Badge variant="outline">Tailwind CSS</Badge>
|
|
673
|
+
<Badge variant="outline">Next.js</Badge>
|
|
674
|
+
</div>
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### Contadores y Notificaciones
|
|
678
|
+
|
|
679
|
+
```tsx
|
|
680
|
+
<div className="flex items-center gap-2">
|
|
681
|
+
<span className="text-sm">New messages</span>
|
|
682
|
+
<Badge variant="destructive" className="h-5 min-w-5 rounded-full px-1">
|
|
683
|
+
12
|
|
684
|
+
</Badge>
|
|
685
|
+
</div>
|
|
686
|
+
|
|
687
|
+
<div className="flex items-center gap-2">
|
|
688
|
+
<span className="text-sm">Unread</span>
|
|
689
|
+
<Badge>3</Badge>
|
|
690
|
+
</div>
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
### Etiquetas de Producto
|
|
694
|
+
|
|
695
|
+
```tsx
|
|
696
|
+
// En tarjeta de producto
|
|
697
|
+
<div className="relative">
|
|
698
|
+
<img src={productImage} alt="Product" />
|
|
699
|
+
<div className="absolute top-2 left-2 flex gap-2">
|
|
700
|
+
<Badge variant="destructive">-50%</Badge>
|
|
701
|
+
<Badge variant="default">New</Badge>
|
|
702
|
+
</div>
|
|
703
|
+
</div>
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
### Información de Usuario
|
|
707
|
+
|
|
708
|
+
```tsx
|
|
709
|
+
<div className="flex items-center gap-3">
|
|
710
|
+
<Avatar className="size-10">
|
|
711
|
+
<AvatarImage src={userAvatar} />
|
|
712
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
713
|
+
</Avatar>
|
|
714
|
+
<div>
|
|
715
|
+
<div className="flex items-center gap-2">
|
|
716
|
+
<span className="font-medium">John Doe</span>
|
|
717
|
+
<Badge variant="default-medium">
|
|
718
|
+
<BadgeCheckIcon />
|
|
719
|
+
Verified
|
|
720
|
+
</Badge>
|
|
721
|
+
</div>
|
|
722
|
+
<div className="flex gap-2 mt-1">
|
|
723
|
+
<Badge variant="outline" size="sm">
|
|
724
|
+
Admin
|
|
725
|
+
</Badge>
|
|
726
|
+
<Badge variant="outline" size="sm">
|
|
727
|
+
Pro
|
|
728
|
+
</Badge>
|
|
729
|
+
</div>
|
|
730
|
+
</div>
|
|
731
|
+
</div>
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
### Lista de Tareas/Items
|
|
735
|
+
|
|
736
|
+
```tsx
|
|
737
|
+
<ul className="space-y-2">
|
|
738
|
+
<li className="flex items-center justify-between">
|
|
739
|
+
<span>Complete project documentation</span>
|
|
740
|
+
<Badge variant="success">Done</Badge>
|
|
741
|
+
</li>
|
|
742
|
+
<li className="flex items-center justify-between">
|
|
743
|
+
<span>Review pull requests</span>
|
|
744
|
+
<Badge variant="warning">In Progress</Badge>
|
|
745
|
+
</li>
|
|
746
|
+
<li className="flex items-center justify-between">
|
|
747
|
+
<span>Deploy to production</span>
|
|
748
|
+
<Badge variant="outline">Todo</Badge>
|
|
749
|
+
</li>
|
|
750
|
+
</ul>
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
### Filtros Removibles
|
|
754
|
+
|
|
755
|
+
```tsx
|
|
756
|
+
import { XIcon } from "lucide-react";
|
|
757
|
+
|
|
758
|
+
<div className="flex gap-2">
|
|
759
|
+
<Badge asChild>
|
|
760
|
+
<button className="cursor-pointer hover:bg-accent/80">
|
|
761
|
+
Category: Electronics
|
|
762
|
+
<XIcon className="h-3 w-3 ml-1" />
|
|
763
|
+
</button>
|
|
764
|
+
</Badge>
|
|
765
|
+
<Badge asChild>
|
|
766
|
+
<button className="cursor-pointer hover:bg-accent/80">
|
|
767
|
+
Price: $50-$100
|
|
768
|
+
<XIcon className="h-3 w-3 ml-1" />
|
|
769
|
+
</button>
|
|
770
|
+
</Badge>
|
|
771
|
+
</div>;
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
## Mejores Prácticas
|
|
775
|
+
|
|
776
|
+
### Selección de Variantes
|
|
777
|
+
|
|
778
|
+
```tsx
|
|
779
|
+
{/* ✅ Correcto - Variantes semánticas */}
|
|
780
|
+
<Badge variant="success">Approved</Badge>
|
|
781
|
+
<Badge variant="destructive">Rejected</Badge>
|
|
782
|
+
<Badge variant="warning">Pending Review</Badge>
|
|
783
|
+
|
|
784
|
+
{/* ❌ Incorrecto - Variantes genéricas para estados importantes */}
|
|
785
|
+
<Badge variant="secondary">Approved</Badge> {/* Debería ser success */}
|
|
786
|
+
<Badge variant="outline">Error</Badge> {/* Debería ser destructive */}
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
### Badges Numéricos
|
|
790
|
+
|
|
791
|
+
```tsx
|
|
792
|
+
{
|
|
793
|
+
/* ✅ Correcto - Circular con fuente mono */
|
|
794
|
+
}
|
|
795
|
+
<Badge className="h-5 min-w-5 rounded-full px-1 font-mono tabular-nums">
|
|
796
|
+
99+
|
|
797
|
+
</Badge>;
|
|
798
|
+
|
|
799
|
+
{
|
|
800
|
+
/* ❌ Incorrecto - Rectangular para números */
|
|
801
|
+
}
|
|
802
|
+
<Badge>99+</Badge>;
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Tamaño de Texto
|
|
806
|
+
|
|
807
|
+
```tsx
|
|
808
|
+
{/* ✅ Correcto - Textos cortos */}
|
|
809
|
+
<Badge>New</Badge>
|
|
810
|
+
<Badge>Sale</Badge>
|
|
811
|
+
<Badge variant="success">Active</Badge>
|
|
812
|
+
|
|
813
|
+
{/* ❌ Incorrecto - Textos muy largos */}
|
|
814
|
+
<Badge>This is a very long badge text that should be avoided</Badge>
|
|
815
|
+
|
|
816
|
+
{/* ✅ Mejor - Usa Tooltip para textos largos */}
|
|
817
|
+
<Tooltip>
|
|
818
|
+
<TooltipTrigger>
|
|
819
|
+
<Badge>Info</Badge>
|
|
820
|
+
</TooltipTrigger>
|
|
821
|
+
<TooltipContent>
|
|
822
|
+
This is the full explanation that was too long for the badge
|
|
823
|
+
</TooltipContent>
|
|
824
|
+
</Tooltip>
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### Accesibilidad en Badges Clickeables
|
|
828
|
+
|
|
829
|
+
```tsx
|
|
830
|
+
{
|
|
831
|
+
/* ✅ Correcto - Link semántico */
|
|
832
|
+
}
|
|
833
|
+
<Badge asChild>
|
|
834
|
+
<a href="/category" aria-label="View React category">
|
|
835
|
+
React
|
|
836
|
+
</a>
|
|
837
|
+
</Badge>;
|
|
838
|
+
|
|
839
|
+
{
|
|
840
|
+
/* ✅ Correcto - Botón con aria-label */
|
|
841
|
+
}
|
|
842
|
+
<Badge asChild>
|
|
843
|
+
<button onClick={handleRemove} aria-label="Remove React filter">
|
|
844
|
+
React
|
|
845
|
+
<XIcon />
|
|
846
|
+
</button>
|
|
847
|
+
</Badge>;
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
### Consistencia Visual
|
|
851
|
+
|
|
852
|
+
```tsx
|
|
853
|
+
{
|
|
854
|
+
/* ✅ Correcto - Tamaños consistentes en el mismo contexto */
|
|
855
|
+
}
|
|
856
|
+
<div className="flex gap-2">
|
|
857
|
+
<Badge variant="outline">React</Badge>
|
|
858
|
+
<Badge variant="outline">TypeScript</Badge>
|
|
859
|
+
<Badge variant="outline">Next.js</Badge>
|
|
860
|
+
</div>;
|
|
861
|
+
|
|
862
|
+
{
|
|
863
|
+
/* ❌ Incorrecto - Mezcla innecesaria de tamaños */
|
|
864
|
+
}
|
|
865
|
+
<div className="flex gap-2">
|
|
866
|
+
<Badge size="lg">React</Badge>
|
|
867
|
+
<Badge>TypeScript</Badge>
|
|
868
|
+
<Badge size="lg">Next.js</Badge>
|
|
869
|
+
</div>;
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
## Notas de Implementación
|
|
873
|
+
|
|
874
|
+
- Basado en CVA (class-variance-authority) para variants system
|
|
875
|
+
- Usa Radix UI Slot para la prop `asChild`
|
|
876
|
+
- Los iconos SVG se auto-dimensionan: 12px (default), 16px (lg)
|
|
877
|
+
- Width es `w-fit` para auto-ajustarse al contenido
|
|
878
|
+
- Hover automático solo en badges que son links: `[a&]:hover`
|
|
879
|
+
- Focus ring usa `focus-visible` (solo teclado)
|
|
880
|
+
- `shrink-0` evita que badges se encojan en flex layouts
|
|
881
|
+
- Border es transparente en la mayoría de variantes
|
|
882
|
+
- Transiciones solo en `color` y `box-shadow` para mejor performance
|
|
883
|
+
- Sistema de slots con `data-slot="badge"` para identificación
|
|
884
|
+
|
|
885
|
+
## Accesibilidad
|
|
886
|
+
|
|
887
|
+
### Badges No Interactivos
|
|
888
|
+
|
|
889
|
+
```tsx
|
|
890
|
+
{/* ✅ Correcto - Solo visual, no necesita ARIA */}
|
|
891
|
+
<Badge variant="success">Active</Badge>
|
|
892
|
+
<Badge variant="outline">React</Badge>
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
### Badges Interactivos
|
|
896
|
+
|
|
897
|
+
```tsx
|
|
898
|
+
{
|
|
899
|
+
/* ✅ Correcto - Link con texto descriptivo */
|
|
900
|
+
}
|
|
901
|
+
<Badge asChild>
|
|
902
|
+
<a href="/category/new">New Items</a>
|
|
903
|
+
</Badge>;
|
|
904
|
+
|
|
905
|
+
{
|
|
906
|
+
/* ✅ Correcto - Botón con aria-label */
|
|
907
|
+
}
|
|
908
|
+
<Badge asChild>
|
|
909
|
+
<button aria-label="Remove tag: JavaScript" onClick={handleRemove}>
|
|
910
|
+
JavaScript
|
|
911
|
+
<XIcon />
|
|
912
|
+
</button>
|
|
913
|
+
</Badge>;
|
|
914
|
+
|
|
915
|
+
{
|
|
916
|
+
/* ✅ Correcto - Badge numérico con contexto */
|
|
917
|
+
}
|
|
918
|
+
<span className="flex items-center gap-2">
|
|
919
|
+
<span id="notification-label">Unread notifications</span>
|
|
920
|
+
<Badge aria-labelledby="notification-label">5</Badge>
|
|
921
|
+
</span>;
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
### Contraste de Colores
|
|
925
|
+
|
|
926
|
+
- ✅ Todas las variantes sólidas (default, success, warning, destructive) tienen contraste AAA
|
|
927
|
+
- ✅ Variantes "medium" tienen contraste AA para texto
|
|
928
|
+
- ✅ Iconos en variantes "medium" usan colores vibrantes para mejor visibilidad
|
|
929
|
+
- ⚠️ Verifica contraste si usas colores personalizados
|
|
930
|
+
|
|
931
|
+
### Screen Readers
|
|
932
|
+
|
|
933
|
+
```tsx
|
|
934
|
+
{
|
|
935
|
+
/* ✅ Badges decorativos - ocultos de screen readers */
|
|
936
|
+
}
|
|
937
|
+
<div className="flex items-center gap-2">
|
|
938
|
+
<span>New features available</span>
|
|
939
|
+
<Badge aria-hidden="true">3</Badge>
|
|
940
|
+
</div>;
|
|
941
|
+
|
|
942
|
+
{
|
|
943
|
+
/* ✅ Badges con información importante - incluidos */
|
|
944
|
+
}
|
|
945
|
+
<div>
|
|
946
|
+
<span>Order status: </span>
|
|
947
|
+
<Badge variant="success">Completed</Badge>
|
|
948
|
+
</div>;
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
## Troubleshooting
|
|
952
|
+
|
|
953
|
+
### Badge Demasiado Ancho
|
|
954
|
+
|
|
955
|
+
**Problema**: El badge es más ancho de lo esperado.
|
|
956
|
+
|
|
957
|
+
**Solución**:
|
|
958
|
+
|
|
959
|
+
```tsx
|
|
960
|
+
// ❌ Badge con texto largo
|
|
961
|
+
<Badge>This is a very long badge</Badge>
|
|
962
|
+
|
|
963
|
+
// ✅ Texto más corto
|
|
964
|
+
<Badge>Long...</Badge>
|
|
965
|
+
|
|
966
|
+
// ✅ O usa max-width
|
|
967
|
+
<Badge className="max-w-[100px] truncate">
|
|
968
|
+
This is a very long badge
|
|
969
|
+
</Badge>
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
### Iconos No Se Alinean
|
|
973
|
+
|
|
974
|
+
**Problema**: Los iconos no están centrados verticalmente.
|
|
975
|
+
|
|
976
|
+
**Solución**:
|
|
977
|
+
|
|
978
|
+
```tsx
|
|
979
|
+
// ❌ Incorrecto - icono con tamaño personalizado
|
|
980
|
+
<Badge>
|
|
981
|
+
<CheckIcon className="h-5 w-5" /> {/* Muy grande */}
|
|
982
|
+
Verified
|
|
983
|
+
</Badge>
|
|
984
|
+
|
|
985
|
+
// ✅ Correcto - sin clase size (auto-dimensionado)
|
|
986
|
+
<Badge>
|
|
987
|
+
<CheckIcon /> {/* Auto: 12px */}
|
|
988
|
+
Verified
|
|
989
|
+
</Badge>
|
|
990
|
+
|
|
991
|
+
// ✅ También correcto - size lg con iconos más grandes
|
|
992
|
+
<Badge size="lg">
|
|
993
|
+
<CheckIcon /> {/* Auto: 16px */}
|
|
994
|
+
Verified
|
|
995
|
+
</Badge>
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
### Badge No Es Clickeable
|
|
999
|
+
|
|
1000
|
+
**Problema**: El badge no responde a clicks.
|
|
1001
|
+
|
|
1002
|
+
**Solución**:
|
|
1003
|
+
|
|
1004
|
+
```tsx
|
|
1005
|
+
// ❌ Incorrecto - badge span no es clickeable
|
|
1006
|
+
<Badge onClick={handleClick}>Click me</Badge>
|
|
1007
|
+
|
|
1008
|
+
// ✅ Correcto - usa asChild con button
|
|
1009
|
+
<Badge asChild>
|
|
1010
|
+
<button onClick={handleClick}>Click me</button>
|
|
1011
|
+
</Badge>
|
|
1012
|
+
|
|
1013
|
+
// ✅ O usa asChild con link
|
|
1014
|
+
<Badge asChild>
|
|
1015
|
+
<a href="/link">Click me</a>
|
|
1016
|
+
</Badge>
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
## Referencias
|
|
1020
|
+
|
|
1021
|
+
- CVA (Class Variance Authority): https://cva.style/docs
|
|
1022
|
+
- Radix UI Slot: https://www.radix-ui.com/primitives/docs/utilities/slot
|
|
1023
|
+
- shadcn/ui Badge: https://ui.shadcn.com/docs/components/badge
|
|
1024
|
+
- WCAG Contrast Guidelines: https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html
|