Builtin Library
README.md
knob
Rotary knob built on canvas interaction props. Renders a 270° dial
as a track polyline + fill polyline + needle line, and wires
drag/reset handlers via widgetState. Auto-registers per-id handlers
on the current Z.app so callers only need to supply onChange.
Exports
knob(id: string, value: number, lo: number?, hi: number?, opts: KnobOpts?) -> WidgetNode— module returns the builder function directly.
Options:
defaultValue: number?— restored on double-click. Omit to disable reset.onChange: string?— callback id; fires with{ value = number }on drag/reset commit.tooltip: string?— when set, wraps the canvas in a transparent tooltip panel.width: number?,height: number?— canvas size. Default34 × 34.arcWidth: number?— track/fill stroke width. Default4.trackColor: string?,fillColor: string?,capColor: string?— palette overrides.style: table?,app: App?— standard plumbing.
Usage
local Z = require("@builtin::modules.zui")
Z.knob("master-gain", state.gain, 0, 1, {
defaultValue = 0.75,
onChange = "audio:gain",
tooltip = "Master gain",
})
Notes
- Vertical drag updates the value:
1px = 0.5% of span, or0.05%when Shift is held (10× finer for fine adjustment). Drag up increases. - Double-click restores
defaultValueif set; otherwise no-op. - Live state lives in
ui.widgetState(id, "value")— first render seeds from the suppliedvalue, thereafter the drag handler owns it. This mirrors theZ.collapsibleauto-stash pattern. - Handlers are registered once per id via
app._knobHandlers; subsequent renders are no-ops on the handler side. - The fill polyline is omitted when only one segment is filled so the renderer's min-2-points guard isn't tripped.
- The tooltip wrap is only added when
opts.tooltipis set so non-tooltip knobs stay flat.