import React from 'react'; import { FlatKnob, logTaper } from 'dreamknob'; import { CodeBlock } from '../components/CodeBlock'; const Step: React.FC<{ n: number; title: string; children: React.ReactNode }> = ({ n, title, children, }) => (

{String(n).padStart(2, '0')} {title}

{children}
); export const GettingStarted: React.FC = () => (
Getting started

Your first knob in five minutes

Everything below is copy-pasteable. The only rule to remember: every control needs an aria-label (or a visible label wired via aria-labelledby).

= 18, react-dom >= 18`} />

Zero runtime dependencies, ESM + CJS, full TypeScript types. No CSS file to import — everything is SVG and inline styles.

Pass defaultValue and the knob manages its own state.{' '} defaultValue is also the double-click reset target.

`} />

For app state, pass value + onChange. The second argument tells you what caused the change — useful later for undo/automation.

setGain(v)} // meta.source: 'drag' | 'wheel' | 'keyboard' | 'reset' | 'api' min={-60} max={12} step={0.5} unit=" dB" aria-label="Gain" />`} />

The default is grab-and-rotate (the pointer angle drives the value). Prefer the up/down plugin feel, or MIDI-style pickup? One prop each. Users always get scroll-wheel, arrow keys, Shift-fine, Escape-cancel and double-click reset for free.

// drag up/down like a plugin // never jumps when grabbed off-position // angle deltas, no jump either`} />

step snaps and sets display precision (float-safe — no{' '} 0.30000000000000004). For audio ranges, use a taper:{' '} logTaper gives equal ratios per turn, so 20 Hz–20 kHz feels right. format controls display without touching the emitted value.

0 for log defaultValue={440} decimals={0} format={v => v >= 1000 ? \`\${(v / 1000).toFixed(1)}k\` : \`\${Math.round(v)}\`} label="Freq" aria-label="Frequency" />`} />
(v >= 1000 ? `${(v / 1000).toFixed(1)}k` : `${Math.round(v)}`)} label="Freq" aria-label="Frequency example" />
{/* every knob/fader/meter below inherits the tokens */} `} />

Use base="light" on light backgrounds. Per-instance color props always win over the theme.

① Always pass aria-label. ② logTaper needs{' '} min > 0 (it falls back to linear otherwise). ③ Controlled mode means you own the value — if you don't call setState in{' '} onChange, the knob won't move. ④ Hovering captures the scroll wheel by default; pass wheelRequiresFocus if your UI scrolls. ⑤ The knob is a div, not an input — use name="…" if you need it in a plain <form> post.

);