Skip to main content

Slider

An input where the user selects a value from within a given range.

Pair with Field.* for description/error wiring in forms. Pass aria-label to Slider so the rendered thumb has an accessible name:

Drag to adjust playback volume.

import { Field } from "@ngrok/mantle/field";import { Slider } from "@ngrok/mantle/slider"; <Field.Item name="volume">	<Field.Label>Volume</Field.Label>	<Field.Control>		<Slider aria-label="Volume" defaultValue={67} max={100} step={1} />	</Field.Control>	<Field.Description>Drag to adjust playback volume.</Field.Description></Field.Item>;

Or render the control on its own:

import { Slider } from "@ngrok/mantle/slider"; <Slider aria-label="Volume" defaultValue={67} max={100} step={1} /><Slider aria-label="Disabled volume" defaultValue={67} max={100} step={1} disabled /><Slider aria-label="Vertical volume" defaultValue={67} max={100} step={1} orientation="vertical" />

Examples

With TanStack Form

Use @tanstack/react-form with zod to keep a single-thumb slider controlled. Radix emits slider values as an array, so pass the first value into field.handleChange.

import { Button } from "@ngrok/mantle/button";import { Field, toErrorMessages } from "@ngrok/mantle/field";import { Slider } from "@ngrok/mantle/slider";import { useForm } from "@tanstack/react-form";import { z } from "zod"; export const formSchema = z.object({	volume: z.number().min(25, "Choose at least 25."),});function Example() {	const defaultValues = {		volume: 50,	};	const form = useForm({		defaultValues,		validators: {			onSubmit: formSchema,		},		onSubmit: ({ value }) => {			// Handle form submission here		},	}); 	return (		<form			onSubmit={(event) => {				event.preventDefault();				event.stopPropagation();				void form.handleSubmit();			}}		>			<form.Field name="volume">				{(field) => (					<Field.Item name={field.name}>						<Field.Label>Volume</Field.Label>						<Field.Control>							<Slider								aria-label="Volume"								value={field.state.value}								onBlur={field.handleBlur}								onValueChange={(value) => field.handleChange(value[0] ?? 0)}								max={100}								step={1}							/>						</Field.Control>						<Field.Errors messages={toErrorMessages(field.state.meta.errors)} />					</Field.Item>				)}			</form.Field>			<Button type="submit" appearance="filled" intent="neutral">				Submit			</Button>		</form>	);}

Single thumb

A basic slider with a single thumb for selecting a single value. You can pass a single number instead of an array.

import { Slider } from "@ngrok/mantle/slider"; <Slider aria-label="Volume" defaultValue={75} max={100} step={1} />;

Range

Use two values to create a range slider with two thumbs.

import { Slider } from "@ngrok/mantle/slider"; <Slider aria-label="Price" defaultValue={[25, 50]} max={100} step={5} />;

Multiple thumbs

Use more than two values to create a slider with multiple thumbs.

import { Slider } from "@ngrok/mantle/slider"; <Slider aria-label="Breakpoint" defaultValue={[10, 20, 70]} max={100} step={10} />;

Color

Use the color prop to change the color of the slider range. Accepts any Tailwind bg-* class.

import { Slider } from "@ngrok/mantle/slider"; <Slider aria-label="Warning threshold" defaultValue={67} max={100} step={1} color="bg-warning-600" /><Slider aria-label="Danger threshold" defaultValue={67} max={100} step={1} color="bg-danger-600" /><Slider aria-label="Success threshold" defaultValue={67} max={100} step={1} color="bg-emerald-600" />

Ticks

Use the showTicks prop to show tick marks along the track, one per step, spread evenly. When the range is not a multiple of step, the ticks do not land on the step values.

import { Slider } from "@ngrok/mantle/slider"; <Slider aria-label="Volume" defaultValue={50} max={100} step={10} showTicks /><Slider aria-label="Price" defaultValue={[20, 80]} max={100} step={20} showTicks />

API Reference

Slider

The Slider is built on top of Radix Slider. It accepts all props from the Radix Slider Root component.

defaultValue and value both accept number | number[], but they must be the same type — you cannot mix a single number with a number[].

PropTypeDefaultDescription
color`bg-${string}`"bg-accent-600"The color of the slider range. Accepts any Tailwind bg-* class.
aria-labelstring—Accessible name forwarded to the rendered thumb. Range sliders derive per-thumb labels from it.
aria-labelledbystring—IDREF forwarded to every thumb, so a range slider names both thumbs with the same text. Prefer aria-label.
defaultValuenumber | number[]—The value of the slider when initially rendered. Use when you do not need to control the state of the slider.
showTicksbooleanfalseWhether to show tick marks along the track, one per step, spread evenly.
valuenumber | number[]—The controlled value of the slider. Must be used with onValueChange.
onValueChange(value: number[]) => void—Event handler called when the value changes.
onValueCommit(value: number[]) => void—Event handler called when the value changes at the end of an interaction (e.g. on mouse up or on blur).
namestring—The name of the slider. Submitted with its owning form as part of a name/value pair.
disabledbooleanfalseWhen true, prevents the user from interacting with the slider.
orientation"horizontal" | "vertical""horizontal"The orientation of the slider.
minnumber0The minimum value for the range.
maxnumber100The maximum value for the range.
stepnumber1The stepping interval.
minStepsBetweenThumbsnumber1The minimum permitted steps between multiple thumbs.
invertedbooleanfalseWhether the slider is visually inverted.