Skip to Content
ComponentsAtomsSlider

Slider

Atom

Slider ajusta um valor dentro de uma faixa conhecida. Use quando a posição relativa importa tanto quanto o número.

Slider funciona bem para limiares, sensibilidade e parâmetros operacionais com ordem clara. Evite quando o valor exato é mais importante que a comparação visual; nesses casos, use Input numérico.

Exemplos copiáveis

React

import * as React from "react" type PulsoSliderProps = { label: string min?: number max?: number step?: number value: number onChange: (value: number) => void description?: string } export function PulsoSlider({ label, min = 0, max = 100, step = 1, value, onChange, description, }: PulsoSliderProps) { const clampedValue = Math.min(max, Math.max(min, value)) const percent = ((clampedValue - min) / (max - min)) * 100 const descriptionId = React.useId() function updateValue(nextValue: number) { const stepped = Math.round(nextValue / step) * step onChange(Math.min(max, Math.max(min, stepped))) } return ( <div className="grid gap-2"> <div className="flex items-baseline justify-between gap-4"> <label className="font-mono text-[10.5px] uppercase tracking-[var(--tracking-kicker)] text-[var(--fg-subtle)]"> {label} </label> <span className="font-mono text-sm tabular-nums text-[var(--fg-strong)]"> {clampedValue} </span> </div> <input type="range" min={min} max={max} step={step} value={clampedValue} onChange={(event) => updateValue(Number(event.target.value))} aria-label={label} aria-describedby={description ? descriptionId : undefined} style={{ background: `linear-gradient(to right, var(--primary) 0%, var(--primary) ${percent}%, var(--border-strong) ${percent}%, var(--border-strong) 100%)`, }} className="h-[18px] w-full cursor-pointer appearance-none rounded-full accent-[var(--primary)] focus-visible:outline focus-visible:outline-[var(--ring-width)] focus-visible:outline-offset-2 focus-visible:outline-[var(--ring)] disabled:cursor-not-allowed disabled:opacity-60" /> <div className="flex justify-between font-mono text-[10px] uppercase tracking-[0.05em] text-[var(--fg-subtle)]"> <span>{min}</span> <span>{max}</span> </div> {description ? ( <p id={descriptionId} className="text-xs text-[var(--fg-muted)]"> {description} </p> ) : null} </div> ) }
const [threshold, setThreshold] = React.useState(62) <PulsoSlider label="Limiar de alerta" value={threshold} onChange={setThreshold} min={0} max={100} description="Acima deste valor, o sinal entra em atenção operacional." />

Quando usar

  • Limiar, sensibilidade ou peso operacional.
  • Ajuste relativo com faixa conhecida.
  • Parâmetro que pode ser testado e revertido.
  • Poucos passos discretos ou faixa contínua simples.

Quando não usar

  • Para datas, categorias ou valores sem ordem clara.
  • Quando o número exato precisa ser digitado.
  • Para risco operacional sem explicar consequência dos limiares.
  • Para ações destrutivas ou irreversíveis.

Acessibilidade

  • Sempre mostre o valor atual em texto.
  • Use label programático e texto visível.
  • O controle precisa funcionar por teclado.
  • Explique o que muda ao cruzar limiares importantes.

Regras

  1. Slider precisa de min, max e valor atual claros.
  2. Ticks só quando poucos passos discretos importam.
  3. Motion deve ser sutil e seguir tokens.
  4. Não use Slider para esconder decisão complexa.
  5. Para risco, explique consequência; o número sozinho não basta.
Last updated on