Skip to content

Architecture Decision Records ​

Decisions behind @jolly-pixel/ui that are hard to reverse, surprising without context, or the result of a real trade-off. The package README indexes the guides and the API reference.

A choice confined to one component's API belongs in that component's API page, not here. Numbers are never reused: gaps are records that were merged into another one or moved to the API docs.

#Decision
0001Custom elements are the public API, the facade only constructs them
0002Controlled elements, stateful facade
0003One shared field contract on a base class, not a mixin or controller
0005disabled, readonly and lockedBy combine rather than override
0007Tokens are declared once on scope hosts, using light-dark()
0008Two token tiers: private ramps, public semantics
0009Control backgrounds are alpha stops of one ink
0010Non-text contrast is deliberately not met for control boundaries
0011Roboto Mono is inlined as a base64 data URI, one weight
0012Placement is separate from content
0014jolly-color drops input[type="color"]
0015Measurement is separate from display, ./stats is DOM-free, and metric sources are structural
0016Built-in metrics and icons carry no privilege over registered ones
0017ui declares a presence port and owns the presence schema
0018Locks are advisory, live in the holder's presence, and only paint
0020Keyboard ownership follows focus, and an open layer claims every key
0021Structural math types, no three dependency
0022Layout persists through derived keys and a stated reconciliation algorithm
0023Field events are not cancelable, and carry the value alone
0024No spec imports a component, so testable logic lives in plain modules
0025Lit is a peer dependency and the barrel is never side-effect-free (superseded by 0041)
0027The facade writes a math value component-wise, and an axis key is the domain identity
0031jolly-log is an ambient feed, and jolly-toast stays deferred
0033The layout snapshot is the only layout state, groups and columns included
0037Colour is a tone on the glyph and an area on the pane, and a dialog's intent is not a tone
0040A declarative binding reads through to its source and keeps no mirror
0041Elements register through their own entry points, and the root registers none

Scope boundary ​

ui owns anything expressible without knowing what a voxel, a layer or an asset is. Domain-coupled composites stay in editors and are built from these parts. Asset and object reference pickers, block and blockset libraries, 3D preview tiles, and curve and gradient editors are out of scope.

jolly-split and menubar or dropdown menus are deferred rather than rejected: no consumer in this repository names one, so there is nothing to validate a design against. jolly-context-menu left that list once a tree needed right-click row actions; it opens only at a point until a button menu has a consumer. jolly-toast stays deferred for a different reason: editors/voxel-map needed an ambient feed, not an alert, and got jolly-log instead. See ADR-0031.

Open questions ​

  • Whether jolly-tree virtualizes. Deferred until a consumer exceeds a few hundred nodes.
  • Whether pane state beyond order persists through Tweakpane-style exportState / importState. Not built: no consumer to validate a serialisation format against.
  • Whether a central shortcut registry and user-rebindable shortcuts are needed, and where overrides persist. If built, spatial bindings match event.code (so KeyW stays the physical key on AZERTY) and command bindings match event.key (so undo stays on the key labelled Z). @jolly-pixel/controls key chords already match this way ("KeyQ" is a position, "z" a printed letter), so a registry would build on them.
  • Whether jolly-flags and jolly-layer-grid need per-bit mixedness. A bitmask across a multi-selection genuinely is mixed bit by bit, which FieldValue<number> cannot express.
  • Relative multi-edit is not expressible. { value: T } carries one absolute value; Unity applies a delta to each selected object instead, which would need a second detail shape and write-back path.
  • Whether JollyField becomes public. Promoting it is additive (ADR-0003).