Knob

Rotary control for parameters - drag, wheel, keyboard, optional fader-style vertical pan, and reset via double-tap.

Rotary knob for continuous parameters (level, cutoff, pan, etc.). The registry component wraps Knob primitives from @audio-ui/react with size variants and theme styles; behavior and geometry are documented below.

Knob
Knob arc

Overview

  • Interaction model: Circular drag by default, optional vertical “fader” pan, mouse wheel, keyboard nudging, and double-tap / double-click to snap back to defaultValue.
  • Feedback: Track rail, highlighted arc between anchor and value when useful, and a needle aligned to the current value.
  • Accessibility: The draggable surface is a role="slider" with aria-valuenow / min / max; label via aria-label or aria-labelledby.

Installation

Usage

import { Knob } from "@/components/audio/knob";

Uncontrolled - initial value only:

<Knob defaultValue={50} max={100} min={0} step={1} />

Controlled - drive the value from state (typical in audio UIs):

const [cutoff, setCutoff] = useState(1000);
 
<Knob
  max={20_000}
  min={20}
  onValueChange={setCutoff}
  step={1}
  value={cutoff}
/>

Pass defaultValue even when controlled if you use double-tap reset; it defines the value the knob jumps back to (still clamped and stepped).

Interaction

Pointer

BehaviorDetails
Circular drag (default)Value tracks accumulated rotation around the center from the value at pointer down. Uses dragSensitivity to choose the angular reference (see Pointer mapping).
Vertical fader dragSet dragOptions={{ verticalPanEnabled: true }}. After a small movement threshold, a mostly-vertical drag nudges the value like a fader; circular drag still works when the gesture is more rotational.
Double-tap / double-clickTwo quick releases with ≤ ~12px movement from each pointer down, within ~320ms, resets to defaultValue, or to the midpoint of min…max if defaultValue is omitted. Fires onValueCommit like a normal commit.

Default geometry uses a large sweep (~288° from angleGapRad), so arc and revolution can feel similar; use a smaller angleRange if you want arc to span the full range in less than one physical turn. Values always clamp to min…max (no wrap).

Keyboard

Focused knob:

KeyAction
ArrowUp / ArrowRightIncrease by step
ArrowDown / ArrowLeftDecrease by step
PageUpIncrease by step × 10
PageDownDecrease by step × 10
Homemin
Endmax

Wheel

When the knob is focused, vertical wheel deltas step the value (same idea as key nudging).

API reference

Knob accepts size and className plus primitive props from KnobPrimitive.RootProps.

Value and state

PropTypeDefaultDescription
valuenumber-Controlled value.
defaultValuenumber-Uncontrolled starting value; also the double-tap reset target when provided.
minnumber0Minimum.
maxnumber100Maximum.
stepnumber1Quantization step (drag, wheel, keyboard, reset).
disabledbooleanfalseDisables pointer, wheel, and keyboard.
onValueChange(value: number) => void-Live updates while dragging or adjusting.
onValueCommit(value: number) => void-When the gesture ends (pointer up, wheel tick, reset, etc.).
aria-labelstring-Accessible name for the slider.
aria-labelledbystring-ID of a labeling element.

Size and rail

PropTypeDefaultDescription
size"sm" | "default" | "lg" | "xl""default"Diameter variant.
classNamestring-On the root wrapper.
arcRadiusnumber23Arc radius in the 48×48 viewBox.
arcStrokeWidthnumber3Track / arc stroke width.
angleGapRadnumberπ/5Bottom gap in radians; drives default angleOffset / angleRange.
angleOffsetnumberfrom gapDial start angle in degrees (optional override).
angleRangenumberfrom gapTotal sweep in degrees (optional override).
anchornumber-Secondary value for the highlighted arc segment.
indicatorSpan[number, number][0.24, 0.58]Needle inner / outer radius as fractions of track radius.
indicatorWidthnumber2.75Needle stroke width.

Pointer and drag

PropTypeDefaultDescription
dragSensitivity"arc" | "revolution""arc"arc: one full span matches angleRange (as radians). revolution: one full span matches 360° of pointer travel. Both are relative to the value at pointer down and clamp to min…max.
dragOptionssee below-Pan vs rotate, dead zone, vertical sensitivity.

dragOptions (Knob.DragOptions)

FieldDefaultPurpose
verticalPanEnabledfalseAllow vertical fader-style drag when true.
panSensitivityDivisor150Vertical pan scale: (max - min) / divisor per unit delta.
centerDeadZoneRel / centerDeadZoneMinPx0.08 / 2Hub radius where angle follows pointer without accumulating huge jumps.
modeLockMinPx / modeLockRel6 / 0.055Movement before locking rotate vs pan mode.
panMinVerticalPx10Minimum vertical movement to consider pan.
panDominanceRatio2.5Pan wins when movedY > movedX × ratio.

Additional HTML attributes on the root are forwarded where valid.

Examples

Disabled state

Knob
Knob arc

Disabled

Knob
Knob arc

Enabled

Size variants

Knob
Knob arc
Knob
Knob arc
Knob
Knob arc
Knob
Knob arc

Rail, anchor, and range highlight

Use anchor to show a reference point on the rail (for example center on a bipolar control). The arc highlights the interval between anchor and the current value.

Knob
Knob arc

Value only

Knob
Knob arc

With anchor range

Pointer mapping

Each preview shows one mapping in isolation (live value under the control).

Default arc (circular)

Knob
Knob arc
50

Vertical fader-style drag

Knob
Knob arc
50

Revolution (360° reference)

Knob
Knob arc
50

Reset with double-tap

Knob
Knob arc
72

Double-tap the control to jump back to 30 (defaultValue).

Fine step precision (step={0.01})

Knob
Knob arc
0.50

Live value vs committed value callbacks

Knob
Knob arc
Live: 64
Committed: 64

Filter cutoff

Knob
Knob arc
1000 Hz

Channel strip

Channel 1
Pan
Knob arc
C
Output
Gain
Knob arc
50%
FX
Reverb
Knob arc
50%
FX
Delay
Knob arc
50%
FX
Drive
Knob arc
50%
FX

Last updated 4/15/2026