Modifier
Ordered layout and decoration for App pages, as in Compose.
Layout and decoration go through the modifier prop, like the modifier parameter of Compose components. Import Modifier from supernode/app and build it by chaining calls. Modifiers apply in call order, exactly as in Compose.
import { Modifier, Text } from "supernode/app";
<Text modifier={Modifier.padding(8).clip(12).background("#FFFFFF").padding(16).fillMaxWidth()}>
Hello
</Text>| Modifier | Behavior |
|---|---|
padding(all) / padding({ start, top, end, bottom }) / padding({ horizontal, vertical }) | Adds space around what follows in the chain. |
width(dp) / height(dp) / size(dp) / size(width, height) | Sets a fixed size. |
fillMaxWidth(fraction?) / fillMaxHeight(fraction?) / fillMaxSize(fraction?) | Fills a fraction of the parent, in (0, 1]. Defaults to 1. |
weight(weight, fill?) | Shares the remaining space of a Column or Row. See Weight. |
background(color) | Draws a background. See Color values. |
clip(radius) | Rounds the corners of everything drawn after it. |
append(other) | Appends another chain. See Combining modifiers. |
Like Modifier.padding in Compose, padding takes a number for all edges, an edge object { start, top, end, bottom }, or an axis object { horizontal, vertical }; one object cannot mix the two forms. start and end follow the layout direction. Numbers are in dp. Views size to their content by default.
Order
Each modifier wraps everything after it, so the same calls in a different order produce a different result:
<Column>
{/* Padding before the background acts as an outer margin. */}
<Text modifier={Modifier.padding(8).background("#FFE0E0")}>Margin</Text>
{/* Padding after the background is inner padding. */}
<Text modifier={Modifier.background("#FFE0E0").padding(8)}>Padding</Text>
{/* Clip before the background to round it. */}
<Text modifier={Modifier.clip(12).background("#FFE0E0").padding(8)}>Rounded</Text>
</Column>Weight
Like Modifier.weight in Compose's RowScope and ColumnScope, weight shares the remaining space along a Row or Column between the children that have one, in proportion to their weights. It is only allowed on direct children of Column and Row (children of a fragment count as children of the enclosing container); anywhere else it is rejected with the path of the view. With fill = false a child takes at most its share instead of being stretched to it.
import { Modifier, Row, Spacer, Text } from "supernode/app";
<Row verticalAlignment="center" modifier={Modifier.fillMaxWidth().padding(16)}>
<Text>Title</Text>
{/* Pushes "Edit" to the end of the row. */}
<Spacer modifier={Modifier.weight(1)} />
<Text>Edit</Text>
</Row>Combining modifiers
Modifiers are immutable: every call returns a new chain. Use append to combine a modifier received from a parent with your own, or to add one conditionally. It is named append rather than Compose's then because objects with a then method are treated as promises by await. append only accepts a Modifier from supernode/app.
import { Modifier, Text } from "supernode/app";
function Tag({ label, selected, modifier = Modifier }: { label: string; selected: boolean; modifier?: Modifier }) {
return (
<Text modifier={modifier.padding({ horizontal: 8, vertical: 4 }).append(selected ? Modifier.background("#E0F0FF") : Modifier)}>
{label}
</Text>
);
}