Skip to content
Tier

Slider marks

Pro

A slider with marks along its track, values it is pulled to, and its value above the thumb while it moves: for a setting with a few values that matter (a default, a recommended level, the plan's limit) among many it could take.

Marks are ticks (with a word under each that has a label); a mark the value has passed takes the accent colour, and in forced colours it is a filled shape. detents are values the thumb is pulled to by the pointer: within snap of one, the value becomes it exactly, never a value between. The keys step as usual, by step, so every value stays reachable. Dragged past an end, the track stretches a little toward the pointer while the thumb and the value stay at the end, and springs back when the person lets go.

The readout above the thumb is for the eye (hidden from screen readers, which hear the thumb's value in format's words). Name the thumb with label; right to left, the track runs from the right and the arrow keys follow it.

A mark's word is also read with the thumb's value when the thumb sits on it: "1.0, Default".

Markdown
Version 5.2.0· other versions

This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).

Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0, 4.2.0 and 4.3.0: the page came later, or had another name then.

Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.

Preview

Loading the preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/slider-marks

Brings in: locale, motion, slider, tokens, utils · npm: @base-ui/react@^1.9.0, lucide-react@^1.67.0

Usage

TSX · The example above
"use client"

import * as React from "react"
import { SliderMarks } from "@/components/candor/ui/slider-marks"

// Marks show the values that matter; the pointer is pulled to the default and the recommended level, and the keys
// still step by 0.1 so every value is reachable. The value shows above the thumb while it moves.
export default function Example() {
  const [temperature, setTemperature] = React.useState(0.7)
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <div className="flex items-baseline justify-between text-sm">
        <span aria-hidden className="font-medium">
          Temperature
        </span>
        <span className="text-muted-foreground tabular-nums">{temperature.toFixed(1)}</span>
      </div>
      <SliderMarks
        label="Temperature"
        min={0}
        max={2}
        step={0.1}
        value={temperature}
        onValueChange={setTemperature}
        marks={[{ value: 0, label: "Exact" }, { value: 1, label: "Default" }, { value: 2, label: "Loose" }]}
        detents={[0.7, 1]}
        format={(n) => n.toFixed(1)}
      />
    </div>
  )
}

<SliderMarks>

PropTypeDefaultDescription
valuenumber | undefined—The value, when the app controls it.
defaultValuenumber | undefined—The value at first, when the slider keeps its own state.
onValueChange((value: number) => void) | undefined—Called with the value as the person moves the thumb: a detent's value exactly when the thumb is pulled to one.
onValueCommit((value: number) => void) | undefined—Called with the value when the person lets go, or after a key press: the value to act on.
minnumber | undefined0The lowest value.
maxnumber | undefined100The highest value.
stepnumber | undefined1How far one arrow key moves the value.
labelrequiredstring—The thumb's name, what the setting is: "Temperature".
marksSliderMark[] | undefined[]Marks along the track: a tick at each value, and its word under it when it has one.
detentsnumber[] | undefined[]Values the thumb is pulled to by the pointer, within `snap`.
snapnumber | undefined—How near a detent the pointer pulls the value to it, in the slider's units. Defaults to 2% of the range.
readout"always" | "drag" | "never" | undefined"drag"When the value shows above the thumb: `always`, only while it is dragged or focused (`drag`), or `never`.
format((value: number) => string) | undefined—The value in words, for the readout and screen readers: `(n) => `${n} °C``. Defaults to the locale's number.
lockedstring | null | undefined—Why the setting can't be changed right now. The thumb stays focusable, ignores the pointer and keys, and says why.
classNamestring | undefined—Classes for the outer box.

Strings

The fixed words, in English by default. Change any of them under sliderMarks in <LocaleProvider strings={{ … }}>; the table is exported as sliderMarksStrings.

KeyEnglish
valueAtMark{value}, {mark}

Motion

MomentFamilyWhat it does
marktintA mark takes the accent colour as the value passes it.
releasemoveThe track springs back from a stretch past its end when the person lets go; none under calm.

Set with --cd-motion-slider-marks-<moment>-* in your brand file; the families are in the design reference.

Types

SliderMark
One mark on a `SliderMarks` track: a value, and a word under it if it has one.
{ /** Where the mark sits, in the slider's units. */ value: number; /** The word under the mark: "Default", "Recommended". Left out, the mark is a tick alone. */ label?: string | undefined; }