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.
OptionTypeDescription
wrapbooleanAllow children to wrap onto multiple lines. Useful for narrow Android layouts.
rowSpacingnumberSpacing between wrapped lines.
maxItemsInEachRownumberCap the number of items per line when wrapping is enabled.
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.scroll(children, opts?)

Wraps its children in a scrollable container.

ui.spacer(size?, opts?)

Inserts flexible space. The size parameter sets the spacing in dp (default: 8).

Text

ui.text(content, opts?)

Renders a text string. Use opts.style to apply a typographic role:
StyleDescription
"headline"Large display heading
"title"Section or card title
"body"Default body copy
"caption"Small supplementary text
"code"Inline monospace text

ui.code(content, opts?)

Renders content as a monospace code block.

Interactive

ui.button(label, actionId, opts?)

A tappable button that fires a registered action when pressed.
OptionTypeDescription
argsobjectArguments forwarded to the action handler.
weightnumberConsume remaining horizontal space inside a row.
widthnumberExplicit width override in dp.
Button labels always render on a single line. Providing weight or an explicit width overrides the default fill behavior.

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.
OptionTypeDescription
multilinebooleanAllow the input to expand to multiple lines.

Cards and navigation

ui.card(children, opts?)

An elevated 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.
OptionTypeDescription
pagestringThe id of the page registered with registerPage.
labelstringButton label text.
iconstringOptional icon name.
widthstring | numberWidth override, e.g. "fill" to expand the button.

Progress and composition

ui.progress(value?, opts?)

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

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.
Row children fill available width by default. 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.