Slider
A slider allows a user to select one or more values within a range
Usage
import { Slider } from '@heroui/react';Anatomy
import { Slider, Label } from '@heroui/react';
export default () => (
<Slider>
<Label />
<Slider.Output />
<Slider.Track>
<Slider.Fill />
<Slider.Thumb />
</Slider.Track>
</Slider>
)Examples
Disabled
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
Range
Render Function
Customization
Tailwind CSS
Global CSS
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;
}
}Styling Reference
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:
:hoveror[data-hovered="true"]on thumb - Focus:
:focus-visibleor[data-focus-visible="true"]on thumb - Dragging:
[data-dragging="true"]on thumb - Disabled:
:disabledor[data-disabled="true"]on slider or thumb
API Reference
Slider
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | number[] | - | The current value (controlled) |
defaultValue | number | 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 |
minValue | number | 0 | The slider's minimum value |
maxValue | number | 100 | The slider's maximum value |
step | number | 1 | The slider's step value |
formatOptions | Intl.NumberFormatOptions | - | The display format of the value label |
orientation | "horizontal" | "vertical" | "horizontal" | The orientation of the slider |
isDisabled | boolean | - | Whether the slider is disabled |
aria-label | string | - | Accessibility label for the slider |
aria-labelledby | string | - | ID of element that labels the slider |
className | string | - | Additional CSS classes |
children | ReactNode | RenderFunction | - | Slider content or render function |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, SliderRenderProps> | - | Overrides the default DOM element with a custom render function. |
Slider.Output
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
children | ReactNode | RenderFunction | - | Output content or render function |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, SliderOutputRenderProps> | - | Overrides the default DOM element with a custom render function. |
Slider.Track
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
children | ReactNode | RenderFunction | - | Track content or render function |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, SliderTrackRenderProps> | - | Overrides the default DOM element with a custom render function. |
Slider.Fill
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
style | CSSProperties | - | Inline styles |
Slider.Thumb
| Prop | Type | Default | Description |
|---|---|---|---|
index | number | 0 | Index of the thumb within the slider |
isDisabled | boolean | - | Whether this thumb is disabled |
name | string | - | The name of the input element, used when submitting an HTML form |
className | string | - | Additional CSS classes |
children | ReactNode | RenderFunction | - | Thumb content or render function |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, SliderThumbRenderProps> | - | Overrides the default DOM element with a custom render function. |
Render Props
When using render functions with Slider.Output or Slider.Track, these values are provided:
| Prop | Type | Description |
|---|---|---|
state | SliderState | The state of the slider |
values | number[] | Values managed by the slider by thumb index |
getThumbValueLabel | (index: number) => string | Returns the string label for the specified thumb's value |
orientation | "horizontal" | "vertical" | The orientation of the slider |
isDisabled | boolean | Whether 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.





