@adamosuiteservices/ui 2.11.20 → 2.12.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/dist/accordion-rounded.cjs +1 -1
- package/dist/accordion-rounded.js +1 -1
- package/dist/{button-BzVY7053.js → button-CMWUcYpz.js} +54 -54
- package/dist/button-CmLeuaI0.cjs +75 -0
- package/dist/button-group.cjs +6 -6
- package/dist/button-group.js +20 -20
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/{calendar-IAVS_7up.cjs → calendar-DUvRetFW.cjs} +1 -1
- package/dist/{calendar-BIttOd3g.js → calendar-yJWQTCer.js} +1 -1
- package/dist/calendar.cjs +1 -1
- package/dist/calendar.js +1 -1
- package/dist/combobox-BhDOduAb.cjs +40 -0
- package/dist/{combobox-DI-WK3Ng.js → combobox-CYOGlfQe.js} +91 -88
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.js +1 -1
- package/dist/components/ui/button/button.d.ts +1 -1
- package/dist/components/ui/input-otp/index.d.ts +1 -0
- package/dist/components/ui/input-otp/input-otp.d.ts +11 -0
- package/dist/components/ui/input-otp.d.ts +11 -0
- package/dist/context-menu.cjs +38 -36
- package/dist/context-menu.js +54 -52
- package/dist/date-picker-selector.cjs +1 -1
- package/dist/date-picker-selector.js +4 -4
- package/dist/dropdown-menu.cjs +48 -52
- package/dist/dropdown-menu.js +164 -168
- package/dist/{input-DFvZLcgm.js → input-BCiOr4Fy.js} +7 -6
- package/dist/{input-CWDpI1Ua.cjs → input-Bz5k4w94.cjs} +7 -6
- package/dist/input-group.cjs +5 -5
- package/dist/input-group.js +10 -10
- package/dist/input-otp.cjs +68 -0
- package/dist/input-otp.js +384 -0
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/pagination.cjs +2 -2
- package/dist/pagination.js +4 -3
- package/dist/select.cjs +22 -20
- package/dist/select.js +112 -111
- package/dist/sidebar.cjs +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/styles.css +1 -1
- package/docs/components/ui/accordion-rounded.md +2 -2
- package/docs/components/ui/button-group.md +986 -984
- package/docs/components/ui/button.md +1156 -1137
- package/docs/components/ui/combobox.md +33 -2
- package/docs/components/ui/command.md +484 -454
- package/docs/components/ui/context-menu.md +574 -540
- package/docs/components/ui/dropdown-menu.md +743 -709
- package/docs/components/ui/input.md +362 -362
- package/docs/components/ui/select.md +357 -352
- package/package.json +8 -3
- package/dist/button-B_VHdPPV.cjs +0 -76
- package/dist/combobox-DplJzBX6.cjs +0 -37
|
@@ -1,362 +1,362 @@
|
|
|
1
|
-
# Input Component
|
|
2
|
-
|
|
3
|
-
Campo de entrada de formulario estilizado. Wrapper sobre `<input>` HTML nativo con estilos consistentes, validación visual y soporte para todos los tipos nativos.
|
|
4
|
-
|
|
5
|
-
## Descripción
|
|
6
|
-
|
|
7
|
-
El componente `Input` muestra un campo de entrada de formulario o un componente que luce como un campo de entrada.
|
|
8
|
-
|
|
9
|
-
## Importación
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
import { Input } from "@adamosuiteservices/ui/input";
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Uso Básico
|
|
16
|
-
|
|
17
|
-
```tsx
|
|
18
|
-
<Input type="email" placeholder="Email" />
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**Componentes**: 1 (Input)
|
|
22
|
-
|
|
23
|
-
## Con Label
|
|
24
|
-
|
|
25
|
-
```tsx
|
|
26
|
-
<div className="grid w-full max-w-sm items-center gap-2">
|
|
27
|
-
<Label htmlFor="email">Email</Label>
|
|
28
|
-
<Input type="email" id="email" placeholder="Email" />
|
|
29
|
-
</div>
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Con Botón
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
<div className="flex w-full max-w-sm items-center gap-2">
|
|
36
|
-
<Input type="email" placeholder="Email" />
|
|
37
|
-
<Button type="submit" variant="outline">
|
|
38
|
-
Subscribe
|
|
39
|
-
</Button>
|
|
40
|
-
</div>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Tipos de Input
|
|
44
|
-
|
|
45
|
-
### Email
|
|
46
|
-
|
|
47
|
-
```tsx
|
|
48
|
-
<Input type="email" placeholder="correo@ejemplo.com" />
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Password
|
|
52
|
-
|
|
53
|
-
```tsx
|
|
54
|
-
<Input type="password" placeholder="Contraseña" />
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Number
|
|
58
|
-
|
|
59
|
-
```tsx
|
|
60
|
-
<Input type="number" placeholder="Edad" />
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Text
|
|
64
|
-
|
|
65
|
-
```tsx
|
|
66
|
-
<Input type="text" placeholder="Nombre" />
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Search
|
|
70
|
-
|
|
71
|
-
```tsx
|
|
72
|
-
<Input type="search" placeholder="Buscar..." />
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### URL
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
<Input type="url" placeholder="https://ejemplo.com" />
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Tel
|
|
82
|
-
|
|
83
|
-
```tsx
|
|
84
|
-
<Input type="tel" placeholder="+1 (555) 123-4567" />
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Date
|
|
88
|
-
|
|
89
|
-
```tsx
|
|
90
|
-
<Input type="date" />
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### File
|
|
94
|
-
|
|
95
|
-
```tsx
|
|
96
|
-
<div className="grid w-full max-w-sm items-center gap-2">
|
|
97
|
-
<Label htmlFor="picture">Picture</Label>
|
|
98
|
-
<Input id="picture" type="file" />
|
|
99
|
-
</div>
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Estados
|
|
103
|
-
|
|
104
|
-
### Disabled
|
|
105
|
-
|
|
106
|
-
```tsx
|
|
107
|
-
<Input disabled type="email" placeholder="Email" />
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### ReadOnly
|
|
111
|
-
|
|
112
|
-
```tsx
|
|
113
|
-
<Input readOnly value="Solo lectura" />
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Invalid
|
|
117
|
-
|
|
118
|
-
```tsx
|
|
119
|
-
<Input
|
|
120
|
-
type="email"
|
|
121
|
-
placeholder="Enter email"
|
|
122
|
-
aria-invalid
|
|
123
|
-
defaultValue="invalid-email"
|
|
124
|
-
/>
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Tamaños Personalizados
|
|
128
|
-
|
|
129
|
-
```tsx
|
|
130
|
-
{
|
|
131
|
-
/* Pequeño */
|
|
132
|
-
}
|
|
133
|
-
<Input type="text" placeholder="Small input" className="h-
|
|
134
|
-
|
|
135
|
-
{
|
|
136
|
-
/* Por defecto */
|
|
137
|
-
}
|
|
138
|
-
<Input type="text" placeholder="Default input" />;
|
|
139
|
-
|
|
140
|
-
{
|
|
141
|
-
/* Grande */
|
|
142
|
-
}
|
|
143
|
-
<Input type="text" placeholder="Large input" className="h-
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Con Validación
|
|
147
|
-
|
|
148
|
-
```tsx
|
|
149
|
-
<div className="space-y-2">
|
|
150
|
-
<Label htmlFor="email">Email</Label>
|
|
151
|
-
<Input
|
|
152
|
-
id="email"
|
|
153
|
-
type="email"
|
|
154
|
-
placeholder="correo@ejemplo.com"
|
|
155
|
-
aria-invalid={hasError}
|
|
156
|
-
/>
|
|
157
|
-
{hasError && <p className="text-destructive text-sm">Email inválido</p>}
|
|
158
|
-
</div>
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## Props
|
|
162
|
-
|
|
163
|
-
| Prop | Tipo | Default | Descripción |
|
|
164
|
-
| ------------ | ------------------------------------------------------------------------------------------------------- | -------- | ---------------------------- |
|
|
165
|
-
| type | `"text" \| "email" \| "password" \| "number" \| "file" \| "search" \| "url" \| "tel" \| "date" \| etc.` | `"text"` | Tipo de input HTML nativo |
|
|
166
|
-
| placeholder | `string` | - | Texto placeholder |
|
|
167
|
-
| disabled | `boolean` | `false` | Desactiva el input |
|
|
168
|
-
| readOnly | `boolean` | `false` | Input solo lectura |
|
|
169
|
-
| value | `string \| number` | - | Valor controlado |
|
|
170
|
-
| defaultValue | `string \| number` | - | Valor inicial no controlado |
|
|
171
|
-
| onChange | `(e) => void` | - | Callback al cambiar valor |
|
|
172
|
-
| aria-invalid | `boolean` | `false` | Marca el input como inválido |
|
|
173
|
-
| className | `string` | - | Clases CSS adicionales |
|
|
174
|
-
|
|
175
|
-
## Características del Estilo
|
|
176
|
-
|
|
177
|
-
### Focus
|
|
178
|
-
|
|
179
|
-
El input tiene un anillo de enfoque visible:
|
|
180
|
-
|
|
181
|
-
```css
|
|
182
|
-
focus-visible:ring-ring/50
|
|
183
|
-
focus-visible:ring-[3px]
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Estados de Validación
|
|
187
|
-
|
|
188
|
-
- Borde normal: `border-input`
|
|
189
|
-
- Inválido: `aria-invalid:border-destructive` con anillo rojo
|
|
190
|
-
|
|
191
|
-
### Modo Oscuro
|
|
192
|
-
|
|
193
|
-
```css
|
|
194
|
-
dark: bg-input/30;
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### File Input
|
|
198
|
-
|
|
199
|
-
Los file inputs tienen estilos especiales para el botón:
|
|
200
|
-
|
|
201
|
-
```css
|
|
202
|
-
file:h-7
|
|
203
|
-
file:text-sm
|
|
204
|
-
file:font-medium
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## Casos de Uso Comunes
|
|
208
|
-
|
|
209
|
-
### Formulario de Login
|
|
210
|
-
|
|
211
|
-
```tsx
|
|
212
|
-
<form className="space-y-4">
|
|
213
|
-
<div className="space-y-2">
|
|
214
|
-
<Label htmlFor="email">Email</Label>
|
|
215
|
-
<Input id="email" type="email" placeholder="correo@ejemplo.com" />
|
|
216
|
-
</div>
|
|
217
|
-
<div className="space-y-2">
|
|
218
|
-
<Label htmlFor="password">Password</Label>
|
|
219
|
-
<Input id="password" type="password" />
|
|
220
|
-
</div>
|
|
221
|
-
<Button type="submit">Iniciar Sesión</Button>
|
|
222
|
-
</form>
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### Búsqueda
|
|
226
|
-
|
|
227
|
-
```tsx
|
|
228
|
-
<div className="flex items-center gap-2">
|
|
229
|
-
<SearchIcon className="h-4 w-4 text-muted-foreground" />
|
|
230
|
-
<Input type="search" placeholder="Buscar..." className="flex-1" />
|
|
231
|
-
</div>
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### Input con Contador
|
|
235
|
-
|
|
236
|
-
```tsx
|
|
237
|
-
const [text, setText] = useState("");
|
|
238
|
-
const maxLength = 100;
|
|
239
|
-
|
|
240
|
-
<div className="space-y-2">
|
|
241
|
-
<Label htmlFor="bio">Bio</Label>
|
|
242
|
-
<Input
|
|
243
|
-
id="bio"
|
|
244
|
-
value={text}
|
|
245
|
-
onChange={(e) => setText(e.target.value)}
|
|
246
|
-
maxLength={maxLength}
|
|
247
|
-
placeholder="Escribe tu bio..."
|
|
248
|
-
/>
|
|
249
|
-
<p className="text-sm text-muted-foreground">
|
|
250
|
-
{text.length} / {maxLength}
|
|
251
|
-
</p>
|
|
252
|
-
</div>;
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
## Accesibilidad
|
|
256
|
-
|
|
257
|
-
- Siempre usa un `<Label>` asociado con el input
|
|
258
|
-
- Usa `aria-invalid` para estados de error
|
|
259
|
-
- Usa `aria-describedby` para mensajes de ayuda
|
|
260
|
-
- Los placeholders no reemplazan a los labels
|
|
261
|
-
- El input soporta navegación por teclado nativa
|
|
262
|
-
|
|
263
|
-
## Notas de Implementación
|
|
264
|
-
|
|
265
|
-
- Usa el prefijo `` en todos los estilos
|
|
266
|
-
- Basado en el elemento HTML `<input>` nativo
|
|
267
|
-
- Soporta todas las props nativas de HTML input
|
|
268
|
-
- Los iconos SVG internos se redimensionan automáticamente
|
|
269
|
-
- Tiene transición suave en color y box-shadow
|
|
270
|
-
|
|
271
|
-
## Referencias
|
|
272
|
-
|
|
273
|
-
- Documentación de shadcn/ui: <https://ui.shadcn.com/docs/components/input>
|
|
274
|
-
- MDN Input: <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input>
|
|
275
|
-
|
|
276
|
-
## Características Avanzadas
|
|
277
|
-
|
|
278
|
-
**Forms**: Inputs en formularios de registro, login, contacto
|
|
279
|
-
**Search**: Barras de búsqueda con `type="search"`
|
|
280
|
-
**File upload**: Selección de archivos con `type="file"`
|
|
281
|
-
**Numbers**: Cantidades, precios, edades con `type="number"`
|
|
282
|
-
**Dates**: Selección de fechas con `type="date"`
|
|
283
|
-
**Validation**: Campos con validación visual via `aria-invalid`
|
|
284
|
-
|
|
285
|
-
## Estados y Data Attributes
|
|
286
|
-
|
|
287
|
-
### Focus
|
|
288
|
-
|
|
289
|
-
- **Focused**: `focus-visible:ring-ring/50`, `focus-visible:ring-[3px]`, `focus-visible:border-ring`
|
|
290
|
-
|
|
291
|
-
### Validation
|
|
292
|
-
|
|
293
|
-
- **Invalid**: `aria-invalid:border-destructive`, `aria-invalid:ring-destructive/20`
|
|
294
|
-
- **Valid**: Border normal `border-input`
|
|
295
|
-
|
|
296
|
-
### Estado Disabled
|
|
297
|
-
|
|
298
|
-
- **Disabled**: `opacity-50`, `pointer-events-none`, `cursor-not-allowed`
|
|
299
|
-
|
|
300
|
-
### Estilos File Input
|
|
301
|
-
|
|
302
|
-
- **File button**: `file:h-
|
|
303
|
-
|
|
304
|
-
## Estilos Base
|
|
305
|
-
|
|
306
|
-
- **Height**: `h-
|
|
307
|
-
- **Border**: `border`, `border-input`, `rounded-md`
|
|
308
|
-
- **Padding**: `px-3
|
|
309
|
-
- **Font**: `text-base md:text-sm`
|
|
310
|
-
- **Shadow**: `shadow-xs`
|
|
311
|
-
- **Background**: `bg-transparent`, `dark:bg-input/30`
|
|
312
|
-
- **Transitions**: `transition-[color,box-shadow]`
|
|
313
|
-
- **Selection**: `selection:bg-primary selection:text-primary-foreground`
|
|
314
|
-
|
|
315
|
-
## Guía de Accesibilidad
|
|
316
|
-
|
|
317
|
-
- ✅ **Label**: Siempre usa `<Label>` asociado con `htmlFor` e `id`
|
|
318
|
-
- ✅ **ARIA**: Usa `aria-invalid` para estados de error
|
|
319
|
-
- ✅ **Description**: Usa `aria-describedby` para mensajes de ayuda
|
|
320
|
-
- ✅ **Placeholder**: No reemplaza label, solo ayuda visual
|
|
321
|
-
- ✅ **Keyboard**: Navegación nativa (Tab, Arrow keys en number/date)
|
|
322
|
-
- ✅ **Required**: Usa `required` para campos obligatorios
|
|
323
|
-
- ✅ **Autocomplete**: Usa `autoComplete` para mejorar UX
|
|
324
|
-
- ⚠️ **Error messages**: Asocia con `aria-describedby` para screen readers
|
|
325
|
-
|
|
326
|
-
## Detalles de Implementación
|
|
327
|
-
|
|
328
|
-
- **HTML nativo**: Wrapper sobre `<input>` con estilos aplicados
|
|
329
|
-
- **Props forwarding**: Acepta todas las props HTML nativas
|
|
330
|
-
- **Validation**: Usa atributos nativos (`required`, `pattern`, `min`, `max`) + `aria-invalid`
|
|
331
|
-
- **File input**: Estilos especiales para el botón "Choose file"
|
|
332
|
-
- **Focus ring**: 3px con 50% opacity para visibilidad sin ser invasivo
|
|
333
|
-
- **Shadow**: Sutil `shadow-xs` para profundidad
|
|
334
|
-
- **Responsive**: `text-base` en mobile, `text-sm` en desktop (`md:`)
|
|
335
|
-
- **Dark mode**: Background semi-transparente `dark:bg-input/30`
|
|
336
|
-
|
|
337
|
-
## Diferencias con Textarea
|
|
338
|
-
|
|
339
|
-
| Aspecto | Input | Textarea |
|
|
340
|
-
| ---------- | --------------------------------- | ------------------------- |
|
|
341
|
-
| **Líneas** | Single-line | Multi-line |
|
|
342
|
-
| **Height** | Fijo (h-9) | Variable (min-h-20) |
|
|
343
|
-
| **Resize** | No | Sí (vertical por defecto) |
|
|
344
|
-
| **Tipos** | Múltiples (email, password, etc.) | Solo text |
|
|
345
|
-
| **Uso** | Datos cortos | Texto largo |
|
|
346
|
-
|
|
347
|
-
## Troubleshooting
|
|
348
|
-
|
|
349
|
-
**Placeholder no se ve**: Verifica color con `placeholder:text-muted-foreground`
|
|
350
|
-
**Focus ring no aparece**: Usa `:focus-visible` no `:focus`, asegúrate de no override con `outline-none` sin ring
|
|
351
|
-
**Estilos no aplican**: Verifica que uses `className` con Tailwind válido
|
|
352
|
-
**File input no se ve bien**: Usa clases `file:*` para estilizar botón
|
|
353
|
-
**Invalid state no funciona**: Asegúrate de usar `aria-invalid` no solo `invalid`
|
|
354
|
-
**Height inconsistente**: Input tiene `h-9` default, usa `className` para override
|
|
355
|
-
**Dark mode no funciona**: Verifica tema configurado y clase `dark:` aplicándose
|
|
356
|
-
**Number input permite texto**: Navegador valida, pero usa validación JS adicional
|
|
357
|
-
|
|
358
|
-
## Referencias Adicionales
|
|
359
|
-
|
|
360
|
-
- **shadcn/ui Input**: <https://ui.shadcn.com/docs/components/input>
|
|
361
|
-
- **MDN Input**: <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input>
|
|
362
|
-
- **WAI-ARIA Input**: <https://www.w3.org/WAI/ARIA/apg/patterns/input/>
|
|
1
|
+
# Input Component
|
|
2
|
+
|
|
3
|
+
Campo de entrada de formulario estilizado. Wrapper sobre `<input>` HTML nativo con estilos consistentes, validación visual y soporte para todos los tipos nativos.
|
|
4
|
+
|
|
5
|
+
## Descripción
|
|
6
|
+
|
|
7
|
+
El componente `Input` muestra un campo de entrada de formulario o un componente que luce como un campo de entrada.
|
|
8
|
+
|
|
9
|
+
## Importación
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { Input } from "@adamosuiteservices/ui/input";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Uso Básico
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Input type="email" placeholder="Email" />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Componentes**: 1 (Input)
|
|
22
|
+
|
|
23
|
+
## Con Label
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
<div className="grid w-full max-w-sm items-center gap-2">
|
|
27
|
+
<Label htmlFor="email">Email</Label>
|
|
28
|
+
<Input type="email" id="email" placeholder="Email" />
|
|
29
|
+
</div>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Con Botón
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<div className="flex w-full max-w-sm items-center gap-2">
|
|
36
|
+
<Input type="email" placeholder="Email" />
|
|
37
|
+
<Button type="submit" variant="outline">
|
|
38
|
+
Subscribe
|
|
39
|
+
</Button>
|
|
40
|
+
</div>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Tipos de Input
|
|
44
|
+
|
|
45
|
+
### Email
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
<Input type="email" placeholder="correo@ejemplo.com" />
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Password
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<Input type="password" placeholder="Contraseña" />
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Number
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
<Input type="number" placeholder="Edad" />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Text
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
<Input type="text" placeholder="Nombre" />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Search
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<Input type="search" placeholder="Buscar..." />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### URL
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
<Input type="url" placeholder="https://ejemplo.com" />
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Tel
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
<Input type="tel" placeholder="+1 (555) 123-4567" />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Date
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<Input type="date" />
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### File
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
<div className="grid w-full max-w-sm items-center gap-2">
|
|
97
|
+
<Label htmlFor="picture">Picture</Label>
|
|
98
|
+
<Input id="picture" type="file" />
|
|
99
|
+
</div>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Estados
|
|
103
|
+
|
|
104
|
+
### Disabled
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
<Input disabled type="email" placeholder="Email" />
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### ReadOnly
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
<Input readOnly value="Solo lectura" />
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Invalid
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<Input
|
|
120
|
+
type="email"
|
|
121
|
+
placeholder="Enter email"
|
|
122
|
+
aria-invalid
|
|
123
|
+
defaultValue="invalid-email"
|
|
124
|
+
/>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Tamaños Personalizados
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
{
|
|
131
|
+
/* Pequeño */
|
|
132
|
+
}
|
|
133
|
+
<Input type="text" placeholder="Small input" className="h-9 text-sm" />;
|
|
134
|
+
|
|
135
|
+
{
|
|
136
|
+
/* Por defecto */
|
|
137
|
+
}
|
|
138
|
+
<Input type="text" placeholder="Default input" />; {/* h-10 por defecto */}
|
|
139
|
+
|
|
140
|
+
{
|
|
141
|
+
/* Grande */
|
|
142
|
+
}
|
|
143
|
+
<Input type="text" placeholder="Large input" className="h-11" />;
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Con Validación
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
<div className="space-y-2">
|
|
150
|
+
<Label htmlFor="email">Email</Label>
|
|
151
|
+
<Input
|
|
152
|
+
id="email"
|
|
153
|
+
type="email"
|
|
154
|
+
placeholder="correo@ejemplo.com"
|
|
155
|
+
aria-invalid={hasError}
|
|
156
|
+
/>
|
|
157
|
+
{hasError && <p className="text-destructive text-sm">Email inválido</p>}
|
|
158
|
+
</div>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Props
|
|
162
|
+
|
|
163
|
+
| Prop | Tipo | Default | Descripción |
|
|
164
|
+
| ------------ | ------------------------------------------------------------------------------------------------------- | -------- | ---------------------------- |
|
|
165
|
+
| type | `"text" \| "email" \| "password" \| "number" \| "file" \| "search" \| "url" \| "tel" \| "date" \| etc.` | `"text"` | Tipo de input HTML nativo |
|
|
166
|
+
| placeholder | `string` | - | Texto placeholder |
|
|
167
|
+
| disabled | `boolean` | `false` | Desactiva el input |
|
|
168
|
+
| readOnly | `boolean` | `false` | Input solo lectura |
|
|
169
|
+
| value | `string \| number` | - | Valor controlado |
|
|
170
|
+
| defaultValue | `string \| number` | - | Valor inicial no controlado |
|
|
171
|
+
| onChange | `(e) => void` | - | Callback al cambiar valor |
|
|
172
|
+
| aria-invalid | `boolean` | `false` | Marca el input como inválido |
|
|
173
|
+
| className | `string` | - | Clases CSS adicionales |
|
|
174
|
+
|
|
175
|
+
## Características del Estilo
|
|
176
|
+
|
|
177
|
+
### Focus
|
|
178
|
+
|
|
179
|
+
El input tiene un anillo de enfoque visible:
|
|
180
|
+
|
|
181
|
+
```css
|
|
182
|
+
focus-visible:ring-ring/50
|
|
183
|
+
focus-visible:ring-[3px]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Estados de Validación
|
|
187
|
+
|
|
188
|
+
- Borde normal: `border-input`
|
|
189
|
+
- Inválido: `aria-invalid:border-destructive` con anillo rojo
|
|
190
|
+
|
|
191
|
+
### Modo Oscuro
|
|
192
|
+
|
|
193
|
+
```css
|
|
194
|
+
dark: bg-input/30;
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### File Input
|
|
198
|
+
|
|
199
|
+
Los file inputs tienen estilos especiales para el botón:
|
|
200
|
+
|
|
201
|
+
```css
|
|
202
|
+
file:h-7
|
|
203
|
+
file:text-sm
|
|
204
|
+
file:font-medium
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Casos de Uso Comunes
|
|
208
|
+
|
|
209
|
+
### Formulario de Login
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
<form className="space-y-4">
|
|
213
|
+
<div className="space-y-2">
|
|
214
|
+
<Label htmlFor="email">Email</Label>
|
|
215
|
+
<Input id="email" type="email" placeholder="correo@ejemplo.com" />
|
|
216
|
+
</div>
|
|
217
|
+
<div className="space-y-2">
|
|
218
|
+
<Label htmlFor="password">Password</Label>
|
|
219
|
+
<Input id="password" type="password" />
|
|
220
|
+
</div>
|
|
221
|
+
<Button type="submit">Iniciar Sesión</Button>
|
|
222
|
+
</form>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Búsqueda
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
<div className="flex items-center gap-2">
|
|
229
|
+
<SearchIcon className="h-4 w-4 text-muted-foreground" />
|
|
230
|
+
<Input type="search" placeholder="Buscar..." className="flex-1" />
|
|
231
|
+
</div>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Input con Contador
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
const [text, setText] = useState("");
|
|
238
|
+
const maxLength = 100;
|
|
239
|
+
|
|
240
|
+
<div className="space-y-2">
|
|
241
|
+
<Label htmlFor="bio">Bio</Label>
|
|
242
|
+
<Input
|
|
243
|
+
id="bio"
|
|
244
|
+
value={text}
|
|
245
|
+
onChange={(e) => setText(e.target.value)}
|
|
246
|
+
maxLength={maxLength}
|
|
247
|
+
placeholder="Escribe tu bio..."
|
|
248
|
+
/>
|
|
249
|
+
<p className="text-sm text-muted-foreground">
|
|
250
|
+
{text.length} / {maxLength}
|
|
251
|
+
</p>
|
|
252
|
+
</div>;
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Accesibilidad
|
|
256
|
+
|
|
257
|
+
- Siempre usa un `<Label>` asociado con el input
|
|
258
|
+
- Usa `aria-invalid` para estados de error
|
|
259
|
+
- Usa `aria-describedby` para mensajes de ayuda
|
|
260
|
+
- Los placeholders no reemplazan a los labels
|
|
261
|
+
- El input soporta navegación por teclado nativa
|
|
262
|
+
|
|
263
|
+
## Notas de Implementación
|
|
264
|
+
|
|
265
|
+
- Usa el prefijo `` en todos los estilos
|
|
266
|
+
- Basado en el elemento HTML `<input>` nativo
|
|
267
|
+
- Soporta todas las props nativas de HTML input
|
|
268
|
+
- Los iconos SVG internos se redimensionan automáticamente
|
|
269
|
+
- Tiene transición suave en color y box-shadow
|
|
270
|
+
|
|
271
|
+
## Referencias
|
|
272
|
+
|
|
273
|
+
- Documentación de shadcn/ui: <https://ui.shadcn.com/docs/components/input>
|
|
274
|
+
- MDN Input: <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input>
|
|
275
|
+
|
|
276
|
+
## Características Avanzadas
|
|
277
|
+
|
|
278
|
+
**Forms**: Inputs en formularios de registro, login, contacto
|
|
279
|
+
**Search**: Barras de búsqueda con `type="search"`
|
|
280
|
+
**File upload**: Selección de archivos con `type="file"`
|
|
281
|
+
**Numbers**: Cantidades, precios, edades con `type="number"`
|
|
282
|
+
**Dates**: Selección de fechas con `type="date"`
|
|
283
|
+
**Validation**: Campos con validación visual via `aria-invalid`
|
|
284
|
+
|
|
285
|
+
## Estados y Data Attributes
|
|
286
|
+
|
|
287
|
+
### Focus
|
|
288
|
+
|
|
289
|
+
- **Focused**: `focus-visible:ring-ring/50`, `focus-visible:ring-[3px]`, `focus-visible:border-ring`
|
|
290
|
+
|
|
291
|
+
### Validation
|
|
292
|
+
|
|
293
|
+
- **Invalid**: `aria-invalid:border-destructive`, `aria-invalid:ring-destructive/20`
|
|
294
|
+
- **Valid**: Border normal `border-input`
|
|
295
|
+
|
|
296
|
+
### Estado Disabled
|
|
297
|
+
|
|
298
|
+
- **Disabled**: `opacity-50`, `pointer-events-none`, `cursor-not-allowed`
|
|
299
|
+
|
|
300
|
+
### Estilos File Input
|
|
301
|
+
|
|
302
|
+
- **File button**: `file:h-full`, `file:items-center`, `file:-ml-3`, `file:pl-3`, `file:mr-3`, `file:text-sm`, `file:font-medium`, `file:bg-transparent`
|
|
303
|
+
|
|
304
|
+
## Estilos Base
|
|
305
|
+
|
|
306
|
+
- **Height**: `h-10` (~40px) por defecto
|
|
307
|
+
- **Border**: `border`, `border-input`, `rounded-md`
|
|
308
|
+
- **Padding**: `px-3` (sin padding vertical, el height define la altura)
|
|
309
|
+
- **Font**: `text-base md:text-sm`
|
|
310
|
+
- **Shadow**: `shadow-xs`
|
|
311
|
+
- **Background**: `bg-transparent`, `dark:bg-input/30`
|
|
312
|
+
- **Transitions**: `transition-[color,box-shadow]`
|
|
313
|
+
- **Selection**: `selection:bg-primary selection:text-primary-foreground`
|
|
314
|
+
|
|
315
|
+
## Guía de Accesibilidad
|
|
316
|
+
|
|
317
|
+
- ✅ **Label**: Siempre usa `<Label>` asociado con `htmlFor` e `id`
|
|
318
|
+
- ✅ **ARIA**: Usa `aria-invalid` para estados de error
|
|
319
|
+
- ✅ **Description**: Usa `aria-describedby` para mensajes de ayuda
|
|
320
|
+
- ✅ **Placeholder**: No reemplaza label, solo ayuda visual
|
|
321
|
+
- ✅ **Keyboard**: Navegación nativa (Tab, Arrow keys en number/date)
|
|
322
|
+
- ✅ **Required**: Usa `required` para campos obligatorios
|
|
323
|
+
- ✅ **Autocomplete**: Usa `autoComplete` para mejorar UX
|
|
324
|
+
- ⚠️ **Error messages**: Asocia con `aria-describedby` para screen readers
|
|
325
|
+
|
|
326
|
+
## Detalles de Implementación
|
|
327
|
+
|
|
328
|
+
- **HTML nativo**: Wrapper sobre `<input>` con estilos aplicados
|
|
329
|
+
- **Props forwarding**: Acepta todas las props HTML nativas
|
|
330
|
+
- **Validation**: Usa atributos nativos (`required`, `pattern`, `min`, `max`) + `aria-invalid`
|
|
331
|
+
- **File input**: Estilos especiales para el botón "Choose file"
|
|
332
|
+
- **Focus ring**: 3px con 50% opacity para visibilidad sin ser invasivo
|
|
333
|
+
- **Shadow**: Sutil `shadow-xs` para profundidad
|
|
334
|
+
- **Responsive**: `text-base` en mobile, `text-sm` en desktop (`md:`)
|
|
335
|
+
- **Dark mode**: Background semi-transparente `dark:bg-input/30`
|
|
336
|
+
|
|
337
|
+
## Diferencias con Textarea
|
|
338
|
+
|
|
339
|
+
| Aspecto | Input | Textarea |
|
|
340
|
+
| ---------- | --------------------------------- | ------------------------- |
|
|
341
|
+
| **Líneas** | Single-line | Multi-line |
|
|
342
|
+
| **Height** | Fijo (h-9) | Variable (min-h-20) |
|
|
343
|
+
| **Resize** | No | Sí (vertical por defecto) |
|
|
344
|
+
| **Tipos** | Múltiples (email, password, etc.) | Solo text |
|
|
345
|
+
| **Uso** | Datos cortos | Texto largo |
|
|
346
|
+
|
|
347
|
+
## Troubleshooting
|
|
348
|
+
|
|
349
|
+
**Placeholder no se ve**: Verifica color con `placeholder:text-muted-foreground`
|
|
350
|
+
**Focus ring no aparece**: Usa `:focus-visible` no `:focus`, asegúrate de no override con `outline-none` sin ring
|
|
351
|
+
**Estilos no aplican**: Verifica que uses `className` con Tailwind válido
|
|
352
|
+
**File input no se ve bien**: Usa clases `file:*` para estilizar botón
|
|
353
|
+
**Invalid state no funciona**: Asegúrate de usar `aria-invalid` no solo `invalid`
|
|
354
|
+
**Height inconsistente**: Input tiene `h-9` default, usa `className` para override
|
|
355
|
+
**Dark mode no funciona**: Verifica tema configurado y clase `dark:` aplicándose
|
|
356
|
+
**Number input permite texto**: Navegador valida, pero usa validación JS adicional
|
|
357
|
+
|
|
358
|
+
## Referencias Adicionales
|
|
359
|
+
|
|
360
|
+
- **shadcn/ui Input**: <https://ui.shadcn.com/docs/components/input>
|
|
361
|
+
- **MDN Input**: <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input>
|
|
362
|
+
- **WAI-ARIA Input**: <https://www.w3.org/WAI/ARIA/apg/patterns/input/>
|