JS Bridge API Reference¶
Complete reference for all JavaScript functions available in Pulp UI scripts. These functions are registered by the WidgetBridge and callable from any .js file loaded by the script engine.
Status: experimental
Widget Creation¶
Basic Controls¶
createKnob(id, parentId) // Rotary knob control
createFader(id, orientation, parentId) // Linear slider ("vertical" | "horizontal")
createToggle(id, parentId) // On/off switch
createCheckbox(id, parentId) // Checkbox control
createToggleButton(id, parentId) // Stateful push button
createLabel(id, text, parentId) // Text display
createIcon(id, type, parentId) // Icon glyph ("image_upload" | "send" | "search" | "close")
Data Visualization¶
createMeter(id, orientation, parentId) // Level meter with peak hold
createWaveform(id, parentId) // Waveform display
createSpectrum(id, parentId) // Frequency spectrum analyzer
createXYPad(id, parentId) // 2D parameter control
createProgress(id, parentId) // Progress bar
Input¶
Custom Drawing¶
Layout Containers¶
createRow(id, parentId) // Flex row (horizontal)
createCol(id, parentId) // Flex column (vertical)
createModal(id, parentId) // Full-screen modal overlay (Escape + backdrop dismiss)
createGrid(id, parentId) // CSS Grid container
createPanel(id, parentId) // Generic container with styling
createScrollView(id, parentId) // Scrollable container
All creation functions return the widget id string. The parentId parameter specifies where in the view tree to insert the widget.
Widget Values¶
setValue(id, value) // Set normalized value (0-1) on Knob, Fader, Toggle, Checkbox, ToggleButton
getValue(id) // Get normalized value — returns number
setLabel(id, text) // Set label text on Knob, Fader, Toggle, ToggleButton, Label
setText(id, text) // Set text on TextEditor or Label
getText(id) // Get text from TextEditor or Label — returns string
Widget-Specific Data¶
setItems(id, ["Option A", "Option B"]) // Set Combo dropdown items
setSelected(id, index) // Set Combo selection without firing "select"
setProgress(id, 0.75) // Set Progress bar value (0-1)
setMeterLevel(id, peak, rms) // Set Meter peak and RMS levels
setXY(id, x, y) // Set XYPad position (0-1 each axis)
setWaveformData(id, [0.1, -0.3, ...]) // Set WaveformView sample data
setSpectrumData(id, [0.5, 0.8, ...]) // Set SpectrumView frequency bins
setPlaceholder(id, "Type here...") // Set TextEditor placeholder text
setScrollContentSize(id, width, height) // Set ScrollView content dimensions
setPanelStyle(id, bgToken, borderToken, radius, width) // Style Panel via tokens
Parameter Store¶
getParam(name) // Read normalized parameter value by name — returns number
setParam(name, value) // Write normalized parameter value by name
Parameters are defined in C++ (define_parameters) and shared with the audio thread via lock-free atomics. setParam triggers DAW host notification automatically.
Flexbox Layout¶
| Property | Type | Example | Description |
|---|---|---|---|
direction |
string | "row", "column" |
Flex direction |
gap |
number | 8 |
Gap between children (px) |
row_gap |
number | 8 |
Row gap for wrap layouts |
column_gap |
number | 12 |
Column gap for wrap layouts |
padding_top |
number | 16 |
Top padding (px) |
padding_right |
number | 16 |
Right padding |
padding_bottom |
number | 16 |
Bottom padding |
padding_left |
number | 16 |
Left padding |
margin_top |
number | 8 |
Top margin |
margin_right |
number | 8 |
Right margin |
margin_bottom |
number | 8 |
Bottom margin |
margin_left |
number | 8 |
Left margin |
width |
number | 200 |
Fixed width (px) |
height |
number | 40 |
Fixed height (px) |
min_width |
number | 100 |
Minimum width |
max_width |
number | 400 |
Maximum width |
min_height |
number | 30 |
Minimum height |
max_height |
number | 300 |
Maximum height |
flex_grow |
number | 1 |
Flex grow factor |
flex_shrink |
number | 0 |
Flex shrink factor |
flex_basis |
number | 100 |
Flex basis (px) |
order |
number | 2 |
Layout order |
justify_content |
string | "center" |
Main axis alignment |
align_items |
string | "center" |
Cross axis alignment |
align_self |
string | "stretch" |
Self alignment override |
justify_self |
string | "start" |
Self justify override |
Grid Layout¶
| Property | Type | Example | Description |
|---|---|---|---|
template_columns |
string | "1fr 2fr 1fr" |
Column track definitions |
template_rows |
string | "auto 1fr" |
Row track definitions |
column_gap |
number | 8 |
Column gap (px) |
row_gap |
number | 8 |
Row gap (px) |
gap |
number | 8 |
Both column and row gap |
column_start |
number | 1 |
Grid column start line |
column_end |
number | 3 |
Grid column end line |
row_start |
number | 1 |
Grid row start line |
row_end |
number | 2 |
Grid row end line |
Typography¶
setFontSize(id, 14) // Font size in pixels
setFontWeight(id, 700) // Font weight (100-900)
setFontStyle(id, "italic") // "normal" | "italic"
setLetterSpacing(id, 0.5) // Letter spacing (px)
setLineHeight(id, 1.5) // Line height multiplier
setTextAlign(id, "center") // "left" | "center" | "right"
setTextColor(id, "#ffffff") // Text color (CSS Color L4)
setTextTransform(id, "uppercase") // "uppercase" | "lowercase" | "capitalize" | "none"
setTextDecoration(id, "underline") // "underline" | "line-through" | "overline" | "none"
setTextOverflow(id, "ellipsis") // "ellipsis" | "clip"
setMultiLine(id, 1) // Enable multi-line text (0 or 1)
Visual Styling¶
setBackground(id, "#1a1a2e") // Background color
setBackgroundGradient(id, "linear-gradient(to right, #ff0000, #0000ff)") // CSS gradient
setBorder(id, "#333333", 1, 8) // Border color, width, radius
setOpacity(id, 0.5) // Opacity (0-1)
setBoxShadow(id, 0, 4, 8, 0, "rgba(0,0,0,0.3)") // Shadow: offsetX, offsetY, blur, spread, color
setFilter(id, "blur(4px)") // CSS filter string
setOverflow(id, "hidden") // "visible" | "hidden"
setCursor(id, "pointer") // "pointer" | "crosshair" | "text" | "grab" | "default"
setVisible(id, true) // Show/hide widget
setZIndex(id, 10) // Stacking order
Transforms¶
setTranslate(id, x, y) // Translate in pixels
setScale(id, sx, sy) // Scale factor (1.0 = normal)
setRotation(id, degrees) // Rotation in degrees
setTransformOrigin(id, x, y) // Origin (0-1 normalized, 0.5 = center)
setPosition(id, "absolute") // "static" | "relative" | "absolute" | "fixed" | "sticky"
setTop(id, px) // CSS top offset
setRight(id, px) // CSS right offset
setBottom(id, px) // CSS bottom offset
setLeft(id, px) // CSS left offset
Animation¶
// Animate a single property
animate(id, property, targetValue, durationMs, easingName)
// Example: animate("knob", "opacity", 1.0, 300, "ease_out_cubic")
// Properties: "value", "opacity", "x", "y", "scale", "rotation"
// Define keyframe sequences
defineKeyframes("pulse", [
{ offset: 0, opacity: 0.5, scale: 1.0 },
{ offset: 0.5, opacity: 1.0, scale: 1.1 },
{ offset: 1, opacity: 0.5, scale: 1.0 },
])
// Apply keyframe animation
setAnimation(id, "pulse", 1000) // name, duration in ms
// Set transition duration for property changes
setTransitionDuration(id, 200) // milliseconds
// Motion tokens (theme-integrated timing)
setMotionToken("motion.duration.fast", 80)
getMotionToken("motion.duration.fast") // returns 80
Easing Functions¶
linear, ease_in_quad, ease_out_quad, ease_in_out_quad, ease_in_cubic, ease_out_cubic, ease_in_out_cubic, ease_in_quart, ease_out_quart, ease_in_out_quart, ease_in_expo, ease_out_expo, ease_in_out_expo
Events¶
// Register event types (required before on() will fire)
registerClick(id) // Enable click events
registerHover(id) // Enable mouseenter/mouseleave events
registerPointer(id) // Enable pointer events (pointerdown/pointermove/pointerup)
registerGesture(id) // Enable gesture events (gesturestart/gesturechange/gestureend)
// Listen for events
on(id, "change", (value) => { }) // Knob, Fader, Checkbox value changed
on(id, "toggle", (state) => { }) // Toggle, ToggleButton state changed
on(id, "click", () => { }) // Click (requires registerClick)
on(id, "mouseenter", () => { }) // Mouse enter (requires registerHover)
on(id, "mouseleave", () => { }) // Mouse leave (requires registerHover)
// Inspector (developer tool)
enableInspectClick()
on("__inspect__", "click", (id) => { }) // Cmd+click reports widget ID
Pointer Events (W3C PointerEvent)¶
Unified input model — same code works for mouse (macOS), touch (iOS), and stylus (Apple Pencil):
el.addEventListener("pointerdown", (e) => {
console.log(e.pointerId); // Stable per-finger ID (0 = primary)
console.log(e.pointerType); // "mouse", "touch", or "pen"
console.log(e.isPrimary); // true for first finger / mouse
console.log(e.clientX, e.clientY);
console.log(e.pressure); // 0.0–1.0 (Apple Pencil force)
console.log(e.altitudeAngle); // Pencil tilt (radians)
console.log(e.azimuthAngle); // Pencil rotation (radians)
});
el.addEventListener("pointermove", (e) => {
// API shape is present now; extra native touch samples only appear when the
// platform producer populates them.
for (const pt of e.getCoalescedEvents()) {
drawLine(pt.clientX, pt.clientY);
}
});
el.addEventListener("pointerup", (e) => { /* finger/mouse released */ });
el.addEventListener("pointercancel", (e) => { /* touch cancelled by system */ });
getCoalescedEvents() / getPredictedEvents() are currently structural JS APIs.
The native iOS coalescedTouches / predictedTouches enrichment path is still
planned, so callers should be prepared for the current event or an empty list.
Pointer Capture¶
Lock pointer events to an element during drag, even if the pointer leaves its bounds:
el.addEventListener("pointerdown", (e) => {
el.setPointerCapture(e.pointerId);
});
el.addEventListener("gotpointercapture", (e) => { /* capture acquired */ });
el.addEventListener("lostpointercapture", (e) => { /* capture released */ });
// Capture is automatically released on pointerup
Gesture Events¶
High-level multi-touch and trackpad gestures:
el.addEventListener("gesturestart", (e) => { /* two-finger gesture began */ });
el.addEventListener("gesturechange", (e) => {
console.log(e.scale); // Pinch zoom factor (1.0 = no change)
console.log(e.rotation); // Rotation in radians
});
el.addEventListener("gestureend", (e) => { /* gesture ended */ });
Works on macOS trackpad (magnifyWithEvent/rotateWithEvent) and iOS multi-touch.
touch-action CSS¶
Control default gesture handling on touch platforms:
el.style.touchAction = "none"; // Disable all default gestures
el.style.touchAction = "pan-x"; // Allow horizontal panning only
el.style.touchAction = "manipulation"; // Allow pan + pinch, disable double-tap zoom
Canvas 2D Drawing¶
All canvas functions take the canvas widget id as the first parameter.
State¶
canvasSave(id) // Push graphics state
canvasRestore(id) // Pop graphics state
canvasClear(id) // Clear all draw commands
Shapes¶
canvasRect(id, x, y, w, h, color) // Filled rectangle
canvasStrokeRect(id, x, y, w, h, color, lineWidth) // Rectangle outline
canvasFillCircle(id, x, y, radius, color) // Filled circle
canvasStrokeLine(id, x1, y1, x2, y2, color, lineWidth) // Line segment
canvasFillText(id, text, x, y, fontSize, color) // Rendered text
Paths¶
canvasBeginPath(id) // Start new path
canvasMoveTo(id, x, y) // Move pen
canvasLineTo(id, x, y) // Line segment
canvasQuadTo(id, cpx, cpy, x, y) // Quadratic Bezier curve
canvasCubicTo(id, cp1x, cp1y, cp2x, cp2y, x, y) // Cubic Bezier curve
canvasClosePath(id) // Close path to start point
canvasFillPath(id) // Fill current path
canvasStrokePath(id) // Stroke current path
Style¶
canvasSetFillColor(id, color) // Fill color for shapes/paths
canvasSetStrokeColor(id, color) // Stroke color for outlines/paths
canvasSetLineWidth(id, width) // Line width in pixels
canvasSetFont(id, fontFamily, fontSize) // Font for text rendering
Transforms¶
canvasTranslate(id, x, y) // Translate origin
canvasScale(id, sx, sy) // Scale drawing
canvasRotate(id, radians) // Rotate drawing
Theme¶
setTheme("dark") // Built-in: "dark", "light", "pro_audio"
getThemeJson() // Returns full theme as JSON string
applyTokenDiff(jsonString) // Apply partial theme overrides from JSON
importDesignTokens(w3cJson) // Apply W3C Design Tokens JSON to the current theme
exportDesignTokens() // Export current theme as W3C Design Tokens JSON
saveStylePreset(name, object) // Persist a style payload as JSON
loadStylePreset(name) // Load a saved style payload object
setAICli(command) // Override the AI CLI command used by JS tools
getAICli() // Read the current AI CLI command
Layout & Geometry¶
layout() // Trigger layout recalculation on all widgets
removeWidget(id) // Remove widget from tree
getLayoutRect(id) // Returns { x, y, width, height, top, right, bottom, left } in root coords
getRootSize() // Returns { width, height } of root view (for vw/vh units)
getComputedValue(id, property) // Returns resolved CSS property value as string
measureText(text, fontSize) // Returns { width, ascent, descent, lineHeight }
Platform Integration¶
// Context menus
registerContextMenu(id, callbackName) // Register right-click handler: callbackName(x, y)
showContextMenu(itemsJSON, x, y) // Show native popup menu, returns selected id or -1
// itemsJSON: '[{"id":1,"label":"Cut"},{"separator":true}]'
// Keyboard shortcuts
registerShortcut(keyCode, modifiers, callbackName) // Global shortcut: callbackName()
// File dialogs
showOpenDialog(title, filterDesc, extensions) // Returns path or "" (extensions: "js;json;txt")
showSaveDialog(title, filterDesc, extensions) // Returns path or ""
chooseFolder(title) // Returns path or ""
Visual Properties¶
setPointerEvents(id, "none"|"auto") // CSS pointer-events (skip in hit testing)
setVisibility(id, "visible"|"hidden") // CSS visibility (hidden preserves layout)
setWhiteSpace(id, "normal"|"nowrap") // CSS white-space
setUserSelect(id, "none"|"text") // CSS user-select
Utility¶
compileShader(skslCode) // Validate SkSL shader — returns { success, error }
exec(command) // Run shell command — returns output string
execAsync(command, callbackId) // Run shell command in background, dispatches callbackId:result later
Widget Styling Extensions¶
setWidgetShader(id, skslCode) // Apply custom SkSL body shader to Knob/Fader/Toggle
clearWidgetShader(id) // Remove custom shader and restore default paint
setWidgetSchema(id, schemaJson) // Apply declarative widget schema to Knob/Fader/Toggle
clearWidgetSchema(id) // Remove widget schema override
setWidgetLottie(id, lottieJson) // Store Lottie JSON on Knob/Fader/Toggle
seekWidgetLottie(id, time01) // Scrub stored Lottie state to a normalized time
These APIs are intended for the design tool and other style-system workflows.
The recommended restyling path is preset/material or declarative-schema driven.
The built-in design-tool workflow also routes higher-level audio-plugin style
families (for example precision analyzer, heritage hardware, retro character,
modular neon, mastering lab, and console strip) into deterministic per-widget
presets before applying SkSL.
setWidgetShader remains available as a lower-level developer escape hatch when
you need direct SkSL control. Widget shaders receive the standard widget uniforms
(resolution, value, time, token colors), and time is driven from the
view FrameClock when the host is actively rendering.
setWidgetLottie currently stores animation state for tool workflows; native
Skottie rendering is still partial.
AI CLI Templates¶
setAICli(command) accepts a shell command template. The design tool and
pulp design-debug expand these placeholders before execution:
{prompt_file}: temp file containing the full structured prompt{model}: selected provider-specific model id{provider}: provider id such asclaudeorcodex{reasoning_effort}: selected effort (low,medium,high,xhigh) when supported{output_file}: optional temp file for CLIs that write their result to disk
The current built-in defaults are:
- Claude: cat {prompt_file} | claude --print --model {model}
- Codex: cat {prompt_file} | codex exec - --model {model} ... -c model_reasoning_effort={reasoning_effort} -o {output_file}
execAsync() is the non-blocking shell path used by the interactive design tool
chat. The headless pulp design-debug harness uses the same prompt builder and
command-template expansion so provider/model metadata stays aligned across both tools.
Color Format¶
All color parameters accept CSS Color Level 4 syntax:
"#RGB" // Short hex
"#RRGGBB" // Hex
"#RRGGBBAA" // Hex with alpha
"rgb(255, 128, 0)" // RGB
"rgba(255, 128, 0, 0.5)" // RGBA
"hsl(30, 100%, 50%)" // HSL
"hsla(30, 100%, 50%, 0.5)" // HSLA
"transparent" // Named colors
Legacy Positioning API¶
Widget creation functions also accept absolute coordinates for backward compatibility:
createKnob(id, x, y, w, h) // Absolute position
createFader(id, x, y, w, h, orientation)
createToggle(id, x, y, w, h)
createLabel(id, text, x, y, w, h)
Prefer the parentId API with flex/grid layout for new code.