Slider
Pick a value or a range on a track that follows your finger.
sliderrangeinput
Preview
Slider preview
Live · keyboard ready
Volume
When to use
- Approximate values like volume, opacity, or a price range.
- Ranges with two thumbs, labelled marks, and a formatted readout.
When not to use
- Use number-field when the exact number matters.
- Use progress to show a value people cannot change.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "slider",
"type": "registry:ui",
"title": "Slider",
"description": "Pick a value or a range on a track that follows your finger.",
"categories": [
"inputs"
],
"dependencies": [
"motion"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/slider/slider.tsx",
"type": "registry:component",
"target": "@components/manicat/slider/slider.tsx"
},
{
"path": "registry/components/slider/slider.module.css",
"type": "registry:component",
"target": "@components/manicat/slider/slider.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/slider",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/slider",
"markdown": "https://uiarc.dev/components/slider/markdown",
"tags": [
"slider",
"range",
"input"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { useState } from "react";
import type { SliderValue } from "@/components/manicat/slider/slider";
import { Slider } from "@/components/manicat/slider/slider";
export function SliderExample() {
const [volume, setVolume] = useState<SliderValue>(40);
return <Slider label="Volume" value={volume} onValueChange={setVolume} />;
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Volume A labelled slider with the value reflected next to the control.
Volume
A labelled slider with the value reflected next to the control. preview
Live · keyboard ready
Volume
Currently 40%.
volume-a-labelled-slider-with-the-value-reflected-next-to-the-control-.tsxtsx
"use client";
import { useState } from "react";
import { Slider } from "@/components/manicat/slider/slider";
import type { SliderValue } from "@/components/manicat/slider/slider";
export function SliderVolumeExample() {
const [volume, setVolume] = useState<SliderValue>(40);
return (
<div className="grid w-full max-w-sm gap-2">
<Slider label="Volume" value={volume} onValueChange={setVolume} />
<p className="text-sm text-(color:--text-muted)">Currently {String(volume)}%.</p>
</div>
);
}
Keyboard interactions
| Keys | Action |
|---|---|
| ArrowRight / ArrowUp | Increases by step. |
| ArrowLeft / ArrowDown | Decreases by step. |
| Shift + Arrow / PageUp / PageDown | Moves by largeStep. |
| Home / End | Moves to the lowest or highest allowed value for that thumb. |
Accessibility
- Each thumb is role="slider" with aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext from format, and aria-orientation.
- Thumbs are named by label, or by thumbLabels for ranges.
- The readout, bubble, and marks are aria-hidden because the thumbs carry the value.
Motion
- Released drags carry a little momentum before snapping; the bubble springs up over an active thumb and digits roll in the readout. At a limit the thumb strains toward the key press and springs back.
- Reduced motion removes momentum, the strain, and digit rolling, and turns off CSS transitions.
Responsive behavior
- It fills its column; the track uses touch-action pan-y, so horizontal drags move the thumb while vertical swipes scroll the page.
- On coarse pointers the value bubble sits higher so the finger does not cover it.
- The bubble and end mark labels clamp inside the track so they never overflow the edges.
Performance
- Drags write motion values with pointer capture, so the thumb follows 1:1 without React re-renders per frame.
- onValueChange fires on every step; put fetching or heavy work in onValueCommit.
Notes for AI
- Use for approximate values and ranges like volume, price filters, or opacity. Use number-field when the exact number matters.
- Controlled or uncontrolled; pass a tuple for a range. Put heavy work such as fetching in onValueCommit, not onValueChange.
- Pass name to submit through hidden inputs. Exported as both named and default.