Combobox
Busca em lista
Escolha múltipla
Lista com famílias
import { Combobox } from '@rivocode/ui'Quando usar
Escolha em lista longa, com busca.
Use quando a lista é grande demais para caber na cabeça de quem escolhe, ou quando ela vem do servidor.
Compõe com ComboboxInput, ComboboxContent, ComboboxList e
ComboboxItem. Lista com famílias de verdade ganha ComboboxGroup,
ComboboxGroupLabel e ComboboxSeparator entre uma família e outra.
Com multiple, a escolha vira fichas dentro do próprio campo: ComboboxChips
em volta, ComboboxValue para saber o que está escolhido e um ComboboxChip
por escolha.
Quando não usar
Com cinco opções fixas, use Select: ele custa menos, não pede digitação e não
tem estado de "nada encontrado" para tratar. Busca numa lista que a pessoa
enxerga inteira só acrescenta um teclado no caminho.
Quando o que a pessoa digita também vale (uma cidade que não está na lista,
um termo de busca), use Autocomplete. Aqui a lista manda: o valor final tem
que ser uma das opções, e texto que não casa com nenhuma se perde ao sair do
campo.
E não use para navegar. Campo com busca que leva a outra tela é Command, a
paleta. O combobox devolve um valor a um formulário, e quem escolhe nele espera
que a escolha fique escrita ali, não que a página troque.
No React Native
Traduz: o @rivocode/ui-native exporta Combobox - a lista abre numa folha com busca sem acento, e a folha sobe com o teclado; items na raiz, não ComboboxItem por filho. A API não é a mesma do web (no nativo tudo é controlado), e a tabela de paridade diz o que muda peça a peça.
API
| Prop | Tipo |
|---|---|
actionsRef0.4.0A ref to imperative actions. | RefObject<Actions | null> |
autoComplete0.4.0Provides a hint to the browser for autofill. | string |
autoHighlight0.4.0Whether the first matching item is highlighted automatically while filtering. | boolean |
defaultInputValue0.4.0The uncontrolled input value when initially rendered. | stringnumberreadonly string[] |
defaultOpen0.4.0Whether the popup is initially open. | boolean |
defaultValue0.4.0The uncontrolled selected value of the combobox when it's initially rendered. | ComboboxValueType<Value, Multiple> | null |
disabled0.4.0Whether the component should ignore user interaction. | boolean |
filter0.4.0Filter function used to match items vs input query. | ((itemValue: Value, query: string, itemToString?: ((itemValue: Value) => string)undefined) => boolean)null |
filteredItems0.4.0Filtered items to display in the list. | readonly any[] | readonly Group<any>[] |
form0.4.0Identifies the form that owns the internal input. | string |
grid0.4.0Whether list items are presented in a grid layout. | boolean |
highlightItemOnHover0.4.0Whether moving the pointer over items should highlight them. | boolean |
inline0.4.0Whether the list is rendered inline without using the component's own popup. | boolean |
inputRef0.4.0A ref to the hidden input element. | Ref<HTMLInputElement> |
inputValue0.4.0The input value of the combobox. | stringnumberreadonly string[] |
isItemEqualToValue0.4.0Custom comparison logic used to determine if a combobox item value matches the current selected value. | ((itemValue: Value, value: Value) => boolean) |
items0.4.0The items to be displayed in the list. | readonly any[] | readonly Group<any>[] |
itemToStringLabel0.4.0When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for display in the input. | ((itemValue: Value) => string) |
itemToStringValue0.4.0When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for form submission. | ((itemValue: Value) => string) |
limit0.4.0The maximum number of items to display in the list. | number |
locale0.4.0The locale to use for string comparison. | LocalesArgument |
loopFocus0.4.0Whether to loop keyboard focus back to the input when the end of the list is reached while using the arrow keys. | boolean |
modal0.4.0Determines if the popup enters a modal state when open. | boolean |
multiple0.4.0Whether multiple items can be selected. | Multiple |
name0.4.0Identifies the field when a form is submitted. | string |
onInputValueChange0.4.0Event handler called when the input value changes. | ((inputValue: string, eventDetails: ChangeEventDetails) => void) |
onItemHighlighted0.4.0Callback fired when an item is highlighted or unhighlighted. | ((highlightedValue: Value | undefined, eventDetails: HighlightEventDetails) => void) |
onOpenChange0.4.0Event handler called when the popup is opened or closed. | ((open: boolean, eventDetails: ChangeEventDetails) => void) |
onOpenChangeComplete0.4.0Event handler called after any animations complete when the popup is opened or closed. | ((open: boolean) => void) |
onValueChange0.4.0Event handler called when the selected value of the combobox changes. | ((value: ComboboxValueType<Value, Multiple> | (Multiple extends true ? never : null), eventDetails: ChangeEventDetails) => void) |
open0.4.0Whether the popup is currently open. | boolean |
openOnInputClick0.4.0Whether the popup opens when clicking the input. | boolean |
readOnly0.4.0Whether the user should be unable to choose a different option from the popup. | boolean |
required0.4.0Whether the user must choose a value before submitting a form. | boolean |
value0.4.0The selected value of the combobox. | ComboboxValueType<Value, Multiple> | null |
virtualized0.4.0Whether the items are being externally virtualized. | boolean |
Partes
Combobox se monta com estas peças. Todas vivem nesta página, porque separar cada uma num endereço obrigaria a abrir seis abas para montar uma tela.
ComboboxChip
/combobox-chip.mdUma escolha, com o xis de tirar.
O xis por dentro diz o que se remove. Quando a ficha é texto, o nome sai pronto
do próprio conteúdo ("Remover Clínica São Lucas"), e quando ela não é (um
Avatar, um Badge), o aria-label da ficha é que responde. Sem um dos dois o
leitor de tela lê uma fila de "Remover, Remover, Remover", e a WCAG 2.4.6 pede
que o nome distinga.
labels.remove recebe o texto da ficha e devolve o nome, para trocar o verbo ou
traduzir:
<ComboboxChip labels={{ remove: (label) => `Tirar ${label} da seleção` }}>
Clínica São Lucas
</ComboboxChip>
| Prop | Tipo |
|---|---|
labelsO que o leitor de tela ouve no xis. | { remove?: ((label: string) => string) | undefined; } |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxChipState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxChips
/combobox-chips.mdA moldura das fichas da escolha múltipla, com o campo de busca dentro dela.
O campo entra como último filho, e não ao lado: as fichas e a digitação são o mesmo campo aos olhos de quem usa, e separar os dois faz a busca parecer um filtro de outra coisa.
Dentro dela, o clearable do ComboboxInput sai de cena: cada ficha já tem o
seu xis, e um limpar geral encostado neles é o botão errado no lugar mais fácil
de acertar sem querer.
| Prop | Tipo |
|---|---|
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxChipsState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxContent
/combobox-content.mdO painel da lista, em portal com o tema. Traz a mensagem de vazio por dentro, em emptyMessage.
side, align e sideOffset posicionam o painel, com o mesmo significado e a
mesma folga padrão de 6px do MenuContent, do SelectContent, do
PopoverContent e do TooltipContent.
| Prop | Tipo |
|---|---|
alignAlinhamento no eixo do lado escolhido. | Align |
emptyMessage0.4.0O que aparece quando a busca nao acha nada. | ReactNode |
finalFocus0.4.0Determines the element to focus when the popup is closed. | booleanRefObject<HTMLElementnull>((closeType: InteractionType) => voidbooleanHTMLElementnull) |
initialFocus0.4.0Determines the element to focus when the popup is opened. | booleanRefObject<HTMLElementnull>((openType: InteractionType) => voidbooleanHTMLElementnull) |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxPopupState>ReactElement<unknown, stringJSXElementConstructor<any>> |
sideLado preferido do gatilho. | Side |
sideOffsetDistancia entre o gatilho e o painel, em pixels. | number | OffsetFunction |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxGroup
/combobox-group.mdUma seção da lista, com ComboboxGroupLabel de cabeçalho.
Serve para lista longa que tem famílias de verdade: clientes por cidade, produtos por categoria. Agrupar por agrupar aumenta a altura da lista sem diminuir a busca, que é justamente o que a peça existe para resolver.
| Prop | Tipo |
|---|---|
items0.4.0Items to be rendered within this group. | readonly any[] |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxGroupState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxInput
/combobox-input.mdO campo de busca com o limpar e a seta encostados. Vive dentro do Combobox.
O className veste a raiz, que aqui é a moldura que segura o campo e os dois
botões, e não o <input>. Para alcançar cada uma delas pelo nome, use
classNames com as partes wrapper e input:
<ComboboxInput classNames={{ input: "font-mono" }} />
É a diferença que separava esta peça do AutocompleteInput, que não tem moldura
e por isso veste o próprio campo com o className.
| Prop | Tipo |
|---|---|
classNamesClasse por parte: `wrapper`, `input`. | Partial<Record<"input" | "wrapper", string>> |
clearable0.4.0Mostra o botao de limpar quando ha escolha. | boolean |
disabled0.4.0Whether the component should ignore user interaction. | boolean |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxInputState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxItem
/combobox-item.mdUma opção. Mostra o visto quando escolhida.
| Prop | Tipo |
|---|---|
disabled0.4.0Whether the component should ignore user interaction. | boolean |
index0.4.0The index of the item in the list. | number |
nativeButton0.4.0Whether the component renders a native `<button>` element when replacing it via the `render` prop. | boolean |
onClick0.4.0An optional click handler for the item when selected. | ((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void) |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxItemState>ReactElement<unknown, stringJSXElementConstructor<any>> |
value0.4.0A unique value that identifies this item. | any |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxList
/combobox-list.mdA lista. Recebe uma funcao que desenha cada item, e não filhos soltos: é assim que a Base UI filtra sem redesenhar tudo.
| Prop | Tipo |
|---|---|
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxListState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxSeparator
/combobox-separator.mdA linha entre dois ComboboxGroup da lista.
É a irmã do SelectSeparator, e fecha a paridade com o MenuSeparator: as três
listas da biblioteca cortam do mesmo jeito. Como no Select, ela sai com
role="presentation": um nó com papel próprio no meio das opções quebraria o
"opção 3 de 12" que o leitor de tela anuncia.
Quando não usar
Enquanto a busca é o caminho principal, a linha decora e não orienta: quem digita três letras nunca vê o corte, porque a lista filtrada some com ele. Ela serve à lista parada, aberta e curta o bastante para ser lida de uma vez, e aí só entre grupos que têm nome.
| Prop | Tipo |
|---|---|
orientationThe orientation of the separator. | Orientation |
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, ComboboxSeparatorState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
ComboboxValue
/combobox-value.mdO que está escolhido, para as fichas saberem o que desenhar.
Não renderiza elemento nenhum: recebe uma função e devolve o que ela montar. É a
peça que faltava para o ComboboxChips servir para alguma coisa. Sem ela, a
escolha múltipla com ficha só era possível importando direto da Base UI.
| Prop | Tipo |
|---|---|
placeholder0.5.0The placeholder value to display when no value is selected. | ReactNode |