@modoki/engine / index / UIBinding
Variable: UIBinding
constUIBinding:Trait<{highlightColor:number;highlightComponent:string;highlightProperty:string;highlightTarget:string;highlightTextColor:number;highlightValue:string;inputBinding:string;textBinding:string;visibleBinding:string;visibleOp:string;visibleValue:string; }>
UIBinding — connects UI content to Zustand store fields.
Covers text templating, two-way input, state-driven VISIBILITY, and a small "active highlight" rule. Visibility: the authored UIElement.isVisible is still the base source of truth; a visibleBinding (below) can ADDITIONALLY hide the element from a store field (both must be true), and — like a button's UIAction kind:'set' — it's a play-time effect that never reaches disk (the editor ignores it so bound elements stay authorable).
Active highlight reads the SOURCE OF TRUTH directly (no mirrored store flag): the element renders with highlightColor as its background whenever the live value of highlightComponent.highlightProperty on the entity referenced by highlightTarget (a guid) string-equals highlightValue. The canonical use is a clip-selector button that lights up while its clip is the one currently playing — highlightTarget→the animated entity, component SkeletalAnimator, property clip, value this button's clip name. Disabled when highlightColor < 0 (the default).
⚠️ REPAINT INVARIANT (the watched value must dirty the UI): the highlight re-resolves only when the UI tree rebuilds, which happens on a UI dirty signal — i.e. when the watched trait is written through setTrait/writeTraitField (these call markUIDirty) or by a UIAction kind:'set' binding. If a SYSTEM mutates the watched value via a raw entity.set/updateEach (the per-frame ECS write path, which deliberately bypasses the dirty system for performance), the highlight will NOT update until some other UI change dirties the tree. The canonical clip-selector is safe because the clip is changed via a set binding. To highlight a value a game system drives directly, that writer must call markUIDirty() after the write. (Locked by uiTreeHighlight.test.ts "does NOT re-resolve … without a dirty signal".)