<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# Slider

A labeled slider on the Field contract: pass `label`, and a `defaultValue` (or `value` with `onValueChange`). A value array, `defaultValue={[20, 80]}`, gives a range with a thumb per value. `showValue` shows the value, formatted with `format`. Each thumb has a 44px touch area on phones.

```tsx
import { Slider } from "@/components/ouro/slider/slider";
```

## Example

```tsx
<Slider label="Servings" name="servings" defaultValue={4} min={1} max={12} showValue />
<Slider label="Price" name="price" defaultValue={[10, 40]} format={{ style: "currency", currency: "USD" }} showValue />
```

## Use instead when

- Use `NumberField` instead when people need an exact number, and `RadioGroup` for a few named choices.

## Props

Type: `SliderProps<Value>`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `className` | `string` |  | Layout only: margins, width, grid placement (`mt-4`, `col-span-2`). Appearance classes warn in development; style sliders in your theme. |
| `defaultValue` | `Value` |  | The starting value, when the slider keeps its own. An array gives a range: `defaultValue={[20, 80]}`. |
| `description` | `ReactNode` |  | Supporting text under the label, read after the label through `aria-describedby`. |
| `disabled` | `boolean` |  | Disables the slider and fades it. |
| `error` | `ReadonlyErrorMessages` |  | What is wrong, from your server action or client check. The message (or several, as a list) shows under the slider, which gets `aria-invalid` and the destructive color. A message is text or a React node (one with a link); an empty string or array means valid. |
| `format` | `Intl.NumberFormatOptions` |  | How the value reads, as `Intl.NumberFormat` options, for `showValue` and screen readers: `{ style: "percent" }`, `{ style: "currency", currency: "EUR" }`. |
| `hideLabel` | `boolean` |  | Hides the label visually; screen readers still read it as the slider's name. |
| `label` (required) | `string` |  | What the slider sets, shown above it and read as its name. Required: every control needs a name. To hide it visually, keep it and add `hideLabel`. |
| `largeStep` | `number` | `10` | The step for Page Up, Page Down and Shift with an arrow key. |
| `locale` | `Intl.LocalesArgument` | the browser's, once hydrated; en-US in the server's HTML | The locale for `format`. |
| `max` | `number` | `100` | The highest value. |
| `min` | `number` | `0` | The lowest value. |
| `name` | `string` |  | The form field name the value submits under; a range submits one entry per thumb. |
| `onValueChange` | `((value: SliderOutput<Value>) => void)` |  | Called with the new value as the user drags, presses the track or uses the keyboard: a number, or an array for a range. |
| `onValueCommitted` | `((value: SliderOutput<Value>) => void)` |  | Called once the user lets go (or with each key press), with the final value. Use it to save. |
| `ref` | `Ref<HTMLInputElement>` |  | The first thumb's `<input type="range">`. |
| `showValue` | `boolean` |  | Shows the formatted value at the end of the slider; a range shows both ends: `$10 – $40`. |
| `step` | `number` | `1` | The distance between values. |
| `thumbLabels` | `readonly string[]` | ["Minimum", "Maximum"] | What each thumb of a range is called, before the label: screen readers hear "Minimum, Price". Translate them with your app. |
| `value` | `Value` |  | The value, when you control it. An array gives a thumb per value: `value={[20, 80]}` is a range. |

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `errorMessage`: Not a prop. Ouro UI uses `error`: `<Slider error="Required.">`.
- `helperText`: Not a prop. Ouro UI uses `description`: `<Slider description="...">`.
- `invalid`: Not a prop. `error` marks the slider invalid: `<Slider error="What is wrong">`.
- `isDisabled`: Not a prop. Ouro UI uses `disabled`: `<Slider disabled>`.
- `isInvalid`: Not a prop. `error` marks the slider invalid: `<Slider error="What is wrong">`.
- `isRequired`: Not a prop. A slider always has a value, so it is never missing: `<Slider defaultValue={50}>`.
- `maxValue`: Not a prop. Ouro UI uses `max`: `<Slider max={10}>`.
- `minValue`: Not a prop. Ouro UI uses `min`: `<Slider min={1}>`.
- `onChange`: Not a prop. Slider reports the value itself: `<Slider onValueChange={(value) => …}>`.
- `range`: Not a prop. A value array gives a thumb per value: `<Slider defaultValue={[20, 80]}>`.
- `required`: Not a prop. A slider always has a value, so it is never missing: `<Slider defaultValue={50}>`.
- `showTooltip`: Not a prop. Ouro UI uses `showValue`: `<Slider showValue>`.
- `valueLabelDisplay`: Not a prop. Ouro UI uses `showValue`: `<Slider showValue>`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`). Your classes always win over Ouro UI's: Slider merges `className` last with `cn` (tailwind-merge), so a class that conflicts with its own replaces it.[^layout-classes]

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

## Types

### `ErrorMessage`

One error message: text, or a React element for a message that carries a link or other markup.

```ts
type ErrorMessage = string | ReactElement;
```

### `ReadonlyErrorMessages`

A read-only message view accepted by fields and Form; mutable input arrays remain valid.

```ts
type ReadonlyErrorMessages = ErrorMessage | readonly ErrorMessage[];
```

### `SliderOutput`

The value Slider reports: a number for one thumb, an array for a range.

```ts
type SliderOutput<Value extends SliderValue> = Value extends readonly number[] ? number[] : number;
```

### `SliderValue`

A slider's value: one number, or one per thumb for a range.

```ts
type SliderValue = number | readonly number[];
```

[^layout-classes]: test:registry/ouro/components/ouro/slider/slider.test.tsx::Slider > lets app layout classes win on the root verify:testExists(registry/ouro/components/ouro/slider/slider.test.tsx::Slider > lets app layout classes win on the root)
