satelllte/react-knob-headless

React Knob Headless

Unstyled & accessible knob primitive for React.

Features

  • Knob primitive component. Tailored for audio applications in React.
  • Unstyled. Can be styled with any styling solution: Vanilla CSS, Tailwind, Emotion, anything.
  • Smooth drag gesture, which supports mouse & touch devices. Powered by @use-gesture.
  • Accessibility support. Follows ARIA Slider pattern.

Installation

Install the component from your command line.

npm install --save-exact react-knob-headless

Examples

Simple linear knob

By default, the knob interpolation occurs linearly, which is useful for values like "sustain", "dry/wet", "pan", etc.

50%

Interpolated knob

A custom interpolation can be made whenever knob values should distribute non-linearly. It achieved by consuming a pair of "mapTo01" & "mapFrom01" props. This is useful for values like "frequency", "attack", "release", etc.

440 Hz

Horizontal orientation

The knob gesture can occur along horizontal (X) axis instead of vertical (Y) one, but it's not common in audio applications.

50%

Gotchas

  • The package is not in stable version yet. So, just in case, it's recommended to lock its version in your "package.json" file by installing it via "--save-exact" flag.

API

KnobHeadless

The primary knob primitive. This is the place where interaction happens.

PropTypeDefaultDescription
PropvalueRawTypenumberDefaultCurrent value. Make sure it's not rounded.
PropvalueMinTypenumberDefaultMinimum value.
PropvalueMaxTypenumberDefaultMaximum value.
PropdragSensitivityTypenumberDefaultThe sensitivity of the drag gesture. Must be a positive float value. Play with this value in different browsers to find the best one for your use case. Recommended value: 0.006 (quite optimal for most scenarios, so far).
PropvalueRawRoundFnTypefunctionDefaultThe rounding function for the raw value.
PropvalueRawDisplayFnTypefunctionDefaultThe function for mapping raw value to the human-readable text.
ProponValueRawChangeTypefunctionDefaultCallback for when the raw value changes. Note, that you shouldn't round the value here, instead, you have to do it inside "valueRawRoundFn".
ProporientationTypeunionDefaultverticalOrientation of the knob and its gesture. Can be "vertical" or "horizontal".
PropincludeIntoTabOrderTypebooleanDefaultfalseWhether to include the element into the sequential tab order. If true, the element will be focusable via the keyboard by tabbing. In most audio applications, the knob is usually controlled by the mouse / touch, so it's not needed.
PropmapTo01TypefunctionDefaultmapTo01Linear()Used for mapping the value to the normalized knob position (number from 0 to 1). This is the place for making the interpolation, if non-linear one is required. Example: logarithmic scale of frequency input, when knob center position 0.5 corresponds to ~ 1 kHz (instead of 10.1 kHz which is the "linear" center of frequency range).
PropmapFrom01TypefunctionDefaultmapFrom01Linear()Opposite of "mapTo01".
Proparia-label | aria-labelledbyTypestringDefaultLabelling for accesibility purposes.
Prop...restType...DefaultThe rest of HTML "div" element props.

KnobHeadlessLabel

The optional primitive for visual accessive labelling of the knob.

PropTypeDefaultDescription
PropidTypestringDefaultUnique identifier for HTML "label" element. Must be provided to the knob via "aria-labelledby".
Prop...restType...DefaultThe rest of HTML "label" element props.

KnobHeadlessOutput

The optional primitive for visual accessive output display of the knob.

PropTypeDefaultDescription
ProphtmlForTypestringDefaultUnique identifier of the knob to relate the output with. Must be provided to the knob via "id".
Prop...restType...DefaultThe rest of HTML "output" element props.

useKnobKeyboardControls

A primitive for enabling keyboard controls.

PropTypeDefaultDescription
PropvalueRawTypenumberDefaultSame as "valueRaw" prop of "KnobHeadless".
PropvalueMinTypenumberDefaultSame as "valueMin" prop of "KnobHeadless".
PropvalueMaxTypenumberDefaultSame as "valueMax" prop of "KnobHeadless".
PropstepTypenumberDefaultStep value. Typically it's 1% of the range.
PropstepLargerTypenumberDefaultLarger step value. Typically it's 10% of the range.
ProponValueRawChangeTypefunctionDefaultSame callback as "KnobHeadless" has, with "event" in 2nd argument.
PropnoDefaultPreventionTypebooleanDefaultfalseTo prevent scrolling, "event.preventDefault()" is called when the value changes, but for most cases you don't need to change this behaviour. However, if your application needs some more customized one, you can set this prop to true and handle scroll prevention on your own.