SliderPreview

A slider allows a user to select one or more values within a range

Import

import { Slider } from '@heroui/react';

Usage

30
import {Label, Slider} from "@heroui/react";

export function Default() {
  return (
    <Slider className="w-full max-w-xs" defaultValue={30}>
      <Label>Volume</Label>
      <Slider.Output />
      <Slider.Track>
        <Slider.Fill />
        <Slider.Thumb />
      </Slider.Track>
    </Slider>
  );
}

Anatomy

Import the Slider component and access all parts using dot notation.

import { Slider, Label } from '@heroui/react';

export default () => (
  <Slider>
    <Label />
    <Slider.Output />
    <Slider.Track>
      <Slider.Fill />
      <Slider.Thumb />
    </Slider.Track>
  </Slider>
)

Range Slider Anatomy

import { Slider, Label } from '@heroui/react';

export default () => (
  <Slider defaultValue={[25, 75]}>
    <Label />
    <Slider.Output />
    <Slider.Track>
      {({state}) => (
        <>
          <Slider.Fill />
          {state.values.map((_, i) => (
            <Slider.Thumb key={i} index={i} />
          ))}
        </>
      )}
    </Slider.Track>
  </Slider>
)

Vertical

30
import {Label, Slider} from "@heroui/react";

export function Vertical() {
  return (
    <div className="flex h-64 items-center justify-center">
      <Slider className="h-full" defaultValue={30} orientation="vertical">
        <Label>Volume</Label>
        <Slider.Output />
        <Slider.Track>
          <Slider.Fill />
          <Slider.Thumb />
        </Slider.Track>
      </Slider>
    </div>
  );
}

Range

$100.00 – $500.00
"use client";

import {Label, Slider} from "@heroui/react";

export function Range() {
  return (
    <Slider
      className="w-full max-w-xs"
      defaultValue={[100, 500]}
      formatOptions={{currency: "USD", style: "currency"}}
      maxValue={1000}
      minValue={0}
      step={50}
    >
      <Label>Price Range</Label>
      <Slider.Output />
      <Slider.Track>
        {({state}) => (
          <>
            <Slider.Fill />
            {state.values.map((_, i) => (
              <Slider.Thumb key={i} index={i} />
            ))}
          </>
        )}
      </Slider.Track>
    </Slider>
  );
}

Disabled

30
import {Label, Slider} from "@heroui/react";

export function Disabled() {
  return (
    <Slider isDisabled className="w-full max-w-xs" defaultValue={30}>
      <Label>Volume</Label>
      <Slider.Output />
      <Slider.Track>
        <Slider.Fill />
        <Slider.Thumb />
      </Slider.Track>
    </Slider>
  );
}

Styling

Passing Tailwind CSS classes

import { Slider, Label } from '@heroui/react';

function CustomSlider() {
  return (
    <Slider className="w-full">
      <Label>Volume</Label>
      <Slider.Output className="text-muted-fg text-sm" />
      <Slider.Track className="h-2 rounded-full bg-surface-secondary">
        <Slider.Fill className="bg-accent" />
        <Slider.Thumb className="size-4 rounded-full bg-accent" />
      </Slider.Track>
    </Slider>
  );
}

Customizing the component classes

To customize the Slider component classes, you can use the @layer components directive.
Learn more.

@layer components {
  .slider {
    @apply flex flex-col gap-2;
  }

  .slider__output {
    @apply text-muted-fg text-sm;
  }

  .slider-track {
    @apply relative h-2 w-full rounded-full bg-surface-secondary;
  }

  .slider-fill {
    @apply absolute h-full rounded-full bg-accent;
  }

  .slider-thumb {
    @apply size-4 rounded-full bg-accent border-2 border-background;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The Slider component uses these CSS classes (View source styles):

Base Classes

  • .slider - Base slider container
  • .slider__output - Output element displaying current value(s)
  • .slider-track - Track element containing fill and thumbs
  • .slider-fill - Fill element showing selected range
  • .slider-thumb - Individual thumb element

State Classes

  • .slider[data-disabled="true"] - Disabled slider state
  • .slider[data-orientation="vertical"] - Vertical orientation
  • .slider-thumb[data-dragging="true"] - Thumb being dragged
  • .slider-thumb[data-focus-visible="true"] - Thumb keyboard focused
  • .slider-thumb[data-disabled="true"] - Disabled thumb state
  • .slider-track[data-fill-start="true"] - Fill starts at beginning
  • .slider-track[data-fill-end="true"] - Fill ends at end

Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

  • Hover: :hover or [data-hovered="true"] on thumb
  • Focus: :focus-visible or [data-focus-visible="true"] on thumb
  • Dragging: [data-dragging="true"] on thumb
  • Disabled: :disabled or [data-disabled="true"] on slider or thumb

API Reference

Slider Props

PropTypeDefaultDescription
valuenumber | number[]-The current value (controlled)
defaultValuenumber | number[]-The default value (uncontrolled)
onChange(value: number | number[]) => void-Handler called when the value changes
onChangeEnd(value: number | number[]) => void-Handler called when dragging ends
minValuenumber0The slider's minimum value
maxValuenumber100The slider's maximum value
stepnumber1The slider's step value
formatOptionsIntl.NumberFormatOptions-The display format of the value label
orientation"horizontal" | "vertical""horizontal"The orientation of the slider
isDisabledboolean-Whether the slider is disabled
aria-labelstring-Accessibility label for the slider
aria-labelledbystring-ID of element that labels the slider
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Slider content or render function

Slider.Output Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Output content or render function

Slider.Track Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Track content or render function

Slider.Fill Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
styleCSSProperties-Inline styles

Slider.Thumb Props

PropTypeDefaultDescription
indexnumber0Index of the thumb within the slider
isDisabledboolean-Whether this thumb is disabled
namestring-The name of the input element, used when submitting an HTML form
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Thumb content or render function

RenderProps

When using render functions with Slider.Output or Slider.Track, these values are provided:

PropTypeDescription
stateSliderStateThe state of the slider
valuesnumber[]Values managed by the slider by thumb index
getThumbValueLabel(index: number) => stringReturns the string label for the specified thumb's value
orientation"horizontal" | "vertical"The orientation of the slider
isDisabledbooleanWhether the slider is disabled

Examples

Basic Usage

import { Slider, Label } from '@heroui/react';

<Slider defaultValue={30}>
  <Label>Volume</Label>
  <Slider.Output />
  <Slider.Track>
    <Slider.Fill />
    <Slider.Thumb />
  </Slider.Track>
</Slider>

Range Slider

import { Slider, Label } from '@heroui/react';

<Slider
  defaultValue={[100, 500]}
  formatOptions={{style: "currency", currency: "USD"}}
  maxValue={1000}
  minValue={0}
  step={50}
>
  <Label>Price Range</Label>
  <Slider.Output />
  <Slider.Track>
    {({state}) => (
      <>
        <Slider.Fill />
        {state.values.map((_, i) => (
          <Slider.Thumb key={i} index={i} />
        ))}
      </>
    )}
  </Slider.Track>
</Slider>

Controlled Value

import { Slider, Label } from '@heroui/react';
import { useState } from 'react';

function ControlledSlider() {
  const [value, setValue] = useState(25);

  return (
    <>
      <Slider value={value} onChange={setValue}>
        <Label>Volume</Label>
        <Slider.Output />
        <Slider.Track>
          <Slider.Fill />
          <Slider.Thumb />
        </Slider.Track>
      </Slider>
      <p>Current value: {value}</p>
    </>
  );
}

Custom Value Formatting

import { Slider, Label } from '@heroui/react';

<Slider
  defaultValue={60}
  formatOptions={{style: "currency", currency: "USD"}}
>
  <Label>Price</Label>
  <Slider.Output />
  <Slider.Track>
    <Slider.Fill />
    <Slider.Thumb />
  </Slider.Track>
</Slider>

Vertical Orientation

import { Slider, Label } from '@heroui/react';

<Slider defaultValue={30} orientation="vertical" aria-label="Volume">
  <Label>Volume</Label>
  <Slider.Output />
  <Slider.Track>
    <Slider.Fill />
    <Slider.Thumb />
  </Slider.Track>
</Slider>

Custom Output Display

import { Slider, Label } from '@heroui/react';

<Slider defaultValue={[25, 75]}>
  <Label>Range</Label>
  <Slider.Output>
    {({state}) => 
      state.values.map((_, i) => state.getThumbValueLabel(i)).join(' – ')
    }
  </Slider.Output>
  <Slider.Track>
    {({state}) => (
      <>
        <Slider.Fill />
        {state.values.map((_, i) => (
          <Slider.Thumb key={i} index={i} />
        ))}
      </>
    )}
  </Slider.Track>
</Slider>

Accessibility

The Slider component implements the ARIA slider pattern and provides:

  • Full keyboard navigation support (Arrow keys, Home, End, Page Up/Down)
  • Screen reader announcements for value changes
  • Proper focus management
  • Support for disabled states
  • HTML form integration via hidden input elements
  • Internationalization support with locale-aware value formatting
  • Right-to-left (RTL) language support

For more information, see the React Aria Slider documentation.