Kit

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 by step; Shift + ←/→ jumps by 10×; Home / End snap to min / max; PageUp / PageDown jump by 10×.
  • RTL: when the document dir is rtl (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. Pass name to wire it up.

On this page