Select
Fechado
Aberto
Dentro de campo
Agrupado por família
import { Select } from '@rivocode/ui'Quando usar
Escolha única em lista.
Compõe com SelectTrigger, SelectValue, SelectContent e SelectItem.
Lista com famílias de verdade ganha SelectGroup com SelectGroupLabel, e
SelectSeparator entre uma família e outra.
Passe items com { label, value } na raiz. Sem isso o gatilho mostra o
valor cru em vez do rótulo, e essa é a armadilha mais fácil de cair aqui.
Renderiza em portal, então exige o RivoProvider.
Quando não usar
Quando a lista é grande demais para caber na cabeça de quem escolhe, ou quando
ela vem do servidor, use Combobox: ele traz a busca junto. Rolar cento e
vinte cidades numa lista sem campo de digitar é o mesmo trabalho de procurar
numa gaveta.
Para duas ou três opções que cabem lado a lado, o RadioGroup mostra todas de
uma vez e economiza o clique de abrir. E para um liga-desliga, o Switch.
No React Native
Traduz, e a forma de escrever é outra. No web o Select pede items na raiz e as quatro partes (SelectTrigger, SelectValue, SelectContent, SelectItem); no nativo ele é uma tag só (<Select items={…} value={…} onValueChange={…} label="Período" />), e a lista abre numa folha de baixo, que é o idioma da plataforma para escolher. O label é obrigatório: é por ele que o leitor de tela anuncia o gatilho, papel que no web era do SelectTrigger.
API
| Prop | Tipo |
|---|---|
actionsRef0.4.0A ref to imperative actions. | RefObject<SelectRootActions | null> |
autoComplete0.4.0Provides a hint to the browser for autofill. | string |
defaultOpen0.4.0Whether the select popup is initially open. | boolean |
defaultValue0.4.0The uncontrolled value of the select when it's initially rendered. | SelectValueType<Value, Multiple> | null |
disabled0.4.0Whether the component should ignore user interaction. | boolean |
form0.4.0Identifies the form that owns the hidden input. | string |
highlightItemOnHover0.4.0Whether moving the pointer over items should highlight them. | boolean |
inputRef0.4.0A ref to access the hidden input element. | Ref<HTMLInputElement> |
isItemEqualToValue0.4.0Custom comparison logic used to determine if a select item value matches the current selected value. | ((itemValue: Value, value: Value) => boolean) |
items0.4.0Data structure of the items rendered in the select popup. | readonly Group<any>[]readonly { label: ReactNode; value: any; }[]Record<string, ReactNode> |
itemToStringLabel0.4.0When the item values are objects (`<Select.Item value={object}>`), this function converts the object value to a string representation for display in the trigger. | ((itemValue: Value) => string) |
itemToStringValue0.4.0When the item values are objects (`<Select.Item value={object}>`), this function converts the object value to a string representation for form submission. | ((itemValue: Value) => string) |
modal0.4.0Determines if the select 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 |
onOpenChange0.4.0Event handler called when the select popup is opened or closed. | ((open: boolean, eventDetails: SelectRootChangeEventDetails) => void) |
onOpenChangeComplete0.4.0Event handler called after any animations complete when the select popup is opened or closed. | ((open: boolean) => void) |
onValueChange0.4.0Event handler called when the value of the select changes. | ((value: SelectValueType<Value, Multiple> | (Multiple extends true ? never : null), eventDetails: SelectRootChangeEventDetails) => void) |
open0.4.0Whether the select popup is currently open. | boolean |
readOnly0.4.0Whether the user should be unable to choose a different option from the select popup. | boolean |
required0.4.0Whether the user must choose a value before submitting a form. | boolean |
value0.4.0The value of the select. | SelectValueType<Value, Multiple> | null |
Partes
Select 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.
SelectContent
/select-content.mdA lista flutuante do select.
Nasce com a largura do gatilho e rola sozinha quando não cabe na tela. O portal
usa o contêiner do RivoProvider, então o tema vale dentro dela.
side, align e sideOffset posicionam o painel, como nas outras peças que
flutuam. Pedir qualquer um dos três troca o modo de posicionamento: por
padrão a lista se sobrepõe ao gatilho para alinhar o item escolhido com o texto
dele, e nesse modo não há lado nem folga a respeitar. Quem não pede nada
continua com o alinhamento pelo item.
<SelectContent side="top" align="start">
<SelectItem value="abertas">Abertas</SelectItem>
</SelectContent>
| Prop | Tipo |
|---|---|
alignAlinhamento no eixo do lado escolhido. | Align |
finalFocus0.4.0Determines the element to focus when the select popup is closed. | booleanRefObject<HTMLElementnull>((closeType: 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, SelectPopupState>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.
SelectGroup
/select-group.mdUma família dentro da lista, com o SelectGroupLabel de cabeçalho.
Natureza de operação separada em entrada e saída, UF por região, plano de contas por grupo: a lista longa que tem famílias de verdade lê-se por partes, e não de cima a baixo.
O desenho é o do ComboboxGroup, e não o do MenuGroup com label: as duas são
peças de formulário e listam opções, e quem troca uma pela outra ao descobrir que
a lista cresceu não deveria ter que reescrever a árvore.
<SelectContent>
<SelectGroup>
<SelectGroupLabel>Saída</SelectGroupLabel>
<SelectItem value="5102">Venda de mercadoria</SelectItem>
<SelectItem value="5915">Remessa para conserto</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectGroupLabel>Entrada</SelectGroupLabel>
<SelectItem value="1202">Devolução de venda</SelectItem>
</SelectGroup>
</SelectContent>
O items da raiz continua sendo a lista inteira e plana: é por ele que o
gatilho traduz o valor guardado no rótulo que a pessoa leu. O grupo arruma a
lista aberta, e não o que o gatilho mostra.
O SelectGroupLabel vive dentro do grupo porque é o grupo que aponta o
aria-labelledby para ele. Título escrito ao lado não nomeia nada, e nenhum
tipo reclama.
Quando não usar
Quando agrupar é a tentativa de domar uma lista que ficou grande demais, o
remédio é outro: Combobox, que traz a busca. Rolar cento e vinte cidades
arrumadas por região continua sendo rolar cento e vinte cidades, e o cabeçalho só
acrescenta altura ao caminho.
Grupo de dois itens não paga o cabeçalho que cobra. Sem famílias de verdade, a lista plana diz a mesma coisa em menos linhas.
| Prop | Tipo |
|---|---|
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, SelectGroupState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
SelectItem
/select-item.mdUma opção da lista.
O value é o que volta no onValueChange; o conteúdo é o que a pessoa lê. A
marca de escolhido tem coluna própria, então rótulo curto e longo alinham pela
mesma vertical.
| Prop | Tipo |
|---|---|
disabled0.4.0Whether the component should ignore user interaction. | boolean |
label0.4.0Specifies the text label to use when the item is matched during keyboard text navigation. | string |
nativeButton0.4.0Whether the component renders a native `<button>` element when replacing it via the `render` prop. | boolean |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, SelectItemState>ReactElement<unknown, stringJSXElementConstructor<any>> |
value0.4.0A unique value that identifies this select item. | any |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
SelectSeparator
/select-separator.mdA linha entre dois grupos da lista.
Ela sai com role="presentation", e não com o role="separator" do
MenuSeparator. A diferença não é de aparência: dentro de uma lista de opções,
um nó com papel próprio entra na contagem que o leitor de tela anuncia ("opção 3
de 12"), e a conta passa a não bater com o que se vê.
Quando não usar
Sem SelectGroup em volta, ela separa o quê? Numa lista plana a linha vira
divisão sem critério: quem lê procura o motivo do corte e não acha. Se o motivo
existe, ele tem nome, e o nome é um SelectGroupLabel.
| 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, SelectSeparatorState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
SelectTrigger
/select-trigger.mdO campo fechado do select: mostra a escolha e abre a lista.
Tem a mesma altura e a mesma borda do Input, para um formulário misto não sair
desalinhado. A seta é desenhada aqui, não passe ícone por fora.
| Prop | Tipo |
|---|---|
disabled0.4.0Whether the component should ignore user interaction. | boolean |
nativeButton0.4.0Whether the component renders a native `<button>` element when replacing it via the `render` prop. | boolean |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, SelectTriggerState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
SelectValue
/select-value.mdO texto do gatilho: o que está escolhido agora.
Passe items com { label, value } no Select para ele mostrar o rótulo.
Sem isso ele mostra o valor cru, porque só a lista sabe traduzir um pelo outro.
É contrato da Base UI, e a armadilha mais fácil de cair neste componente.
| Prop | Tipo |
|---|---|
placeholder0.4.0The placeholder value to display when no value is selected. | ReactNode |
render0.4.0Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ComponentRenderFn<HTMLProps, SelectValueState>ReactElement<unknown, stringJSXElementConstructor<any>> |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.