DreamKnob/packages/dreamknob/README.md
Dreamodus 60a02cb1db Initial release: dreamknob library + showcase
React + TypeScript knob/fader library with a headless interaction core
(rotary, relative-drag and track modes, wheel, keyboard, a11y), SVG
primitives, nine prebuilt skins, seven-segment display engine, and a
Vite showcase with gallery, live playground and API docs.
2026-07-12 14:26:52 -07:00

110 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# dreamknob
Studio-grade React knobs & faders. Rotary, linear, 2D, 3D, digital and analog — with a
headless core, any number range, any decimal precision, and colors you fully control.
Zero runtime dependencies.
```
npm install dreamknob
```
## Quick start
```tsx
import { FlatKnob } from 'dreamknob'
function Volume() {
const [value, setValue] = useState(64)
return (
<FlatKnob
size={90}
value={value}
onChange={setValue}
min={0}
max={100}
step={0.5}
label="Volume"
unit="%"
aria-label="Volume"
/>
)
}
```
Uncontrolled works too: pass `defaultValue` instead of `value`/`onChange`
(it also becomes the double-click reset target).
## Interaction model
Every component shares one core:
| Gesture | Behaviour |
| --- | --- |
| Drag | `rotary` (grab & turn, follows the pointer angle), `vertical`, `horizontal`, `both`, or absolute `track-*` (faders) |
| Scroll wheel | one `step` per notch, `Shift` = fine |
| `↑ → / ↓ ←` | ± one step (`Shift` = 10×) |
| `PageUp/PageDown` | ± 10 % of range |
| `Home/End` | min / max |
| Double-click | reset to `defaultValue` |
| Touch / pen | pointer capture, `touch-action: none` |
All knobs render `role="slider"` with `aria-valuemin/max/now/text`.
## Value handling
- `min` / `max` — any numbers (negative, fractional, huge).
- `step` — decimal snap increments (`0.5`, `0.001`, `1e-7`…) with float-drift-safe
rounding; display precision inferred automatically, overridable via `decimals`.
- `values={[0.25, 0.5, 1, 2, 4]}` — discrete allowed values.
- `steps={5}` — evenly spaced detents (selector knobs).
- `taper``linearTaper` (default), `logTaper` (frequencies), `powTaper(n)` (gain),
or your own `{ toNormalized, fromNormalized }`.
- `onChange` / `onChangeStart` / `onChangeEnd` — gesture-aware callbacks.
## Prebuilt skins
```tsx
import {
FlatKnob, // clean 2D arc knob (arcFrom="center" for pan knobs)
MetalKnob, // 3D brushed aluminum, knurled rim (tone="silver" | "dark")
RubberKnob, // 3D soft-touch synth knob with glow halo
VintageKnob, // chicken-head bakelite over a printed scale
LEDKnob, // segmented LED ring + true seven-segment readout
NeonKnob, // glowing arc for dark UIs
SteppedKnob, // detented selector (positions={['LP','BP','HP']})
Fader, // linear channel fader, vertical or horizontal
LEDFader, // segmented LED meter-fader with color zones
SegmentDisplay, // standalone seven-segment numeric display
} from 'dreamknob'
```
Every skin takes the core props plus `size`, `label`, `showValue`, `unit`, `format`,
and per-part color props (`color`, `trackColor`, `faceColor`, `bodyColor`, …).
## Compose your own
```tsx
import { Knob, Arc, Pointer, Ticks, KnobValue } from 'dreamknob'
<Knob size={96} min={-24} max={24} step={0.5} defaultValue={0} aria-label="Trim">
<Ticks count={25} activeColor="#ffd23e" />
<Arc radius={36} thickness={3} color="#ffd23e" from="center" />
<Pointer type="triangle" radius={33} length={9} width={8} color="#ffd23e" />
<KnobValue unit=" dB" />
</Knob>
```
`<Knob>` also accepts a render function: `{(ctx) => <YourSVG angle={ctx.angle} />}`.
## Fully headless
```tsx
import { useKnob } from 'dreamknob'
const { value, normalized, angle, isDragging, bind, setValue } = useKnob({
min: 0, max: 11, step: 0.1, defaultValue: 11, 'aria-label': 'Volume',
})
return <div {...bind}>your own rendering</div>
```
MIT