Slider

Pick a value or a range on a track that follows your finger.

sliderrangeinput
Preview
Slider preview
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
Volume

Currently 40%.

Keyboard interactions

KeysAction
ArrowRight / ArrowUpIncreases by step.
ArrowLeft / ArrowDownDecreases by step.
Shift + Arrow / PageUp / PageDownMoves by largeStep.
Home / EndMoves 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.