Skip to content
Components

Slider

Selects a single value or a range from a continuous scale, rendering one draggable thumb per value. Import from "@instruments/materia-ui/components/slider". Built on Base UI primitives for accessible behaviour.

Usage

import { Slider } from "@instruments/materia-ui/components/slider";

Best practices

  • Pass value/defaultValue as a number for one thumb or an array - one number per thumb; a two-element array renders a range and the thumb count follows the array length.

  • Set min/max/step to real domain bounds (defaults 0–100) rather than rescaling values yourself after onValueChange.

  • For exact numeric entry use Input type="number"; reserve Slider for approximate selection along a continuous range.

  • Name every thumb with thumbLabels. aria-label on the root labels the group, not the handles, and a handle is what a screen reader lands on.

  • On variant="channel", give the channel its colour with trackBackground and keep the thumb legible against it with getThumbColor; the app owns the colour maths, the slider only paints the result.

  • Use labelStart/labelEnd for visible end captions and getValueText for what a screen reader hears; the captions are hidden from assistive technology. Channel affordances adapted from

Props

PropTypeDefaultDescription
thumbLabelsreadonly string[]

Accessible name for each thumb, in thumb order - ["Minimum", "Maximum"] for a range. The role="slider" input lives inside the THUMB, so an aria-label on the root names the group and leaves the handle itself nameless. Anything shorter than the thumb count falls back to the root's own label.

travelToValueboolean

Let the thumb travel to a value it did not receive from the pointer. The thumb is positioned from the value, so a change made anywhere but the track - a keyboard step, a jump button, a URL - teleports it, and the reader loses where it went and how far. With this on, the thumb travels and the distance it covers says how far the value moved. A DRAG is exempt: the thumb must stay under the finger, so the travel is switched off for the duration of the gesture and back on when it ends. Off by default, because a slider that is only ever dragged gains nothing.

onDraggingChange(dragging: boolean) => void

Told when a drag starts and ends. A consumer usually has something else that should behave differently under the finger - a preview that should stop animating each step, a readout that should stop settling - and the state is already tracked here for {@link travelToValue}.

variant"default" | "channel""default"

Which instrument this is. "default" is the 6px line. "channel" is the 48px pressed channel with a 40px glass thumb that Colour Studio's colour controls and the catalogue reader's page transport both use: same geometry, same grab cursors, same two-speed press - the glass compresses in 120ms and the thumb's core rises out of it 80ms later on a gentle overshoot, which is what makes the core feel like it moves independently of the glass. It sets GEOMETRY AND BEHAVIOUR ONLY. The channel's own fill, the thumb's material and whatever sits at its centre belong to the consumer, because they are what the two instruments do not share: one carries a colour ramp, the other the shape of a book.

trackBackgroundstring

A CSS gradient painted on the channel, such as a lightness ramp. It is a runtime colour value, so it travels as an inline style on the track. Channel variant only.

getThumbColor(value: number, index: number) => string

The colour of each thumb's core, given the thumb's live value and index, so contrast follows the app's own ramp. Channel variant only.

labelStartReactNode

A visible caption at the start of the channel. Hidden from assistive technology, which gets the thumb's own name and value. Channel variant only.

labelEndReactNode

A visible caption at the end of the channel. Hidden from assistive technology, which gets the thumb's own name and value. Channel variant only.

getValueText(value: number, index: number) => string

Describe a value in domain language ("62% lightness") for screen readers, instead of the bare number.

Composition

Builds on

Flex, Text