# @suaveplan/react-control-surface - React 19 atomic-control surface renderer for @suaveplan/control-surface-schema. Foundation chunk: error codes, telemetry, skin contract, binding registry + handlers, grouping primitives, and the simple atomic controls (TextLabel, Image, LED, Switch2, Switch3, ButtonMomentary, ButtonLatching). React 19 atomic-control surface renderer for `@suaveplan/control-surface-schema`. This is the **foundation chunk** of the package — it lands the package scaffolding (error codes, telemetry, skin contract, binding registry + handlers, grouping primitives) and the seven simple atomic controls: - `` — decorative read-only text. - `` — decorative image element. - `` — boolean/0..1 brightness indicator. - `` — two-state toggle (`role="switch"`). - `` — three-state toggle. - `` — press-and-hold trigger. - `` — sticky toggle. The remaining controls (knob, sliders, displays, meters, XY pad, jog wheel, piano key, drum pad) and the `` runtime walker land in follow-up chunks. ## Documentation tree - [button-latching](./src/controls/button-latching/button-latching.md) — `` is the sticky toggle: a click latches the button on, the next click latches it off. It is the counte… - [button-latching](./src/controls/button-latching/button-latching.md) — `` is the sticky toggle: a click latches the button on, the next click latches it off. It is the counte… - [button-momentary](./src/controls/button-momentary/button-momentary.md) — `` is the press-and-hold trigger control. Pressing it emits `max` into `onChange`; releasing it emits… - [button-momentary](./src/controls/button-momentary/button-momentary.md) — `` is the press-and-hold trigger control. Pressing it emits `max` into `onChange`; releasing it emits… - [digital-display](./src/controls/digital-display/digital-display.md) — Read-only 7-segment / LCD-style readout for the control surface. The component is a typed information sink: it accepts… - [digital-display](./src/controls/digital-display/digital-display.md) — Read-only 7-segment / LCD-style readout for the control surface. The component is a typed information sink: it accepts… - [drum-pad](./src/controls/drum-pad/drum-pad.md) — Velocity-sensitive drum pad. Maps a pointer or keyboard press to a velocity 0..1 then through `[min, max]` so the same… - [drum-pad](./src/controls/drum-pad/drum-pad.md) — Velocity-sensitive drum pad. Maps a pointer or keyboard press to a velocity 0..1 then through `[min, max]` so the same… - [image](./src/controls/image/image.md) — `` is the decorative image control. Like ``, it appears in the closed `ControlKind` enumeration so a… - [image](./src/controls/image/image.md) — `` is the decorative image control. Like ``, it appears in the closed `ControlKind` enumeration so a… - [jog-wheel](./src/controls/jog-wheel/jog-wheel.md) — `` is an endless rotary control inspired by DJ-deck jog wheels. Unlike a knob, it does not have an absolute v… - [jog-wheel](./src/controls/jog-wheel/jog-wheel.md) — `` is an endless rotary control inspired by DJ-deck jog wheels. Unlike a knob, it does not have an absolute v… - [knob](./src/controls/knob/knob.md) — Rotary knob control — the cornerstone interaction primitive for the 2D control surface. Renders an SVG circle with a ro… - [knob](./src/controls/knob/knob.md) — Rotary knob control — the cornerstone interaction primitive for the 2D control surface. Renders an SVG circle with a ro… - [led](./src/controls/led/led.md) — `` is the output indicator control. It accepts a numeric value in the standard `BoundControlProps` domain and rend… - [led](./src/controls/led/led.md) — `` is the output indicator control. It accepts a numeric value in the standard `BoundControlProps` domain and rend… - [meter-peak](./src/controls/meter-peak/meter-peak.md) — `` is a digital-style peak meter that shows the instantaneous input level alongside a held-then-decaying pea… - [meter-peak](./src/controls/meter-peak/meter-peak.md) — `` is a digital-style peak meter that shows the instantaneous input level alongside a held-then-decaying pea… - [meter-spectral](./src/controls/meter-spectral/meter-spectral.md) — `` renders a real-time bar graph of magnitude bins. Each bin is drawn as a vertical bar whose height is… - [meter-spectral](./src/controls/meter-spectral/meter-spectral.md) — `` renders a real-time bar graph of magnitude bins. Each bin is drawn as a vertical bar whose height is… - [meter-vu](./src/controls/meter-vu/meter-vu.md) — `` renders a single-channel level meter with the classic analogue VU response defined by IEC 60268-10: a 300 m… - [meter-vu](./src/controls/meter-vu/meter-vu.md) — `` renders a single-channel level meter with the classic analogue VU response defined by IEC 60268-10: a 300 m… - [piano-key](./src/controls/piano-key/piano-key.md) — A single piano key. Two visual kinds (`white` / `black`) and three visual states (`idle` / `pressed` / `highlighted`).… - [piano-key](./src/controls/piano-key/piano-key.md) — A single piano key. Two visual kinds (`white` / `black`) and three visual states (`idle` / `pressed` / `highlighted`).… - [slider-h](./src/controls/slider-h/slider-h.md) — Horizontal slider control — the X-axis counterpart of ``. Every behavioural decision is delegated to the share… - [slider-h](./src/controls/slider-h/slider-h.md) — Horizontal slider control — the X-axis counterpart of ``. Every behavioural decision is delegated to the share… - [slider-v](./src/controls/slider-v/slider-v.md) — Vertical slider control. Pointer interaction sets the value directly from `clientY` against the rendered track rect — d… - [slider-helpers](./src/controls/slider-v/slider-helpers.md) — Shared pure functions for both `` and `` so that value resolution, detent snapping, and keyboard step… - [slider-v](./src/controls/slider-v/slider-v.md) — Vertical slider control. Pointer interaction sets the value directly from `clientY` against the rendered track rect — d… - [switch-2](./src/controls/switch-2/switch-2.md) — `` is the two-position toggle control. It implements the WAI-ARIA "switch" pattern (`role="switch"` + `aria-ch… - [switch-2](./src/controls/switch-2/switch-2.md) — `` is the two-position toggle control. It implements the WAI-ARIA "switch" pattern (`role="switch"` + `aria-ch… - [switch-3](./src/controls/switch-3/switch-3.md) — `` is the three-position toggle, modelling the kind of "down-centre-up" or "low-mid-high" switch found on outb… - [switch-3](./src/controls/switch-3/switch-3.md) — `` is the three-position toggle, modelling the kind of "down-centre-up" or "low-mid-high" switch found on outb… - [text-label](./src/controls/text-label/text-label.md) — `` is the decorative read-only control that renders a static text string. It is included in the `ControlKind… - [text-label](./src/controls/text-label/text-label.md) — `` is the decorative read-only control that renders a static text string. It is included in the `ControlKind… - [xy-pad](./src/controls/xy-pad/xy-pad.md) — `` is an accessible 2-axis touch surface that emits normalised `{ x, y }` coordinates as the user drags a pointe… - [xy-pad](./src/controls/xy-pad/xy-pad.md) — `` is an accessible 2-axis touch surface that emits normalised `{ x, y }` coordinates as the user drags a pointe… - [error-codes](./src/error-codes/error-codes.md) — The `error-codes` module owns the stable, namespaced registry of every error code that `@suaveplan/react-control-surfac… - [error-codes](./src/error-codes/error-codes.md) — The `error-codes` module owns the stable, namespaced registry of every error code that `@suaveplan/react-control-surfac… - [group](./src/grouping/group/group.md) — `` is the layout primitive used for internal nodes of a control surface tree. It accepts a layout descriptor (CS… - [group](./src/grouping/group/group.md) — `` is the layout primitive used for internal nodes of a control surface tree. It accepts a layout descriptor (CS… - [panel](./src/grouping/panel/panel.md) — `` is the labelled grouping primitive that wraps a group of controls in a titled box, optionally with collapse-t… - [panel](./src/grouping/panel/panel.md) — `` is the labelled grouping primitive that wraps a group of controls in a titled box, optionally with collapse-t… - [rack](./src/grouping/rack/rack.md) — `` is the grouping primitive that models a hardware-rack frame — a horizontal (default) or vertical sequence of f… - [rack](./src/grouping/rack/rack.md) — `` is the grouping primitive that models a hardware-rack frame — a horizontal (default) or vertical sequence of f… - [runtime](./src/runtime/surface.md) — `` is the runtime that turns a validated `ControlSurface` document into a live React DOM tree. It performs a d… - [binding-registry](./src/runtime/binding-registry/binding-registry.md) — `BindingRegistry` is the discriminated dispatcher that links every bound control on a surface to the consumer-side logi… - [compound](./src/runtime/binding-registry/handlers/compound.md) — The `compound` handler is the binding-registry slot responsible for fanning a single control's value out to multiple le… - [dmx](./src/runtime/binding-registry/handlers/dmx.md) — The `dmx` handler is the binding-registry slot reserved for DMX universe / channel updates. The `@suaveplan/react-dmx`… - [midi-in](./src/runtime/binding-registry/handlers/midi-in.md) — The `midiIn` handler is the binding-registry slot that hosts an inbound MIDI subscription — a control bound this way re… - [midi-out](./src/runtime/binding-registry/handlers/midi-out.md) — The `midiOut` handler is the binding-registry slot that converts a control's value into an outbound MIDI Control Change… - [plugin-param](./src/runtime/binding-registry/handlers/plugin-param.md) — The `pluginParam` handler is the binding-registry slot that dispatches a control's value to a plugin parameter via `use… - [transport](./src/runtime/binding-registry/handlers/transport.md) — The `transport` handler is the binding-registry slot that dispatches a control's value to the audio transport — play/st… - [binding-registry](./src/runtime/binding-registry/binding-registry.md) — `BindingRegistry` is the discriminated dispatcher that links every bound control on a surface to the consumer-side logi… - [surface](./src/runtime/surface.md) — `` is the runtime that turns a validated `ControlSurface` document into a live React DOM tree. It performs a d… - [skin](./src/skin/surface-skin-provider.md) — `` is the single React boundary that activates a skin for every atomic control inside its subtree.… - [surface-skin-provider](./src/skin/surface-skin-provider.md) — `` is the single React boundary that activates a skin for every atomic control inside its subtree.… - [telemetry](./src/telemetry/telemetry.md) — The `telemetry` module is the single owner of every OpenTelemetry instrument emitted by `@suaveplan/react-control-surfa… - [telemetry](./src/telemetry/telemetry.md) — The `telemetry` module is the single owner of every OpenTelemetry instrument emitted by `@suaveplan/react-control-surfa… ## Bindings `BindingRegistry` discriminates on `Binding["kind"]` (defined by `@suaveplan/control-surface-schema`) and dispatches to the registered handler. Built-in handlers integrate with sibling packages: - `pluginParam` — bridges to `useParameter` from `@suaveplan/react-audio`. - `transport` — bridges to `useTransport` from `@suaveplan/react-audio`. - `midiOut` — bridges to `useMidiOutput` from `@suaveplan/react-midi`. - `midiIn` — bridges to `useMidiInput` from `@suaveplan/react-midi`. - `dmx` — throws `REACT_CONTROL_SURFACE.BINDING_HANDLER_MISSING` until the `@suaveplan/react-dmx` integration arrives in a later chunk. - `compound` — fans out to every leaf in registration order. Every handler is invoked through the same `BoundControlBinder` shape so the runtime never special-cases binding kinds. ## Skin contract `` injects CSS variables on a wrapping `
` — every atomic control reads its visual styling exclusively through CSS variable resolution. JS-level skin dispatch is forbidden by the spec: changing the skin is a pure CSS-variable swap. ## Telemetry - `control_surface_interactions_total{kind}` — counter incremented on every user-driven `onChange` from an atomic control. - `control_surface_render_duration_ms` — histogram recorded by the runtime per surface render commit (registered for future chunks).