@adamosuiteservices/ui 2.11.14 → 2.11.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/colors.css +1 -1
  2. package/dist/styles.css +1 -1
  3. package/dist/themes.css +1 -1
  4. package/docs/AI-GUIDE.md +321 -321
  5. package/docs/components/layout/sidebar.md +399 -399
  6. package/docs/components/layout/toaster.md +436 -436
  7. package/docs/components/ui/accordion-rounded.md +584 -584
  8. package/docs/components/ui/accordion.md +269 -269
  9. package/docs/components/ui/button-group.md +984 -984
  10. package/docs/components/ui/button.md +1137 -1137
  11. package/docs/components/ui/calendar.md +1159 -1159
  12. package/docs/components/ui/card.md +1455 -1455
  13. package/docs/components/ui/checkbox.md +292 -292
  14. package/docs/components/ui/collapsible.md +323 -323
  15. package/docs/components/ui/command.md +454 -454
  16. package/docs/components/ui/context-menu.md +540 -540
  17. package/docs/components/ui/dialog.md +628 -628
  18. package/docs/components/ui/dropdown-menu.md +709 -709
  19. package/docs/components/ui/field.md +706 -706
  20. package/docs/components/ui/hover-card.md +446 -446
  21. package/docs/components/ui/input.md +362 -362
  22. package/docs/components/ui/kbd.md +434 -434
  23. package/docs/components/ui/label.md +359 -359
  24. package/docs/components/ui/pagination.md +650 -650
  25. package/docs/components/ui/popover.md +536 -536
  26. package/docs/components/ui/progress.md +182 -182
  27. package/docs/components/ui/radio-group.md +311 -311
  28. package/docs/components/ui/select.md +352 -352
  29. package/docs/components/ui/separator.md +214 -214
  30. package/docs/components/ui/sheet.md +142 -142
  31. package/docs/components/ui/skeleton.md +140 -140
  32. package/docs/components/ui/slider.md +341 -341
  33. package/docs/components/ui/spinner.md +170 -170
  34. package/docs/components/ui/switch.md +408 -408
  35. package/docs/components/ui/tabs-underline.md +106 -106
  36. package/docs/components/ui/tabs.md +122 -122
  37. package/docs/components/ui/textarea.md +243 -243
  38. package/docs/components/ui/toggle.md +237 -237
  39. package/docs/components/ui/tooltip.md +317 -317
  40. package/docs/components/ui/typography.md +280 -280
  41. package/package.json +1 -1
@@ -1,352 +1,352 @@
1
- # Select
2
-
3
- Dropdown de selección con búsqueda y scroll. Basado en Radix UI con 10 subcomponentes.
4
-
5
- ## Descripción
6
-
7
- El componente `Select` muestra una lista de opciones en las que el usuario puede seleccionar una opción de la lista.
8
-
9
- ## Importación
10
-
11
- ```typescript
12
- import {
13
- Select,
14
- SelectContent,
15
- SelectGroup,
16
- SelectItem,
17
- SelectLabel,
18
- SelectTrigger,
19
- SelectValue,
20
- } from "@adamosuiteservices/ui/select";
21
- ```
22
-
23
- ## Anatomía
24
-
25
- ```tsx
26
- <Select>
27
- <SelectTrigger className="w-[180px]">
28
- <SelectValue placeholder="Select option" />
29
- </SelectTrigger>
30
- <SelectContent>
31
- <SelectItem value="option1">Option 1</SelectItem>
32
- <SelectItem value="option2">Option 2</SelectItem>
33
- </SelectContent>
34
- </Select>
35
- ```
36
-
37
- **Componentes**: 10 (Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton)
38
-
39
- ## Props
40
-
41
- ### Select (Root)
42
-
43
- | Prop | Tipo | Descripción |
44
- | --------------- | ------------------------- | ---------------------------- |
45
- | `defaultValue` | `string` | Valor inicial (uncontrolled) |
46
- | `value` | `string` | Valor controlado |
47
- | `onValueChange` | `(value: string) => void` | Callback al cambiar valor |
48
- | `disabled` | `boolean` | Deshabilita el select |
49
- | `required` | `boolean` | Campo requerido |
50
- | `name` | `string` | Nombre (formularios) |
51
-
52
- ### SelectTrigger
53
-
54
- | Prop | Tipo | Descripción |
55
- | ----------- | ------------------- | ---------------------- |
56
- | `size` | `"sm" \| "default"` | Tamaño del trigger |
57
- | `className` | `string` | Clases CSS adicionales |
58
-
59
- **Nota**: `size="sm"` = h-8, `size="default"` = h-9
60
-
61
- ### SelectValue
62
-
63
- | Prop | Tipo | Descripción |
64
- | ------------- | -------- | ----------------------------- |
65
- | `placeholder` | `string` | Texto cuando no hay selección |
66
-
67
- ### SelectContent
68
-
69
- | Prop | Tipo | Descripción |
70
- | ----------- | ------------------------------ | ---------------------- |
71
- | `position` | `"popper" \| "item-aligned"` | Posición del dropdown |
72
- | `align` | `"start" \| "center" \| "end"` | Alineación horizontal |
73
- | `className` | `string` | Clases CSS adicionales |
74
-
75
- ### SelectItem
76
-
77
- | Prop | Tipo | Descripción |
78
- | ----------- | --------- | ---------------------- |
79
- | `value` | `string` | Valor único del item |
80
- | `disabled` | `boolean` | Deshabilita este item |
81
- | `className` | `string` | Clases CSS adicionales |
82
-
83
- ### SelectLabel
84
-
85
- | Prop | Tipo | Descripción |
86
- | ----------- | -------- | ---------------------------------- |
87
- | `className` | `string` | Clases CSS para el label del grupo |
88
-
89
- ## Patrones de Uso
90
-
91
- ### Básico
92
-
93
- ```tsx
94
- import {
95
- Select,
96
- SelectContent,
97
- SelectItem,
98
- SelectTrigger,
99
- SelectValue,
100
- } from "@adamosuiteservices/ui/select";
101
-
102
- <Select>
103
- <SelectTrigger className="w-[180px]">
104
- <SelectValue placeholder="Select a theme" />
105
- </SelectTrigger>
106
- <SelectContent>
107
- <SelectItem value="light">Light</SelectItem>
108
- <SelectItem value="dark">Dark</SelectItem>
109
- <SelectItem value="system">System</SelectItem>
110
- </SelectContent>
111
- </Select>;
112
- ```
113
-
114
- ### Controlado
115
-
116
- ```tsx
117
- import { useState } from "react";
118
-
119
- function App() {
120
- const [value, setValue] = useState("");
121
-
122
- return (
123
- <Select value={value} onValueChange={setValue}>
124
- <SelectTrigger className="w-[180px]">
125
- <SelectValue placeholder="Select a language" />
126
- </SelectTrigger>
127
- <SelectContent>
128
- <SelectItem value="javascript">JavaScript</SelectItem>
129
- <SelectItem value="typescript">TypeScript</SelectItem>
130
- <SelectItem value="python">Python</SelectItem>
131
- </SelectContent>
132
- </Select>
133
- );
134
- }
135
- ```
136
-
137
- ### Con Label
138
-
139
- ```tsx
140
- import { Label } from "@adamosuiteservices/ui/label";
141
-
142
- <div className="grid w-full max-w-sm items-center gap-2">
143
- <Label htmlFor="email-provider">Email provider</Label>
144
- <Select>
145
- <SelectTrigger id="email-provider">
146
- <SelectValue placeholder="Select a provider" />
147
- </SelectTrigger>
148
- <SelectContent>
149
- <SelectItem value="gmail">Gmail</SelectItem>
150
- <SelectItem value="outlook">Outlook</SelectItem>
151
- <SelectItem value="yahoo">Yahoo</SelectItem>
152
- </SelectContent>
153
- </Select>
154
- </div>;
155
- ```
156
-
157
- ### Con Grupos
158
-
159
- ```tsx
160
- import { SelectGroup, SelectLabel } from "@adamosuiteservices/ui/select";
161
-
162
- <Select>
163
- <SelectTrigger className="w-[200px]">
164
- <SelectValue placeholder="Select a fruit" />
165
- </SelectTrigger>
166
- <SelectContent>
167
- <SelectGroup>
168
- <SelectLabel>Fruits</SelectLabel>
169
- <SelectItem value="apple">Apple</SelectItem>
170
- <SelectItem value="banana">Banana</SelectItem>
171
- <SelectItem value="blueberry">Blueberry</SelectItem>
172
- </SelectGroup>
173
- </SelectContent>
174
- </Select>;
175
- ```
176
-
177
- ### Con Iconos
178
-
179
- ```tsx
180
- import { Icon } from "@adamosuiteservices/ui/icon";
181
-
182
- <Select>
183
- <SelectTrigger className="w-[200px]">
184
- <SelectValue placeholder="Select a fruit" />
185
- </SelectTrigger>
186
- <SelectContent>
187
- <SelectItem value="apple">
188
- <Icon symbol="nutrition" className="mr-2 text-lg" />
189
- Apple
190
- </SelectItem>
191
- <SelectItem value="banana">
192
- <Icon symbol="nutrition" className="mr-2 text-lg" />
193
- Banana
194
- </SelectItem>
195
- <SelectItem value="cherry">
196
- <Icon symbol="nutrition" className="mr-2 text-lg" />
197
- Cherry
198
- </SelectItem>
199
- </SelectContent>
200
- </Select>;
201
- ```
202
-
203
- ### Tamaño Pequeño
204
-
205
- ```tsx
206
- <Select>
207
- <SelectTrigger size="sm" className="w-[160px]">
208
- <SelectValue placeholder="Small select" />
209
- </SelectTrigger>
210
- <SelectContent>
211
- <SelectItem value="xs">Extra Small</SelectItem>
212
- <SelectItem value="sm">Small</SelectItem>
213
- <SelectItem value="md">Medium</SelectItem>
214
- </SelectContent>
215
- </Select>
216
- ```
217
-
218
- ### Scrollable
219
-
220
- ```tsx
221
- <Select>
222
- <SelectTrigger className="w-[280px]">
223
- <SelectValue placeholder="Select a timezone" />
224
- </SelectTrigger>
225
- <SelectContent>
226
- <SelectGroup>
227
- <SelectLabel>North America</SelectLabel>
228
- <SelectItem value="est">Eastern Standard Time (EST)</SelectItem>
229
- <SelectItem value="cst">Central Standard Time (CST)</SelectItem>
230
- <SelectItem value="mst">Mountain Standard Time (MST)</SelectItem>
231
- <SelectItem value="pst">Pacific Standard Time (PST)</SelectItem>
232
- </SelectGroup>
233
- <SelectGroup>
234
- <SelectLabel>Europe & Africa</SelectLabel>
235
- <SelectItem value="gmt">Greenwich Mean Time (GMT)</SelectItem>
236
- <SelectItem value="cet">Central European Time (CET)</SelectItem>
237
- <SelectItem value="eet">Eastern European Time (EET)</SelectItem>
238
- </SelectGroup>
239
- </SelectContent>
240
- </Select>
241
- ```
242
-
243
- ### Con Validación
244
-
245
- ```tsx
246
- import { Button } from "@adamosuiteservices/ui/button";
247
-
248
- function App() {
249
- const [value, setValue] = useState("");
250
- const [error, setError] = useState("");
251
-
252
- const handleValidate = () => {
253
- if (!value) {
254
- setError("Please select a priority level");
255
- } else {
256
- setError("");
257
- }
258
- };
259
-
260
- return (
261
- <div className="space-y-4">
262
- <div className="grid w-full max-w-sm items-center gap-2">
263
- <Label htmlFor="priority">
264
- Priority level <span className="text-destructive">*</span>
265
- </Label>
266
- <Select value={value} onValueChange={setValue}>
267
- <SelectTrigger
268
- id="priority"
269
- className={error ? "border-destructive" : ""}
270
- >
271
- <SelectValue placeholder="Select priority" />
272
- </SelectTrigger>
273
- <SelectContent>
274
- <SelectItem value="low">Low</SelectItem>
275
- <SelectItem value="medium">Medium</SelectItem>
276
- <SelectItem value="high">High</SelectItem>
277
- </SelectContent>
278
- </Select>
279
- {error && <p className="text-destructive text-sm">{error}</p>}
280
- </div>
281
- <Button onClick={handleValidate} variant="outline">
282
- Validate Selection
283
- </Button>
284
- </div>
285
- );
286
- }
287
- ```
288
-
289
- ### Deshabilitado
290
-
291
- ```tsx
292
- <Select disabled>
293
- <SelectTrigger className="w-[180px]">
294
- <SelectValue placeholder="Select a theme" />
295
- </SelectTrigger>
296
- <SelectContent>
297
- <SelectItem value="light">Light</SelectItem>
298
- <SelectItem value="dark">Dark</SelectItem>
299
- </SelectContent>
300
- </Select>
301
- ```
302
-
303
- ## Casos de Uso### Configuración
304
-
305
- ```tsx## Casos de Uso
306
-
307
- **Selección simple**: Elegir una opción de lista larga
308
- **Formularios**: País, estado, categoría, idioma
309
- **Filtros**: Ordenar por, filtrar por tipo
310
- **Settings**: Theme, tamaño de texto, timezone
311
- **Navegación**: Cambio rápido entre secciones/vistas
312
-
313
- ## Estilos Base
314
-
315
- - **Trigger height**: `h-9` (default), `h-8` (sm)
316
- - **Border**: `border-input` con `shadow-xs`
317
- - **Focus**: `ring-ring/50` con `ring-[3px]`
318
- - **Content**: `bg-popover` con `shadow-md` y `border`
319
- - **Item hover**: `bg-accent text-accent-foreground`
320
- - **Check icon**: Icon `check` con `text-lg` en item seleccionado
321
-
322
- ## Accesibilidad
323
-
324
- - ✅ **Role**: `role="combobox"` en trigger, `role="option"` en items
325
- - ✅ **ARIA**: `aria-expanded`, `aria-controls`, `aria-selected`
326
- - ✅ **Keyboard**: Arrow keys, Enter, Escape, Type-ahead search
327
- - ✅ **Focus**: Focus trap en content abierto
328
- - ✅ **Label**: Asociar con `id` en SelectTrigger
329
-
330
- ## Notas de Implementación
331
-
332
- - **Radix UI**: Basado en `@radix-ui/react-select`
333
- - **Portal**: SelectContent se renderiza en portal
334
- - **Iconos**: Icon `expand_more` en trigger, Icon `check` en items seleccionados, Icon `expand_less`/`expand_more` en scroll buttons
335
- - **Scroll buttons**: Auto-mostrados cuando content es scrollable
336
- - **Position**: `popper` (default) para absolute positioning
337
- - **Type-ahead**: Buscar items escribiendo
338
-
339
- ## Troubleshooting
340
-
341
- **Dropdown no abre**: Verifica que SelectContent esté dentro de Select
342
- **No muestra valor**: Asegura que `value` del item seleccionado coincida con `value` del Select
343
- **Portal issues**: SelectContent usa Portal, puede afectar z-index
344
- **Width mismatch**: SelectTrigger necesita `className="w-[Xpx]"` explícito
345
- **Scroll no funciona**: Scroll automático cuando items exceden max-height
346
- **Placeholder no desaparece**: SelectValue.placeholder solo visible cuando no hay valor
347
-
348
- ## Referencias
349
-
350
- - **Radix UI Select**: <https://www.radix-ui.com/primitives/docs/components/select>
351
- - **shadcn/ui Select**: <https://ui.shadcn.com/docs/components/select>
352
- ```
1
+ # Select
2
+
3
+ Dropdown de selección con búsqueda y scroll. Basado en Radix UI con 10 subcomponentes.
4
+
5
+ ## Descripción
6
+
7
+ El componente `Select` muestra una lista de opciones en las que el usuario puede seleccionar una opción de la lista.
8
+
9
+ ## Importación
10
+
11
+ ```typescript
12
+ import {
13
+ Select,
14
+ SelectContent,
15
+ SelectGroup,
16
+ SelectItem,
17
+ SelectLabel,
18
+ SelectTrigger,
19
+ SelectValue,
20
+ } from "@adamosuiteservices/ui/select";
21
+ ```
22
+
23
+ ## Anatomía
24
+
25
+ ```tsx
26
+ <Select>
27
+ <SelectTrigger className="w-[180px]">
28
+ <SelectValue placeholder="Select option" />
29
+ </SelectTrigger>
30
+ <SelectContent>
31
+ <SelectItem value="option1">Option 1</SelectItem>
32
+ <SelectItem value="option2">Option 2</SelectItem>
33
+ </SelectContent>
34
+ </Select>
35
+ ```
36
+
37
+ **Componentes**: 10 (Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton)
38
+
39
+ ## Props
40
+
41
+ ### Select (Root)
42
+
43
+ | Prop | Tipo | Descripción |
44
+ | --------------- | ------------------------- | ---------------------------- |
45
+ | `defaultValue` | `string` | Valor inicial (uncontrolled) |
46
+ | `value` | `string` | Valor controlado |
47
+ | `onValueChange` | `(value: string) => void` | Callback al cambiar valor |
48
+ | `disabled` | `boolean` | Deshabilita el select |
49
+ | `required` | `boolean` | Campo requerido |
50
+ | `name` | `string` | Nombre (formularios) |
51
+
52
+ ### SelectTrigger
53
+
54
+ | Prop | Tipo | Descripción |
55
+ | ----------- | ------------------- | ---------------------- |
56
+ | `size` | `"sm" \| "default"` | Tamaño del trigger |
57
+ | `className` | `string` | Clases CSS adicionales |
58
+
59
+ **Nota**: `size="sm"` = h-8, `size="default"` = h-9
60
+
61
+ ### SelectValue
62
+
63
+ | Prop | Tipo | Descripción |
64
+ | ------------- | -------- | ----------------------------- |
65
+ | `placeholder` | `string` | Texto cuando no hay selección |
66
+
67
+ ### SelectContent
68
+
69
+ | Prop | Tipo | Descripción |
70
+ | ----------- | ------------------------------ | ---------------------- |
71
+ | `position` | `"popper" \| "item-aligned"` | Posición del dropdown |
72
+ | `align` | `"start" \| "center" \| "end"` | Alineación horizontal |
73
+ | `className` | `string` | Clases CSS adicionales |
74
+
75
+ ### SelectItem
76
+
77
+ | Prop | Tipo | Descripción |
78
+ | ----------- | --------- | ---------------------- |
79
+ | `value` | `string` | Valor único del item |
80
+ | `disabled` | `boolean` | Deshabilita este item |
81
+ | `className` | `string` | Clases CSS adicionales |
82
+
83
+ ### SelectLabel
84
+
85
+ | Prop | Tipo | Descripción |
86
+ | ----------- | -------- | ---------------------------------- |
87
+ | `className` | `string` | Clases CSS para el label del grupo |
88
+
89
+ ## Patrones de Uso
90
+
91
+ ### Básico
92
+
93
+ ```tsx
94
+ import {
95
+ Select,
96
+ SelectContent,
97
+ SelectItem,
98
+ SelectTrigger,
99
+ SelectValue,
100
+ } from "@adamosuiteservices/ui/select";
101
+
102
+ <Select>
103
+ <SelectTrigger className="w-[180px]">
104
+ <SelectValue placeholder="Select a theme" />
105
+ </SelectTrigger>
106
+ <SelectContent>
107
+ <SelectItem value="light">Light</SelectItem>
108
+ <SelectItem value="dark">Dark</SelectItem>
109
+ <SelectItem value="system">System</SelectItem>
110
+ </SelectContent>
111
+ </Select>;
112
+ ```
113
+
114
+ ### Controlado
115
+
116
+ ```tsx
117
+ import { useState } from "react";
118
+
119
+ function App() {
120
+ const [value, setValue] = useState("");
121
+
122
+ return (
123
+ <Select value={value} onValueChange={setValue}>
124
+ <SelectTrigger className="w-[180px]">
125
+ <SelectValue placeholder="Select a language" />
126
+ </SelectTrigger>
127
+ <SelectContent>
128
+ <SelectItem value="javascript">JavaScript</SelectItem>
129
+ <SelectItem value="typescript">TypeScript</SelectItem>
130
+ <SelectItem value="python">Python</SelectItem>
131
+ </SelectContent>
132
+ </Select>
133
+ );
134
+ }
135
+ ```
136
+
137
+ ### Con Label
138
+
139
+ ```tsx
140
+ import { Label } from "@adamosuiteservices/ui/label";
141
+
142
+ <div className="grid w-full max-w-sm items-center gap-2">
143
+ <Label htmlFor="email-provider">Email provider</Label>
144
+ <Select>
145
+ <SelectTrigger id="email-provider">
146
+ <SelectValue placeholder="Select a provider" />
147
+ </SelectTrigger>
148
+ <SelectContent>
149
+ <SelectItem value="gmail">Gmail</SelectItem>
150
+ <SelectItem value="outlook">Outlook</SelectItem>
151
+ <SelectItem value="yahoo">Yahoo</SelectItem>
152
+ </SelectContent>
153
+ </Select>
154
+ </div>;
155
+ ```
156
+
157
+ ### Con Grupos
158
+
159
+ ```tsx
160
+ import { SelectGroup, SelectLabel } from "@adamosuiteservices/ui/select";
161
+
162
+ <Select>
163
+ <SelectTrigger className="w-[200px]">
164
+ <SelectValue placeholder="Select a fruit" />
165
+ </SelectTrigger>
166
+ <SelectContent>
167
+ <SelectGroup>
168
+ <SelectLabel>Fruits</SelectLabel>
169
+ <SelectItem value="apple">Apple</SelectItem>
170
+ <SelectItem value="banana">Banana</SelectItem>
171
+ <SelectItem value="blueberry">Blueberry</SelectItem>
172
+ </SelectGroup>
173
+ </SelectContent>
174
+ </Select>;
175
+ ```
176
+
177
+ ### Con Iconos
178
+
179
+ ```tsx
180
+ import { Icon } from "@adamosuiteservices/ui/icon";
181
+
182
+ <Select>
183
+ <SelectTrigger className="w-[200px]">
184
+ <SelectValue placeholder="Select a fruit" />
185
+ </SelectTrigger>
186
+ <SelectContent>
187
+ <SelectItem value="apple">
188
+ <Icon symbol="nutrition" className="mr-2 text-lg" />
189
+ Apple
190
+ </SelectItem>
191
+ <SelectItem value="banana">
192
+ <Icon symbol="nutrition" className="mr-2 text-lg" />
193
+ Banana
194
+ </SelectItem>
195
+ <SelectItem value="cherry">
196
+ <Icon symbol="nutrition" className="mr-2 text-lg" />
197
+ Cherry
198
+ </SelectItem>
199
+ </SelectContent>
200
+ </Select>;
201
+ ```
202
+
203
+ ### Tamaño Pequeño
204
+
205
+ ```tsx
206
+ <Select>
207
+ <SelectTrigger size="sm" className="w-[160px]">
208
+ <SelectValue placeholder="Small select" />
209
+ </SelectTrigger>
210
+ <SelectContent>
211
+ <SelectItem value="xs">Extra Small</SelectItem>
212
+ <SelectItem value="sm">Small</SelectItem>
213
+ <SelectItem value="md">Medium</SelectItem>
214
+ </SelectContent>
215
+ </Select>
216
+ ```
217
+
218
+ ### Scrollable
219
+
220
+ ```tsx
221
+ <Select>
222
+ <SelectTrigger className="w-[280px]">
223
+ <SelectValue placeholder="Select a timezone" />
224
+ </SelectTrigger>
225
+ <SelectContent>
226
+ <SelectGroup>
227
+ <SelectLabel>North America</SelectLabel>
228
+ <SelectItem value="est">Eastern Standard Time (EST)</SelectItem>
229
+ <SelectItem value="cst">Central Standard Time (CST)</SelectItem>
230
+ <SelectItem value="mst">Mountain Standard Time (MST)</SelectItem>
231
+ <SelectItem value="pst">Pacific Standard Time (PST)</SelectItem>
232
+ </SelectGroup>
233
+ <SelectGroup>
234
+ <SelectLabel>Europe & Africa</SelectLabel>
235
+ <SelectItem value="gmt">Greenwich Mean Time (GMT)</SelectItem>
236
+ <SelectItem value="cet">Central European Time (CET)</SelectItem>
237
+ <SelectItem value="eet">Eastern European Time (EET)</SelectItem>
238
+ </SelectGroup>
239
+ </SelectContent>
240
+ </Select>
241
+ ```
242
+
243
+ ### Con Validación
244
+
245
+ ```tsx
246
+ import { Button } from "@adamosuiteservices/ui/button";
247
+
248
+ function App() {
249
+ const [value, setValue] = useState("");
250
+ const [error, setError] = useState("");
251
+
252
+ const handleValidate = () => {
253
+ if (!value) {
254
+ setError("Please select a priority level");
255
+ } else {
256
+ setError("");
257
+ }
258
+ };
259
+
260
+ return (
261
+ <div className="space-y-4">
262
+ <div className="grid w-full max-w-sm items-center gap-2">
263
+ <Label htmlFor="priority">
264
+ Priority level <span className="text-destructive">*</span>
265
+ </Label>
266
+ <Select value={value} onValueChange={setValue}>
267
+ <SelectTrigger
268
+ id="priority"
269
+ className={error ? "border-destructive" : ""}
270
+ >
271
+ <SelectValue placeholder="Select priority" />
272
+ </SelectTrigger>
273
+ <SelectContent>
274
+ <SelectItem value="low">Low</SelectItem>
275
+ <SelectItem value="medium">Medium</SelectItem>
276
+ <SelectItem value="high">High</SelectItem>
277
+ </SelectContent>
278
+ </Select>
279
+ {error && <p className="text-destructive text-sm">{error}</p>}
280
+ </div>
281
+ <Button onClick={handleValidate} variant="outline">
282
+ Validate Selection
283
+ </Button>
284
+ </div>
285
+ );
286
+ }
287
+ ```
288
+
289
+ ### Deshabilitado
290
+
291
+ ```tsx
292
+ <Select disabled>
293
+ <SelectTrigger className="w-[180px]">
294
+ <SelectValue placeholder="Select a theme" />
295
+ </SelectTrigger>
296
+ <SelectContent>
297
+ <SelectItem value="light">Light</SelectItem>
298
+ <SelectItem value="dark">Dark</SelectItem>
299
+ </SelectContent>
300
+ </Select>
301
+ ```
302
+
303
+ ## Casos de Uso### Configuración
304
+
305
+ ```tsx## Casos de Uso
306
+
307
+ **Selección simple**: Elegir una opción de lista larga
308
+ **Formularios**: País, estado, categoría, idioma
309
+ **Filtros**: Ordenar por, filtrar por tipo
310
+ **Settings**: Theme, tamaño de texto, timezone
311
+ **Navegación**: Cambio rápido entre secciones/vistas
312
+
313
+ ## Estilos Base
314
+
315
+ - **Trigger height**: `h-9` (default), `h-8` (sm)
316
+ - **Border**: `border-input` con `shadow-xs`
317
+ - **Focus**: `ring-ring/50` con `ring-[3px]`
318
+ - **Content**: `bg-popover` con `shadow-md` y `border`
319
+ - **Item hover**: `bg-accent text-accent-foreground`
320
+ - **Check icon**: Icon `check` con `text-lg` en item seleccionado
321
+
322
+ ## Accesibilidad
323
+
324
+ - ✅ **Role**: `role="combobox"` en trigger, `role="option"` en items
325
+ - ✅ **ARIA**: `aria-expanded`, `aria-controls`, `aria-selected`
326
+ - ✅ **Keyboard**: Arrow keys, Enter, Escape, Type-ahead search
327
+ - ✅ **Focus**: Focus trap en content abierto
328
+ - ✅ **Label**: Asociar con `id` en SelectTrigger
329
+
330
+ ## Notas de Implementación
331
+
332
+ - **Radix UI**: Basado en `@radix-ui/react-select`
333
+ - **Portal**: SelectContent se renderiza en portal
334
+ - **Iconos**: Icon `expand_more` en trigger, Icon `check` en items seleccionados, Icon `expand_less`/`expand_more` en scroll buttons
335
+ - **Scroll buttons**: Auto-mostrados cuando content es scrollable
336
+ - **Position**: `popper` (default) para absolute positioning
337
+ - **Type-ahead**: Buscar items escribiendo
338
+
339
+ ## Troubleshooting
340
+
341
+ **Dropdown no abre**: Verifica que SelectContent esté dentro de Select
342
+ **No muestra valor**: Asegura que `value` del item seleccionado coincida con `value` del Select
343
+ **Portal issues**: SelectContent usa Portal, puede afectar z-index
344
+ **Width mismatch**: SelectTrigger necesita `className="w-[Xpx]"` explícito
345
+ **Scroll no funciona**: Scroll automático cuando items exceden max-height
346
+ **Placeholder no desaparece**: SelectValue.placeholder solo visible cuando no hay valor
347
+
348
+ ## Referencias
349
+
350
+ - **Radix UI Select**: <https://www.radix-ui.com/primitives/docs/components/select>
351
+ - **shadcn/ui Select**: <https://ui.shadcn.com/docs/components/select>
352
+ ```