moduix

Slider

A range input for selecting one value or a range of values.

API Reference

Original primitive API

Behavior, accessibility details, and low-level props are documented by Base UI.

Base UI API

Basic

Volume
40%
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";export function SliderDemo() {  return (    <Slider defaultValue={40}>      <SliderLabel>Volume</SliderLabel>      <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>      <SliderThumb aria-label="Volume" />    </Slider>  );}

Full list of component variables available for project-level overrides.

PropertyDefaultDescription
--slider-colorvar(--color-foreground)Controls the default slider text color.
--slider-control-padding-x0.625remControls vertical control horizontal padding.
--slider-control-padding-y0.625remControls horizontal control vertical padding.
--slider-disabled-opacityvar(--opacity-disabled)Controls disabled slider opacity.
--slider-focus-ring-colorvar(--color-ring)Controls thumb focus ring color.
--slider-gap0.5remControls spacing between slider slots.
--slider-height12remControls the vertical slider control height.
--slider-indicator-bgvar(--color-primary)Controls filled indicator color.
--slider-indicator-radiusinheritControls filled indicator corner radius.
--slider-label-colorvar(--slider-color)Controls label text color.
--slider-label-font-sizevar(--text-sm)Controls label font size.
--slider-label-font-weightvar(--weight-regular)Controls label font weight.
--slider-label-line-heightvar(--line-height-text-sm)Controls label line height.
--slider-thumb-bgvar(--color-background)Controls thumb background color.
--slider-thumb-border-colorvar(--color-border)Controls thumb border color.
--slider-thumb-border-widthvar(--border-width-sm)Controls thumb border width.
--slider-thumb-radiusvar(--radius-full)Controls thumb corner radius.
--slider-thumb-shadowvar(--shadow-sm)Controls thumb shadow.
--slider-thumb-shadow-draggingvar(--shadow-md)Controls thumb shadow while dragging.
--slider-thumb-size1remControls thumb width and height.
--slider-track-bgvar(--color-muted)Controls track background color.
--slider-track-border-colorvar(--color-border)Controls track border color.
--slider-track-border-widthvar(--border-width-sm)Controls track border width.
--slider-track-radiusvar(--radius-full)Controls track corner radius.
--slider-track-size0.375remControls track thickness.
--slider-transitionvar(--transition-default)Controls thumb transition timing.
--slider-value-colorvar(--slider-color)Controls value text color.
--slider-value-font-sizevar(--text-sm)Controls value font size.
--slider-value-font-weightvar(--weight-regular)Controls value font weight.
--slider-value-line-heightvar(--line-height-text-sm)Controls value line height.
--slider-width12remControls the horizontal slider root width.
--slider-width-verticalfit-contentControls the vertical slider root width.

Interactive variables scoped for docs preview without changing size scale tokens.

PropertyValueDefaultDescription
--slider-colorvar(--color-foreground)Controls default slider text color.
--slider-focus-ring-colorvar(--color-ring)Controls thumb focus ring color.
--slider-indicator-bgvar(--color-primary)Controls filled indicator color.
--slider-track-bgvar(--color-muted)Controls track background color.
--slider-track-border-colorvar(--color-border)Controls track border color.
--slider-track-radiusvar(--radius-full)Controls track corner radius.
--slider-track-size0.375remControls track thickness.
--slider-thumb-bgvar(--color-background)Controls thumb background color.
--slider-thumb-border-colorvar(--color-border)Controls thumb border color.
--slider-thumb-size1remControls thumb width and height.

Anatomy

Slider renders the Base UI control, track, and indicator internally, so consumers only compose the meaningful content: label, value, and thumbs. Add one SliderThumb for each value in the slider.

Slider
├─ SliderLabel
├─ SliderValue
└─ internal control
   └─ internal track
      ├─ internal indicator
      └─ SliderThumb[index]
<Slider defaultValue={40}>
  <SliderLabel>Volume</SliderLabel>
  <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>
  <SliderThumb aria-label="Volume" />
</Slider>
PartRole
SliderRoot state machine. Controls value, range values, steps, orientation, disabled state, and form integration.
SliderLabelVisible label connected to the slider inputs. Use it when the control has a readable label on screen.
SliderValueOptional formatted value display. It receives formatted values and raw numeric values as render arguments.
SliderThumbInteractive handle. Render one thumb for a single value and multiple indexed thumbs for a range.

The control, track, and indicator are service-like slots for this component. They stay internal by default and can be styled through classNames.control, classNames.track, and classNames.indicator when token-level customization is not enough.

Composition

Use Slider for behavior props such as value, defaultValue, onValueChange, onValueCommitted, min, max, step, largeStep, minStepsBetweenValues, orientation, thumbAlignment, thumbCollisionBehavior, name, and form.

Use SliderThumb for the accessible name of each handle. A visible SliderLabel labels the group, but multi-thumb sliders still need distinct aria-label values on each thumb.

Style the root with className, visible parts with their own className, and internally rendered track structure with classNames:

<Slider
  defaultValue={56}
  className={styles.slider}
  classNames={{
    control: styles.control,
    track: styles.track,
    indicator: styles.indicator,
  }}
>
  <SliderLabel>Temperature</SliderLabel>
  <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>
  <SliderThumb aria-label="Temperature" className={styles.thumb} />
</Slider>

Examples

Range

Pass an array value and render one SliderThumb for each value to let users select a range.

Price range
20 - 70
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";import { useState } from "react";export function RangeSliderDemo() {  const [value, setValue] = useState([20, 70] as readonly number[]);  return (    <Slider value={value} min={0} max={100} onValueChange={setValue}>      <SliderLabel>Price range</SliderLabel>      <SliderValue>{([minValue, maxValue]) => `${minValue} - ${maxValue}`}</SliderValue>      <SliderThumb index={0} aria-label="Minimum price" />      <SliderThumb index={1} aria-label="Maximum price" />    </Slider>  );}

Steps and Constraints

Use step, largeStep, and minStepsBetweenValues to make range selection snap to meaningful increments. thumbCollisionBehavior controls what happens when thumbs meet.

Budget
$250 - $750
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";import { useState } from "react";const priceFormatter = new Intl.NumberFormat("en-US", {  style: "currency",  currency: "USD",  maximumFractionDigits: 0,});export function SteppedRangeSliderDemo() {  const [value, setValue] = useState([250, 750] as readonly number[]);  return (    <Slider      value={value}      min={0}      max={1000}      step={50}      largeStep={200}      minStepsBetweenValues={2}      thumbCollisionBehavior="none"      format={{        style: "currency",        currency: "USD",        maximumFractionDigits: 0,      }}      onValueChange={setValue}    >      <SliderLabel>Budget</SliderLabel>      <SliderValue>        {(_, [minValue, maxValue]) =>          `${priceFormatter.format(minValue)} - ${priceFormatter.format(maxValue)}`        }      </SliderValue>      <SliderThumb index={0} aria-label="Minimum budget" />      <SliderThumb index={1} aria-label="Maximum budget" />    </Slider>  );}

Controlled

Control the value from React state when the slider needs to synchronize with another control.

Brightness
24%
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";import { useState } from "react";import styles from "./slider.module.css";export function ControlledSliderDemo() {  const [value, setValue] = useState(24);  return (    <div className={styles.stack}>      <Slider value={value} onValueChange={setValue}>        <SliderLabel>Brightness</SliderLabel>        <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>        <SliderThumb aria-label="Brightness" />      </Slider>      <input        className={styles.range}        type="range"        min={0}        max={100}        value={value}        onChange={(event) => {          setValue(Number(event.target.value));        }}      />    </div>  );}
.stack {  display: grid;  gap: var(--spacing-4);}.range {  width: 12rem;}

Vertical

Set orientation="vertical" and size the vertical track with CSS custom properties.

Output
60%
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";import styles from "./slider.module.css";export function VerticalSliderDemo() {  return (    <div className={styles.verticalContainer}>      <Slider orientation="vertical" defaultValue={60} className={styles.verticalSlider}>        <SliderLabel>Output</SliderLabel>        <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>        <SliderThumb aria-label="Output" />      </Slider>    </div>  );}
.verticalContainer {  display: flex;  height: 14rem;}.verticalSlider {  --slider-width-vertical: auto;  --slider-height: 12rem;}

Edge Thumb Alignment

Use thumbAlignment="edge" when the thumb should stay inside the control at the minimum and maximum values.

Zoom
0%
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";export function EdgeThumbAlignmentSliderDemo() {  return (    <Slider defaultValue={0} thumbAlignment="edge">      <SliderLabel>Zoom</SliderLabel>      <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>      <SliderThumb aria-label="Zoom" />    </Slider>  );}

Disabled

Use disabled to make the whole slider non-interactive while preserving its current value.

Notifications
32%
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";export function DisabledSliderDemo() {  return (    <Slider defaultValue={32} disabled>      <SliderLabel>Notifications</SliderLabel>      <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>      <SliderThumb aria-label="Notifications" />    </Slider>  );}

Custom Styles

Use className for the root and classNames for internally rendered slots.

Temperature
56%
import {  Slider,  SliderLabel,  SliderValue,  SliderThumb,} from "moduix";import styles from "./slider.module.css";export function CustomClassesSliderDemo() {  return (    <Slider      defaultValue={56}      classNames={{        control: styles.customControl,        track: styles.customTrack,        indicator: styles.customIndicator,      }}    >      <SliderLabel>Temperature</SliderLabel>      <SliderValue>{([formattedValue]) => `${formattedValue}%`}</SliderValue>      <SliderThumb aria-label="Temperature" className={styles.customThumb} />    </Slider>  );}
.customControl {  --slider-control-padding-y: var(--spacing-3);}.customTrack {  --slider-track-size: 0.625rem;  --slider-track-bg: color-mix(in oklab, var(--color-chart-4) 18%, var(--color-muted));  --slider-track-border-color: transparent;}.customIndicator {  --slider-indicator-bg: var(--color-chart-4);}.customThumb {  --slider-thumb-size: 1.25rem;  --slider-thumb-bg: var(--color-chart-4);  --slider-thumb-border-color: var(--color-background);}

On this page