Nash Switch
← Design system · Componentes N.A.S.H. DS Toggle Switch 329:2890

Switch

O interruptor de qualquer preferência: um trilho de 48 × 24 em pílula, o thumb de 20 que viaja 24 e acende no accent com o Accent Glow, e o Automatic, o thumb esticado pelo trilho inteiro. Três estados desenhados (Off, On, Automatic) e os que um interruptor precisa além deles: hover, pressão, foco pelo teclado, desabilitado. O accent é o do modo, a mesma tabela das quatro peças anteriores. Os nomes são os do mapa de vocabulário: aria-checked true, false e mixed.

modo no ar: Chatúltimo gesto: nenhumpasse o cursor · aperte · clique · Tab e espaço

Os três estados

O quadro do Figma, congelado: não respondem ao ponteiro. State=Off, On e Automatic, como a referência desenhou; ao lado, o Hover e o Pressed que a peça define e o Figma ainda não desenha. Em código, aria-checked e data-state.

Off On Automatic Hover · pendente Pressed · pendente

Anatomia

Ligado e Automatic, ampliados 2,2×. Numerado é o que o CSS desenha; cotado é o que o Figma mede.

Trilho 48 × 24 · raio 12 · stroke 1,5 por dentro Thumb 20 a 2 da borda · viaja 24 · Automatic 44 × 20 · área de toque 44
  1. A casca.O label com o checkbox nativo dentro (ou o button role="switch"), 44 de alto no mínimo: a área de toque que a descrição do Figma pede, com o trilho de 24 no meio. É ela que recebe o ponteiro, o clique e o teclado.
  2. O trilho.48 × 24 em pílula, #0D0F12 a 32% com o vidro desfocado atrás; #1F2128 a 40% sob o ponteiro; #080A0D a 32% apertado, e, ligado, o mesmo #080A0D tingido com o accent a 12% (26% no Automatic). Os três fills são tokens do kit (--nash-placa, -hover, -pressed).
  3. Os anéis, 1,5px por dentro.Branco 15 › 6 › 2 › 0 no Off e no Automatic; accent 45 › 18 › 6 › 0 ligado ou em foco pelo teclado. A mesma máscara das quatro peças anteriores.
  4. O thumb.20, a 2 da borda, fundido em branco 11% com a borda de 0,5: o knob do Figma. Viaja 24 (--nash-switch-travel) e toma o accent com o Accent Glow (16px a 48%) ligado; no Automatic se estica até 44, o trilho inteiro, com o brilho a 20 e o reflexo branco por baixo. A pressão o alonga 15% na direção do gesto.
  5. A luz do cursor.Névoa de 2,4 alturas do trilho no accent a 12% e o anel aceso no ponto mais perto do ponteiro. Só existe com o ponteiro em cima; mais forte apertada ou ligada. Sobre o rótulo, aponta pra borda mais perto.
  6. A aura.Um elemento próprio (i.nash-switch-halo) que segue o contorno da pílula: uma sombra do accent a 48% cujas duas bordas são tokens registrados (--nash-switch-halo-inner/-outer). Ligar abre a borda de fora até 12px; desligar move a borda de dentro, e a luz é comida de dentro pra fora.
  7. O rótulo.O texto que a página escreveu, à direita, embrulhado pelo JS em .nash-switch-label; t3 (13) e toma o accent em 140 quando o interruptor liga. Opcional: as preferências do app escrevem o rótulo na linha, fora da peça.

O que o Figma diz e o que a peça faz

Coluna a coluna: a medida do Figma, o que o kit já tinha, e o que a peça adotou. O identificador sai do mapa de vocabulário; o Figma dá a base.

Figma 329:2890O kit / as quatro peçasA peça
Trilho 48 × 24, full-round; knob 20 a 2 da borda; no On à direita48 × 24, bolinha 20 que viajava --nash-curso (24)iguais; a viagem é --nash-switch-travel, calculada da geometria (48 − 20 − 2 × 2 = 24). A página que precisa de outra densidade escreve --nash-switch-track-width, -track-height e -thumb-size
Off: fill #1F2128 40% · stroke branco 11%--nash-branco-12 no trilho, sem anel#0D0F12 32% em repouso (--nash-placa), #1F2128 40% sob o ponteiro (--nash-placa-hover), #080A0D 32% apertado: as três placas da família. O fill do Off no Figma é a placa de hover; o anel é o branco 15 › 6 › 2 › 0 das irmãs
Knob fundido em branco 11%, borda 0,5 (Knob Surface)--nash-branco-62, sem bordabranco 11% com a borda de 0,5, como o Figma
On: accent 12% no fundo, 35% na borda; knob no accent com o Accent Glow (#3F8CFF 48%, raio 16)--nash-branco-18 no trilho; a bolinha no --accent com --nash-glow-curto (10px a 32%)trilho #080A0D tingido com o accent a 12%; anel de accent 45 › 18 › 6 › 0; o thumb no accent com o brilho de 16px a 48% (o Accent Glow), que respira. O accent é o do modo (data-mode); o Figma desenha o On em verde e anota #3F8CFF
Automatic: knob 44 × 20, branco 11%, borda 0,5, Accent Glow a 20 + brilho branco 30% (0 5 13,75); trilho com accent 26%, stroke branco 15%—aria-checked="mixed" (ou :indeterminate no checkbox): o thumb se estica até 44, o trilho tinge a 26%, o anel branco fica; os dois brilhos do Figma. E um laço: a luz percorre o thumb em 2,4s
Sem Hover, Pressed, foco, desabilitadooutline de 2px no foco; o efeito deslize (180, halo 260)hover (placa + luz do cursor), pressão (o thumb alonga 15% na direção do gesto, 100/160), :focus-visible (anel de accent + outline), :disabled (50%). Pendentes no Figma
"Área clicável até cobrir 44 × 44"—a casca tem 44 de alto no mínimo (--nash-alvo-solto); o trilho de 24 fica no meio
Nomes: Toggle Switch, State=Off · On · Automatic, knob.nash-switch, .nash-switch-track, .nash-switch-thumb, .nash-deslize.nash-switch (Toggle está na lista de nomes vetados do mapa); aria-checked="false|true|mixed"; .nash-switch-thumb. O deslize entrou na peça: efeito de um componente só não é camada. Token --nash-switch-*, runtime --nash-runtime-*, evento nash:change
Escala de tempo--nash-escala--nash-switch-time-scale, com --nash-escala da família como fallback
Movimento reduzido.nash-reduzido[data-motion="reduced"] num ancestral, o nome do vocabulário

O que se move

Toda curva é a de saída do kit. Dois laços, cada um preso a um estado: a respiração do ligado (um número, --nash-switch-breath, que o Accent Glow e a aura leem; ao desligar ele pausa onde está em vez de sumir) e a varredura do Automatic (outro número, --nash-switch-scan, que a luz dentro do thumb lê; pausa do mesmo jeito).

Ponteiro entra hover

A placa sobe de 32% a 40% e a luz do cursor acende. O anel branco já está a 1. Ligado e Automatic têm placa própria: o Figma não define Hover sobre On.

passe o cursor pelos dois
propriedadede → paratempo
placa#0D0F12 32% → #1F2128 40%180ms
luz do cursor0 → 1260ms

A luz do cursor vidro

Uma névoa de 2,4 alturas do trilho no accent e o anel aceso no ponto mais próximo do ponteiro. Segue em 70ms; apaga em 260 quando o ponteiro sai. Sobre o rótulo, a luz aponta pra borda mais perto. Apertada ou ligada, a névoa é mais forte.

arraste o cursor devagar pelo trilho e pelo rótulo
camadacortempo
névoaaccent 12% (ligado 18%, apertada 24%), 2,4 alturas260ms · segue em 70
anelaccent 70%, 1,4 altura260ms

Pressão pendente no Figma

A placa desce pro #080A0D e o thumb alonga 15% na direção do gesto em 100ms — desligado cresce pra direita, ligado pra esquerda, o Automatic encolhe dos dois lados; solta em 160. Não fica: o que fica é aria-checked.

segure o ponteiro apertado e solte fora, pra não trocar o estado
propriedadede → paratempo
placa→ #080A0D 32%180ms
thumblargura 20 → 23, ancorado no lado em que está100ms · solta em 160
luz do cursor12% → 24%260ms

Ligar, desligar, Automatic aria-checked

Ligar: o thumb viaja 24 pela curva de saída em 180 e toma o accent em 140; o trilho desce pro #080A0D tingido com o accent a 12%, o anel branco apaga e o de accent acende; o rótulo toma o accent. O Accent Glow espera 120 e vai a 22px antes de assentar em 16 — a curva do ponto da aba — com uma onda que se abre da borda e apaga, e a aura se abre do trilho até 12px além em 420. Total: 540ms. Depois, ligado, respira: brilho e aura, laço de 1,8s. Desligar: tudo volta nos mesmos tempos; o brilho apaga em 320; a aura é comida de dentro pra fora em 600 — a borda de dentro da sombra caminha até a de fora enquanto a luz cai — e a respiração pausa onde está, então nada salta. Automatic: o thumb se estica até o trilho inteiro em 180, o trilho tinge a 26%, os brilhos do Figma acendem em 320, e a luz começa a percorrer o thumb. O evento é nash:change, com true, false ou 'mixed'.

Ligar · 540ms

Desligar · 600ms

Automatic · 320ms, depois o laço de 2400

Automatic aria-checked="mixed"

O terceiro estado do Figma: o thumb ocupa os dois lados de uma vez. Enquanto dura, uma névoa do accent a 28%, meio thumb de largura, percorre o thumb de 15% a 85% e volta, em 2,4s. É um número registrado (--nash-switch-scan) numa animação que já existe em repouso, parada: sair do Automatic pausa em vez de remover.

propriedadede → paratempo
thumblargura 20 → 44; branco 11%180ms · 140ms
trilho→ #080A0D 32% com o accent a 26%180ms
brilhoAccent Glow 0 → 20px a 48%; reflexo branco 30% por baixo320ms
a luz no thumb--nash-switch-scan 0 → 1 → 0, ease-in-outlaço 2400ms

Foco pelo teclado pendente no Figma

Tab chega no checkbox, invisível dentro da casca; o trilho ganha o outline de 2px e o anel de accent. Espaço alterna. Na forma de botão, o próprio botão recebe o foco.

Tab até aqui, espaço pra ligar
propriedadede → paratempo
outline2px no accent, 2px fora do trilho0ms
anel de accent0 → 1260ms

A entrada uma vez

O trilho: opacidade 0 → 1 e scale 0,9 → 1 em 420ms, com `backwards`: o interruptor chega, não pisca.

propriedadede → paratempo
opacidade · scale0 → 1 · 0,9 → 1420ms

Uso

Dois arquivos do kit. A forma nativa liga e desliga sem JS; carregar o JS completa a luz, a aura, o rótulo e o evento em todo .nash-switch da página.

<link rel="stylesheet" href="css/nash-switch.css" />   ← depois de nash-componentes.css

// a forma nativa, a que o app e o site escrevem:
<label class="nash-switch" for="som"><input type="checkbox" id="som" /><span class="nash-switch-track"><i class="nash-switch-thumb"></i></span><span>Som do site</span></label>

// a forma curta — o JS completa o checkbox, o trilho e o rótulo:
<label class="nash-switch">Auto-chat</label>

// sem formulário:
<button class="nash-switch" role="switch" aria-checked="false">Câmera lenta</button>
<script src="js/nash-switch.js"></script>

const som = NashSwitch.mount('#som', {         // o id do checkbox ou da casca
  checked: 'mixed',                          // true · false · 'mixed' (Automatic)
  label: 'Som do site',                      // ou o texto que a página escreveu
  onChange(checked, s) {}                    // true · false · 'mixed'
})
som.setChecked(true)                          // checked + indeterminate no checkbox; aria-checked no botão
som.isChecked()                               // true · false · 'mixed'
som.el.addEventListener('nash:change', (e) => e.detail)   // { checked }

// variante congelada, pra documentação — não responde ao ponteiro:
<button class="nash-switch" role="switch" aria-checked="true" data-state="hover">Ligado</button>

// no interruptor:  aria-checked="true|false|mixed" (botão) · checked · indeterminate · disabled (checkbox) · data-mode="chat|voz|design|imagem|social"
// tokens:    --nash-switch-accent  · --nash-switch-travel (24)  · --nash-switch-track-width / -track-height / -thumb-size (densidade de tela)  · --nash-switch-time-scale
// na família:  --nash-escala: 4  (câmera lenta)  · [data-motion="reduced"]

Decisões