Skip to main content
Aether’s ui factory provides a set of declarative node types that render as native Android Compose views inside surfaces, components, and pages. Each factory call returns a plain node descriptor object; Aether’s Android renderer resolves these descriptors into Compose components at display time.

Import

You can also access ui directly from the aether parameter passed to your extension factory:

Node types reference

Layout

ui.column(children, opts?)

Stacks its children vertically.

ui.row(children, opts?)

Arranges children horizontally. By default the row fills the available width and keeps all children on one line. A direct child may set weight to consume the remaining horizontal space while sibling controls keep their intrinsic size.

ui.box(children, opts?)

An overlay/stack container that draws children on top of each other.

ui.node("scroll", { children, ...opts })

Wraps its children in a scrollable container.

ui.spacer(size?, opts?)

Inserts fixed space. The size parameter sets both its width and height in dp (default: 8).

Text

ui.text(content, opts?)

Renders a text string. Use opts.style to apply a typographic role:

ui.code(content, opts?)

Renders content as monospace text.

Interactive

ui.button(label, actionId, opts?)

A tappable button that fires a registered action when pressed.
Button labels always render on a single line. Providing weight or an explicit width controls how much horizontal space the button uses.

ui.iconButton(icon, actionId, opts?)

An icon-only button. Use this to conserve horizontal space when a text label isn’t needed.

ui.switch(label, checked, actionId, opts?)

A labeled toggle switch. Pass the current boolean state as checked.
The switch factory signature is ui.switch(label, checked, actionId, opts?). Unlike button, the current state is a positional argument — not an option — so the action handler always receives an up-to-date value.

ui.input(value, actionId, opts?)

A text input field. Pass the current string value as the first argument.

Cards and navigation

ui.card(children, opts?)

A card container that groups related content.

ui.node("pageButton", opts)

A navigation button that opens the registered page with the given id when tapped. Use ui.node("pageButton", { page, label?, icon?, width? }) — there is no dedicated ui.pageButton factory function.

Progress and composition

ui.progress(value?, opts?)

Renders a circular progress indicator. Omit value for an indeterminate (spinning) state; pass a number between 0 and 1 for determinate circular progress.

ui.core()

A placeholder that marks where the wrapped native or replacement content should render inside a wrap-mode component registration. Use it inside registerComponent calls with mode: "wrap".

Combining nodes — full surface example

The example below registers an action that increments a persistent counter and a surface that renders it above the chat composer.
All ui.* factories return a plain JavaScript object — the node descriptor. Aether’s Android renderer resolves these objects to Compose components when the surface or page is displayed.
Rows fill the available width by default, while their children keep their intrinsic size. Set weight on one child to let it expand while sibling controls keep their intrinsic size. For example, placing { weight: 1 } on a button stretches it to fill the remaining row space alongside a fixed-width label.