Slider
BetaElige un valor o un rango dentro de una escala, cuando la relación importa más que el número exacto.
registry/ds/slider.tsxVolumen
Cuota mensual
Deshabilitado
"use client";
import { useState } from "react";
import { Slider } from "@/registry/ds/slider";
export default function SliderBasic() {
const [range, setRange] = useState<number | number[]>([20000, 80000]);
return (
<div className="flex w-80 flex-col gap-8">
<Slider label="Volumen" defaultValue={40} showValue format={(v) => `${v}%`} />
<Slider label="Cuota mensual" min={0} max={150000} step={5000} value={range} onValueChange={setRange} showValue format={(v) => `$ ${v.toLocaleString("es-AR")}`} />
<Slider label="Deshabilitado" defaultValue={60} disabled />
</div>
);
}Cuándo usarlo
Para valores donde ver la posición ayuda más que escribir: volumen, presupuesto, un filtro de precio. Si la persona tiene un número exacto en la cabeza, es un Number field.
- Mostrá siempre el valor (
showValue) con su unidad. - Pasos sensatos: 5.000 en montos, 1 en porcentajes. Un paso muy fino vuelve imposible acertar.
- Rango con dos thumbs para "entre X e Y".
- Si el cambio dispara algo costoso (un fetch), usá
onValueCommitted.
Con campo numérico
Un valor, dos controles: el slider para explorar y un Number field para escribir el número exacto. Los dos leen y escriben el mismo estado.
Cuota máxima
7 carreras dentro del presupuesto.
"use client";
import { useState } from "react";
import { NumberField } from "@/registry/ds/number-field";
import { Slider } from "@/registry/ds/slider";
/** Un valor, dos controles: el slider para explorar, el campo numérico para escribir el número exacto */
export default function SliderControlled() {
const [cuota, setCuota] = useState<number | null>(45000);
const pesos = (v: number) => `$ ${v.toLocaleString("es-AR")}`;
return (
<div className="flex w-80 flex-col gap-5">
<Slider label="Cuota máxima" min={10000} max={150000} step={1000} value={cuota ?? 10000} onValueChange={(v) => setCuota(Array.isArray(v) ? v[0] : v)} showValue format={pesos} />
<NumberField aria-label="Cuota máxima, exacta" size="sm" value={cuota} onValueChange={setCuota} min={10000} max={150000} step={1000} format={{ style: "currency", currency: "ARS", maximumFractionDigits: 0 }} className="max-w-48" />
<p className="text-sm text-fg-muted">
{cuota !== null && cuota >= 100000 ? "Entran todas las carreras." : "7 carreras dentro del presupuesto."}
</p>
</div>
);
}Medidas
| Parte | Medida |
|---|---|
| Pista | alto 6 · radius-full · ancho 100 % |
| Thumb | 20 · borde 2 |
| Área de agarre | 36 de alto (padding vertical 8) |
| Label / valor | Text sm / Medium · Text sm |
| Parte | Propiedad | Token |
|---|---|---|
| Pista | Fondo | bg/surface |
| Relleno | Fondo | primary/solid |
| Thumb | Fondo | bg/elevated |
| Thumb | Borde → arrastrando | primary/accent |
| Thumb | Sombra | Elevation/sm |
| Foco | Anillo 2 px, separado 2 px | focus/ring |
| Deshabilitado | Todo | opacity-disabled |
Instalación
npx shadcn@latest add https://polen.cdc.cool/r/slider.jsonPlayground
Configurá el componente y copiá el snippet: se genera del mismo estado que renderiza el preview.
Cuota mensual
Formato
Paso
<Slider label="Cuota mensual" defaultValue={40} showValue />Props
Sobre Base UI Slider.
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
value / defaultValue | number | number[] | 0 | Un número, o [min, max] para rango. |
onValueChange | (value) => void | — | En cada movimiento. |
onValueCommitted | (value) => void | — | Al soltar. |
min · max · step | number | 0 · 100 · 1 | Escala y paso. |
label · showValue · format | ReactNode · boolean · (v) => string | — | Label visible, valor a la derecha y cómo escribirlo. |
disabled · name · aria-label | — | — | Como en el resto. |
| Tecla | Qué hace |
|---|---|
| ←→ | Un paso. |
| PageUpPageDown | Diez pasos. |
| HomeEnd | Mínimo / máximo. |
- Cada thumb es un
role="slider"conaria-valuenow/min/maxy el valor formateado comoaria-valuetext; en rango se llaman "Mínimo" y "Máximo". - El thumb mide 20 pero el área de agarre vertical es 36: cumple el target mínimo.
- El valor nunca se comunica solo con la posición:
showValue.