Saltar al contenido principal

Select

Elegir de listas. Estilo personalizado. Simplificar opciones.

Your database is created in the same region.
1'use client';
2
3import { Label } from '@/components/ui/label';
4import { Select } from '@/components/ui/select';
5
6const regions = [
7 { value: 'us-east-1', label: 'US East, Virginia' },
8 { value: 'us-west-2', label: 'US West, Oregon' },
9 { value: 'eu-central-1', label: 'Europe, Frankfurt' },
10 { value: 'sa-east-1', label: 'South America, Sao Paulo' },
11 { value: 'ap-southeast-1', label: 'Asia Pacific, Singapore' },
12];
13
14export function Default() {
15 return (
16 <div className="flex w-full max-w-sm flex-col gap-1.5">
17 <Label htmlFor="deploy-region" description="Your database is created in the same region.">
18 Deployment region
19 </Label>
20 <Select defaultValue="eu-central-1">
21 <Select.Trigger id="deploy-region" placeholder="Pick a region" />
22 <Select.Content>
23 {regions.map((region) => (
24 <Select.Item key={region.value} value={region.value}>
25 {region.label}
26 </Select.Item>
27 ))}
28 </Select.Content>
29 </Select>
30 </div>
31 );
32}

Instalación

pnpm dlx nachui add select

Anatomía

1import { Select } from '@/components/ui/select';
1<Select defaultValue="one">
2 <Select.Trigger placeholder="Elegí una opción" />
3 <Select.Content>
4 <Select.Item value="one">Opción 1</Select.Item>
5 <Select.Item value="two">Opción 2</Select.Item>
6 </Select.Content>
7</Select>

Composición

Utiliza la siguiente composición para construir un Select:
Select
├── Select.Trigger
└── Select.Content
├── Select.Group
│ ├── Select.Label
│ └── Select.Item
└── Select.Separator
El trigger muestra solo la etiqueta del elemento seleccionado. Pasale children únicamente cuando quieras renderizar otra cosa en su lugar.

Variantes

Predeterminado (Default)

Your database is created in the same region.
1'use client';
2
3import { Label } from '@/components/ui/label';
4import { Select } from '@/components/ui/select';
5
6const regions = [
7 { value: 'us-east-1', label: 'US East, Virginia' },
8 { value: 'us-west-2', label: 'US West, Oregon' },
9 { value: 'eu-central-1', label: 'Europe, Frankfurt' },
10 { value: 'sa-east-1', label: 'South America, Sao Paulo' },
11 { value: 'ap-southeast-1', label: 'Asia Pacific, Singapore' },
12];
13
14export function Default() {
15 return (
16 <div className="flex w-full max-w-sm flex-col gap-1.5">
17 <Label htmlFor="deploy-region" description="Your database is created in the same region.">
18 Deployment region
19 </Label>
20 <Select defaultValue="eu-central-1">
21 <Select.Trigger id="deploy-region" placeholder="Pick a region" />
22 <Select.Content>
23 {regions.map((region) => (
24 <Select.Item key={region.value} value={region.value}>
25 {region.label}
26 </Select.Item>
27 ))}
28 </Select.Content>
29 </Select>
30 </div>
31 );
32}

Opciones Agrupadas (Grouped Items)

Envolvé los elementos relacionados en Select.Group y dale a cada grupo un Select.Label.
1'use client';
2
3import { Label } from '@/components/ui/label';
4import { Select } from '@/components/ui/select';
5
6const teams = [
7 {
8 label: 'Engineering',
9 members: [
10 { value: 'lucia', label: 'Lucia Mendez' },
11 { value: 'marco', label: 'Marco Rivas' },
12 { value: 'priya', label: 'Priya Nair' },
13 ],
14 },
15 {
16 label: 'Design',
17 members: [
18 { value: 'ines', label: 'Ines Duarte' },
19 { value: 'tomas', label: 'Tomas Fuentes' },
20 ],
21 },
22 {
23 label: 'Support',
24 members: [
25 { value: 'noa', label: 'Noa Bergman' },
26 { value: 'hugo', label: 'Hugo Salas' },
27 ],
28 },
29];
30
31export function GroupedItems() {
32 return (
33 <div className="flex w-full max-w-sm flex-col gap-1.5">
34 <Label htmlFor="assignee">Assign ticket to</Label>
35 <Select>
36 <Select.Trigger id="assignee" placeholder="Unassigned" />
37 <Select.Content>
38 {teams.map((team) => (
39 <Select.Group key={team.label}>
40 <Select.Label>{team.label}</Select.Label>
41 {team.members.map((member) => (
42 <Select.Item key={member.value} value={member.value}>
43 {member.label}
44 </Select.Item>
45 ))}
46 </Select.Group>
47 ))}
48 </Select.Content>
49 </Select>
50 </div>
51 );
52}

Teclado

TeclaAcción
Enter, Espacio, FlechasAbre la lista y enfoca el elemento seleccionado
ArrowUp, ArrowDownSe mueve entre elementos
Home, EndSalta al primer o último elemento
Una letraEnfoca el siguiente elemento cuya etiqueta empieza con ella
Enter, EspacioSelecciona el elemento enfocado
EscapeCierra la lista y devuelve el foco al trigger

Referencia de API

Select

PropTipoPor defectoDescripción
valuestring-Valor controlado
defaultValuestring''Valor inicial cuando no es controlado
onValueChange(value: string) => void-Se llama cuando cambia el valor seleccionado
openboolean-Estado de apertura controlado
defaultOpenbooleanfalseEstado de apertura inicial cuando no es controlado
onOpenChange(open: boolean) => void-Se llama cuando cambia el estado de apertura
disabledbooleanfalseDeshabilita el trigger
namestring-Renderiza un input oculto para que el valor se envíe con formularios
requiredboolean-Marca el input oculto como requerido
classNamestring-Clases CSS adicionales para el contenedor

Select.Trigger

Acepta todos los atributos de button, así que id y aria-label funcionan como siempre.
PropTipoPor defectoDescripción
placeholderstring-Texto que se muestra cuando no hay ningún elemento elegido
size'sm' | 'default' | 'lg''default'Alto y padding del trigger
childrenReactNode-Reemplaza la etiqueta seleccionada con contenido propio
classNamestring-Clases CSS adicionales

Select.Content

PropTipoPor defectoDescripción
sideOffsetnumber4Separación entre el trigger y la lista
classNamestring-Clases CSS adicionales

Select.Item

PropTipoPor defectoDescripción
valuestring-Valor que se informa cuando se selecciona el elemento
textValuestring-Etiqueta para el trigger cuando los children no son texto plano
disabledbooleanfalseLo salta en la navegación por teclado y bloquea la selección
classNamestring-Clases CSS adicionales

Select.Group, Select.Label, Select.Separator

PropTipoPor defectoDescripción
classNamestring-Clases CSS adicionales
¿Encontraste algo que mejorar?

¿Notaste un error, tipografía o detalle faltante en esta página? Ayúdanos a mejorar la documentación abriendo un issue en GitHub.

Crear un Issue
Ctrl+I