Slider
Single-value range input on top of Ark UI's slider primitives. Marks, floating label, sizes, colors — keyboard, RTL, and ARIA handled upstream.
The Slider wraps Ark UI's Slider state machine, so keyboard navigation (←/→, Home/End, PageUp/PageDown), RTL flipping, and ARIA wiring come for free. The wrapper layers a styled track / range / thumb, optional marks, and a floating label that follows the thumb.
import { Slider } from '@42/ui-react/slider';
<Slider defaultValue={40} label="40%" />Playground
Component
Presets
Props
Code
<Component defaultValue={40} color="" disabled={false} min={0} max={0} step={0} showLabelOnHover={false} size="xs"/>Sizes
Five track thicknesses — xs through xl. The thumb scales to match.
<Slider size="xs" defaultValue={40} />
<Slider size="sm" defaultValue={40} />
<Slider size="md" defaultValue={40} />
<Slider size="lg" defaultValue={40} />
<Slider size="xl" defaultValue={40} />Colors
The accent palette is brand (default), gray, green, orange, and red.
<Slider color="brand" defaultValue={60} />
<Slider color="gray" defaultValue={60} />
<Slider color="green" defaultValue={60} />
<Slider color="orange" defaultValue={60} />
<Slider color="red" defaultValue={60} />Marks
Pass marks to paint dots along the track. Each mark is { value, label? } — the label is rendered below the dot. Marks don't restrict input; they're purely visual unless you pair them with a matching step.
<Slider
defaultValue={50}
marks={[
{ value: 0, label: '0' },
{ value: 25, label: '25' },
{ value: 50, label: '50' },
{ value: 75, label: '75' },
{ value: 100, label: '100' },
]}
/>For a segmented stepper, combine marks with step:
<Slider
min={0}
max={10}
step={1}
defaultValue={4}
marks={Array.from({ length: 11 }, (_, i) => ({ value: i }))}
/>Floating label
label accepts any ReactNode and floats above the thumb. By default it appears on hover, focus, or drag (showLabelOnHover). Set it to false to always show.
<Slider label="35%" /> {/* on hover/focus */}
<Slider label="35%" showLabelOnHover={false} /> {/* always visible */}
<Slider label={null} /> {/* no label */}The label must be serializable. To bind it to the current value, drive the slider as a controlled input from a client component (see below).
Controlled
onChange fires on every change (drag, keyboard, click). onChangeEnd fires once the interaction settles — use it to debounce expensive work (network calls, expensive re-renders downstream).
A controlled value is also how you wire a dynamic label, since the label has to be computed in the same client tree as the slider:
'use client';
import { useState } from 'react';
import { Slider } from '@42/ui-react/slider';
export function VolumeSlider() {
const [value, setValue] = useState(50);
return (
<Slider
value={value}
onChange={setValue}
onChangeEnd={(v) => commitToServer(v)}
label={`${value}%`}
/>
);
}Disabled
<Slider defaultValue={60} disabled />API
Prop
Type
All other props are forwarded to the underlying Ark Slider.Root.
Accessibility
- Keyboard:
←/→step bystep;Shift + ←/→jumps by 10×;Home/Endsnap tomin/max;PageUp/PageDownjump by 10×. - RTL: when the document
dirisrtl(or a parent sets it), Ark inverts the thumb direction so→still increases the value visually. - Focus ring is keyboard-only (
focus-visible:) so pointer interactions stay quiet. - A hidden
<input>is rendered inside each thumb so the slider integrates with native<form>submission. Passnameto wire it up.