Select

Formulario

Seletor de uma opção entre várias, com overlay, grupos, rótulos e navegação por teclado sobre o primitivo Radix.

Carregando

Instalação

Recebe correções por update de versão. O caminho recomendado.

npm i @trdr/ui

import { Select } from "@trdr/ui/select"

Uso

import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton } from "@trdr/ui/select"

export function Exemplo() {
  return <Select />
}

Variantes

GrupoValoresPadrão
variant
outlineghost
outline
size
defaultlg
default

Props

SelectPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root>
SelectGroupPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Group>
SelectValuePropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>
SelectTriggerPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>, VariantProps<typeof selectTriggerVariants>
PropTipoDescrição
iconLeft?React.ReactNodeCorresponde ao `iconLead` do Dropdown legado: um icone decorativo antes do valor, com o mesmo chip de fundo (`surface-secondary`) que o legado usava para destacar o icone da borda do trigger.
SelectScrollUpButtonPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
SelectScrollDownButtonPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
SelectContentPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
SelectLabelPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
SelectItemPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
SelectSeparatorPropsestende React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>

Quando usar

Use o select para escolher um valor entre um conjunto conhecido de opcoes, quando a lista nao precisa ficar visivel o tempo todo: ativo de uma corretora, categoria de um formulario, unidade de uma grandeza. Ele abre um overlay com a lista completa e fecha ao selecionar, navegar com Escape ou clicar fora.

Quando nao usar

Nao use select para duas ou tres opcoes mutuamente exclusivas sempre visiveis: um radio-group comunica isso melhor porque nao exige um clique extra so para ver as alternativas. Nao use select para o campo de valor acoplado a um seletor da boleta de operacao (o antigo "Combo Input"): esse caso agora e o input-group, uma composicao diferente porque tem um campo de texto editavel, nao so uma lista fechada de opcoes.

Anatomia

<Select>                                 contexto, nao renderiza DOM
  <SelectTrigger data-slot="select-trigger">
    <span data-slot="select-icon-lead">  opcional, so quando iconLeft e passado
    <SelectValue data-slot="select-value" />
    <ChevronDown data-slot="select-chevron" />
  </SelectTrigger>
  <SelectContent data-slot="select-content">   portal + posicionamento
    <SelectGroup data-slot="select-group">
      <SelectLabel data-slot="select-label" />
      <SelectItem data-slot="select-item">
        <span data-slot="select-item-indicator" />   check, so quando selecionado
      </SelectItem>
    </SelectGroup>
    <SelectSeparator data-slot="select-separator" />
  </SelectContent>
</Select>

Variantes

  • variant no SelectTrigger: outline (borda visivel, padrao) e ghost (sem borda, se funde no fundo ao redor). Equivalente ao booleano stroke do Dropdown legado, renomeado para o vocabulario variant/size/tone do restante da biblioteca: stroke={true} virou outline, stroke={false} virou ghost.
  • size: default (24px de altura) e lg (32px), a mesma escala do Button e do Input.
  • iconLeft: icone decorativo antes do valor, com o mesmo chip de fundo (surface-secondary) do iconLead legado.

O estado "ativo" do legado (state="active", borda tingida enquanto a lista esta aberta) e automatico aqui: o SelectTrigger usa data-[state=open]:border-ring, refletindo o estado real do Radix em vez de uma prop que o consumidor precisava setar a mao.

Migracao do componente legado

O Dropdown do Hub antigo (Dropdown.tsx + .trdr-dropdown) era um botao sem overlay proprio: ele so trocava de aparencia (state="active"), e quem abria e fechava a lista, e quem desenhava as opcoes, era o consumidor em outro lugar. Isso significava reimplementar navegacao por teclado, fechamento por clique fora e posicionamento toda vez que o Hub usava um dropdown de verdade. Aqui o Select e o primitivo Radix inteiro: ganha overlay, Escape, seta para cima/baixo, digitacao para buscar por letra e portal, de graca. O preco dessa migracao e que o Select precisa de SelectItems de verdade (nao so uma string de valor), e o "sem borda" que era a prop stroke virou a variante variant="ghost".

Acessibilidade

  • SelectTrigger tem role="combobox" e aria-expanded geridos pelo Radix; funciona por teclado (Espaco/Enter/setas abrem, Escape fecha sem selecionar, digitar letras pula para a opcao correspondente).
  • Todo SelectTrigger sem rotulo visivel ao lado precisa de aria-label (ou um label associado por id, fora de escopo aqui).
  • SelectItem desabilitado usa data-disabled do proprio Radix, nunca so opacidade visual: o item some da navegacao por teclado junto com a mudanca de estilo.
  • O indicador de selecao (select-item-indicator) reserva o mesmo espaco esteja ou nao marcado, entao o texto de todos os itens fica alinhado, selecionados ou nao.

Slots e tokens

Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.

[data-slot="select-chevron"][data-slot="select-content"][data-slot="select-group"][data-slot="select-icon-lead"][data-slot="select-item"][data-slot="select-item-indicator"][data-slot="select-label"][data-slot="select-scroll-down-button"][data-slot="select-scroll-up-button"][data-slot="select-separator"][data-slot="select-trigger"][data-slot="select-value"][data-slot="select-viewport"]
21 tokens usados
bg-accentbg-border-subtlebg-popoverbg-surface-primarybg-surface-secondaryborder-borderborder-border-strongborder-ringborder-transparentoutline-nonering-offset-2ring-offset-backgroundring-ringshadow-mdtext-accent-foregroundtext-auxtext-b3text-content-brandtext-content-primarytext-content-tertiarytext-popover-foreground