KDS
Forms

Switch

Toggle de efeito imediato — on / off, sem botão Salvar.

Overview

Switch é um toggle visual que sinaliza estado ligado / desligado. A diferença crítica em relação ao Checkbox é comportamental: Switch tem efeito imediato — o usuário move o controle e a mudança é persistida agora, sem botão Salvar. Checkbox faz parte de uma form que será submetida.

Use Switch em painéis de configurações (notificações, dark mode, permissões), feature flags, controles de produto. Não use Switch em forms multi-campo que terminam num Submit — ali, Checkbox é o componente correto.

Preview
Switch com Label ao lado.

Anatomy

<Switch>
  ├─ [data-slot="switch"]
  ├─ [data-state="checked" | "unchecked"]
  ├─ [data-size="sm" | "default"]
  └─ <Thumb /> (translate-x baseado no state)
</Switch>

Usage

import { Switch } from "@kalvner/kds/forms/switch";
import { Label } from "@kalvner/kds/forms/label";

export function NotificationsToggle() {
  return (
    <div className="flex items-center gap-3">
      <Switch
        id="notify"
        onCheckedChange={(v) => persist({ notify: v })}
      />
      <Label htmlFor="notify">Notificações</Label>
    </div>
  );
}

Props

PropTipoDefaultDescrição
checkedbooleanControlado.
defaultCheckedbooleanfalseNão controlado.
onCheckedChange(v: boolean) => voidCallback.
size'sm' | 'default''default'Altura do switch + thumb.
disabledbooleanfalseBloqueia interação.
idstringVincula ao Label.

Variants

Sizes
sm para listas densas, default para painéis.

States

Off
Background input, thumb à esquerda.
On
Background primary, thumb à direita.
Disabled
Sem pointer events, opacidade reduzida.
With label on the side
Padrão de painel de configurações.

Composition

Settings panel
Linhas com label + descrição + switch à direita.

Resumo diário e alertas importantes.

Recomendado — adiciona uma camada extra de segurança.

When to use

  • Configurações persistidas imediatamente (dark mode, notificações, feature flags do produto).
  • Permissões granulares em painéis de admin.
  • Qualquer "ligar/desligar" que tem efeito agora, sem submit.

When not to use

  • Em formulários multi-campo que terminam num submit — use Checkbox. Switch num form com Submit gera ambiguidade (a configuração foi aplicada agora ou só após submit?).
  • Para escolher entre múltiplas opções — use RadioGroup.
  • Para acionar uma ação destrutiva — use Button com Dialog de confirmação.

Best practices

  • Estado on é a configuração ativa. "Notificações" = ON significa notificações ativas. Evite labels invertidas como "Desativar notificações" — confunde o usuário do estado.
  • Persiste em onChange. Se a operação pode falhar (rede), mostre estado optimista + rollback em erro com Toast.
  • Não desabilite sem explicação. Switch desabilitado merece um Tooltip ou helper text dizendo o porquê.
  • Sem label "On / Off" próprio. O Label descreve o que é controlado; o estado é inferido do Switch.

Accessibility

ConcernComportamento
RolesRadix expõe role="switch" + aria-checked.
KeyboardTab foca; Space ou Enter alterna.
LabelVincule via htmlFor + id ou aria-label.
Disableddisabled bloqueia foco e interação.
Touch targetDefault size (32×18px) é pequeno para mobile — combine com Label clicável (a linha inteira em painéis), ampliando a área hit.
AnúncioLeitores de tela falam "ligado" / "desligado" + texto do label.
  • Checkbox — quando o valor faz parte de um form a ser submetido.
  • Form — wrappers de RHF para forms estruturados.

On this page