Slider
MD, under 1950B gzippedA native range input with an RTL-correct thumb direction.
- Category
- Forms & input
- Budget
- md, several states or a live subscription
- Runtime deps
- None
Preview
This is the exact fixture the conformance suite renders in CI. Switch the language to see the component mirror and reformat.
Install
npx shadcn@latest add https://kata-ui-rho.vercel.app/r/slider.jsonCopies the source into your project. Pulls in 1 primitive: cn.
Source
"use client";
import { useId } from "react";
import { cn } from "../lib/cn";
import { useLocale } from "../lib/use-locale";
export interface SliderProps {
value: number;
min?: number;
max?: number;
step?: number;
label: string;
onChange: (value: number) => void;
className?: string;
}
/**
* A native range input. The direction the thumb moves for "increase" already
* flips correctly under `dir="rtl"` in every real browser — a from-scratch
* custom slider has to reimplement that by hand and reliably gets it
* backwards on the first attempt.
*/
export function Slider({ value, min = 0, max = 100, step = 1, label, onChange, className }: SliderProps) {
const id = useId();
const { locale } = useLocale();
return (
<div className={cn("flex flex-col gap-1.5 text-start", className)}>
<div className="flex justify-between text-sm">
<label htmlFor={id}>{label}</label>
<span aria-hidden="true">{new Intl.NumberFormat(locale).format(value)}</span>
</div>
<input
id={id}
type="range"
min={min}
max={max}
step={step}
value={value}
onChange={(event) => onChange(Number(event.target.value))}
className="h-2 w-full cursor-pointer accent-blue-600"
/>
</div>
);
}
What CI checks
- Bundled, minified and gzipped against its tier budget
- Audited by axe in the state previewed above
- Rendered through react-dom/server with no browser globals
- Scanned for network calls, dangerous sinks, and unguarded animation