PluginUI

Envelope Editor

envelope-editorControls

A worked example of composing the kit rather than adding a new control. The envelope display sits above four knobs, and both edit the same value: drag a handle and the knobs follow; turn a knob and the shape follows. The editor owns the state and passes each child a controlled value.

Bone / Studio
Loading interactive preview…
Planar / Flat
Loading interactive preview…
Midnight / Minimal
Loading interactive preview…
Ember / Vintage
Loading interactive preview…
Ink / Studio
Loading interactive preview…
Mint / Flat
Loading interactive preview…

Install

Copies the source into your project. Anything it depends on comes with it.

$ pnpm dlx shadcn@latest add @pluginui/core-envelope-editor

Pulls in

First time? Add the registry to your components.json once:

components.json
{
  "registries": {
    "@pluginui": "https://pluginui.com/r/{name}.json"
  }
}

Usage

Connect the documented props to your application or host.

example.tsx
import { EnvelopeEditor } from "@/components/ui/envelope-editor"

<EnvelopeEditor
  defaultValue={{ attack: 0.01, decay: 0.2, sustain: 0.6, release: 0.4 }}
  onChange={(adsr) => voice.setEnvelope(adsr)}
/>

Props

PropTypeDefaultDescription
value{ attack, decay, sustain, release }—Controlled envelope. Omit for uncontrolled operation.
defaultValueADSR{ 0.01, 0.2, 0.6, 0.4 }Starting envelope when uncontrolled, and the reset target.
onChange(value: ADSR) => void—Fires on every edit.
onChangeEnd(value: ADSR) => void—Fires once when a gesture finishes.
rangesEnvelopeRanges—Per-segment bounds, shared by the display and the knobs. Defaults: A/D 1 ms–4 s, S 0–1, R 1 ms–8 s.
variant"default" | "compact""default"Layout preset. Compact shrinks the module: ~104 px display, mini knobs, tighter gaps, and a fixed four-column knob strip that never wraps. Explicit displayHeight/knobVariant still win.
framebooleanfalseWrap the editor in a framed panel with a surface fill, hairline border, themed radius and tight padding. The frame reads as one self-contained module, with the display recessed like a window.
displayHeightnumber160Height of the envelope display in pixels. The compact variant defaults it to 104.
knobVariantKnobVariant"small"Visual style passed through to the four knobs, including panel for fixed rounded rings and neutral caps. The compact variant defaults it to mini.
curve"linear" | "exponential""linear"Curve shape forwarded to the shared envelope display; exponential rounds the attack, decay and release segments.
knobIndicator"line" | "dot""line"Marker style passed through to the knobs.
hideKnobsbooleanfalseHide the knob row, leaving just the draggable shape.

Interaction

  • Drag with pointer capture, so the gesture keeps tracking past the edge of the control.
  • Shift while dragging for a fine pass; release it mid-gesture and coarse tracking resumes.
  • Double-click resets to defaultValue.
  • Arrow keys step normally, Shift+arrow steps finely, PageUp/PageDown jump by ten, Home/End go to the extremes.
  • Proper slider and switch roles with live aria-valuetext, so a screen reader announces the formatted value rather than the raw number.
  • The scroll wheel adjusts the value while the pointer is over the control; stepped ranges move at least one declared step per notch by default.