Skip to content

Components · Slider

Slider

A continuous numeric control for thresholds, lookbacks and weights: a small thumb, a much larger hit target, and a value shown only while it is being used.

Examples

One value

Arrow keys step by step, Home and End jump to the bounds, and the value bubble appears on hover, focus and drag.

Signals below this score are dropped.

Relative weight in the composite score.

A range

RangeSlider is two thumbs over one inclusive pair. The value is always handed back sorted, so a consumer never re-orders it.

Never closer than five points.

18 to 64

Compact, with nothing to reveal

`showValue="never"` and ticks without captions reserve no room, so the root is the groove and the thumb — 20px at `md` rather than 38px. That is the shape a toolbar or a table cell wants, and it is the only configuration in which the slider does not grow.

States and orientation

Disabled is expressed with colour, never with whole-component opacity, so the label and value stay readable. A vertical slider is sized by the consumer's box.

Invalid swaps the accent for the negative tone and sets aria-invalid on the thumb.

35

Range

Marks are declared by the consumer, never generated.

In a form

A slider is a control like any other: it takes its label, description and error from Field, and it submits through the form's own lifecycle.

Percent of peak equity before the run stops.

Cap per instrument.

Settings pattern

The shape a real settings pane takes: a label, a live value, a switch for the on/off axis and a slider for the amount.

Alert on drawdown

Posts to the research channel when a run crosses the limit.

Applied to the daily equity curve.

Usage

import { RangeSlider, Slider } from "@luc/ui/slider";
<RangeSlider value={band} onValueChange={setBand} min={0} max={100} aria-label="Percentile band" />

`value` is a number on `Slider` and a two-item pair on `RangeSlider`, which hands the pair back sorted so a caller never re-orders it.

API

Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.

Exported symbols
ExportKindSignature
RangeSlider22 documented props({ value, defaultValue, onValueChange, onValueCommit, min, max, thumbLabels, ...props }: RangeSliderProps) => import("@types/react").JSX.Element
Slider21 documented props({ value, defaultValue, onValueChange, onValueCommit, min, max, ...props }: SliderProps) => import("@types/react").JSX.Element

Slider props

Type: SliderProps

Values the compiler reads from the declaration.

Slider props
PropTypeDefaultNotes
asChild?inheritedboolean | undefined—
defaultValue?number | undefined—
dir?inheritedDirection | undefined—
disabled?inheritedboolean | undefined—
form?inheritedstring | undefined—
formatValue?((value: number) => ReactNode) | undefined—
invalid?boolean | undefined—
inverted?inheritedboolean | undefined—
label?string | undefined—Accessible name for the thumb when no `Field` label is present.
marks?readonly SliderMark[] | undefined—Optional ticks. Never generated automatically.
max?inheritednumber | undefined—
min?inheritednumber | undefined—
minStepsBetweenThumbs?inheritednumber | undefined—
name?inheritedstring | undefined—
onValueChange?((value: number) => void) | undefined—
onValueCommit?((value: number) => void) | undefined—Fired when a drag or key-step settles — the right place to commit.
orientation?inherited"horizontal" | "vertical" | undefined—
showValue?ValueDisplay | undefined—When to print the value next to the thumb. Default `auto` (hover, focus, drag).
size?ControlSize | undefined—
step?inheritednumber | undefined—
value?number | undefined—Single value.
RangeSlider props22 props

RangeSlider props

Type: RangeSliderProps

Values the compiler reads from the declaration.

RangeSlider props
PropTypeDefaultNotes
asChild?inheritedboolean | undefined—
defaultValue?readonly [number, number] | undefined—
dir?inheritedDirection | undefined—
disabled?inheritedboolean | undefined—
form?inheritedstring | undefined—
formatValue?((value: number) => ReactNode) | undefined—
invalid?boolean | undefined—
inverted?inheritedboolean | undefined—
label?string | undefined—
marks?readonly SliderMark[] | undefined—Optional ticks. Never generated automatically.
max?inheritednumber | undefined—
min?inheritednumber | undefined—
minStepsBetweenThumbs?number | undefined—Minimum gap between the two thumbs, in `step` increments.
name?inheritedstring | undefined—
onValueChange?((value: [number, number]) => void) | undefined—
onValueCommit?((value: [number, number]) => void) | undefined—
orientation?inherited"horizontal" | "vertical" | undefined—
showValue?ValueDisplay | undefined—When to print the value next to the thumb. Default `auto` (hover, focus, drag).
size?ControlSize | undefined—
step?inheritednumber | undefined—
thumbLabels?readonly [string, string] | undefined—One accessible name per thumb, when "minimum"/"maximum" is not enough.
value?readonly [number, number] | undefined—Inclusive `[minimum, maximum]` pair.

Guidelines

Do

  • Use a slider when the range matters more than the exact number; a value that has to be typed exactly is `NumberInput`.
  • Show the formatted value and keep the label outside the control: a bare thumb is a guess, and a bubble is not a name.
  • Name each end of a range with `thumbLabels`, so the pair is not announced as two identical controls.

Don't

  • Re-purpose the value bubble as the permanent label — it appears on hover, focus and drag by design, and is absent at rest.
  • Let the two ends cross: `minStepsBetweenThumbs` is the gap the thumbs keep, and a band that can invert is not a band.
  • Rescale a percentage and format it as a fraction: `formatValue` is display only and the submitted number is unchanged.

Two components, one shell

Slider
One value: a threshold, a weight, a lookback. `value` is a number.
RangeSlider
Two ends of one band. The pair comes back sorted, and `minStepsBetweenThumbs` is the gap the thumbs keep.

Accessibility

Every thumb is a focusable slider with its own value bounds, so the arrow keys step it, Home and End jump to the ends, and the value is announced from the thumb rather than from the decorative bubble. A range therefore needs one name per thumb — `thumbLabels` for a pair, `label` for a single value — and a disabled slider keeps its colour treatment so the label and the value stay readable.

Luc UI v1.0RangeSliderdark theme