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
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
- Slider precisa de
min,maxe valor atual claros. - Ticks só quando poucos passos discretos importam.
- Motion deve ser sutil e seguir tokens.
- Não use Slider para esconder decisão complexa.
- Para risco, explique consequência; o número sozinho não basta.
Last updated on