DOCS / UI REFERENCE
Hooks & utilities
Everything ships in @vsreact/core — no utility grab-bag dependencies. Parameter and animation hooks have their own pages; this is the rest of the toolbox.
State & timing
const [bypassed, toggleBypass] = useToggle(false); // stable toggle fn
const previous = usePrevious(preset); // last render's value
const query = useDebounced(text, 250); // settles after silence
const level = useThrottled(rawLevel, 33); // at most ~30fps
useInterval(() => setPhase((p) => p + 0.05), 16); // null pauses ituseToggle(initial?)→[on, toggle, set]— the toggle function is stable, safe foronClick.usePrevious(value)—undefinedon the first render.useDebounced(value, delayMs)— waits for quiet;useThrottled(value, intervalMs)— leading + trailing, never more than once per interval.useInterval(callback, intervalMs | null)— declarative interval on the host scheduler; the callback stays fresh without restarting the timer.
Pointer & layout
const [hovered, hoverProps] = useHover();
<View {...hoverProps} style={{ opacity: hovered ? 1 : 0.7 }} />
const [rect, onLayout] = useLayoutRect(); // root-space rect from onLayout
const overlay = useOverlay(); // a slot in the top-most layeruseHover()— hover as state, for logic beyond whathover:class variants cover.useLayoutRect()/useOverlay()— the popover building blocks; see Events & gestures.useRootSize()(since 0.0.25) — the editor's current width/height as state, seeded at mount and updated on host resize: the foundation for resizable editors.useEditorSize()(since 0.0.27) →[size, setSize]— the two-way version: the read half isuseRootSize, andsetSize(width, height)asks the host to resize itself. The call round-trips through the native resize — the host applies the size it grants and echoes it back through theresizeevent, sosizealways reflects what the host settled on. Build resize grips and preset size buttons with it.
Audio data
const [level, setLevel] = useState(0);
useNativeEvent("meter", (m) => setLevel(m.level));
const history = useRollingBuffer(level, 64); // last 64 values
return <Waveform values={history} width={220} label="ENV" />;useRollingBuffer(value, length?)— a fixed rolling window of a live scalar; feeds<Waveform>/<Bars>. The pure stepperpushRollingis exported too.usePeakHold(value, {holdMs, decayPerSecond})— the held peak that drives<Meter>’s peak line.
Native bridge
useNativeEvent(name, handler)— lifetime subscription with an always-fresh handler; see Native messaging.useNativeValue(name, initial)— the latest payload of a C++ event, held as state:const m = useNativeValue("meter", { level: 0 }).useParameter(id)/useParameterList()— see Audio parameters.useTween/useSpring— see Animation.
Value formatting
formatDb(-12.53) // "-12.5 dB" (-Infinity → "-inf dB")
formatHz(1200) // "1.2 kHz"
formatMs(1250) // "1.25 s"
formatPercent(0.42) // "42%"
formatSemitones(7) // "+7 st"
midiNoteName(60) // "C4"
midiNoteToHz(69) // 440 — feed your oscillator from PianoKeyboard
hzToMidiNote(440) // 69
mapRange(v, 0, 1, -60, 6) // linear remap, optional clampPure functions, made for NumberBox’s format prop and value labels next to knobs.
cx()
The className composer — strings, arrays, object maps, falsy values dropped. Details in Styling.