--- title: Slider description: Sliders let users pick a numeric value or range along a track. They work well when the approximate value matters more than precise typing. category: Forms --- import { meta as SliderMeta, Default, Range, ValuePrecision } from '@/content/stories/slider'; import Canvas from '@/components/component-docs/canvas'; import Demo from '@/components/component-docs/demo'; export const config = { dependencies: { components: [Canvas, Demo], scripts: [ '../../components/component-docs/demo.script.tsx', '../../components/component-docs/canvas.script.tsx', '../../components/component-docs/controls.script.tsx', ], }, }; # Slider

Sliders let users pick a numeric value or range along a track. They work well when the approximate value matters more than precise typing.

## Try it ## Usage The live `value` property is always a `number[]`. The HTML attribute is comma-separated (`value="50"` or `value="25,75"`). JSX may pass a number or an array. Two numbers are range mode; `variant="range"` only seeds `[25, 75]` when `value` is not already a pair. Set `min`, `max`, and `step` for the numeric domain. Set `orientation="vertical"` for a vertical track. ```tsx import { RuiSlider } from '@ecopages/radiant-ui/slider'; import { RuiField } from '@ecopages/radiant-ui/field'; import { RuiLabel } from '@ecopages/radiant-ui/label'; Volume ``` ## Custom markup `` coordinates any light-DOM tree that matches its query contract. The `RuiSlider` helper stamps these targets; it is not required. ```tsx import '@ecopages/radiant-ui/slider';
Volume
``` BEM classes are presentation-only. The host owns thumb `aria-*` and track CSS variables. Set `name` on the host to submit with a native form. ## Range selection

Pass `value={[25, 75]}` for minimum/maximum filters. Set `minDistance` to prevent the thumbs from overlapping.

## Step size and readout

Match `step` to meaningful increments. `valuePrecision` only formats the readout, tooltips, and `aria-valuetext`. It defaults to the decimal places in `step`, so a stored `0.30000000000000004` still displays as `0.3`. Round committed values in application code when you need a canonical number.

```tsx ``` ## Theming Slider surfaces map to **semantic roles**, never Tailwind palette steps: | Part | CSS roles | | --- | --- | | Track (`.rui-slider__range-track`) | `--rui-track-fill` (`--rui-track-mix` of `--on-background`) | | Fill (`.rui-slider__range-fill`) | `primary` | | Thumb (`.rui-slider__thumb`) | `background` surface, `primary` border, `--shadow-control` (`--rui-slider-thumb-shadow`) | | Value readout (`.rui-slider__value`) | `on-surface` | | Focus ring | `focus-ring` | Range thumb positions come from `--rui-slider-min` / `--rui-slider-max`. The `RuiSlider` view seeds those inline variables (and the value readout) during SSR; the host updates them while dragging. Unfilled track contrast is shared with knobs. Set the mix or a solid color on an ancestor: ```css :root { --rui-track-mix: 28%; } .panel { --rui-track-color: var(--surface-container-high); } ``` Override `--rui-slider-track-color` on `rui-slider` when only the slider should change. Range mode also accepts presentation variables on `rui-slider`. Set track and thumb corner radii independently — they follow shape tokens such as `--radius-control` and `--radius-container`: ```css rui-slider { --rui-slider-track-radius: var(--radius-container); --rui-slider-thumb-radius: var(--radius-control); } ``` Switching the radius pack (sharp, default, soft) updates both when they reference shape tokens. ## API `RuiSlider` owns the light-DOM surface. Pass `showValue` for the default readout, `valueTitle` for hover tooltips, or compose a custom readout with `RuiSliderValue`. ### Attributes | Attribute | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `single` · `range` | `single` | Single-thumb or dual-thumb range. | | `orientation` | `horizontal` · `vertical` | `horizontal` | Track axis. | | `value` | `string` | `50` | Comma-separated thumb values (`50` or `25,75`). The JS property is `number[]`. | | `min` | `number` | `0` | Range minimum. | | `max` | `number` | `100` | Range maximum. | | `step` | `number` | `1` | Arrow-key and pointer snap interval. | | `value-precision` | `number` | decimal places in `step` | Maximum fraction digits in the value readout. | | `min-distance` | `number` | `0` | Minimum gap enforced between range thumbs. | | `disabled` | `boolean` | `false` | Disables interaction. | | `read-only` | `boolean` | `false` | Prevents value changes while leaving thumbs focusable. | | `label` | `string` | `''` | Accessible name for the slider. | | `name` | `string` | `''` | Form field name on this host. Range mode also submits `{name}-max`. | | `show-value` | `boolean` | `false` | Shows the default value readout below the track. | | `value-title` | `boolean` | `false` | Mirrors the live value in the control `title` on hover. | ### Light-DOM contract | Target | Required | Host writes | Author owns | | --- | --- | --- | --- | | `[data-ref="root"]` | yes | `rui-slider--*` layout classes | the root node | | `[data-ref="rangeTrack"]` | yes | inline `--rui-slider-*`, optional `title` | the track node; view seeds geometry | | `[data-thumb]` | yes | `hidden`, `disabled`, `tabindex`, `aria-*` value attrs | thumb elements (`value`, `min`, or `max`); view seeds `aria-valuenow` | | `[data-ref="header"]` | no | `hidden` | header row | | `[data-ref="label"]` | no | `hidden`, `textContent` | label text | | `[data-ref="value"]` | no | `textContent` | readout node; view seeds the formatted value | | `[data-default-value]` | no | `hidden` (via `showValue`) | default readout when no custom value child | Do not set thumb `tabindex`. Nested hosts: none. The `RuiSlider` view seeds readout text, track CSS variables, and `aria-valuenow` so the first paint matches the hydrated control. ### Events | Event | Detail | Description | | --- | --- | --- | | `rui-change` | `{ value: number[] }` | Emitted as the value moves; `[50]` in single mode, `[25, 75]` in range mode. | ### View helpers | Component | Target stamped | Notes | | --- | --- | --- | | `RuiSlider` | full `[data-ref]` tree under `[data-ref="root"]` | Supplies default `RuiSliderValue` with `[data-default-value]` when `children` omitted. Seeds readout text and track geometry for SSR. | | `RuiSliderValue` | `[data-ref="value"]` | Live readout; view seeds the formatted value, host updates `textContent` while dragging. | ### CSS classes Public BEM classes (documented via `@cssclass` on the element): | Class | Description | | --- | --- | | `.rui-slider` | Root; wraps the label, track, and value readout. | | `.rui-slider--range` | Range-mode surface. | | `.rui-slider--vertical` | Vertical track layout. | | `.rui-slider__label` | Optional visible label. | | `.rui-slider__value` | Live numeric readout. | | `.rui-slider__range` | Track wrapper. | | `.rui-slider__range-track` | Track surface behind the thumb(s). | | `.rui-slider__range-fill` | Filled span from the origin to the current value (single) or between thumbs (range). | | `.rui-slider__thumb` | Thumb button (`role="slider"`). | ### Theme roles | Part | CSS variables consumed | | --- | --- | | Track | `--rui-track-color` / `--rui-track-mix` | | Fill / thumb | `--primary` | | Thumb surface | `--background` | | Value readout | `--on-surface` | | Focus | `--focus-ring` | ### Component CSS variables Set on `rui-slider`. Defaults shown; all accept any length or shape token. | Variable | Default | Applies to | | --- | --- | --- | | `--rui-slider-track-size` | `0.375rem` | Track thickness | | `--rui-slider-track-length` | `12rem` | Max track length (vertical / horizontal cap) | | `--rui-slider-track-color` | `--rui-track-color` or `--rui-track-fill` | Track background | | `--rui-slider-fill-color` | `--primary` | Selected range fill | | `--rui-slider-track-radius` | `--radius-control` | Track and fill corner radius | | `--rui-slider-thumb-size` | `1.25rem` | Thumb width and height | | `--rui-slider-thumb-radius` | `--radius-control` | Thumb corner radius | | `--rui-slider-thumb-border-width` | `2px` | Thumb border | | `--rui-slider-thumb-border-color` | `--primary` | Thumb border color | | `--rui-slider-thumb-background` | `--background` | Thumb fill | | `--rui-slider-thumb-shadow` | `0 2px 8px rgb(0 0 0 / 0.12)` | Thumb shadow | ## Accessibility - Sliders expose `role="slider"` with `aria-valuenow`, `aria-valuemin`, `aria-valuemax`, and a formatted `aria-valuetext`. - Pair with a visible label and optionally a live value readout. - Arrow keys adjust the value; Page Up/Down jump by larger increments.