For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Slider

A draggable input for selecting a numeric value or range, with support for steps, vertical orientation, and audio feedback.

Volume40%
Price range$20 – $70
Step (25)50
Disabled
import { useState } from "react";
import { Slider } from "@/components/ui/slider";

export const SliderDemo = () => {
  const [single, setSingle] = useState([40]);
  const [range, setRange] = useState([20, 70]);
  const [stepped, setStepped] = useState([50]);

  return (
    <div className="flex flex-col gap-8 px-2">
      {/* Default */}
      <div className="flex flex-col gap-2">
        <div className="text-muted-foreground flex justify-between text-xs">
          <span>Volume</span>
          <span>{single[0]}%</span>
        </div>
        <Slider value={single} onValueChange={setSingle} min={0} max={100} sounds />
      </div>
      {/* Range */}
      <div className="flex flex-col gap-2">
        <div className="text-muted-foreground flex justify-between text-xs">
          <span>Price range</span>
          <span>${range[0]} – ${range[1]}</span>
        </div>
        <Slider value={range} onValueChange={setRange} min={0} max={100} sounds />
      </div>
      {/* Stepped */}
      <div className="flex flex-col gap-2">
        <div className="text-muted-foreground flex justify-between text-xs">
          <span>Step (25)</span>
          <span>{stepped[0]}</span>
        </div>
        <Slider value={stepped} onValueChange={setStepped} min={0} max={100} step={25} sounds />
      </div>
      {/* Disabled */}
      <div className="flex flex-col gap-2">
        <span className="text-muted-foreground text-xs">Disabled</span>
        <Slider defaultValue={[60]} disabled />
      </div>
      {/* Vertical */}
      <div className="flex items-end gap-6">
        {[30, 60, 80].map((v, i) => (
          <Slider key={i} defaultValue={[v]} orientation="vertical" className="h-28" />
        ))}
      </div>
    </div>
  );
};

Range slider

Pass two values to defaultValue (or value) to render a range slider with two thumbs.

<Slider defaultValue={[20, 70]} min={0} max={100} />

Step

<Slider defaultValue={[50]} step={25} />

Vertical

<Slider defaultValue={[60]} orientation="vertical" className="h-32" />

Controlled

const [value, setValue] = useState([40]);
 
<Slider value={value} onValueChange={setValue} />

With sounds

Pass sounds to play a tick on every value change.

<Slider defaultValue={[50]} sounds />

Props

PropTypeDefaultDescription
defaultValuenumber[][0]Uncontrolled initial value
valuenumber[]—Controlled value
onValueChange(value: number[]) => void—Fires on every thumb move
onValueCommit(value: number[]) => void—Fires on pointer up / key release
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Step interval
orientation"horizontal" | "vertical""horizontal"Slider direction
disabledbooleanfalseDisables interaction
soundsbooleanfalsePlays tick audio on value change

Usage

import { Slider } from "@/components/ui/slider";
 
<Slider defaultValue={[50]} max={100} step={1} />

Specs

# Mint — Slider Specs
 
## Component
- name: slider
- file: registry/mint/slider.tsx
- installs to: components/ui/slider.tsx
- dependencies: radix-ui
- registryDependencies: none
 
## What is it
A Radix UI Slider wrapper for selecting a numeric value or a range. Thumbs
are auto-generated from the length of the value/defaultValue array — pass one
value for a single thumb, two for a range slider with two thumbs. Prefer
Slider over a plain input[type=range] when you need range selection, step
snapping, vertical orientation, or audio feedback.
 
## Visual identity
Minimal and tactile. A muted track with a primary-coloured fill and a
circular thumb with a subtle shadow creates clear affordance without visual
noise. The rounded-full geometry is consistent with Mint's radius
language. In dark mode the thumb's background inverts to the dark surface
colour, keeping contrast clean.
 
## Design tokens
--muted: oklch(0.96 0.02 155) / oklch(0.2 0.03 155)         — track background
--primary: oklch(0.5 0.14 155) / oklch(0.62 0.15 155)       — range fill and thumb border
--background: oklch(1 0 0) / oklch(0.145 0 0)        — thumb fill
--ring: oklch(0.5 0.14 155) / oklch(0.62 0.15 155)          — focus ring on thumb (ring-ring/50)
 
## Sub-components
- Slider (Root)   → outer positioning container; owns orientation, disabled, and data-slot="slider"
- SliderTrack     → full-width/height muted bar; data-slot="slider-track"
- SliderRange     → primary-coloured fill between origin and thumb(s); data-slot="slider-range"
- SliderThumb     → draggable circular handle, one per value entry; data-slot="slider-thumb"
 
## States
- focus-visible: 3px ring in --ring/50 on the thumb; outline-none suppresses default
- disabled:      data-[disabled]:opacity-50 on root; disabled:pointer-events-none on thumb
- orientation=vertical: data-[orientation=vertical] swaps flex direction, width, and height classes on root, track, and range
 
## Conventions
- Range slider: pass two values to defaultValue/value (e.g. defaultValue={[20, 70]})
- Vertical sliders require an explicit height on the Slider element (e.g. className="h-32")
- sounds / haptic: GIN Design exclusive — plays a "tick" audio via useFeedback on every onValueChange
- Sub-components expose data-slot="slider", data-slot="slider-track", data-slot="slider-range", and data-slot="slider-thumb" for CSS targeting
- Thumbs are rendered dynamically from the value array length — do not render SliderThumb manually
- Always provide an accessible label via aria-label or an associated <label> element

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/slider