Switch
Alternador on/off sobre o primitivo Radix, com uma prop visual para reproduzir o estado misto do Switch legado.
Instalação
Recebe correções por update de versão. O caminho recomendado.
npm i @trdr/ui
import { Switch } from "@trdr/ui/switch"Uso
import { Switch } from "@trdr/ui/switch"
export function Exemplo() {
return <Switch />
}Props
SwitchPropsestende React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>| Prop | Tipo | Descrição |
|---|---|---|
| mixed? | boolean | Estado misto (indeterminado), herdado do Switch legado (`SwitchType = "on" | "off" | "mixed"`). Decisao de migracao: o Radix Switch so modela `checked` como booleano, sem terceiro estado nativo (ao contrario do Checkbox, cujo `CheckedState` ja inclui "indeterminate"). Reproduzir o misto exigiria bifurcar o primitivo ou reimplementar o Switch do zero, o que contradiz o proposito de usar o Radix como base. Em vez disso, o misto vira uma prop puramente visual por cima do primitivo: com `mixed`, incluimos `aria-checked="mixed"` no objeto de props passado ao `Root` (o Radix monta o seu proprio `aria-checked` antes de espalhar o restante das props recebidas, entao a chave so pode existir quando queremos vencer a sobrescrita; passar `undefined` no lugar de omitir a chave apagaria o valor correto do Radix quando `mixed` for falso) e trocamos o thumb pelo traco central do legado. O `checked` on/off interno do Radix continua existindo por baixo: a primeira interacao do usuario resolve o misto para um dos dois lados, o mesmo comportamento do Checkbox indeterminado. |
Quando usar
Use o switch para ligar ou desligar uma preferencia com efeito imediato: notificacoes, modo escuro, um recurso experimental. Ele e a metafora de uma chave liga/desliga, diferente do checkbox dentro de um formulario que so aplica a mudanca ao confirmar.
Quando nao usar
Nao use switch dentro de um formulario que so aplica a mudanca ao confirmar: use Checkbox.
Nao use switch para selecao unica entre tres ou mais opcoes: isso e toggle-group (quando
existir) ou radio-group.
Anatomia
Switch(data-slot="switch"): a raiz interativa, comrole="switch"herdado do Radix.switch-thumb(data-slot="switch-thumb"): o circulo que desliza entre os dois lados da trilha.switch-mixed-indicator(data-slot="switch-mixed-indicator"): so existe quandomixedesta ativo, um traco central que substitui o thumb, replicando o icone doSwitchlegado.
Rotulo nao faz parte do componente, assim como no Checkbox. Componha com um <label> ou use
aria-label quando nao houver texto visivel.
Decisao sobre o estado misto
O Switch legado do Hub tinha tres estados (on, off, mixed), com um icone de traco no
misto. O Switch do Radix, ao contrario do Checkbox, so modela checked como booleano: nao
existe um terceiro estado nativo equivalente ao indeterminate do checkbox.
Duas saidas eram possiveis: reportar que o misto nao sobrevive a migracao, ou reconstruir o
misto por cima do primitivo sem abrir mao do Radix como base. Escolhemos a segunda. A prop
mixed e puramente visual: quando verdadeira, o componente inclui aria-checked="mixed" no
conjunto de props passado ao Root (o Radix monta o proprio aria-checked antes de espalhar o
restante das props recebidas, entao a chave so existe quando mixed for verdadeiro, nunca como
undefined, senao apagaria o valor correto do Radix quando o switch nao esta misto) e troca o
thumb pelo traco central. O estado interno on/off do Radix continua existindo por baixo do
misto: assim que o usuario interage, o Switch resolve para um dos dois lados, o mesmo
comportamento que o Checkbox ja tem quando sai do indeterminado.
Acessibilidade
role="switch" e aria-checked (incluindo "mixed") chegam corretos ao leitor de tela sem
configuracao adicional. O componente funciona por teclado: Tab foca, Espaco alterna. Estado
desabilitado usa o atributo disabled nativo, nunca so opacidade. Todo Switch sem texto
visivel ao lado precisa de aria-label.
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="switch"][data-slot="switch-mixed-indicator"][data-slot="switch-thumb"]8 tokens usados
bg-backgroundbg-primaryborder-transparentoutline-nonering-offset-2ring-offset-backgroundring-ringshadow-none