@adamosuiteservices/ui 2.13.2 → 2.13.4
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/components/ui/slider/slider.d.ts +5 -2
- package/dist/slider.cjs +7 -8
- package/dist/slider.js +192 -178
- package/dist/styles.css +1 -1
- package/docs/AI-GUIDE.md +321 -321
- package/docs/components/layout/sidebar.md +399 -399
- package/docs/components/layout/toaster.md +436 -436
- package/docs/components/ui/accordion-rounded.md +584 -584
- package/docs/components/ui/accordion.md +269 -269
- package/docs/components/ui/calendar.md +1159 -1159
- package/docs/components/ui/card.md +1455 -1455
- package/docs/components/ui/checkbox.md +292 -292
- package/docs/components/ui/collapsible.md +323 -323
- package/docs/components/ui/dialog.md +628 -628
- package/docs/components/ui/field.md +706 -706
- package/docs/components/ui/hover-card.md +446 -446
- package/docs/components/ui/kbd.md +434 -434
- package/docs/components/ui/label.md +359 -359
- package/docs/components/ui/pagination.md +650 -650
- package/docs/components/ui/popover.md +536 -536
- package/docs/components/ui/progress.md +182 -182
- package/docs/components/ui/radio-group.md +311 -311
- package/docs/components/ui/separator.md +214 -214
- package/docs/components/ui/sheet.md +174 -174
- package/docs/components/ui/skeleton.md +140 -140
- package/docs/components/ui/slider.md +460 -341
- package/docs/components/ui/spinner.md +170 -170
- package/docs/components/ui/switch.md +408 -408
- package/docs/components/ui/tabs-underline.md +106 -106
- package/docs/components/ui/tabs.md +122 -122
- package/docs/components/ui/textarea.md +243 -243
- package/docs/components/ui/toggle.md +237 -237
- package/docs/components/ui/tooltip.md +317 -317
- package/docs/components/ui/typography.md +320 -320
- package/package.json +1 -1
|
@@ -1,359 +1,359 @@
|
|
|
1
|
-
# Label
|
|
2
|
-
|
|
3
|
-
Etiqueta accesible asociada con controles de formulario. Basado en Radix UI Label para accesibilidad mejorada.
|
|
4
|
-
|
|
5
|
-
## Descripción
|
|
6
|
-
|
|
7
|
-
El componente `Label` renderiza una etiqueta accesible asociada con controles de formulario.
|
|
8
|
-
|
|
9
|
-
## Importación
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
import { Label } from "@adamosuiteservices/ui/label";
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Anatomía
|
|
16
|
-
|
|
17
|
-
```tsx
|
|
18
|
-
<Label htmlFor="email">Email</Label>
|
|
19
|
-
<Input id="email" type="email" />
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
**Componentes**: 1 (Label)
|
|
23
|
-
|
|
24
|
-
## Props
|
|
25
|
-
|
|
26
|
-
| Prop | Tipo | Descripción |
|
|
27
|
-
| ----------- | -------- | ------------------------------------------------- |
|
|
28
|
-
| `htmlFor` | `string` | ID del control asociado (conecta label con input) |
|
|
29
|
-
| `className` | `string` | Clases CSS adicionales |
|
|
30
|
-
| ...props | - | Todas las props de Radix UI Label |
|
|
31
|
-
|
|
32
|
-
## Patrones de Uso
|
|
33
|
-
|
|
34
|
-
### Básico con Input
|
|
35
|
-
|
|
36
|
-
```tsx
|
|
37
|
-
import { Input } from "@adamosuiteservices/ui/input";
|
|
38
|
-
|
|
39
|
-
<div className="space-y-2">
|
|
40
|
-
<Label htmlFor="email">Email</Label>
|
|
41
|
-
<Input id="email" type="email" placeholder="Enter your email" />
|
|
42
|
-
</div>;
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Con Checkbox
|
|
46
|
-
|
|
47
|
-
```tsx
|
|
48
|
-
import { Checkbox } from "@adamosuiteservices/ui/checkbox";
|
|
49
|
-
|
|
50
|
-
<div className="flex items-center gap-2">
|
|
51
|
-
<Checkbox id="terms" />
|
|
52
|
-
<Label htmlFor="terms">Accept terms and conditions</Label>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<div className="flex items-center gap-2">
|
|
56
|
-
|
|
57
|
-
<Checkbox id="newsletter" />
|
|
58
|
-
<Label htmlFor="newsletter">Subscribe to our newsletter</Label>
|
|
59
|
-
</div>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Con Radio Group
|
|
63
|
-
|
|
64
|
-
```tsx
|
|
65
|
-
import { RadioGroup, RadioGroupItem } from "@adamosuiteservices/ui/radio-group";
|
|
66
|
-
|
|
67
|
-
<div className="space-y-4">
|
|
68
|
-
<Label>Choose your preferred theme</Label>
|
|
69
|
-
<RadioGroup defaultValue="light" className="space-y-2">
|
|
70
|
-
<div className="flex items-center gap-2">
|
|
71
|
-
<RadioGroupItem value="light" id="light" />
|
|
72
|
-
<Label htmlFor="light">Light</Label>
|
|
73
|
-
</div>
|
|
74
|
-
<div className="flex items-center gap-2">
|
|
75
|
-
<RadioGroupItem value="dark" id="dark" />
|
|
76
|
-
<Label htmlFor="dark">Dark</Label>
|
|
77
|
-
</div>
|
|
78
|
-
<div className="flex items-center gap-2">
|
|
79
|
-
<RadioGroupItem value="system" id="system" />
|
|
80
|
-
<Label htmlFor="system">System</Label>
|
|
81
|
-
</div>
|
|
82
|
-
</RadioGroup>
|
|
83
|
-
</div>;
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Con Switch
|
|
87
|
-
|
|
88
|
-
```tsx
|
|
89
|
-
import { Switch } from "@adamosuiteservices/ui/switch";
|
|
90
|
-
|
|
91
|
-
<div className="flex items-center gap-2">
|
|
92
|
-
<Switch id="notifications" />
|
|
93
|
-
<Label htmlFor="notifications">Enable notifications</Label>
|
|
94
|
-
</div>
|
|
95
|
-
|
|
96
|
-
<div className="flex items-center gap-2">
|
|
97
|
-
<Switch id="analytics" />
|
|
98
|
-
<Label htmlFor="analytics">Allow analytics tracking</Label>
|
|
99
|
-
</div>
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Con Iconos
|
|
103
|
-
|
|
104
|
-
```tsx
|
|
105
|
-
import { Icon } from "@adamosuiteservices/ui/icon";
|
|
106
|
-
import { Input } from "@adamosuiteservices/ui/input";
|
|
107
|
-
|
|
108
|
-
<div className="space-y-6">
|
|
109
|
-
<div className="space-y-2">
|
|
110
|
-
<Label htmlFor="username" className="flex items-center gap-2">
|
|
111
|
-
<Icon symbol="person" className="text-lg" />
|
|
112
|
-
Username
|
|
113
|
-
</Label>
|
|
114
|
-
<Input id="username" placeholder="Enter your username" />
|
|
115
|
-
</div>
|
|
116
|
-
|
|
117
|
-
<div className="space-y-2">
|
|
118
|
-
<Label htmlFor="email" className="flex items-center gap-2">
|
|
119
|
-
<Icon symbol="mail" className="text-lg" />
|
|
120
|
-
Email Address
|
|
121
|
-
</Label>
|
|
122
|
-
<Input id="email" type="email" placeholder="Enter your email" />
|
|
123
|
-
</div>
|
|
124
|
-
|
|
125
|
-
<div className="space-y-2">
|
|
126
|
-
<Label htmlFor="password" className="flex items-center gap-2">
|
|
127
|
-
<Icon symbol="lock" className="text-lg" />
|
|
128
|
-
Password
|
|
129
|
-
</Label>
|
|
130
|
-
<Input id="password" type="password" />
|
|
131
|
-
</div>
|
|
132
|
-
|
|
133
|
-
<div className="space-y-2">
|
|
134
|
-
<Label htmlFor="birthday" className="flex items-center gap-2">
|
|
135
|
-
<Icon symbol="calendar_month" className="text-lg" />
|
|
136
|
-
Date of Birth
|
|
137
|
-
</Label>
|
|
138
|
-
<Input id="birthday" type="date" />
|
|
139
|
-
</div>
|
|
140
|
-
</div>;
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Con Textarea
|
|
144
|
-
|
|
145
|
-
```tsx
|
|
146
|
-
import { Textarea } from "@adamosuiteservices/ui/textarea";
|
|
147
|
-
|
|
148
|
-
<div className="space-y-2">
|
|
149
|
-
<Label htmlFor="message">Message</Label>
|
|
150
|
-
<Textarea id="message" placeholder="Type your message here." />
|
|
151
|
-
</div>
|
|
152
|
-
|
|
153
|
-
<div className="space-y-2">
|
|
154
|
-
<Label htmlFor="feedback">Feedback</Label>
|
|
155
|
-
<Textarea
|
|
156
|
-
id="feedback"
|
|
157
|
-
placeholder="Please share your feedback..."
|
|
158
|
-
className="min-h-[100px]"
|
|
159
|
-
/>
|
|
160
|
-
</div>
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Con Select
|
|
164
|
-
|
|
165
|
-
```tsx
|
|
166
|
-
import {
|
|
167
|
-
Select,
|
|
168
|
-
SelectContent,
|
|
169
|
-
SelectItem,
|
|
170
|
-
SelectTrigger,
|
|
171
|
-
SelectValue,
|
|
172
|
-
} from "@adamosuiteservices/ui/select";
|
|
173
|
-
|
|
174
|
-
<div className="space-y-2">
|
|
175
|
-
<Label htmlFor="country">Country</Label>
|
|
176
|
-
<Select>
|
|
177
|
-
<SelectTrigger id="country">
|
|
178
|
-
<SelectValue placeholder="Select a country" />
|
|
179
|
-
</SelectTrigger>
|
|
180
|
-
<SelectContent>
|
|
181
|
-
<SelectItem value="us">United States</SelectItem>
|
|
182
|
-
<SelectItem value="uk">United Kingdom</SelectItem>
|
|
183
|
-
<SelectItem value="ca">Canada</SelectItem>
|
|
184
|
-
</SelectContent>
|
|
185
|
-
</Select>
|
|
186
|
-
</div>;
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Campos Requeridos
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
import { Input } from "@adamosuiteservices/ui/input";
|
|
193
|
-
|
|
194
|
-
<div className="space-y-2">
|
|
195
|
-
<Label htmlFor="required-email">
|
|
196
|
-
Email Address <span className="text-destructive">*</span>
|
|
197
|
-
</Label>
|
|
198
|
-
<Input id="required-email" type="email" placeholder="Enter your email" required />
|
|
199
|
-
</div>
|
|
200
|
-
|
|
201
|
-
<div className="space-y-2">
|
|
202
|
-
<Label htmlFor="required-name">
|
|
203
|
-
Full Name <span className="text-destructive">*</span>
|
|
204
|
-
</Label>
|
|
205
|
-
<Input id="required-name" placeholder="Enter your full name" required />
|
|
206
|
-
</div>
|
|
207
|
-
|
|
208
|
-
<div className="space-y-2">
|
|
209
|
-
<Label htmlFor="optional-phone">
|
|
210
|
-
Phone Number <span className="text-muted-foreground text-xs">(optional)</span>
|
|
211
|
-
</Label>
|
|
212
|
-
<Input id="optional-phone" type="tel" placeholder="Enter your phone number" />
|
|
213
|
-
</div>
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Con Descripción
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
import { Input } from "@adamosuiteservices/ui/input";
|
|
220
|
-
|
|
221
|
-
<div className="space-y-2">
|
|
222
|
-
<Label htmlFor="username">Username</Label>
|
|
223
|
-
<Input id="username" placeholder="johndoe" />
|
|
224
|
-
<p className="text-sm text-muted-foreground">
|
|
225
|
-
This will be your public display name.
|
|
226
|
-
</p>
|
|
227
|
-
</div>;
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### En Formulario Completo
|
|
231
|
-
|
|
232
|
-
```tsx
|
|
233
|
-
import { Input } from "@adamosuiteservices/ui/input";
|
|
234
|
-
import { Button } from "@adamosuiteservices/ui/button";
|
|
235
|
-
import { Checkbox } from "@adamosuiteservices/ui/checkbox";
|
|
236
|
-
|
|
237
|
-
<form className="space-y-6 max-w-md">
|
|
238
|
-
<div className="space-y-2">
|
|
239
|
-
<Label htmlFor="name">Name</Label>
|
|
240
|
-
<Input id="name" placeholder="John Doe" />
|
|
241
|
-
</div>
|
|
242
|
-
|
|
243
|
-
<div className="space-y-2">
|
|
244
|
-
<Label htmlFor="email">Email</Label>
|
|
245
|
-
<Input id="email" type="email" placeholder="john@example.com" />
|
|
246
|
-
</div>
|
|
247
|
-
|
|
248
|
-
<div className="space-y-2">
|
|
249
|
-
<Label htmlFor="password">Password</Label>
|
|
250
|
-
<Input id="password" type="password" />
|
|
251
|
-
</div>
|
|
252
|
-
|
|
253
|
-
<div className="flex items-center gap-2">
|
|
254
|
-
<Checkbox id="remember" />
|
|
255
|
-
<Label htmlFor="remember">Remember me</Label>
|
|
256
|
-
</div>
|
|
257
|
-
|
|
258
|
-
<Button type="submit" className="w-full">
|
|
259
|
-
Sign Up
|
|
260
|
-
</Button>
|
|
261
|
-
</form>;
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## Casos de Uso Comunes
|
|
265
|
-
|
|
266
|
-
**Forms**: Etiquetas para inputs, selects, textareas
|
|
267
|
-
**Checkboxes**: Labels clickeables junto a checkboxes
|
|
268
|
-
**Radio groups**: Labels para cada opción de radio
|
|
269
|
-
**Switches**: Descripción de toggles
|
|
270
|
-
**Required fields**: Marcar campos obligatorios con asterisco
|
|
271
|
-
**Accessibility**: Asociación semántica label-input
|
|
272
|
-
|
|
273
|
-
## Estilos Base
|
|
274
|
-
|
|
275
|
-
- **Display**: `flex items-center gap-2`
|
|
276
|
-
- **Font**: `text-sm font-medium`
|
|
277
|
-
- **Line height**: `leading-none`
|
|
278
|
-
- **Select**: `select-none` (no seleccionable)
|
|
279
|
-
- **Peer disabled**: `peer-disabled:cursor-not-allowed peer-disabled:opacity-50`
|
|
280
|
-
- **Group disabled**: `group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50`
|
|
281
|
-
|
|
282
|
-
## Estados
|
|
283
|
-
|
|
284
|
-
### Disabled via Peer
|
|
285
|
-
|
|
286
|
-
Cuando el input asociado (`peer`) está disabled:
|
|
287
|
-
|
|
288
|
-
```tsx
|
|
289
|
-
<Input id="disabled" disabled className="peer" />
|
|
290
|
-
<Label htmlFor="disabled">Disabled field</Label>
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
→ Label automáticamente `opacity-50` y `cursor-not-allowed`
|
|
294
|
-
|
|
295
|
-
### Disabled via Group
|
|
296
|
-
|
|
297
|
-
Cuando el contenedor tiene `data-disabled`:
|
|
298
|
-
|
|
299
|
-
```tsx
|
|
300
|
-
<div data-disabled="true">
|
|
301
|
-
<Label htmlFor="field">Field</Label>
|
|
302
|
-
<Input id="field" disabled />
|
|
303
|
-
</div>
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
→ Label automáticamente `opacity-50` y `pointer-events-none`
|
|
307
|
-
|
|
308
|
-
## Accesibilidad
|
|
309
|
-
|
|
310
|
-
- ✅ **Radix UI**: Basado en primitiva de Radix UI con accesibilidad completa
|
|
311
|
-
- ✅ **htmlFor**: Asocia label con control usando `htmlFor` e `id`
|
|
312
|
-
- ✅ **Click target**: Todo el label es clickeable, hace focus al input
|
|
313
|
-
- ✅ **Screen readers**: Anuncia label cuando input recibe focus
|
|
314
|
-
- ✅ **Required**: Marca campos requeridos con asterisco visible
|
|
315
|
-
- ✅ **Disabled**: Estado disabled automático via peer o group
|
|
316
|
-
- ⚠️ **Description**: Usa `aria-describedby` para textos de ayuda
|
|
317
|
-
|
|
318
|
-
## Notas de Implementación
|
|
319
|
-
|
|
320
|
-
- **Radix UI**: Wrapper sobre `@radix-ui/react-label`
|
|
321
|
-
- **Peer awareness**: Detecta input disabled via clase `peer`
|
|
322
|
-
- **Group awareness**: Detecta container disabled via `data-disabled`
|
|
323
|
-
- **Gap auto**: `gap-2` entre icono y texto si hay icono
|
|
324
|
-
- **Clickeable**: Todo el label hace focus al control asociado
|
|
325
|
-
- **Non-selectable**: `select-none` para evitar selección accidental
|
|
326
|
-
- **Flex**: Display flex para alinear iconos fácilmente
|
|
327
|
-
|
|
328
|
-
## htmlFor vs Wrapping
|
|
329
|
-
|
|
330
|
-
```tsx
|
|
331
|
-
{/* Recomendado: htmlFor */}
|
|
332
|
-
<Label htmlFor="email">Email</Label>
|
|
333
|
-
<Input id="email" />
|
|
334
|
-
|
|
335
|
-
{/* No recomendado: wrapping */}
|
|
336
|
-
<Label>
|
|
337
|
-
Email
|
|
338
|
-
<Input />
|
|
339
|
-
</Label>
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
**Usa htmlFor**: Mejor separación, más flexible con layouts, funciona con todos los componentes.
|
|
343
|
-
|
|
344
|
-
## Troubleshooting
|
|
345
|
-
|
|
346
|
-
**Label no hace click**: Verifica que `htmlFor` e `id` coincidan exactamente
|
|
347
|
-
**Disabled no funciona**: Asegúrate de usar `peer` className en el input o `data-disabled` en container
|
|
348
|
-
**Gap no se ve**: Label tiene `gap-2` por defecto, verifica que haya múltiples children
|
|
349
|
-
**Icono desalineado**: Label tiene `items-center`, verifica que el icono tenga tamaño adecuado
|
|
350
|
-
**Required asterisco no se ve**: Usa `<span className="text-destructive">*</span>`
|
|
351
|
-
**Texto muy grande**: Label es `text-sm`, ajusta con className si necesario
|
|
352
|
-
**No seleccionable**: Label tiene `select-none`, normal behavior
|
|
353
|
-
**Peer disabled no aplica**: El input debe tener `className="peer"` además de `disabled`
|
|
354
|
-
|
|
355
|
-
## Referencias
|
|
356
|
-
|
|
357
|
-
- **Radix UI Label**: <https://www.radix-ui.com/primitives/docs/components/label>
|
|
358
|
-
- **shadcn/ui Label**: <https://ui.shadcn.com/docs/components/label>
|
|
359
|
-
- **WAI-ARIA Label**: <https://www.w3.org/WAI/ARIA/apg/patterns/label/>
|
|
1
|
+
# Label
|
|
2
|
+
|
|
3
|
+
Etiqueta accesible asociada con controles de formulario. Basado en Radix UI Label para accesibilidad mejorada.
|
|
4
|
+
|
|
5
|
+
## Descripción
|
|
6
|
+
|
|
7
|
+
El componente `Label` renderiza una etiqueta accesible asociada con controles de formulario.
|
|
8
|
+
|
|
9
|
+
## Importación
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { Label } from "@adamosuiteservices/ui/label";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Anatomía
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Label htmlFor="email">Email</Label>
|
|
19
|
+
<Input id="email" type="email" />
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Componentes**: 1 (Label)
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
| Prop | Tipo | Descripción |
|
|
27
|
+
| ----------- | -------- | ------------------------------------------------- |
|
|
28
|
+
| `htmlFor` | `string` | ID del control asociado (conecta label con input) |
|
|
29
|
+
| `className` | `string` | Clases CSS adicionales |
|
|
30
|
+
| ...props | - | Todas las props de Radix UI Label |
|
|
31
|
+
|
|
32
|
+
## Patrones de Uso
|
|
33
|
+
|
|
34
|
+
### Básico con Input
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { Input } from "@adamosuiteservices/ui/input";
|
|
38
|
+
|
|
39
|
+
<div className="space-y-2">
|
|
40
|
+
<Label htmlFor="email">Email</Label>
|
|
41
|
+
<Input id="email" type="email" placeholder="Enter your email" />
|
|
42
|
+
</div>;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Con Checkbox
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { Checkbox } from "@adamosuiteservices/ui/checkbox";
|
|
49
|
+
|
|
50
|
+
<div className="flex items-center gap-2">
|
|
51
|
+
<Checkbox id="terms" />
|
|
52
|
+
<Label htmlFor="terms">Accept terms and conditions</Label>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div className="flex items-center gap-2">
|
|
56
|
+
|
|
57
|
+
<Checkbox id="newsletter" />
|
|
58
|
+
<Label htmlFor="newsletter">Subscribe to our newsletter</Label>
|
|
59
|
+
</div>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Con Radio Group
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { RadioGroup, RadioGroupItem } from "@adamosuiteservices/ui/radio-group";
|
|
66
|
+
|
|
67
|
+
<div className="space-y-4">
|
|
68
|
+
<Label>Choose your preferred theme</Label>
|
|
69
|
+
<RadioGroup defaultValue="light" className="space-y-2">
|
|
70
|
+
<div className="flex items-center gap-2">
|
|
71
|
+
<RadioGroupItem value="light" id="light" />
|
|
72
|
+
<Label htmlFor="light">Light</Label>
|
|
73
|
+
</div>
|
|
74
|
+
<div className="flex items-center gap-2">
|
|
75
|
+
<RadioGroupItem value="dark" id="dark" />
|
|
76
|
+
<Label htmlFor="dark">Dark</Label>
|
|
77
|
+
</div>
|
|
78
|
+
<div className="flex items-center gap-2">
|
|
79
|
+
<RadioGroupItem value="system" id="system" />
|
|
80
|
+
<Label htmlFor="system">System</Label>
|
|
81
|
+
</div>
|
|
82
|
+
</RadioGroup>
|
|
83
|
+
</div>;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Con Switch
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { Switch } from "@adamosuiteservices/ui/switch";
|
|
90
|
+
|
|
91
|
+
<div className="flex items-center gap-2">
|
|
92
|
+
<Switch id="notifications" />
|
|
93
|
+
<Label htmlFor="notifications">Enable notifications</Label>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div className="flex items-center gap-2">
|
|
97
|
+
<Switch id="analytics" />
|
|
98
|
+
<Label htmlFor="analytics">Allow analytics tracking</Label>
|
|
99
|
+
</div>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Con Iconos
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { Icon } from "@adamosuiteservices/ui/icon";
|
|
106
|
+
import { Input } from "@adamosuiteservices/ui/input";
|
|
107
|
+
|
|
108
|
+
<div className="space-y-6">
|
|
109
|
+
<div className="space-y-2">
|
|
110
|
+
<Label htmlFor="username" className="flex items-center gap-2">
|
|
111
|
+
<Icon symbol="person" className="text-lg" />
|
|
112
|
+
Username
|
|
113
|
+
</Label>
|
|
114
|
+
<Input id="username" placeholder="Enter your username" />
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div className="space-y-2">
|
|
118
|
+
<Label htmlFor="email" className="flex items-center gap-2">
|
|
119
|
+
<Icon symbol="mail" className="text-lg" />
|
|
120
|
+
Email Address
|
|
121
|
+
</Label>
|
|
122
|
+
<Input id="email" type="email" placeholder="Enter your email" />
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<div className="space-y-2">
|
|
126
|
+
<Label htmlFor="password" className="flex items-center gap-2">
|
|
127
|
+
<Icon symbol="lock" className="text-lg" />
|
|
128
|
+
Password
|
|
129
|
+
</Label>
|
|
130
|
+
<Input id="password" type="password" />
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<div className="space-y-2">
|
|
134
|
+
<Label htmlFor="birthday" className="flex items-center gap-2">
|
|
135
|
+
<Icon symbol="calendar_month" className="text-lg" />
|
|
136
|
+
Date of Birth
|
|
137
|
+
</Label>
|
|
138
|
+
<Input id="birthday" type="date" />
|
|
139
|
+
</div>
|
|
140
|
+
</div>;
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Con Textarea
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { Textarea } from "@adamosuiteservices/ui/textarea";
|
|
147
|
+
|
|
148
|
+
<div className="space-y-2">
|
|
149
|
+
<Label htmlFor="message">Message</Label>
|
|
150
|
+
<Textarea id="message" placeholder="Type your message here." />
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<div className="space-y-2">
|
|
154
|
+
<Label htmlFor="feedback">Feedback</Label>
|
|
155
|
+
<Textarea
|
|
156
|
+
id="feedback"
|
|
157
|
+
placeholder="Please share your feedback..."
|
|
158
|
+
className="min-h-[100px]"
|
|
159
|
+
/>
|
|
160
|
+
</div>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Con Select
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
import {
|
|
167
|
+
Select,
|
|
168
|
+
SelectContent,
|
|
169
|
+
SelectItem,
|
|
170
|
+
SelectTrigger,
|
|
171
|
+
SelectValue,
|
|
172
|
+
} from "@adamosuiteservices/ui/select";
|
|
173
|
+
|
|
174
|
+
<div className="space-y-2">
|
|
175
|
+
<Label htmlFor="country">Country</Label>
|
|
176
|
+
<Select>
|
|
177
|
+
<SelectTrigger id="country">
|
|
178
|
+
<SelectValue placeholder="Select a country" />
|
|
179
|
+
</SelectTrigger>
|
|
180
|
+
<SelectContent>
|
|
181
|
+
<SelectItem value="us">United States</SelectItem>
|
|
182
|
+
<SelectItem value="uk">United Kingdom</SelectItem>
|
|
183
|
+
<SelectItem value="ca">Canada</SelectItem>
|
|
184
|
+
</SelectContent>
|
|
185
|
+
</Select>
|
|
186
|
+
</div>;
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Campos Requeridos
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
import { Input } from "@adamosuiteservices/ui/input";
|
|
193
|
+
|
|
194
|
+
<div className="space-y-2">
|
|
195
|
+
<Label htmlFor="required-email">
|
|
196
|
+
Email Address <span className="text-destructive">*</span>
|
|
197
|
+
</Label>
|
|
198
|
+
<Input id="required-email" type="email" placeholder="Enter your email" required />
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<div className="space-y-2">
|
|
202
|
+
<Label htmlFor="required-name">
|
|
203
|
+
Full Name <span className="text-destructive">*</span>
|
|
204
|
+
</Label>
|
|
205
|
+
<Input id="required-name" placeholder="Enter your full name" required />
|
|
206
|
+
</div>
|
|
207
|
+
|
|
208
|
+
<div className="space-y-2">
|
|
209
|
+
<Label htmlFor="optional-phone">
|
|
210
|
+
Phone Number <span className="text-muted-foreground text-xs">(optional)</span>
|
|
211
|
+
</Label>
|
|
212
|
+
<Input id="optional-phone" type="tel" placeholder="Enter your phone number" />
|
|
213
|
+
</div>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Con Descripción
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
import { Input } from "@adamosuiteservices/ui/input";
|
|
220
|
+
|
|
221
|
+
<div className="space-y-2">
|
|
222
|
+
<Label htmlFor="username">Username</Label>
|
|
223
|
+
<Input id="username" placeholder="johndoe" />
|
|
224
|
+
<p className="text-sm text-muted-foreground">
|
|
225
|
+
This will be your public display name.
|
|
226
|
+
</p>
|
|
227
|
+
</div>;
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### En Formulario Completo
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import { Input } from "@adamosuiteservices/ui/input";
|
|
234
|
+
import { Button } from "@adamosuiteservices/ui/button";
|
|
235
|
+
import { Checkbox } from "@adamosuiteservices/ui/checkbox";
|
|
236
|
+
|
|
237
|
+
<form className="space-y-6 max-w-md">
|
|
238
|
+
<div className="space-y-2">
|
|
239
|
+
<Label htmlFor="name">Name</Label>
|
|
240
|
+
<Input id="name" placeholder="John Doe" />
|
|
241
|
+
</div>
|
|
242
|
+
|
|
243
|
+
<div className="space-y-2">
|
|
244
|
+
<Label htmlFor="email">Email</Label>
|
|
245
|
+
<Input id="email" type="email" placeholder="john@example.com" />
|
|
246
|
+
</div>
|
|
247
|
+
|
|
248
|
+
<div className="space-y-2">
|
|
249
|
+
<Label htmlFor="password">Password</Label>
|
|
250
|
+
<Input id="password" type="password" />
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<div className="flex items-center gap-2">
|
|
254
|
+
<Checkbox id="remember" />
|
|
255
|
+
<Label htmlFor="remember">Remember me</Label>
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<Button type="submit" className="w-full">
|
|
259
|
+
Sign Up
|
|
260
|
+
</Button>
|
|
261
|
+
</form>;
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Casos de Uso Comunes
|
|
265
|
+
|
|
266
|
+
**Forms**: Etiquetas para inputs, selects, textareas
|
|
267
|
+
**Checkboxes**: Labels clickeables junto a checkboxes
|
|
268
|
+
**Radio groups**: Labels para cada opción de radio
|
|
269
|
+
**Switches**: Descripción de toggles
|
|
270
|
+
**Required fields**: Marcar campos obligatorios con asterisco
|
|
271
|
+
**Accessibility**: Asociación semántica label-input
|
|
272
|
+
|
|
273
|
+
## Estilos Base
|
|
274
|
+
|
|
275
|
+
- **Display**: `flex items-center gap-2`
|
|
276
|
+
- **Font**: `text-sm font-medium`
|
|
277
|
+
- **Line height**: `leading-none`
|
|
278
|
+
- **Select**: `select-none` (no seleccionable)
|
|
279
|
+
- **Peer disabled**: `peer-disabled:cursor-not-allowed peer-disabled:opacity-50`
|
|
280
|
+
- **Group disabled**: `group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50`
|
|
281
|
+
|
|
282
|
+
## Estados
|
|
283
|
+
|
|
284
|
+
### Disabled via Peer
|
|
285
|
+
|
|
286
|
+
Cuando el input asociado (`peer`) está disabled:
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
<Input id="disabled" disabled className="peer" />
|
|
290
|
+
<Label htmlFor="disabled">Disabled field</Label>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
→ Label automáticamente `opacity-50` y `cursor-not-allowed`
|
|
294
|
+
|
|
295
|
+
### Disabled via Group
|
|
296
|
+
|
|
297
|
+
Cuando el contenedor tiene `data-disabled`:
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
<div data-disabled="true">
|
|
301
|
+
<Label htmlFor="field">Field</Label>
|
|
302
|
+
<Input id="field" disabled />
|
|
303
|
+
</div>
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
→ Label automáticamente `opacity-50` y `pointer-events-none`
|
|
307
|
+
|
|
308
|
+
## Accesibilidad
|
|
309
|
+
|
|
310
|
+
- ✅ **Radix UI**: Basado en primitiva de Radix UI con accesibilidad completa
|
|
311
|
+
- ✅ **htmlFor**: Asocia label con control usando `htmlFor` e `id`
|
|
312
|
+
- ✅ **Click target**: Todo el label es clickeable, hace focus al input
|
|
313
|
+
- ✅ **Screen readers**: Anuncia label cuando input recibe focus
|
|
314
|
+
- ✅ **Required**: Marca campos requeridos con asterisco visible
|
|
315
|
+
- ✅ **Disabled**: Estado disabled automático via peer o group
|
|
316
|
+
- ⚠️ **Description**: Usa `aria-describedby` para textos de ayuda
|
|
317
|
+
|
|
318
|
+
## Notas de Implementación
|
|
319
|
+
|
|
320
|
+
- **Radix UI**: Wrapper sobre `@radix-ui/react-label`
|
|
321
|
+
- **Peer awareness**: Detecta input disabled via clase `peer`
|
|
322
|
+
- **Group awareness**: Detecta container disabled via `data-disabled`
|
|
323
|
+
- **Gap auto**: `gap-2` entre icono y texto si hay icono
|
|
324
|
+
- **Clickeable**: Todo el label hace focus al control asociado
|
|
325
|
+
- **Non-selectable**: `select-none` para evitar selección accidental
|
|
326
|
+
- **Flex**: Display flex para alinear iconos fácilmente
|
|
327
|
+
|
|
328
|
+
## htmlFor vs Wrapping
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
{/* Recomendado: htmlFor */}
|
|
332
|
+
<Label htmlFor="email">Email</Label>
|
|
333
|
+
<Input id="email" />
|
|
334
|
+
|
|
335
|
+
{/* No recomendado: wrapping */}
|
|
336
|
+
<Label>
|
|
337
|
+
Email
|
|
338
|
+
<Input />
|
|
339
|
+
</Label>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**Usa htmlFor**: Mejor separación, más flexible con layouts, funciona con todos los componentes.
|
|
343
|
+
|
|
344
|
+
## Troubleshooting
|
|
345
|
+
|
|
346
|
+
**Label no hace click**: Verifica que `htmlFor` e `id` coincidan exactamente
|
|
347
|
+
**Disabled no funciona**: Asegúrate de usar `peer` className en el input o `data-disabled` en container
|
|
348
|
+
**Gap no se ve**: Label tiene `gap-2` por defecto, verifica que haya múltiples children
|
|
349
|
+
**Icono desalineado**: Label tiene `items-center`, verifica que el icono tenga tamaño adecuado
|
|
350
|
+
**Required asterisco no se ve**: Usa `<span className="text-destructive">*</span>`
|
|
351
|
+
**Texto muy grande**: Label es `text-sm`, ajusta con className si necesario
|
|
352
|
+
**No seleccionable**: Label tiene `select-none`, normal behavior
|
|
353
|
+
**Peer disabled no aplica**: El input debe tener `className="peer"` además de `disabled`
|
|
354
|
+
|
|
355
|
+
## Referencias
|
|
356
|
+
|
|
357
|
+
- **Radix UI Label**: <https://www.radix-ui.com/primitives/docs/components/label>
|
|
358
|
+
- **shadcn/ui Label**: <https://ui.shadcn.com/docs/components/label>
|
|
359
|
+
- **WAI-ARIA Label**: <https://www.w3.org/WAI/ARIA/apg/patterns/label/>
|