Skip to main content

Slider

MD3 Expressive slider: native <input type="range"> controls under MD3 visuals, in five sizes, with range, centered, and vertical configurations.

Basic​

<Slider defaultValue={40} aria-label="Volume" />

Controlled​

onChange receives the native event and the new value — a number, or a [start, end] pair for a range slider. min / max / step default to the native 0 / 100 / 1.

30
const [value, setValue] = useState(30)

<Slider value={value} onChange={(event, next) => setValue(next as number)} aria-label="Brightness" />

Sizes​

Five Expressive sizes set the track thickness and handle height. insetIcon insets an icon in the slider at sizes md, lg, and xl.

<Slider size="md" insetIcon={<VolumeUp />} aria-label="Volume" />

Range​

Pass a [start, end] value to get two handles. Name them with rangeStartLabel / rangeEndLabel (English defaults Minimum / Maximum); aria-label names the group.

<Slider defaultValue={[20, 70]} aria-label="Price" rangeStartLabel="Minimum price" rangeEndLabel="Maximum price" />

Steps, ticks & value label​

showTicks marks each step; showValueLabel shows the value bubble while hovering, focusing, or dragging. valueLabelFormat formats it — a string or number result is also announced through aria-valuetext.

<Slider step={10} showTicks showValueLabel valueLabelFormat={(v) => `${v}%`} aria-label="Opacity" />

Centered​

centered draws the active track from the midpoint outward — useful for signed adjustments.

<Slider centered min={-50} max={50} defaultValue={20} aria-label="Balance" />

Vertical​

Give the slider (or its container) a height.

<div style={{ height: 200 }}>
<Slider orientation="vertical" defaultValue={60} aria-label="Level" />
</div>

Disabled​

Accessibility​

  • Each handle is a native range input: arrow keys step, Home / End jump to min / max, and PageUp / PageDown move by a larger step (10%).
  • Vertical sliders expose aria-orientation="vertical".
  • Name the slider with aria-label or aria-labelledby; range sliders name each handle via rangeStartLabel / rangeEndLabel.
  • ref and extra props land on the root; inputRef reaches the first native input.

Props​

PropTypeDefaultDescription
centeredbooleanfalseDraw the active track from the center outward.
defaultValueSliderValuemin (or `[min, max]` for range)Uncontrolled initial value.
disabledbooleanfalse
inputRefRef<HTMLInputElement>—Ref to the native `<input type="range">` element (the forwarded `ref` points at the root). A range slider renders two inputs; `inputRef` reaches the FIRST (start / minimum) one — query its siblings for the end input if needed.
insetIconReactNode—Icon shown inside the handle (sizes md/lg/xl only).
maxnumber100
minnumber0
onChange((event: ChangeEvent<HTMLInputElement, Element>, value: SliderValue) => void)—Fires with the native event and the new value (same shape as `value`).
orientationenumhorizontalOrientation.
rangeEndLabelstringMaximumAccessible label for the end (maximum) thumb of a range slider.
rangeStartLabelstringMinimumAccessible label for the start (minimum) thumb of a range slider.
showTicksbooleanfalseRender tick marks at each step.
showValueLabelbooleanfalseShow the value-indicator bubble on hover / focus / drag.
sizeenumxsExpressive size (track thickness / handle height).
stepnumber1
valueSliderValue—Controlled value (`number`, or `[start, end]` for range).
valueLabelFormat((value: number) => ReactNode)—Format the value-indicator label. A `string` / `number` result is also announced via `aria-valuetext` so AT reads what the label shows.