Slider
A range input control built on Base UI. Two visual variants (discrete and continuous), five intents, three sizes, horizontal and vertical orientation, range mode, tick marks, value tooltip, and RTL support.
Playground
Installation
pnpm add @tessinaui/uiUsage
import { Slider } from "@tessinaui/ui";
<Slider defaultValue={40} />Examples
Default
A basic discrete slider with a single thumb.
Variants
Two visual styles — discrete thin-track and continuous capsule fill.
Sizes
Three scales — sm, md, and lg.
Intents
Semantic colors — none, error, warning, success, and info.
Range
Pass an array value for a two-thumb range selection.
Value in thumb
Set valueInThumb to render the current value inside the handle, which grows
into a value pill. In range mode each thumb shows its own value.
Marks
Tick marks with custom positions and labels. Ticks inset from both ends so they line up with the thumb and stop short of the rounded track — like a macOS slider.
With Icons
Leading and trailing icons flanking the track.
Variants
| Variant | Description |
|---|---|
discrete | Classic thin-track slider with a pill-shaped thumb. Default. |
continuous | Large capsule/pill fill-style slider with a circular knob inside. |
Intents
| Intent | Color token | Use case |
|---|---|---|
none | bg-primary | Default brand color |
error | bg-error | Error or danger state |
warning | bg-warning | Warning or caution state |
success | bg-success | Success or confirmation state |
info | bg-info | Informational state |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | readonly number[] | — | Controlled value. Pass an array for range mode. |
defaultValue | number | readonly number[] | 40 | Initial uncontrolled value. Pass an array for range mode. |
min | number | 0 | Minimum allowed value |
max | number | 100 | Maximum allowed value |
step | number | 1 | Step increment |
largeStep | number | — | Step for Page Up/Down or Shift+Arrow |
onValueChange | (value: number | readonly number[]) => void | — | Fires on every change |
onValueCommitted | (value: number | readonly number[]) => void | — | Fires on pointer up / key up |
variant | "discrete" | "continuous" | "discrete" | Visual style |
size | "sm" | "md" | "lg" | "md" | Scale |
intent | "none" | "error" | "warning" | "success" | "info" | "none" | Semantic color intent |
orientation | "horizontal" | "vertical" | "horizontal" | Layout direction |
disabled | boolean | false | Disable all interaction |
rounded | "none" | "sm" | "md" | "lg" | "xl" | "full" | "full" | Border radius of track, indicator, and thumb |
marks | boolean | SliderMark[] | false | true = auto-generate at every step (capped at 50). Array = custom positions with optional labels. |
minLabel | ReactNode | — | Label at the min end (left for horizontal, bottom for vertical) |
maxLabel | ReactNode | — | Label at the max end (right for horizontal, top for vertical) |
showValue | boolean | false | Show current value as a floating tooltip above/beside the thumb |
valueInThumb | boolean | false | Render the current value inside the thumb (grows into a value pill). Discrete only; takes precedence over showValue |
label | ReactNode | — | Accessible label (rendered sr-only) |
leadingIcon | ReactNode | — | Icon at the leading end (left for horizontal, bottom for vertical) |
trailingIcon | ReactNode | — | Icon at the trailing end (right for horizontal, top for vertical) |
getAriaLabel | (index: number) => string | — | Accessible label per thumb (range mode) |
getAriaValueText | (formatted, value, index) => string | — | Accessible value text per thumb |
name | string | — | Form field name |
format | Intl.NumberFormatOptions | — | Number format for the value tooltip |
dir | "ltr" | "rtl" | "ltr" | Text direction |
className | string | — | Extra classes on the root element |
SliderMark
| Field | Type | Description |
|---|---|---|
value | number | Value at which to render the tick dot |
label | ReactNode | Optional text label beside the dot |
Range Slider
Pass an array to defaultValue or value to enable range (two-thumb) mode:
<Slider defaultValue={[20, 80]} />Accessibility
- Built on Base UI's
Sliderprimitive — keyboard navigation (Arrow keys, Page Up/Down, Home, End) is handled automatically. - Each thumb renders an
<input type="range">with a proper accessible role. - Use
getAriaLabelin range mode to provide distinct labels for each thumb (e.g. "Minimum price", "Maximum price"). - Tick mark labels are
aria-hidden— they are visual decorations; usegetAriaValueTextfor screen-reader value descriptions. - Focus ring:
has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-offset-2scoped to the thumb container. - All interactive areas meet the WCAG AA 44×44 px minimum touch target.
Skeleton
Animated placeholder for loading states. Wave shimmer (default) and pulse variants, five rounded options, and composable with any layout.
Spacer
A decorative gap-filler. Three axis modes, eight sizes, optional grow-to-fill behaviour, and polymorphic render. Accessibility-hidden by default — screen readers skip it.