Select
Abre uma lista fechada de opções para o usuário escolher uma (ou várias).
'use client';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
export default function SelectDemo() {
return (
<Select name="servico" label="Serviço" placeholder="Selecione um serviço" className="w-full max-w-xs">
<SelectTrigger />
<SelectContent>
<SelectItem id="site">Site institucional</SelectItem>
<SelectItem id="loja">Loja virtual</SelectItem>
<SelectItem id="sistema">Sistema de gestão</SelectItem>
<SelectItem id="landing">Landing page</SelectItem>
</SelectContent>
</Select>
);
}Instalação
npx shadcn@latest add @lenstech/selectUso
import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select"<Select name="servico" label="Serviço" placeholder="Selecione um serviço">
<SelectTrigger />
<SelectContent>
<SelectItem id="site">Site institucional</SelectItem>
<SelectItem id="loja">Loja virtual</SelectItem>
</SelectContent>
</Select>A estrutura é a mesma do shadcn: Select › SelectTrigger + SelectContent › SelectItem. O placeholder
fica no Select (não no SelectValue).
value, não selectedKey
Cada SelectItem é identificado pelo id. Controle a seleção com value / defaultValue e onChange, que
recebe o id escolhido (Key | null) — não o evento. As props selectedKey / onSelectionChange ainda
funcionam, mas estão obsoletas no React Aria. O valor enviado no formulário (via name) também é o id.
Exemplos
Com seções
'use client';
import { Select, SelectContent, SelectItem, SelectSection, SelectTrigger } from '@/components/ui/select';
export default function SelectGroups() {
return (
<Select label="Horário de atendimento" placeholder="Escolha um horário" className="w-full max-w-xs">
<SelectTrigger />
<SelectContent>
<SelectSection title="Manhã">
<SelectItem id="09">09:00</SelectItem>
<SelectItem id="10">10:00</SelectItem>
<SelectItem id="11" isDisabled>
11:00 (ocupado)
</SelectItem>
</SelectSection>
<SelectSection title="Tarde">
<SelectItem id="14">14:00</SelectItem>
<SelectItem id="15">15:00</SelectItem>
<SelectItem id="16">16:00</SelectItem>
</SelectSection>
</SelectContent>
</Select>
);
}Itens dinâmicos e controlado
Passe items ao SelectContent e uma função como filho. Cada objeto precisa de um id.
Endereço: Rua XV de Novembro, 120
'use client';
import { useState } from 'react';
import type { Key } from 'react-aria-components';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
const unidades = [
{ id: 'centro', nome: 'Unidade Centro', endereco: 'Rua XV de Novembro, 120' },
{ id: 'batel', nome: 'Unidade Batel', endereco: 'Av. do Batel, 1450' },
{ id: 'portao', nome: 'Unidade Portão', endereco: 'Rua João Bettega, 88' },
];
export default function SelectControlled() {
const [unidade, setUnidade] = useState<Key | null>('centro');
const atual = unidades.find((u) => u.id === unidade);
return (
<div className="flex w-full max-w-xs flex-col gap-3">
<Select label="Unidade" value={unidade} onChange={setUnidade}>
<SelectTrigger />
<SelectContent items={unidades}>{(u) => <SelectItem>{u.nome}</SelectItem>}</SelectContent>
</Select>
<p className="text-sm text-muted-foreground">Endereço: {atual?.endereco ?? '—'}</p>
</div>
);
}Seleção múltipla
Com selectionMode="multiple", value passa a ser um array de ids e a lista fica aberta enquanto o usuário marca.
'use client';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
export default function SelectMultiple() {
return (
<Select
selectionMode="multiple"
name="pagamentos"
label="Formas de pagamento aceitas"
placeholder="Selecione"
defaultValue={['pix', 'cartao']}
className="w-full max-w-xs"
>
<SelectTrigger />
<SelectContent>
<SelectItem id="pix">Pix</SelectItem>
<SelectItem id="cartao">Cartão</SelectItem>
<SelectItem id="boleto">Boleto</SelectItem>
<SelectItem id="dinheiro">Dinheiro</SelectItem>
</SelectContent>
</Select>
);
}Tamanho pequeno
'use client';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
export default function SelectSizes() {
return (
<div className="flex items-center gap-3 text-sm text-muted-foreground">
<span>Itens por página</span>
<Select aria-label="Itens por página" defaultValue="20">
<SelectTrigger size="sm" className="w-20" />
<SelectContent>
<SelectItem id="10">10</SelectItem>
<SelectItem id="20">20</SelectItem>
<SelectItem id="50">50</SelectItem>
</SelectContent>
</Select>
</div>
);
}Desabilitado
'use client';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
export default function SelectDisabled() {
return (
<Select
label="Estado"
defaultValue="pr"
isDisabled
description="Definido pelo endereço cadastrado."
className="w-full max-w-xs"
>
<SelectTrigger />
<SelectContent>
<SelectItem id="pr">Paraná</SelectItem>
<SelectItem id="sc">Santa Catarina</SelectItem>
<SelectItem id="sp">São Paulo</SelectItem>
</SelectContent>
</Select>
);
}Obrigatório
Tente continuar sem escolher um serviço.
'use client';
import { Button } from '@/components/ui/button';
import { Form } from '@/components/ui/form';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
export default function SelectInvalid() {
return (
<Form onSubmit={(e) => e.preventDefault()} className="w-full max-w-xs">
<Select
name="servico"
label="Serviço"
placeholder="Selecione um serviço"
isRequired
errorMessage="Selecione um serviço para continuar."
>
<SelectTrigger />
<SelectContent>
<SelectItem id="site">Site institucional</SelectItem>
<SelectItem id="loja">Loja virtual</SelectItem>
<SelectItem id="sistema">Sistema de gestão</SelectItem>
</SelectContent>
</Select>
<Button type="submit" className="self-start">
Continuar
</Button>
</Form>
);
}Quando usar
- Use para escolher entre 5 e 15 opções conhecidas (serviço, unidade, estado).
- Não use com até 4 opções — um
Radio Groupdeixa todas visíveis. - Não use com listas longas ou quando o usuário já sabe o que procura — use
Combobox. - Não use para ações (editar, excluir) — use
Menu.
API
Select
Aceita todas as props do Select do React Aria, mais:
Prop
Type
SelectTrigger
Aceita as props do Button do React Aria. Sem filhos, renderiza <SelectValue />.
Prop
Type
SelectContent
Aceita as props do ListBox (items, renderEmptyState…), mais:
Prop
Type
SelectItem, SelectSection e SelectValue
SelectItem e SelectSection são o mesmo que ListBoxItem e ListBoxSection.
SelectValue mostra o valor selecionado — use-o como filho do SelectTrigger para customizar a exibição.