node.widgets. The API separates
ordinary value widgets, per-node mounted surfaces, per-node canvas surfaces,
and type-level widget renderers.
Widget collections
at(index) is explicitly positional and becomes
stale when widgets are inserted, removed, or reordered.
All list reads are frozen snapshots. The collection itself provides mutation
operations:
reorder() requires every current name exactly once. It updates both legacy
and Nodes 2.0 render order. add() rejects duplicate names.
For behavior that belongs to every node of a type, prefer
NodeDefBuilder.addWidget() and install listeners from onCreated.
Values and commits
setValue() is not a bare assignment. It commits exactly as the host’s user
edit protocol does:
- writes the value;
- synchronizes a property-backed widget;
- runs the host and pack callback chain;
- calls node widget-change behavior;
- fires one
changeevent; - advances graph change state.
activate; that event represents a user act.
Widget events
Listeners are additive. Do not capture or replace
widget.callback.
Visibility, disabled state, labels, and options
setHidden() is the replacement for assigning the special
'converted-widget' type. It retains the value and cascades to linked controls.
Visibility, disabled state, and serialization are independent.
Use:
isHidden();isDisabled();isSerialized();getOptions()for a frozen options view;setOption(key, value)for one option.
getOptions().
Linked widgets
Compound controls use an explicit relationship:setLinked() must identify another widget on the node.
Pass an empty array to clear the relationship. Hiding the owner automatically
hides linked controls; reading linked() is useful when their current values
affect behavior.
Height and layout
setHeight() pins the widget’s allocation in graph units. getHeight() returns
the latest host allocation, or undefined before layout.
This differs from MountDef.height: the mount option gives the inner container
a height, while WidgetHandle.setHeight() changes how much node layout assigns
to the widget. Leave the height unpinned for an editor intended to fill spare
space.
Use node.setSizeConstraints() for node-level minimum, maximum, or auto-height
behavior instead of reassigning a size callback.
Serialization
Declared widgets
WidgetDef.serialize controls whether an added widget writes to the saved
workflow:
Destination-specific values
workflow: a workflow saved by the user;prompt: the API payload sent for execution;embedded: the workflow copy embedded into output from that prompt.
setSerializedValue() changes that write only. The live widget stays unchanged.
Handlers are synchronous and the last replacement wins.
Mounting a DOM control on one node
widgets.mount() is the replacement for addDOMWidget:
destroy().
The mounted surface is pack-owned and does not make host-page elements part of the published API. Keep all DOM work inside the supplied container so the code remains renderer-independent.
Mount behavior:
defaultValuemakes the mount value-holding; omit it for decoration;serializedefaults totruefor a value-holding control andfalsefor a decorative mount;sendToPromptdefaults toserializeand can differ for “saved but not sent” readouts;hideOnZoomdefaults totrue;heightreserves an inner container height;hiddencontrols initial visibility.
MountedValue accessor offers get(), set(value), and onChange().
Object defaults are cloned per node so instances do not share mutable data.
A canvas surface owned by the widget
widgets.canvas() lets a pack keep canvas drawing code without drawing into the
host’s shared graph canvas:
draw().
The underlying PointerEvent carries buttons and modifiers. A context-menu
handler claims secondary-click behavior; without one, the node context menu
continues to work.
CanvasHandle.widget exposes the ordinary widget handle. Call redraw() when
external data used by draw() changes.
Interacting with a host text editor
Do not reach forwidget.inputEl. Subscribe to textInteraction:
menuEvent for positioning
a host menu, setValue() with optional restored selection, and focus().
Keyboard and wheel variants expose their relevant modifiers and cancellation
methods.
Defining a widget type
Usedefs.defineWidgetType() when a backend input type needs a renderer on
every node:
widgets.mount():
defineWidgetType()declares presentation for an input type before its nodes join a graph;mount()adds one widget to one live node;- a type-level renderer gets a
WidgetTypeContext, and obtains a node later throughonNodeReady; - registered input types remain widgets rather than silently becoming sockets, which affects both workflow and prompt serialization.