# Fader

> A volume fader in decibels, with tapers, detents, a scale, reset and an editable value.

<ComponentPreview name="fader-demo" />

## Installation

```npm
npx shadcn-svelte@latest add @audiocn-svelte/fader
```

## Usage

```svelte
<script lang="ts">
	import { Fader } from "#lib/components/ui/fader/index.js";

	let gainDb = $state(0);
</script>

<Fader aria-label="Microphone" bind:value={gainDb} />
```

The value is always in dB. The taper decides where each dB value sits on the travel. The thumb snaps to 0 dB while dragging, and double-clicking it resets.

## Anatomy

```svelte
<Fader bind:value={db}>
	<FaderLabel>Microphone</FaderLabel>
	<FaderReset />
	<FaderValue editable />
	<FaderTrack>
		<FaderRange />
		<FaderThumb />
	</FaderTrack>
	<FaderScale />
</Fader>
```

`FaderTrack` accepts any children, so a `LevelMeter` can sit inside it.

## Examples

### Console faders

`taper="audio"` gives more travel around 0 dB, like a mixing console.

<ComponentPreview name="fader-vertical" />

### Bipolar gain

Set `origin={0}` so the fill grows from the middle.

<ComponentPreview name="fader-bipolar" />

### Silence at the bottom

With `silenceAtMin`, the lowest position reports `-Infinity`.

<ComponentPreview name="fader-silence" />

### With a meter in the track

This preview passes the fader value to `useDemoSignal({ gainDb })`, so the meter shows the level after gain.

<ComponentPreview name="fader-with-meter" />

### Sizes

<ComponentPreview name="fader-sizes" />

## Keyboard

| Key                                | Action                         |
| ---------------------------------- | ------------------------------ |
| Arrow keys                         | Change by `step` (0.5 dB)      |
| Shift + arrow, Page Up / Page Down | Change by `largeStep` (6 dB)   |
| Alt + arrow                        | Change by `fineStep` (0.1 dB)  |
| Home / End                         | Minimum (or silence) / maximum |

Holding Alt while dragging uses `fineStep` resolution.

## Theming

| Variable or attribute                           | Meaning                    |
| ----------------------------------------------- | -------------------------- |
| `--fader-track-size`, `--fader-thumb-size`      | Set by `size`              |
| `data-orientation`, `data-variant`, `data-size` | Current settings           |
| `data-dragging`                                 | The thumb is held          |
| `data-at-detent`                                | The value sits on a detent |
| `data-silent`                                   | The value is `-Infinity`   |
| `data-disabled`                                 | Disabled                   |

## Accessibility

The thumb is a slider whose `aria-valuetext` is the formatted value, such as "−6.0 dB" or "Silent". Give the fader a name with `FaderLabel` or `aria-label`.

## API reference

### Fader

<PropsTable
	rows={[
		["value", "number", "resetValue", "The value in dB. Bindable."],
		[
			"onValueChange",
			"(value, details) => void",
			null,
			"details.reason: drag, track-press, keyboard, wheel, reset or input.",
		],
		[
			"onValueCommit",
			"(value) => void",
			null,
			"Fires when a drag ends, after keyboard input and on reset.",
		],
		["min", "number", "-60", null],
		["max", "number", "6", null],
		["step", "number", "0.5", "Arrow keys and drag resolution."],
		["largeStep", "number", "6", "Shift+arrow, Page Up and Page Down."],
		["fineStep", "number", "0.1", "Alt+arrow and Alt+drag."],
		["resetValue", "number", "0", "Restored by double-click and FaderReset."],
		["taper", '"linear" | "audio" | Taper', '"linear"', "Position law."],
		["origin", "number", "min", "Where the range fill starts."],
		["detents", "number[]", "[0]", "Values the thumb snaps to while dragging."],
		["silenceAtMin", "boolean", "false", "The lowest position reports -Infinity."],
		["allowWheel", "boolean", "false", "The wheel adjusts the value while focused."],
		[
			"orientation",
			'"horizontal" | "vertical"',
			'"horizontal"',
			"Inherited from a channel strip.",
		],
		["variant", '"default" | "console"', '"default"', "console has a wide cap thumb."],
		["size", '"sm" | "default" | "lg"', '"default"', null],
		["format", "(db: number) => string", null, "Used by FaderValue and assistive technology."],
		["disabled", "boolean", "false", null],
	]}
/>

### FaderValue

The value is as wide as the longest text the fader's range can show, and right-aligned, so moving the fader never shifts the layout. The editor opens at the same width.

<PropsTable
	rows={[
		["editable", "boolean", "false", 'Click to type a value. Accepts "-6", "−6 dB" and "-inf".'],
	]}
/>

### FaderScale

Takes [`DbScale`](/docs/components/db-scale) props. The range, taper and orientation come from the fader.
