Helix/UserInterface
Reference for element creation, layout, resources, text, animation, measurement, and events.
Import #
import * as UI from 'Helix/UserInterface';All runtime UI calls are promise-based. Use await UI.*(...). The return types below describe the resolved value (Promise<...> at call site).
Types #
type'row' | 'column' | 'grid' | 'none' optionalwrapboolean optionalwrapLimitnumber optionalgapnumber optionalpadding{ t?: number, r?: number, b?: number, l?: number } optionaljustifyContent'start' | 'center' | 'end' | 'space-between' optionalalignItems'start' | 'center' | 'end' optionalgridColumnsnumber optionalgridRowsnumber optionalcolumnGapnumber optionalrowGapnumber optionalgridFlowByRowboolean optionalgridAlignItems'start' | 'center' | 'end' optionalgridJustifyItems'start' | 'center' | 'end' | 'space-between' optional
size{ x?: number | 'auto', y?: number | 'auto' } optionalmargin{ t?: number, r?: number, b?: number, l?: number } optionalminWidthnumber optionalminHeightnumber optionalmaxWidthnumber optionalmaxHeightnumber optionalordernumber optionalflexGrownumber optionalflexShrinknumber optionalalignSelf'start' | 'center' | 'end' optionalgridColumnnumber optionalgridRownumber optionalgridColumnSpannumber optionalgridRowSpannumber optional
Create, attach, destroy #
optionsaccepts layout/renderable settings, child elements, inputOptions, and virtual handlers: onPress, onActivate, onHover, onDrag, onScroll, onLongPress, onDoubleActivate and onTransform.
createElement(windowId, options): Promise<number>attachRoot(windowId, id): Promise<boolean>attach(windowId, parent, id): Promise<boolean>detach(windowId, parent, id): Promise<boolean>id.destroyElement(windowId, id): Promise<boolean>false.setEnabled(windowId, id, enabled): Promise<boolean>Helix/Renderable require this handle.- See UI/Renderable: Particles for particle configuration and lifecycle functions.
getRenderable(windowId, id): Promise<number>Naming and lookup #
-1 when not found.getElementById(windowId, name): Promise<number>setElementId(windowId, id, name): Promise<boolean>Clipping and masking #
setClipToBounds(windowId, id, enabled): Promise<boolean>setClipToMask(windowId, id, enabled): Promise<boolean>setClipMaskAlphaThreshold(windowId, id, threshold): Promise<boolean>opacityMode: 'composite' and clipToMask: true on the same element currently falls back to propagate behaviour.
Opacity mode #
mode:'propagate' | 'composite'propagate: parent opacity multiplies descendants before blending.composite: subtree renders to an offscreen target, then parent opacity is applied once to the composited result.
setOpacityMode(windowId, id, mode): Promise<boolean>Prefer propagate for simple trees when children do not visually overlap (cheaper, avoids extra offscreen pass). Prefer composite when children overlap or self-layer, especially during fades (avoids self-blend artifacts, but more expensive due to offscreen rendering and texture sampling).
Resources and shaders #
setPanelSlice(windowId, id, { top, right, bottom, left }): Promise<boolean>- Accepts RGB/RGBA arrays, { r, g, b, a? } objects, or hex colour strings.
- Multiplies the frame colour and inherited opacity in stretched, sliced, and cover modes. Use [1,1,1,1] to clear the tint.
- Resolves true on success; rejects invalid targets. Invalid colour formats throw RangeError.
setPanelColour(windowId, id, colour): Promise<boolean>setTexture(windowId, id, path): Promise<boolean>clearTexture(windowId, id): Promise<boolean>blendmay also be provided asblendMode.- Supported blend modes:
'premultiplied-alpha'(default),'opaque','additive', and'alpha'.
setShader(windowId, id, { vert: string, frag: string, blend?: BlendMode }): Promise<boolean>clearShader(windowId, id): Promise<boolean>params:{ v0?: [x,y,z,w], v1?: [x,y,z,w] }
setShaderParams(windowId, params): Promise<boolean>params:{ v0?: [x,y,z,w], v1?: [x,y,z,w] }
setElementShaderParams(windowId, id, params): Promise<boolean>Text helpers #
setTextString(windowId, id, text): Promise<boolean>setTextSize(windowId, id, px): Promise<boolean>setTextLetterSpacing(windowId, id, factor): Promise<boolean>setTextLineSpacing(windowId, id, factor): Promise<boolean>setTextColour(windowId, id, colour): Promise<boolean>[start, end) and returns a stable area ID. The latest overlapping area wins.addColourArea(windowId, id, start, end, colour): Promise<number>listColourAreas(windowId, id): Promise<Array<{ id, start, end, colour }>>deleteColourArea(windowId, id, areaId): Promise<boolean>setTextFont(windowId, id, fontPath): Promise<boolean>justify:'left' | 'center' | 'right'
setTextJustify(windowId, id, justify): Promise<boolean>align:'start' | 'center' | 'end'
setTextVerticalAlign(windowId, id, align): Promise<boolean>basis:'line' | 'ink'ink(default): tighter visual glyph bounds for static labels.line: stable line-box metrics for editable/input text.
setTextMetricsBasis(windowId, id, basis): Promise<boolean>options:{ mipmaps?: boolean, lightHinting?: boolean }
setFontOptions(windowId, fontKey, options): Promise<boolean>Content alignment and positioning #
align:{ x?: 'start' | 'center' | 'end', y?: 'start' | 'center' | 'end' } | 'fill'
setContentAlign(windowId, id, align): Promise<boolean>mode:'raw' | 'contain'
setContentPositioning(windowId, id, mode): Promise<boolean>Layout placement #
item.absolutePosition) in pixels.setLayoutPosition(windowId, id, point): Promise<boolean>item.absoluteAABB).setLayoutAABB(windowId, id, bounds): Promise<boolean>setPosition() updates renderable transform only. Use setLayoutPosition() / setLayoutAABB() when you need layout-space placement.
Animation #
addAnimation(windowId, elementId, frames): Promise<number>updateAnimation(windowId, elementId, animationId, frames): Promise<boolean>startAnimation(windowId, elementId, animationId): Promise<boolean>stopAnimation(windowId, elementId): Promise<boolean>onAnimationEnd(windowId, elementId, animationId, cb): Promise<boolean>Supported easing: inQuad, outQuad, inOutQuad, inCubic, outCubic, inOutCubic, inQuart, outQuart, inOutQuart, inQuint, outQuint, inOutQuint. Easing is destination-based: ease on a keyframe controls the transition from the previous keyframe into that keyframe.
Dynamic t:0 behaviour: if an animation has no keyframe at time: 0.0, startAnimation injects a runtime t:0 frame from the element's current visual state so clip-to-clip transitions remain continuous. If a keyframe at time: 0.0 is authored, the authored frame is used and no dynamic capture is applied.
Measurement #
{ min, max, centre, size }.getRenderableBounds(windowId, id): Promise<Rect>{ x: width, y: height }.getRenderableSize(windowId, id): Promise<Point>- Uses the existing text renderable state (string, font, spacing, style).
idmust reference a text renderable.
measureText(windowId, id): Promise<{ size: Point, lineAdvance: number, lineCount: number }>indexis clamped to valid codepoint range.idmust reference a text renderable.
getTextCaretPosition(windowId, id, index): Promise<Point>localPoint:{ x, y }in element-local coordinates.idmust reference a text renderable.
hitTestText(windowId, id, localPoint): Promise<number>getElementFrame(windowId, id): Promise<Rect>Event handlers (runtime) #
setHitTarget(windowId, id, enabled): Promise<boolean>Virtual handlers enable hit testing and receive one event object. See /helix-input for recognition and ownership.
Virtual handlers receive one typed interaction event. See /helix-input for phases, capture, coordinates, recognition options and cancellation.
Virtual input setters are setOnPress, setOnActivate, setOnHover, setOnDrag, setOnScroll, setOnLongPress, setOnDoubleActivate, setOnTransform and setInputOptions. See /helix-input for their shared event contract.