> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# Slider

Sets an approximate, bounded value by dragging along a track — reach for `NumberInput` when the exact figure matters, since a slider is faster to move than it is to land. A slider should always show its value: pair it with `SliderInput` for entry, or `SliderValue` for a readout. It implies a continuum, so a few fixed choices belong in `SegmentedControl`, `Radio` or `Select`, and on/off in `Switch`.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/Slider) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/inputs-slider--overview)

```tsx
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const Basic = () => (
  <Slider>
    <SliderControl>
      <SliderThumb aria-label='Value' />
    </SliderControl>
  </Slider>
);
```

## Usage

```tsx
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';
```

## Examples

### Range

Two entries in the value make two thumbs; render one `SliderThumb` per entry. The thumbs
cannot cross, so the pair always reads as a valid range.

```tsx
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const Range = () => (
  <Slider defaultValue={[20, 80]}>
    <SliderControl>
      <SliderThumb index={0} />
      <SliderThumb index={1} />
    </SliderControl>
  </Slider>
);
```

### Ticks

`SliderMarks` draws ticks along the scale. Keep `step` aligned to the marks, or the handle
lands between them and the ticks stop meaning anything.

```tsx
import { Slider, SliderControl, SliderMarks, SliderThumb } from '@wallarm-org/design-system/Slider';

export const Ticks = () => (
  <Slider step={25} defaultValue={[50]}>
    <SliderControl>
      <SliderThumb aria-label='Volume' />
      <SliderMarks
        marks={[
          { value: 0, label: '0' },
          { value: 25, label: '25' },
          { value: 50, label: '50' },
          { value: 75, label: '75' },
          { value: 100, label: '100' },
        ]}
      />
    </SliderControl>
  </Slider>
);
```

### Ticks without snapping

The same marks used purely for orientation, with `step` finer than their spacing. Choose this
when the marks are a guide rather than the only valid answers.

```tsx
import { Slider, SliderControl, SliderMarks, SliderThumb } from '@wallarm-org/design-system/Slider';

export const TicksWithoutSnapping = () => (
  <Slider step={1} defaultValue={[40]}>
    <SliderControl>
      <SliderThumb aria-label='Volume' />
      <SliderMarks
        marks={[
          { value: 0, label: '0' },
          { value: 25, label: '25' },
          { value: 50, label: '50' },
          { value: 75, label: '75' },
          { value: 100, label: '100' },
        ]}
      />
    </SliderControl>
  </Slider>
);
```

### Labeled

Marks carrying text, for a scale whose steps are named rather than numeric. The handle snaps
to the labelled positions and announces the label rather than the number, so keep it to a
handful of rungs.

```tsx
import { Slider, SliderControl, SliderMarks, SliderThumb } from '@wallarm-org/design-system/Slider';

export const Labeled = () => (
  <Slider min={0} max={100} step={50} defaultValue={[50]}>
    <SliderControl>
      <SliderThumb aria-label='Risk level' />
      <SliderMarks
        marks={[
          { value: 0, label: 'Low' },
          { value: 50, label: 'Medium' },
          { value: 100, label: 'High' },
        ]}
      />
    </SliderControl>
  </Slider>
);
```

### With tooltip

`tooltip` on a `SliderThumb` shows the value while dragging, then hides it. It suits a value
only checked mid-gesture; anything needed afterwards wants a persistent readout instead,
never both.

```tsx
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const WithTooltip = () => (
  <Slider>
    <SliderControl>
      <SliderThumb aria-label='Value' tooltip />
    </SliderControl>
  </Slider>
);
```

### With input

`SliderInput` is the precision escape hatch: the track for approximate moves, the field for
an exact figure. Typing commits on blur or Enter rather than live, so clamping never fights a
half-typed number.

```tsx
import { Slider, SliderControl, SliderInput, SliderThumb } from '@wallarm-org/design-system/Slider';

export const WithInput = () => (
  <Slider data-testid='slider-with-input'>
    <SliderControl>
      <SliderThumb aria-label='Value' />
    </SliderControl>
    <SliderInput />
  </Slider>
);
```

### Range with input

A field at each end, low on the left and high on the right. Neither crosses the other, so the
fields cannot produce a range the track could not.

```tsx
import { Slider, SliderControl, SliderInput, SliderThumb } from '@wallarm-org/design-system/Slider';

export const RangeWithInput = () => (
  <Slider defaultValue={[20, 80]} data-testid='slider-range-with-input'>
    <SliderInput index={0} />
    <SliderControl>
      <SliderThumb index={0} />
      <SliderThumb index={1} />
    </SliderControl>
    <SliderInput index={1} />
  </Slider>
);
```

### Disabled

The whole control dims and stops responding, handle included. The value stays legible,
because a locked setting is usually one the reader still needs to read.

```tsx
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const Disabled = () => (
  <Slider disabled>
    <SliderControl>
      <SliderThumb aria-label='Value' />
    </SliderControl>
  </Slider>
);
```

### In field

Wrapped in `Field`, which is the form-field shape. The slider reads that context, so the
label and error attach without being passed anything.

```tsx
import { Field, FieldDescription, FieldLabel } from '@wallarm-org/design-system/Field';
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const InField = () => (
  <Field>
    <FieldLabel>Risk threshold</FieldLabel>
    <Slider>
      <SliderControl>
        <SliderThumb />
      </SliderControl>
    </Slider>
    <FieldDescription>Approximate — fine-tune the exact value later.</FieldDescription>
  </Field>
);
```

### Field with error

`invalid` on the `Field` cascades to the handle. The message is `FieldError`'s job, and it
matters here because a slider cannot show a wrong value the way a text field can.

```tsx
import { Field, FieldError, FieldLabel } from '@wallarm-org/design-system/Field';
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const FieldWithError = () => (
  <Field invalid>
    <FieldLabel>Risk threshold</FieldLabel>
    <Slider>
      <SliderControl>
        <SliderThumb />
      </SliderControl>
    </Slider>
    <FieldError>Enter a value between 0 and 100.</FieldError>
  </Field>
);
```

### Field with value

The value beside the label, which is the readout Figma draws for a slider in a form — value
beside label is the drawn default, not one option among several.

```tsx
import { useState } from 'react';
import { Field, FieldLabel } from '@wallarm-org/design-system/Field';
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const FieldWithValue = () => {
  const [value, setValue] = useState([40]);
  return (
    <Field>
      <div className='flex w-full items-center justify-between'>
        <FieldLabel>Risk threshold</FieldLabel>
        <span className='text-sm font-medium text-text-primary tabular-nums'>{value[0]}</span>
      </div>
      <Slider value={value} onValueChange={setValue}>
        <SliderControl>
          <SliderThumb />
        </SliderControl>
      </Slider>
    </Field>
  );
};
```

### Range field with value

Both ends beside the label, comma-separated. For a range this is the only way to read the
value without hovering each thumb.

```tsx
import { useState } from 'react';
import { Field, FieldLabel } from '@wallarm-org/design-system/Field';
import { Slider, SliderControl, SliderThumb } from '@wallarm-org/design-system/Slider';

export const RangeFieldWithValue = () => {
  const [value, setValue] = useState([20, 80]);
  return (
    <Field>
      <div className='flex w-full items-center justify-between'>
        <FieldLabel>Risk range</FieldLabel>
        <span className='text-sm font-medium text-text-primary tabular-nums'>
          {value.join(', ')}
        </span>
      </div>
      <Slider value={value} onValueChange={setValue}>
        <SliderControl>
          <SliderThumb index={0} />
          <SliderThumb index={1} />
        </SliderControl>
      </Slider>
    </Field>
  );
};
```

### With value readout

`SliderValue` reads the slider's own context, so a live readout needs no controlled state of
its own.

```tsx
import { Slider, SliderControl, SliderThumb, SliderValue } from '@wallarm-org/design-system/Slider';

export const WithValueReadout = () => (
  <Slider defaultValue={[60]}>
    <SliderControl>
      <SliderThumb aria-label='Volume' />
    </SliderControl>
    <SliderValue className='w-32 shrink-0 text-right font-medium' />
  </Slider>
);
```

## Props

| Prop                   | Type                                                   | Default | Description                                                                                                                                                                                                                                                                                                             |
| ---------------------- | ------------------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| error                  | `boolean \| undefined`                                 | `false` | Error state → maps to Ark `invalid` (repaints the handle; the message is the Field's job).                                                                                                                                                                                                                              |
| onValueChange          | `((value: number[]) => void) \| undefined`             |         | Fires live during drag with the current value array (`[n]` single, `[low, high]` range).                                                                                                                                                                                                                                |
| onValueChangeEnd       | `((value: number[]) => void) \| undefined`             |         | Fires once on drag release with the committed value array.                                                                                                                                                                                                                                                              |
| form                   | `string \| undefined`                                  |         | The associate form of the underlying input element.                                                                                                                                                                                                                                                                     |
| defaultValue           | `number[] \| undefined`                                | `[50]`  | The initial value of the slider when rendered. Use when you don't need to control the value of the slider.                                                                                                                                                                                                              |
| disabled               | `boolean \| undefined`                                 |         | Whether the slider is disabled                                                                                                                                                                                                                                                                                          |
| name                   | `string \| undefined`                                  |         | The name associated with each slider thumb (when used in a form)                                                                                                                                                                                                                                                        |
| value                  | `number[] \| undefined`                                |         | The controlled value of the slider                                                                                                                                                                                                                                                                                      |
| readOnly               | `boolean \| undefined`                                 |         | Whether the slider is read-only                                                                                                                                                                                                                                                                                         |
| step                   | `number \| undefined`                                  |         | The step value of the slider                                                                                                                                                                                                                                                                                            |
| max                    | `number \| undefined`                                  |         | The maximum value of the slider                                                                                                                                                                                                                                                                                         |
| min                    | `number \| undefined`                                  |         | The minimum value of the slider                                                                                                                                                                                                                                                                                         |
| getAriaValueText       | `((details: ValueTextDetails) => string) \| undefined` |         | Function that returns a human readable value for the slider thumb                                                                                                                                                                                                                                                       |
| minStepsBetweenThumbs  | `number \| undefined`                                  |         | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` \* `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20`                                                                 |
| thumbCollisionBehavior | `"none" \| "push" \| "swap" \| undefined`              |         | Controls how thumbs behave when they collide during pointer interactions. - `none` (default): Thumbs cannot move past each other; excess movement is ignored. - `push`: Thumbs push each other without restoring their previous positions when dragged back. - `swap`: Thumbs swap places when dragged past each other. |
| data-testid            | `string \| undefined`                                  |         |                                                                                                                                                                                                                                                                                                                         |

### SliderInput

| Prop           | Type                                                   | Default | Description                                                  |
| -------------- | ------------------------------------------------------ | ------- | ------------------------------------------------------------ |
| index          | `number \| undefined`                                  | `0`     | Which thumb this box is bound to (0 = single/low, 1 = high). |
| title          | `string \| undefined`                                  |         |                                                              |
| pattern        | `string \| undefined`                                  |         |                                                              |
| defaultChecked | `boolean \| undefined`                                 |         |                                                              |
| autoFocus      | `boolean \| undefined`                                 |         |                                                              |
| id             | `string \| undefined`                                  |         |                                                              |
| tabIndex       | `number \| undefined`                                  |         |                                                              |
| rel            | `string \| undefined`                                  |         |                                                              |
| onChange       | `ChangeEventHandler<T, HTMLInputElement> \| undefined` |         |                                                              |
| type           | `HTMLInputTypeAttribute \| undefined`                  |         |                                                              |
| disabled       | `boolean \| undefined`                                 |         |                                                              |
| name           | `string \| undefined`                                  |         |                                                              |
| alt            | `string \| undefined`                                  |         |                                                              |
| height         | `string \| number \| undefined`                        |         |                                                              |
| src            | `string \| undefined`                                  |         |                                                              |
| width          | `string \| number \| undefined`                        |         |                                                              |
| autoComplete   | `HTMLInputAutoCompleteAttribute \| undefined`          |         |                                                              |
| maxLength      | `number \| undefined`                                  |         |                                                              |
| minLength      | `number \| undefined`                                  |         |                                                              |
| placeholder    | `string \| undefined`                                  |         |                                                              |
| readOnly       | `boolean \| undefined`                                 |         |                                                              |
| required       | `boolean \| undefined`                                 |         |                                                              |
| checked        | `boolean \| undefined`                                 |         |                                                              |
| step           | `string \| number \| undefined`                        |         |                                                              |
| accept         | `string \| undefined`                                  |         |                                                              |
| max            | `string \| number \| undefined`                        |         |                                                              |
| min            | `string \| number \| undefined`                        |         |                                                              |
| multiple       | `boolean \| undefined`                                 |         |                                                              |

### SliderMarks

| Prop     | Type           | Default | Description                                                                                                                                                                                  |
| -------- | -------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| marks \* | `SliderMark[]` |         | Each entry places a tick at `value`; an optional `label` renders below it (and drives `aria-valuetext` for ordinal scales). Align `step` to the marks so drag and arrow-keys snap onto them. |

### SliderThumb

| Prop           | Type                                                 | Default | Description                                                                 |
| -------------- | ---------------------------------------------------- | ------- | --------------------------------------------------------------------------- |
| index          | `number \| undefined`                                | `0`     | Which thumb this is (0 = single/low, 1 = high).                             |
| tooltip        | `boolean \| undefined`                               | `false` | Show an on-drag value bubble above this thumb (DS Tooltip, opened by drag). |
| title          | `string \| undefined`                                |         |                                                                             |
| defaultChecked | `boolean \| undefined`                               |         |                                                                             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                             |
| autoFocus      | `boolean \| undefined`                               |         |                                                                             |
| id             | `string \| undefined`                                |         |                                                                             |
| tabIndex       | `number \| undefined`                                |         |                                                                             |
| rel            | `string \| undefined`                                |         |                                                                             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                             |
| name           | `string \| undefined`                                |         |                                                                             |

### SliderValue

| Prop  | Type                  | Default | Description                                                                          |
| ----- | --------------------- | ------- | ------------------------------------------------------------------------------------ |
| index | `number \| undefined` |         | Show one thumb's value (range). Omit to show all (single → "50", range → "20 – 80"). |
