first commit
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
# `<SliderH>`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Horizontal slider control — the X-axis counterpart of `<SliderV>`.
|
||||
Every behavioural decision is delegated to the shared
|
||||
`slider-helpers` module so the two orientations stay in lockstep:
|
||||
detent snapping, step quantization, keyboard delta sizing, fine-mode
|
||||
factor, and clamp logic are all identical to `<SliderV>`. The only
|
||||
differences are: arrow-key mapping (`ArrowLeft` / `ArrowRight` instead
|
||||
of `ArrowDown` / `ArrowUp`), pointer math reads `clientX` against the
|
||||
rect width, and the SVG rendering is horizontal.
|
||||
|
||||
## Features
|
||||
|
||||
- Pointer capture for drag past the SVG bounds.
|
||||
- Detent snapping (shared with `<SliderV>`).
|
||||
- Keyboard accessibility: arrow keys, Home, End, PageUp, PageDown,
|
||||
Shift fine-mode.
|
||||
- `aria-slider` with `aria-orientation="horizontal"`.
|
||||
- CSS-variable theming reuses the same `--cs-slider-*` tokens as
|
||||
`<SliderV>`.
|
||||
- Auto-rendered detent ticks on the track.
|
||||
- Step-quantized output via `step` (default `0.01`).
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```tsx
|
||||
import { useState } from "react";
|
||||
import { SliderH } from "@suaveplan/react-control-surface";
|
||||
|
||||
export function PanSlider() {
|
||||
const [v, setV] = useState(0);
|
||||
return (
|
||||
<SliderH
|
||||
value={v}
|
||||
onChange={setV}
|
||||
min={-1}
|
||||
max={1}
|
||||
step={0.01}
|
||||
label="Pan"
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
A blend slider with a centre detent, wider track, custom snap radius:
|
||||
|
||||
```tsx
|
||||
import { useState } from "react";
|
||||
import { SliderH } from "@suaveplan/react-control-surface";
|
||||
|
||||
export function DryWetBlend() {
|
||||
const [mix, setMix] = useState(0.5);
|
||||
return (
|
||||
<SliderH
|
||||
value={mix}
|
||||
onChange={setMix}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.001}
|
||||
label="Dry / Wet"
|
||||
detents={[{ at: 0.5, label: "50%" }]}
|
||||
snapThreshold={0.02}
|
||||
trackPx={280}
|
||||
thicknessPx={28}
|
||||
fineModeFactor={0.05}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ---------------- | --------------------- | -------- |
|
||||
| `value` | `number` | required |
|
||||
| `onChange` | `(v: number) => void` | required |
|
||||
| `min` | `number` | required |
|
||||
| `max` | `number` | required |
|
||||
| `step` | `number` | `0.01` |
|
||||
| `disabled` | `boolean` | `false` |
|
||||
| `label` | `string` | — |
|
||||
| `ariaLabel` | `string` | — |
|
||||
| `detents` | `SliderDetent[]` | — |
|
||||
| `snapThreshold` | `number` | 2% span |
|
||||
| `trackPx` | `number` | `160` |
|
||||
| `thicknessPx` | `number` | `24` |
|
||||
| `fineModeFactor` | `number` | `0.1` |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`<SliderH>` imports its helpers from `../slider-v/slider-helpers.js`
|
||||
rather than from the package root so the helper module remains
|
||||
package-private and never leaks into the public barrel. The pointer
|
||||
math reads the rendered rect width so a `width: 100%` host container
|
||||
behaves correctly — value tracks the actual on-screen geometry rather
|
||||
than the configured `trackPx`. When the rect collapses to width 0
|
||||
(offscreen / display:none), the math falls back to `trackPx`.
|
||||
Reference in New Issue
Block a user