SuperNode
App

Components

Native views and layouts for App pages.

Import components from supernode/app. Every component accepts a modifier for layout and decoration. Colors and alignments are described in View.

import { Column, Modifier, Text } from "supernode/app";

Text

Displays text.

<Text fontSize={16} fontWeight="bold" fontStyle="italic" color="#057AF6">
  Hello SuperNode
</Text>
PropTypeDescription
childrenstring or expressionText content.
fontSizenumberFont size in sp. Defaults to 14.
fontWeightFontWeightFont weight. Defaults to "normal". See Font weights.
fontStyle"normal" | "italic"Font style. Defaults to "normal".
colorstring | { light, dark }Text color: a hex color, or separate colors per theme. See Color values.

Font weights

Values match Compose FontWeight.

ValueWeight
"thin"100
"extraLight"200
"light"300
"normal"400
"medium"500
"semiBold"600
"bold"700
"extraBold"800
"black"900

DateText

DateText displays a JavaScript Date in a native date format.

<DateText
  date={lastUpdatedAt}
  format="relative"
  prefix="Updated "
  suffix=" ago"
  color="#777777"
/>
PropTypeDescription
dateDatePoint in time to display. An invalid Date throws an error.
formatDateTextFormatDate format. See Date formats.
prefixstringStatic text before the date.
suffixstringStatic text after the date.
fontSizenumberFont size in sp. Defaults to 14.
fontWeightFontWeightFont weight. Defaults to "normal".
fontStyle"normal" | "italic"Font style. Defaults to "normal".
colorstring | { light, dark }Text color: a hex color, or separate colors per theme.

prefix, the dynamic date, and suffix form one text view and share the same font, color, and wrapping behavior.

Date formats

ValuePurpose
"relative"Displays a duration such as “5 minutes.”
"offset"Displays a signed time offset.
"timer"Displays a countdown or elapsed time.
"date"Displays a fixed calendar date.
"time"Displays a fixed clock time.

The device locale controls formatting and units. The page updates time-dependent text every second while it is visible.

TextField

A controlled text input.

<TextField value={name} placeholder="Name" onValueChange={setName} />
PropTypeDescription
valuestringCurrent input value.
onValueChange(value: string) => voidCalled with the latest string when the input changes.
placeholderstringPlaceholder shown when the value is empty.

Image

<Image src="home_smile_solid" contentScale="crop" modifier={Modifier.size(48)} />
PropTypeDescription
srcstringHTTP(S) URL, image Data URL, relative or absolute path, file: URL, or PikaIcons asset name. See Image sources.
contentScaleContentScaleHow the image is scaled into its bounds. Defaults to "fit". See Content scale.

Content scale

Values match Compose ContentScale:

ValueBehavior
"fit"Scales uniformly so the whole image fits inside the bounds.
"crop"Scales uniformly to fill the bounds, cropping the overflow.
"fillBounds"Stretches to fill the bounds without keeping the aspect ratio.
"fillWidth"Scales uniformly to match the bounds' width.
"fillHeight"Scales uniformly to match the bounds' height.
"inside"Like "fit", but never scales the image up.
"none"Draws the image at its original size.

Image sources

The source format selects the image provider. Relative paths resolve against the script working directory:

<Column>
  <Image src="https://example.com/avatar.png" />
  <Image src="http://example.com/avatar.png" />
  <Image src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" />
  <Image src="home_smile_solid" />
  <Image src="images/avatar.png" />
</Column>

SuperNode downloads remote images before the view is shown. Invalid responses, image data, and asset names fail with an explicit error.

Spacer

Occupies empty space of the size set by its modifier. Like Compose Spacer, it is 0 × 0 when no size is set and does not stretch on its own; give it a weight to fill the remaining space of a Row or Column.

<Row>
  <Text>Left</Text>
  <Spacer modifier={Modifier.width(16)} />
  <Text>Right</Text>
</Row>

HorizontalDivider and VerticalDivider

Render a thin separator line. HorizontalDivider fills the available width; VerticalDivider fills the available height. Both also accept modifier.

<Column>
  <Text>Above</Text>
  <HorizontalDivider color="#FF0000" thickness={2} />
  <Row modifier={Modifier.height(24)}>
    <Text>Left</Text>
    <VerticalDivider />
    <Text>Right</Text>
  </Row>
</Column>
PropTypeDescription
colorstring | { light, dark }Line color: a hex color, or separate colors per theme. Defaults to the theme divider color. See Color values.
thicknessnumberLine thickness in dp. Defaults to 1.

Layouts

Column

Stacks children vertically. Also accepts modifier.

<Column horizontalAlignment="center" spacing={4} modifier={Modifier.padding(12)}>
  <Text>Title</Text>
  <Text>Subtitle</Text>
</Column>
PropTypeDescription
horizontalAlignment"start" | "center" | "end"Horizontal alignment of children. Defaults to "start".
spacingnumberSpace between children in dp, like Arrangement.spacedBy. Defaults to 0.

Row

Stacks children horizontally. Also accepts modifier.

<Row verticalAlignment="center" spacing={8} modifier={Modifier.padding(12)}>
  <Text>Left</Text>
  <Text>Right</Text>
</Row>
PropTypeDescription
verticalAlignment"top" | "center" | "bottom"Vertical alignment of children. Defaults to "top".
spacingnumberSpace between children in dp, like Arrangement.spacedBy. Defaults to 0.

Box

Stacks children on top of each other. Also accepts modifier.

<Box contentAlignment="bottomEnd" modifier={Modifier.padding(12)}>
  <Text>Title</Text>
</Box>
PropTypeDescription
contentAlignmentContentAlignmentWhere children are placed. Defaults to "topStart". See Alignment values.

Example: profile layout

<Row verticalAlignment="center" spacing={12} modifier={Modifier.padding(16)}>
  <Image
    src={profile.avatar}
    contentScale="crop"
    modifier={Modifier.size(64).clip(32)}
  />
  <Column spacing={4}>
    <Text fontSize={16} fontWeight="bold">{profile.nickname}</Text>
    <Text color="#777777">@{profile.id}</Text>
    <Row spacing={12}>
      <Text>{profile.followers} followers</Text>
      <Text>{profile.following} following</Text>
    </Row>
  </Column>
</Row>

On this page