Envelope Editor
envelope-editorControlsA 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-editorPulls in
First time? Add the registry to your components.json once:
{
"registries": {
"@pluginui": "https://pluginui.com/r/{name}.json"
}
}Usage
Connect the documented props to your application or host.
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
| Prop | Type | Default | Description |
|---|---|---|---|
| value | { attack, decay, sustain, release } | — | Controlled envelope. Omit for uncontrolled operation. |
| defaultValue | ADSR | { 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. |
| ranges | EnvelopeRanges | — | 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. |
| frame | boolean | false | Wrap 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. |
| displayHeight | number | 160 | Height of the envelope display in pixels. The compact variant defaults it to 104. |
| knobVariant | KnobVariant | "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. |
| hideKnobs | boolean | false | Hide 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
sliderandswitchroles with livearia-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.