Repository navigation
Composable UI Migration
Compound 1.18.0 ports the existing libraries to Minecraft 26.3. Compound 2.0.0 replaces the legacy UI API with the composable framework on that same platform. This is a major-version change; existing UI consumers need migration.
- Replace
CompoundUIwithComposedUI, andCompoundUIContainerwithComposedUIContainer. Describe the screen with composition scopes instead of registering legacy elements and layouts. - Replace legacy
Element*widgets andLayout*classes with composable controls, containers, and layout properties. UseInventorySlotand the container's slot mapping for inventory screens. - Construct observable values with
State.of(initialValue). Use the interface factories instead of constructing implementation classes. - Use typed tree events and state bindings instead of legacy listener registration. MouseScrollEvent exposes
scrollX()andscrollY(); key events distinguish navigation keys from logical editing shortcuts. CharEvent carries a Unicode code point. - Carets and highlights compose existing rectangles and text; cursor blinking uses the animation system. Keep retained state and animation ownership tied to the screen's lifecycle.
For consumers of earlier framework prototypes, replace scrollDelta() with scrollY(). TextInput no longer exposes setCanLoseFocus/canLoseFocus: tree focus is authoritative. Maximum layout constraints stay within the parent; use the explicit unbounded operations only when intended.
- Use retained
IAnimationTimeline.create()andIAnimatedValue.create(...)for visual-only frame animation. Attach the timeline withscope.useAnimationTimeline(timeline)on one owning node. Detach freezes its clock; reattachment preserves elapsed time. KeepAnimatedStatewithbindLayoutfor measured-size animation. - Replace draw-time pose mutations with
elementScope.transform(...). UsebeforeGeometry(...)for render-only preparation. Keep draw suppliers read-only so rendering, debug outlines, and hit testing share one geometry snapshot. - Mouse callbacks still receive world GUI coordinates. Custom transformed controls should use
elementScope.toLocal(...)and handle the empty optional result. Rotated clipping throws; scissors remain axis-aligned, including clips inside text inputs and scroll areas. -
TextInput.setBordered(false)now hides decoration without changing content insets. SetTextInsets.NONEexplicitly for edge-to-edge content. Both editors exposesetContentInsets,setTextAlignment, andsetBackground;TextArea.setBackgroundVisiblecontrols decoration separately. - Explicit
TextInput.setTextAlignmenttakes precedence over the compatibilitysetCenteredsetter. Single-line construction, replacement, and insertion remove both CR and LF. Both editors share the Java-only editing core; absolute offsets and limits use UTF-16 code units, with caret movement and truncation respecting code-point boundaries.
Start with the consumer API, then the framework reference. The companion Molecule framework-demo branch provides a widget gallery and a working inventory screen.
For standalone tree composition, use ICompositionScope.root(tree). Use AnimatedState.of(...) or AnimatedState.looping(...) outside composition, and IScreenSpriteWriter.stretch(), tiled(), or nineSlice(...) when explicitly choosing sprite scaling.
Custom composables extend Element, custom containers extend Container, and custom drawing
elements extend PrimitiveElement. These replace the prototype base class names. Numeric and
boolean drawing suppliers use IntSupplier, DoubleSupplier, and BooleanSupplier; replace
boxed supplier declarations and use their getAsInt(), getAsDouble(), or getAsBoolean() methods.
Object suppliers such as Supplier<Component> are unchanged. Construct list rows through
ListItem.builder(label) and configure selection, hover, and colors before calling build().