# Slider

Selects one or more numeric values from a bounded range.

This entrypoint now exports two related Angular surfaces:

- `Slider` via `SliderRootComponent` for shadcn-style single-thumb, range,
  multiple-thumb, vertical, disabled, and RTL examples.
- `input[Slider]` via `SliderInputDirective` for browser-native range inputs
  when labels and forms should stay on the native path.

## Import

```ts
import { SliderInputDirective, SliderRootComponent } from '@edsis/component/slider';
```

## Structure

Use `Slider` when you want the richer shadcn-style component.

```html
<Slider [value]="[75]" />
```

Keep `input[Slider]` when a plain native range input is still the best fit.

```html
<input type="range" Slider />
```

## Basic usage

```ts
const volume = signal<readonly number[]>([75]);

<Slider
  aria-label="Volume"
  [min]="0"
  [max]="100"
  [step]="1"
  [value]="volume()"
  (valueChange)="volume.set($event)"
  class="w-full max-w-sm" />
```

## Common patterns

### Range

Two values render a range slider.

```ts
const priceRange = signal<readonly number[]>([25, 50]);

<Slider
  aria-label="Price range"
  min="0"
  max="100"
  step="5"
  [value]="priceRange()"
  (valueChange)="priceRange.set($event)"
  [thumbLabels]="['Minimum price', 'Maximum price']" />
```

### Multiple thumbs

Three or more values render several thumbs in sorted order.

```ts
const equalizer = signal<readonly number[]>([10, 20, 70]);

<Slider
  aria-label="Equalizer"
  min="0"
  max="100"
  step="10"
  [value]="equalizer()"
  (valueChange)="equalizer.set($event)"
  [thumbLabels]="['Bass', 'Mid', 'Treble']" />
```

### Vertical

Set `orientation="vertical"` and provide an explicit height through `class`.

```html
<div class="flex items-center gap-6">
  <Slider aria-label="Primary level" orientation="vertical" [value]="[50]" class="h-40" />
  <Slider aria-label="Secondary level" orientation="vertical" [value]="[25]" class="h-40" />
</div>
```

### Controlled slider

Drive the values from a signal when nearby UI should react immediately.

```ts
const temperatureRange = signal<readonly number[]>([30, 70]);

<Slider
  aria-label="Temperature range"
  min="0"
  max="100"
  step="5"
  [value]="temperatureRange()"
  (valueChange)="temperatureRange.set($event)"
  [thumbLabels]="['Minimum temperature', 'Maximum temperature']" />
```

### Disabled state

```html
<Slider aria-label="Disabled notifications volume" [value]="[50]" disabled />
```

### RTL

The component follows the surrounding document direction automatically.

```html
<section dir="rtl" lang="ar" class="w-full max-w-sm text-right">
  <Slider aria-label="مستوى الصوت" [value]="[75]" class="w-full" />
</section>
```

### Native input companion

Use the exported native directive when the browser-native range input is still
the best Angular fit for forms and `label[for]` wiring.

```html
<label for="native-volume" class="mb-2 block">Volume</label>
<input id="native-volume" type="range" Slider min="0" max="100" step="1" class="w-full max-w-sm" />
```

## API reference

| Input or output                                       | Type                         | Notes                                                                                     |
| ----------------------------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------- |
| `value`                                               | `readonly number[]`          | Array of sorted thumb values. One item renders a single thumb.                            |
| `valueChange`                                         | `readonly number[]`          | Emits the next array whenever a thumb moves.                                              |
| `min`                                                 | `number`                     | Lower bound for every thumb.                                                              |
| `max`                                                 | `number`                     | Upper bound for every thumb.                                                              |
| `step`                                                | `number`                     | Drag and keyboard increment.                                                              |
| `orientation`                                         | `'horizontal' \| 'vertical'` | Vertical sliders need an explicit height via `class`.                                     |
| `disabled`                                            | `boolean`                    | Disables drag and keyboard interaction.                                                   |
| `thumbLabels`                                         | `readonly string[]`          | Optional accessible labels for each thumb.                                                |
| `aria-label` / `aria-labelledby` / `aria-describedby` | `string \| null`             | Applied to thumb semantics. Prefer `thumbLabels` when several thumbs need distinct names. |
| `class`                                               | `string`                     | Width and height utilities on the host component.                                         |

`SliderInputDirective` keeps the native `<input type="range">` API and passes
through ordinary input attributes directly.

## Styling and theming

The rich `Slider` component uses:

- `--secondary` for the track.
- `--primary` for the active range.
- `--background` for the thumb surface.
- `--primary` for the thumb border.
- `--ring` for the focus-visible outline.

Apply width and height utilities through the host `class`, for example
`w-full`, `max-w-sm`, or `h-40` for vertical sliders.

The native input companion keeps its styling in [slider.component.css](./slider.component.css).

## Accessibility

- Each thumb exposes `role="slider"` with `aria-valuemin`, `aria-valuemax`,
  `aria-valuenow`, and `aria-orientation`.
- Provide `thumbLabels` when the slider has several thumbs so each one has a
  distinct accessible name.
- Use `aria-describedby` for helper text, units, or validation guidance.
- The focused thumb stays tabbable while sibling thumbs use roving `tabindex`.
- When you need browser-native label semantics, use `SliderInputDirective`
  instead of forcing the rich component into a native-input role.

## Keyboard interactions

For `Slider`:

- Arrow keys adjust the value by `step`.
- `Page Up` and `Page Down` move by a larger increment.
- `Home` and `End` jump the active thumb to its local minimum or maximum bound.
- Pointer dragging and track clicks move the nearest thumb.

For `SliderInputDirective`, keyboard behavior follows the browser-native range
input model.

## Angular notes

- Prefer `Slider` when you need shadcn-style parity: range selection,
  multiple thumbs, vertical layout, or explicit thumb labels.
- Prefer `SliderInputDirective` when the control should remain a real native
  input inside Angular forms or a traditional field layout.
- The two exports are complementary rather than replacements for one another.

## Source parity

This Angular entrypoint now covers the main shadcn Radix slider examples:
single-thumb preview, range, multiple thumbs, vertical, controlled, disabled,
and RTL. The native `input[Slider]` directive remains intentionally exported
as an Angular companion for browser-native range inputs instead of disappearing
behind the richer component.
