Capítulo 34 de 108
Input de autocomplete com lista de sugestões filtrável, suportando seleção única, múltipla (com chips), agrupamento e itens customizados; construído sobre Base UI Combobox.
Combobox raiz (strings, objetos, ou grupos com { value, items }).items não são strings simples.ComboboxChips/ComboboxChipsInput/ComboboxValue/ComboboxChip em vez de ComboboxInput simples.multiple).ComboboxInput): exibe botão para limpar a seleção.ComboboxInput): controla se o botão de abrir/trigger aparece dentro do input (usado como false no padrão "Popup").ComboboxInput para dentro do ComboboxContent.ComboboxChips) e ComboboxContent, usado em combobox multiple/customizado.ComboboxInput, marca estado de erro visual.const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"] as const
<Combobox items={frameworks}>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => <ComboboxItem key={item} value={item}>{item}</ComboboxItem>}
</ComboboxList>
</ComboboxContent>
</Combobox>
<Combobox items={frameworks} itemToStringValue={(f) => f.label}>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxList>
{(f) => <ComboboxItem key={f.value} value={f}>{f.label}</ComboboxItem>}
</ComboboxList>
</ComboboxContent>
</Combobox>
{label, value} exigindo itemToStringValue para filtragem/exibição correta.const [value, setValue] = React.useState<string[]>([])
<Combobox items={frameworks} multiple value={value} onValueChange={setValue}>
<ComboboxChips>
<ComboboxValue>
{value.map((item) => <ComboboxChip key={item}>{item}</ComboboxChip>)}
</ComboboxValue>
<ComboboxChipsInput placeholder="Add framework" />
</ComboboxChips>
<ComboboxContent>
<ComboboxList>
{(item) => <ComboboxItem key={item} value={item}>{item}</ComboboxItem>}
</ComboboxList>
</ComboboxContent>
</Combobox>
<Combobox items={timezones}>
<ComboboxInput placeholder="Select a timezone" />
<ComboboxContent>
<ComboboxList>
{(group, index) => (
<ComboboxGroup key={group.value} items={group.items}>
<ComboboxLabel>{group.value}</ComboboxLabel>
<ComboboxCollection>
{(item) => <ComboboxItem key={item} value={item}>{item}</ComboboxItem>}
</ComboboxCollection>
{index < timezones.length - 1 && <ComboboxSeparator />}
</ComboboxGroup>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
ComboboxGroup/ComboboxCollection/ComboboxSeparator, cada item do items sendo um grupo { value, items }.<Combobox items={countries} defaultValue={countries[0]}>
<ComboboxTrigger render={<Button variant="outline" className="w-64 justify-between font-normal" />}>
<ComboboxValue />
</ComboboxTrigger>
<ComboboxContent>
<ComboboxInput showTrigger={false} placeholder="Search" />
...
</ComboboxContent>
</Combobox>
ComboboxTrigger + render, com o input de busca movido para dentro do content.| Composição | Estrutura |
|---|---|
| Simples | Combobox > ComboboxInput, ComboboxContent > ComboboxEmpty, ComboboxList > ComboboxItem |
| Com chips (multiple) | Combobox > ComboboxChips > ComboboxValue > ComboboxChip, ComboboxChipsInput; ComboboxContent > ComboboxList |
| Com grupos | ComboboxList > ComboboxGroup > ComboboxLabel, ComboboxCollection > ComboboxItem; ComboboxSeparator entre grupos |
items sem itemToStringValue: quebra a filtragem por texto digitado, pois o combobox não sabe extrair a string de comparação.multiple sem trocar ComboboxInput por ComboboxChips/ComboboxChipsInput: a UI de chips não aparece; a composição muda estruturalmente, não é apenas uma prop.useComboboxAnchor/prop anchor ao customizar o container de chips: o ComboboxContent pode não se posicionar corretamente em relação ao ComboboxChips.<ComboboxInput placeholder="Select a timezone">
<InputGroupAddon>
<GlobeIcon />
</InputGroupAddon>
</ComboboxInput>
InputGroupAddon (composição com Input Group).itemToStringValue é obrigatório sempre que items não são strings puras — é o ponto central para dados de objeto/API real.multiple + ComboboxChips é o padrão de multi-seleção; value/onValueChange viram arrays.ComboboxTrigger com render permite desacoplar o gatilho visual (ex: um Button) do input de busca, útil para combobox tipo "select popup".Item/ItemTitle/ItemDescription dentro de ComboboxItem) funciona porque ComboboxItem aceita qualquer children.ComboboxInput.ComboboxItem.ComboboxTrigger/render.