// preview in
saved for every page

Slider

Sets a value, or a range, by dragging along a track. Best for approximate amounts where seeing the position matters more than typing an exact number.

Built on Base UIPattern WAI-ARIA SliderClient componentSource ↗
minimal · light · #3fa34d
thumbAlignment
disabled

Installation

Set up Camaleo once (Installation), then import it. The skin you load styles the track and the thumbs.

import { Slider } from "@camaleo/react";

Anatomy

One component that renders the control, the track, the filled indicator and one thumb per value. Every part has a data-slot you can target from CSS.

━━━━━━●──────
[data-slot="slider"] › [data-slot="slider-control"][data-slot="slider-track"] · [data-slot="slider-indicator"][data-slot="slider-thumb"]

Examples

Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above.

minimal · light · #3fa34d

Range

Pass an array and you get one thumb per value; name each one with getAriaLabel, since "minimum" and "maximum" aren't visible.

$25,000

With the value shown

Drag it. Show the value next to the label, and pass the same format and locale so screen readers hear "$25,000" instead of "25000".

16 px

Steps

step snaps to the values that make sense; largeStep is what Page Up and Page Down jump by.

Working hours09:00 – 18:00

Range with a minimum gap

minStepsBetweenValues keeps the thumbs apart, here at least two hours between start and end.

Release to save

Save on release

Drag, then let go. onValueCommitted fires once at the end, so you save or fetch once instead of on every pixel.

Shows clinics within this distance of Curitiba, PR.

Inside a Field

FieldLabel names the thumb and FieldDescription explains the scale, with no getAriaLabel needed.

Equalizer

Vertical

orientation="vertical" fits sliders side by side, like an equalizer; getAriaValueText adds the unit, so screen readers say "+4 decibels".

Upgrade to Pro to stream above 720p.

Disabled, with a reason

A locked slider still shows the current value; say what unlocks it right below.

In context

Sliders sit in panels and players. These are whole pieces of UI you can copy, in the skin you picked.

Maré Alta

Luiza Prado

1:12

3:32

Audio playerCard · Slider · IconButton · Text

Price

$150$600
Price filterCard · Slider · Checkbox · Button

Display

16 px

Your order #48213 ships tomorrow.

Text size settingCard · Field · Slider · Switch

Guidelines

$25,000
DoShow the number when it matters.

People choosing a loan need to see the amount, not guess it from a position.

Don’tA bare track for a precise amount.

Where on the bar is $25,000? Nobody can tell.

DoApproximate values.

Volume, brightness, zoom: the effect is the feedback.

Don’tExact values on a long scale.

Dragging to 1987 out of 90 years is fiddly; use a NumberField or an input.

Props

PropTypeDefaultDescription
getAriaLabel((index: number) => string)—Accessible name of each thumb, e.g. (i) => ["Mínimo", "Máximo"][i]. Not needed inside a labelled Field.
getAriaValueTextfunction—Spoken value of each thumb, e.g. (text) => text + " reais". Defaults to the formatted value.
defaultValuenumber | number[]—The uncontrolled value of the slider when it's initially rendered. To render a controlled slider, use the value prop instead.
disabledbooleanfalseWhether the slider should ignore user interaction.
formatIntl.NumberFormatOptions—Options to format the value.
localeIntl.LocalesArgument—The locale used by Intl.NumberFormat when formatting the value. Defaults to the user's runtime locale.
maxnumber100The maximum allowed value of the slider. Should not be equal to min.
minnumber0The minimum allowed value of the slider. Should not be equal to max.
minStepsBetweenValuesnumber0The minimum steps between values in a range slider.
namestring—Identifies the field when a form is submitted.
orientationOrientation'horizontal'The component orientation.
stepnumber1The granularity with which the slider can step through values. (A "discrete" slider.) The min prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.
largeStepnumber10The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down.
thumbAlignment"center" | "edge" | "edge-client-only"'center'How the thumbs line up with the ends: centered on the value (center) or kept inside the track (edge).
thumbCollisionBehavior"none" | "push" | "swap"'push'Controls how thumbs behave when they collide during pointer interactions. - 'push' (default): Thumbs push each other without restoring their previous positions when dragged back. - 'swap': Thumbs swap places when dragged past each other. - 'none': Thumbs cannot move past each other; excess movement is ignored.
valuenumber | number[]—The value of the slider. For range sliders, provide an array with one value per thumb.
onValueChange(value, details) => void—Callback function that is fired when the slider's value changed. Receives the new value as the first argument; the originating event is available as eventDetails.event. The value is also reflected on eventDetails.event.target.value for form integration. The eventDetails.reason indicates what triggered the change: - 'input-change' when the hidden range input emits a change event (for example, via form integration) - 'track-press' when the control track is pressed - 'drag' while dragging a thumb - 'keyboard' for keyboard input - 'none' when the change is triggered without a specific interaction
onValueCommitted(value, details) => void—Callback function that is fired when a value change is committed. Does not fire if the value did not change, or if the change was canceled. **Warning**: This is a generic event, not a change event. The eventDetails.reason indicates what triggered the commit: - 'drag' while dragging a thumb - 'track-press' when the control track is pressed - 'keyboard' for keyboard input - 'input-change' when the hidden range input emits a change event (for example, via form integration) - 'none' when the commit occurs without a specific interaction

Pass an array as value or defaultValue for a range. Inside a Field, the label and description reach the thumbs, and disabled / name can come from there too.

Styling hooks

Restyle it without forking: target the attributes, or set the tokens on a parent, a skin or the slider itself.

Attributes

data-slot"slider" · "slider-control" · "slider-track" · "slider-indicator" · "slider-thumb"
data-draggingpresent while a thumb is dragged
data-orientation"horizontal" · "vertical"
data-disabledpresent when disabled

Tokens it reads

Color

--cml-accent--cml-border--cml-border-control--cml-fg--cml-field-shadow--cml-focus-offset--cml-focus-ring--cml-focus-width

Shape & size

--cml-radius-pill

Type & motion

--cml-duration-fast--cml-ease-standard

This component only

--cml-disabled-opacity--cml-slider-fill--cml-slider-fill-image--cml-slider-fill-inset--cml-slider-thumb-bg--cml-slider-thumb-border--cml-slider-thumb-h--cml-slider-thumb-shadow--cml-slider-thumb-w--cml-slider-track--cml-slider-track-border--cml-slider-track-h

Accessibility

→ / ↑Increases the value by one step (↑ moves a vertical slider up).
← / ↓Decreases the value by one step.
Page Up / Page DownChanges the value by largeStep.
Home / EndJumps to the minimum or maximum.
TabMoves between thumbs, in order.
Was this page helpful? · Edit this page on GitHub