Noctis

Slider

A control for picking a number from a continuous scale. The accent indicator fills the sunken rail up to the thumb, signalling the selected value; a range adds a second thumb and fills between them.

Basic

Compose Slider.Root (which owns the value) with a Slider.Control holding the Slider.Track (and its Slider.Indicator) and a Slider.Thumb. Drive it with value / onValueChange, or omit them and pass defaultValue to let it own its state. Name a label-less slider with aria-label.

Label and value

Wrap Slider.Label and Slider.Value in a Slider.Header — a baseline space-between row above the control that owns the header→rail gap. The label names the slider for assistive tech (no separate aria-label needed) and the value renders the current number, localized and formatted by the Root's format options.

Brightness
60%

Range

Pass a two-number array as the value and render one Slider.Thumb per value with an explicit index. The indicator fills the span between the two thumbs, and each thumb's value text gains a translated start/end suffix for screen readers. Use minStepsBetweenValues to keep a gap between the thumbs, and thumbCollisionBehavior (push · swap · none) to choose what happens when they meet.

Sizes

size sets the control height, rail thickness, and thumb diameter — sm or md (the default).

Value on drag

Compose a Slider.ThumbValue inside a Slider.Thumb for a live readout that floats above the handle while dragging (and on keyboard focus) — so the value stays visible, never hidden under the finger. It is decorative (aria-hidden): the thumb's aria-valuetext remains the announced source of truth, so the value is never read twice.

Vertical

Set orientation="vertical" and give the slider a height; the control runs top-to-bottom and the indicator fills from the bottom up. Everything stays logical, so the layout mirrors correctly under RTL.

Centre fill

By default the indicator fills from the minimum. Set origin to fill from a non-minimum anchor instead — the bipolar case where zero sits in the middle (balance, EQ, brightness ±). The fill spans origin → value in either direction. origin applies to a single-value slider; a range already fills between its two thumbs.

Balance
20

Marks

Layer a Slider.Marks over the control with a Slider.Mark per step to show a tick scale; pass a value to each mark and optional children for a caption (e.g. the min/max ends). A tick the value has passed turns the accent (the fill's signal); the rest read a neutral hairline. The whole layer is decorative (aria-hidden) — the value text already conveys position. Ticks help when an approximate choice on a labelled scale matters more than a precise number.

Validation

Inside a form, reflect an error with aria-invalid (and point aria-describedby at the message): the track border and thumb ring turn danger while the accent fill keeps its meaning. A slider wrapped in a Base UI Field.Root picks up the same cue automatically from the field's data-invalid.

Monthly budget
$0

Keyboard

The thumb is fully keyboard-operable. Arrow keys mirror under RTL, so the value always moves toward the reading direction.

KeyAction
Tab / Shift + TabMove focus onto / off each thumb (the tab order stays constant regardless of visual position).
/ / / Move the value by one step. Left/right mirror under RTL.
Shift + / / / Move the value by largeStep (default 10).
Page Up / Page DownMove the value by largeStep.
Home / EndJump to the minimum / maximum.

Anatomy

Compose the slider from its parts. Slider.Root is a Base UI Slider, so value handling, dragging, keyboard operation, and localization come for free.

  • Slider.Root — owns the value (value / onValueChange, or uncontrolled defaultValue) and the shared size. Pass a number for a single value or a two-number array for a range; set the scale with min / max / step and the value formatting with format. Tune the keyboard with largeStep and the range with minStepsBetweenValues / thumbCollisionBehavior; commit on release (for expensive updates) with onValueCommitted; anchor a bipolar fill with origin. Disable it with disabled.
  • Slider.Header — an optional baseline row above the control holding the Slider.Label + Slider.Value.
  • Slider.Label / Slider.Value — the accessible label and the formatted current value.
  • Slider.Control — the interactive row the rail and thumbs sit centred within.
  • Slider.Track — the sunken rail; holds the Slider.Indicator.
  • Slider.Indicator — the accent fill up to the thumb (or between range thumbs, or from a non-min origin).
  • Slider.Thumb — a draggable handle; render one per value with an index. Base UI stamps data-index on each, a hook for styling the two ends of a range differently.
  • Slider.ThumbValue — an opt-in live readout, composed inside a Slider.Thumb.
  • Slider.Marks / Slider.Mark — an optional tick scale layered over the control.

Every rendered part carries a data-slot (noctis-slider on the root, then noctis-slider-header · noctis-slider-label · noctis-slider-value · noctis-slider-control · noctis-slider-track · noctis-slider-indicator · noctis-slider-thumb · noctis-slider-thumb-value · noctis-slider-marks · noctis-slider-mark · noctis-slider-mark-label) for host-side styling — pair it with the Base UI state attributes (data-orientation, data-dragging, data-disabled, data-focused, data-index, and the field-state data-invalid / data-valid / data-dirty / data-touched).

Accessibility

  • Each thumb is a slider with aria-valuenow / min / max and localized aria-valuetext; for a range, the dependent min/max keep the thumbs from crossing and the tab order stays constant. Give every thumb its own label (getAriaLabel), especially in a range.
  • The drag readout (Slider.ThumbValue) and the tick captions (Slider.Mark) are aria-hidden decoration — the value text stays the single announced source, so nothing is read twice.
  • Focus shows a :focus-visible box-shadow ring that hugs the round thumb; the grow-on-drag and the readout's slide-in respect prefers-reduced-motion (the readout stays, only its motion drops).

On surfaces

The same control re-tuned across the elevation scopes — the root canvas, an elevated panel, a menu, and a sunken well. It stays legible on every layer.

root
elevated
menu
sunken

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The minted tokens are the public override seam: set one on any ancestor and every slider in that region retunes — e.g. .compact { --noctis-slider-thumb-size: 0.875rem; } shrinks the handles beneath it. See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source. Each part gets its own table; the Root forwards the Base UI Slider props it owns the value through. Expand a row for the full type and description.

Slider.Root

Prop

Slider.Header

Prop

Slider.Label

Prop

Slider.Value

Prop

Slider.Control

Prop

Slider.Track

Prop

Slider.Indicator

Prop

Slider.Thumb

Prop

Slider.ThumbValue

Prop

Slider.Marks

Prop

Slider.Mark

Prop

AttributeDescription
data-slotThe slot value marking each rendered part.
data-sizeThe control size the root stamps — `sm` or `md`; the metrics re-point off it.
data-orientation`horizontal` | `vertical` — the control's orientation, stamped by Base UI on every part.
data-draggingPresent on every part while a thumb is being dragged.
data-disabledPresent on every part when the slider is disabled.
data-focusedPresent on the thumb whose input has keyboard focus.
data-invalidPresent on every part when the slider is in an invalid `Field.Root` — the field error cue paints the track border and thumb ring in `danger`. Base UI also stamps the companion `data-valid`, `data-dirty`, and `data-touched` field-state attributes for host-side styling.
data-stateStamped on a step mark the value has reached, switching the tick to the accent (signal).