Capítulo 28 de 108
Exibe uma lista de opções para o usuário escolher, acionada por um botão (trigger custom-styled). Use quando precisar de estilização, animação ou interações complexas além do <select> nativo.
items: array de { label, value } passado ao Select (e reutilizado no map de SelectItem); um item com value: null funciona como placeholder/opção vazia.SelectTrigger / SelectValue: botão que abre o popup e exibe o valor selecionado (ou placeholder).SelectContent: popup com as opções; contém SelectGroup, SelectLabel, SelectItem, SelectSeparator.alignItemWithTrigger (em SelectContent): quando true (default), o popup posiciona o item selecionado sobre o trigger; quando false, alinha pela borda do trigger.disabled: no Select desabilita tudo; em SelectItem desabilita uma opção específica.aria-invalid: em SelectTrigger, combinado com data-invalid no Field, para estado de erro.@base-ui/react (Base UI Select).import {
Select, SelectContent, SelectGroup, SelectItem,
SelectLabel, SelectTrigger, SelectValue,
} from "@/components/ui/select"
const items = [
{ label: "Select a fruit", value: null },
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
]
export function SelectDemo() {
return (
<Select items={items}>
<SelectTrigger className="w-full max-w-48">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
{items.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
)
}
items compartilhado entre o array de dados e o render dos SelectItem.<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
{fruits.map((item) => <SelectItem key={item.value} value={item.value}>{item.label}</SelectItem>)}
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectLabel>Vegetables</SelectLabel>
{vegetables.map((item) => <SelectItem key={item.value} value={item.value}>{item.label}</SelectItem>)}
</SelectGroup>
</SelectContent>
SelectGroup + SelectLabel, separados por SelectSeparator.Composição:
Select
├── SelectTrigger
│ └── SelectValue
└── SelectContent
├── SelectGroup
│ ├── SelectLabel
│ ├── SelectItem
│ └── SelectItem
├── SelectSeparator
└── SelectGroup
├── SelectLabel
├── SelectItem
└── SelectItem
items só para o Select e um segundo array só pro .map() diverge do padrão da doc, que reutiliza o mesmo items.Select quando NativeSelect bastaria: em formulários simples/mobile-first sem necessidade de estilo customizado, prefira NativeSelect (melhor performance e comportamento nativo).items é passado tanto ao Select (para lógica interna, ex. exibir label do valor atual) quanto reaproveitado no .map() dos SelectItem — mantenha uma única fonte de dados.alignItemWithTrigger={false} em SelectContent alinha o popup pela borda do trigger em vez de sobrepor o item selecionado; útil quando o alinhamento por overlay quebra o layout.aria-invalid no SelectTrigger + data-invalid no Field; use FieldError para a mensagem.SelectItem com disabled desabilita apenas aquela opção, mantendo as demais clicáveis.dir para SelectTrigger e SelectContent.Select.Select (ex: toggle alignItemWithTrigger).