VSTDOCSv0.0.17

DOCS / UI REFERENCE

Components

Five primitives cover the render surface. All of them accept className, style, and the pointer props listed in Events & gestures.

<View>

The flexbox container — the div of VSReacT. Backgrounds, borders, rounded corners, shadows, opacity, scroll containers, and knob arcs are all drawn on Views.

TSX
<View className="flex-1 flex-row items-center gap-4 p-6
                 bg-zinc-900 rounded-xl border hover:bg-zinc-800">
  {children}
</View>

<Text>

Draws strings and numbers. Font size, weight, family (font-mono), letter-spacing, line-height, alignment, and color come from classes or style. Text nodes measure themselves into the Yoga layout, so a Text sizes its container like you expect.

TSX
<Text className="text-2xl font-bold tracking-tight text-center">
  {gainDb.toFixed(1)} dB
</Text>

<Image src>

Paints an image from a file path or a data: URI, scaled to its layout box.

TSX
<Image src={logoDataUri} className="w-24 h-24 rounded-full" />

<TextInput>

A real, chrome-stripped juce::TextEditor positioned by Yoga — real caret, selection, and IME, while VSReacT paints the box, border, and focus ring around it.

PROPTYPENOTES
value / defaultValuestringControlled or uncontrolled, exactly like the DOM.
placeholderstringColor via the placeholderColor style key.
disabledbooleanBlocks focus and input.
onChange / onSubmit(value: string) => voidSubmit fires on Enter.
onFocus / onBlur() => voidPair with focus: class variants for focus rings.
TSX
<TextInput
  placeholder="Paste a link…"
  className="w-full p-3 rounded-lg bg-zinc-900 border
             focus:border-lime-400"
  style={{ caretColor: "#C6F135", placeholderColor: "#6b7280" }}
  onSubmit={(url) => native.call("download:start", { url })}
/>

Built-in controls

Beyond the primitives, the SDK ships the classic VST controls, natively painted and drag-driven. Each takes a normalized 0..1 value (or an index) plus color/size props, and each has a Param* twin bound to a host parameter — see Audio parameters.

CONTROLFORNOTES
<Knob>Continuous valuesNatively painted arc, vertical drag, wheel nudge, double-click reset to defaultValue; bipolar sweeps from 12 o’clock for pan-style params.
<Slider>Continuous valuesHorizontal by default; vertical makes it a fader (drag up for more, fill rises from the bottom).
<Toggle>Bypass, on/off, A/BSpring-animated thumb; click to flip.
<XYPad>Two values at once2D drag pad with crosshair — cutoff/resonance, pan/depth. y = 1 is the top.
<Segmented>Exclusive choicesA row of options — oscillator shapes, filter modes.
<Select>Long choice listsA dropdown — the menu renders in the overlay layer, positioned under the trigger via onLayout, scrolls past maxMenuHeight, click-away closes.
<Meter>LevelsHot zone + peak-hold line with decay; feed it 0..1 values (typically pushed from C++ via useNativeEvent).
<GenericEditor>Whole pluginsOne knob per APVTS parameter — a complete UI in one line.
<MacroPad>Centerpiece macrosA circular 2D pad with value-reactive concentric rings — x spreads them, y drives intensity. ParamMacroPad drives two host parameters from one drag.
<HardwareKnob>Hardware feelSkeuomorphic cap with a glowing pointer notch at the rim and a faint tick track; same DAW gestures as Knob.
<Crossfader>Mix controlsThe DRY/WET strip — wide track, grippy rectangular handle, double-click recenters.
<PulseOrb>PresenceA value-reactive orb: glowing core with echo rings that emit faster and brighter as the level rises.
<NumberBox>Fine valuesThe draggable number — BPM, ms, semitones. Drag, wheel-step, double-click reset; ParamNumberBox shows the host’s formatted text.
<Checkbox> / <RadioGroup>Settings panelsCheckbox rows and vertical exclusive options; Param twins map bool and choice parameters.
<ProgressBar> / <Spinner>FeedbackDeterminate progress with optional percent (or an indeterminate sweep); indeterminate spinner painted with the native arc keys.
<PianoKeyboard>PerformanceThe playable keyboard — note-on on press, note-off on release, glissando by dragging across keys; heldNotes paints host MIDI in.
<StepSequencer>PatternsThe rows × steps grid: click cells on and off, downbeat tinting, a playhead column the host drives. Fully controlled.
<ADSREnvelope>EnvelopesThe four-corner envelope editor — drag the attack peak, the decay/sustain corner, and the release corner; ParamADSREnvelope drives four host parameters.
<PitchBend> / <ModWheel>WheelsThe performance wheels: pitch springs back to center on release, mod stays where you leave it; Param twins for both.
<Tabs> / <Disclosure>StructureThe page switcher with an underline tab bar, and the collapsible settings row — both controlled or uncontrolled.
<EQCurve>FiltersThe real summed biquad response (RBJ cookbook) with a draggable node per band — drag for freq/gain, wheel for Q. Pure math exported.
<RingMeter>LevelsA circular level meter on the native arc keys: hot zone, optional center readout via format.
<Button>Actionssolid / outline / ghost variants, three sizes, hover/active baked in.
<Bars>SpectraBottom-anchored bar visualizer with a hot zone — one bar per array entry.
<Waveform>Waveforms & envelopesCentre-mirrored bars; pair with useRollingBuffer for scrolling history.
<Tooltip>Hover helpWraps any child; shows the tip below it after a hover dwell (delayMs), via the overlay layer.
<Modal>DialogsCentered panel over a click-away backdrop — confirms, settings, about boxes.
TSX
<Toggle on={bypassed} label="BYPASS" onChange={setBypassed} />
<Slider vertical height={140} value={mix} onChange={setMix} />
<XYPad x={cutoff} y={resonance} onChange={(x, y) => { setCutoff(x); setResonance(y); }} />
<Segmented options={["SINE", "SAW", "SQR"]} index={shape} onChange={setShape} />

function OutputMeter() {
  const [level, setLevel] = useState(0);
  useNativeEvent("meter", (m) => setLevel(m.level));
  return <Meter value={level} length={140} label="OUT" />;
}

<Tooltip label="Double-click resets to 0 dB">
  <ParamKnob paramId="gain" />
</Tooltip>

<Modal open={showAbout} onClose={() => setShowAbout(false)} title="ABOUT">
  <Text className="text-[12] text-zinc-400">MyPlugin 1.0 — built with VSReacT.</Text>
</Modal>

<NativeView nativeId>

The escape hatch: mounts any juce::Component you registered in the NativeRegistry inside the React layout. React owns its position and size; JUCE owns its painting. Perfect for waveform displays, meters fed from the audio thread, or any legacy component you are not ready to rewrite.

C++ + TSX
// C++ — register a factory
vsreact::NativeRegistry registry;
registry.registerFactory ("waveform", [this] {
    return std::make_unique<WaveformDisplay> (processor);
});

// TSX — position it with flexbox
<NativeView nativeId="waveform" className="flex-1 rounded-lg overflow-hidden" />