.md

Components

Every built-in, with the JSX you write and the native render it produces — screenshots straight off the iOS Simulator, regenerated from the gallery app. Capitalized tags compile to binary ops; styling is props; testID and semanticLabel ride Flutter's real semantics tree.

Content · Layout · Input · Lists · Navigation · Effects

Content

<Text> → Text

Styled text — size, weight, family, color, alignment, maxLines, overflow.

<Text label="The quick brown fox" fontSize={24} fontWeight={800} color="#FF1C1C1E" />
<Text label="jumps over the lazy dog." fontSize={15} color="#FF8E8E93" />
<Text label="Truncates with an ellipsis when it runs out of space to work with"
      maxLines={1} textOverflow={1} fontSize={14} color="#FF0A84FF" />
Text rendered natively on iOS

<RichText> → Text.rich

Inline spans — each Text child becomes a styled TextSpan.

<RichText>
  <Text label="Rich text " fontSize={17} color="#FF1C1C1E" />
  <Text label="mixes " fontSize={17} color="#FF0A84FF" fontWeight={800} />
  <Text label="size, " fontSize={23} color="#FFFF453A" fontWeight={700} />
  <Text label="weight " fontSize={17} color="#FF30D158" fontWeight={800} />
  <Text label="and colour inline." fontSize={17} color="#FF1C1C1E" />
</RichText>
RichText rendered natively on iOS

<Image> → Image

Network, file://, or asset:// sources; BoxFit via contentScale.

<Image src="https://picsum.photos/seed/skal/640/360"
       width="fill" height={180} contentScale={1} cornerRadius={14} />
Image rendered natively on iOS

<Canvas> → CustomPaint

A chainable 2-D drawing context — rects, circles, paths, text. Reads signals; redraws when they change.

<Canvas width={320} height={180} draw={(c) => {
  [60, 110, 80, 140, 95].forEach((v, i) =>
    c.fillStyle(i === 3 ? '#FF0A84FF' : '#FFBF5AF2')
     .fillRect(24 + i * 58, 170 - v, 40, v));
  c.fillStyle('#FF1C1C1E').fontSize(13).fillText('rendered on a signal', 24, 24);
}} />
Canvas rendered natively on iOS

<ActivityIndicator> → CircularProgressIndicator

Indeterminate spinner; color and size are props.

<ActivityIndicator color="#FF0A84FF" width={36} />
ActivityIndicator rendered natively on iOS

<ProgressBar> → LinearProgressIndicator

Determinate with progress 0..1, indeterminate without.

<ProgressBar progress={0.65} color="#FF0A84FF" />
<ProgressBar color="#FFBF5AF2" />   {/* indeterminate */}
ProgressBar rendered natively on iOS

Layout

<Box> → Container

The decorated box — padding, background, corners, borders, shadows, tap/hover/drag handlers.

<Box padding={18} background="#FFFFFFFF" cornerRadius={16}
     borderWidth={1} borderColor="#FFE5E5EA" shadow={8}
     onTap={() => setLiked(!liked())}>
  <Text label="Tap me" fontSize={15} color="#FF1C1C1E" />
</Box>
Box rendered natively on iOS

<Column> → Column

Vertical flex; gap, padding, alignment; children flex with weight.

<Column gap={10}>
  <Box height={44} background="#FF0A84FF" cornerRadius={10} />
  <Box height={44} background="#FF30D158" cornerRadius={10} />
  <Box height={44} background="#FFFF9F0A" cornerRadius={10} />
</Column>
Column rendered natively on iOS

<Row> → Row

Horizontal flex; weight distributes leftover space.

<Row gap={10}>
  <Box weight={1} height={64} background="#FF0A84FF" cornerRadius={10} />
  <Box weight={2} height={64} background="#FF30D158" cornerRadius={10} />
  <Box weight={1} height={64} background="#FFFF9F0A" cornerRadius={10} />
</Row>
Row rendered natively on iOS

<Stack> → Stack

Layered children; top/right/bottom/left props position them absolutely.

<Stack width="fill" height={160}>
  <Box width="fill" height={160} background="#FF0A84FF" cornerRadius={16} />
  <Box top={12} right={12} padding={8} background="#FFFFFFFF" cornerRadius={10}>
    <Text label="badge" fontSize={12} color="#FF0A84FF" />
  </Box>
  <Box bottom={12} left={12} padding={10} background="#66000000" cornerRadius={10}>
    <Text label="caption over the fill" fontSize={13} color="#FFFFFFFF" />
  </Box>
</Stack>
Stack rendered natively on iOS

<Wrap> → Wrap

Flow layout — children wrap to the next line; gap sets both spacings.

<Wrap gap={8}>
  <For each={['solid', 'flutter', 'bun', 'jsc', 'zero-copy', 'bridge', 'native']}>
    {(t) => <Box padding={10} background="#FFF2F2F7" cornerRadius={999}>
      <Text label={t} fontSize={13} color="#FF1C1C1E" /></Box>}
  </For>
</Wrap>
Wrap rendered natively on iOS

<ScrollView> → SingleChildScrollView

Eager scrolling for short content; axis 0 = vertical, 1 = horizontal. Use ListView for long lists.

<ScrollView axis={1} gap={10} height={90}>
  <For each={colors}>
    {(c) => <Box width={90} height={90} background={c} cornerRadius={14} />}
  </For>
</ScrollView>
ScrollView rendered natively on iOS

Input

<Button> → ElevatedButton

label + onClick; disable with enabled={false}.

<Button label="Continue" onClick={() => submit()} />
<Button label="Disabled" enabled={false} />
Button rendered natively on iOS

<TextInput> → TextField

Controlled text field — onChange per keystroke, onSubmit on Enter, secureEntry for passwords.

<TextInput value={name()} placeholder="Your name…"
           onChange={setName} onSubmit={(v) => save(v)} />
TextInput rendered natively on iOS

<Switch> → Switch

Boolean toggle; the app owns the state.

<Switch checked={on()} onChange={setOn} />
Switch rendered natively on iOS

<Checkbox> → Checkbox

Checked/unchecked; onChange(bool).

<Checkbox checked={done()} onChange={setDone} />
Checkbox rendered natively on iOS

<Radio> → Radio

One option in a group the app owns — onChange fires with true.

<For each={options}>
  {(opt, i) => <Row gap={8}>
    <Radio checked={sel() === i()} onChange={() => setSel(i())} />
    <Text label={opt} fontSize={14} />
  </Row>}
</For>
Radio rendered natively on iOS

<Chip> → FilterChip

Toggleable filter chip — label, checked, onChange(bool).

<Chip label="Solid" checked={f().solid} onChange={(v) => toggle('solid', v)} />
Chip rendered natively on iOS

<SegmentedButton> → SegmentedButton

One-of-N selector; children are the segment labels.

<SegmentedButton activeTab={seg()} onChange={setSeg}>
  <Text label="Day" fontSize={13} />
  <Text label="Week" fontSize={13} />
  <Text label="Month" fontSize={13} />
</SegmentedButton>
SegmentedButton rendered natively on iOS

<Slider> → Slider

Continuous value between min and max.

<Slider value={vol()} min={0} max={100} onChange={setVol} />
Slider rendered natively on iOS

<Stepper> → Stepper

Multi-step flows; each Step has a title and a body.

<Stepper activeTab={step()} onChange={setStep}>
  <Step title="Account"><Text label="Name, email, password." fontSize={13} /></Step>
  <Step title="Profile"><Text label="Photo and a short bio." fontSize={13} /></Step>
  <Step title="Done"><Text label="Review and finish." fontSize={13} /></Step>
</Stepper>
Stepper rendered natively on iOS

Lists

<ListView> → ListView.builder

Lazy, virtualized list — thousands of rows stay smooth. axis 1 for horizontal.

<ListView gap={8} height={260}>
  <For each={rows()}>
    {(r) => <Box padding={14} background="#FFFFFFFF" cornerRadius={12}>
      <Text label={r} fontSize={14} color="#FF1C1C1E" /></Box>}
  </For>
</ListView>
ListView rendered natively on iOS

<ListTile> → ListTile

title, subtitle, leading/trailing icons, onTap — the settings-row workhorse.

<ListTile title="Notifications" subtitle="Sounds, banners, badges"
          leadingIcon="notifications" trailingIcon="chevron_right"
          onTap={() => open('notifications')} />
ListTile rendered natively on iOS

<LazyGrid> → GridView.builder

Virtualized grid; crossAxisCount columns, aspectRatio per cell.

<LazyGrid crossAxisCount={3} aspectRatio={1} gap={10} height={240}>
  <For each={items}>
    {(c) => <Box background={c} cornerRadius={14} />}
  </For>
</LazyGrid>
LazyGrid rendered natively on iOS

<ReorderableListView> → ReorderableListView.builder

Drag rows to reorder; onReorder(from, to) updates your source array.

<ReorderableListView height={230} gap={8} onReorder={(from, to) => move(from, to)}>
  <For each={rows()}>
    {(r) => <Box padding={14} background="#FFFFFFFF" cornerRadius={12}>
      <Text label={r} fontSize={14} color="#FF1C1C1E" /></Box>}
  </For>
</ReorderableListView>
ReorderableListView rendered natively on iOS

<PageView> → PageView

Swipeable pages; activeTab is the page index.

<PageView activeTab={page()} onChange={setPage} height={200}>
  <Box background="#FF0A84FF" cornerRadius={16} />
  <Box background="#FF30D158" cornerRadius={16} />
  <Box background="#FFFF9F0A" cornerRadius={16} />
</PageView>
PageView rendered natively on iOS

<AnimatedList> → AnimatedList

Items animate in and out as your array changes.

<AnimatedList height={220}>
  <For each={items()}>
    {(t) => <Box padding={12} background="#FFFFFFFF" cornerRadius={12}>
      <Text label={t} fontSize={14} color="#FF1C1C1E" /></Box>}
  </For>
</AnimatedList>
AnimatedList rendered natively on iOS

<Dismissible> → Dismissible

Swipe a row away; onDismiss removes it from your data.

<Dismissible onDismiss={() => remove(item.id)}>
  <Box padding={14} background="#FFFFFFFF" cornerRadius={12}>
    <Text label="Swipe me away" fontSize={14} color="#FF1C1C1E" />
  </Box>
</Dismissible>
Dismissible rendered natively on iOS

<Tabs> → NavigationBar + IndexedStack

Bottom tab navigation; every tab stays mounted (state survives switching).

<Tabs activeTab={tab()} onChange={setTab} height="fill">
  <Tab title="Home" icon="grid"><Home /></Tab>
  <Tab title="Search" icon="explore"><Search /></Tab>
  <Tab title="Profile" icon="storage"><Profile /></Tab>
</Tabs>
Tabs rendered natively on iOS

<ExpansionTile> → ExpansionTile

Collapsible section; the host animates open/close.

<ExpansionTile title="Advanced settings">
  <Box padding={14}>
    <Text label="Hidden until expanded." fontSize={13} />
  </Box>
</ExpansionTile>
ExpansionTile rendered natively on iOS

<SliverAppBar> → CustomScrollView + SliverAppBar

Collapsing header inside a sliver scroll — pinned, floating, or both.

<CustomScrollView height={320}>
  <SliverAppBar title="Collapsing" height={120} sliverMode="pinned" />
  <SliverList>
    <For each={rows}>{(r) => <ListTile title={r} />}</For>
  </SliverList>
</CustomScrollView>
SliverAppBar rendered natively on iOS

<BottomSheet> → DraggableScrollableSheet

Drag-resizable sheet anchored to the bottom of a Stack.

<Stack width="fill" height={340}>
  <Box width="fill" height={340} background="#FF0A84FF" cornerRadius={16} />
  <BottomSheet initialSize={0.45} minSize={0.2} maxSize={0.9}>
    <Column padding={16} gap={8} background="#FFFFFFFF">
      <Text label="Drag me up" fontSize={15} fontWeight={700} />
    </Column>
  </BottomSheet>
</Stack>
BottomSheet rendered natively on iOS

Effects

<BackdropFilter> → BackdropFilter

Frosted-glass blur over whatever is behind it in a Stack.

<Stack width="fill" height={200}>
  {/* colorful content… */}
  <Box top={50} left={40} right={40} height={100}>
    <BackdropFilter blurRadius={14}>
      <Text label="frosted" fontSize={16} />
    </BackdropFilter>
  </Box>
</Stack>
BackdropFilter rendered natively on iOS

<InteractiveViewer> → InteractiveViewer

Pinch-zoom and pan around a child.

<InteractiveViewer minScale={0.5} maxScale={4}>
  <Image src="…" width="fill" height={220} />
</InteractiveViewer>
InteractiveViewer rendered natively on iOS

<CrossFade> → AnimatedSwitcher

Cross-fades between children when the content swaps.

<CrossFade>
  {day() ? <SunCard /> : <MoonCard />}
</CrossFade>
CrossFade rendered natively on iOS

<DragItem & DropZone> → Draggable + DragTarget

Native drag-and-drop; the drop zone receives the item id.

<DragItem dragData="card-1">
  <Box padding={14} background="#FFFFFFFF" cornerRadius={12}>
    <Text label="Drag me" fontSize={14} />
  </Box>
</DragItem>
<DropZone onDrop={(id) => setDropped(id)}>
  <Box padding={24} borderWidth={2} borderColor="#FF0A84FF" cornerRadius={12}>
    <Text label={dropped() ?? 'Drop here'} fontSize={14} />
  </Box>
</DropZone>
DragItem & DropZone rendered natively on iOS

Not pictured

Navigator/Screen and Hero are navigation transitions (see createRouter), Drawer is the edge-swipe panel, SafeArea is inset plumbing, and dialogs/snackbars/pickers are imperative calls (showDialog, showActionSheet, showSnackbar, showDatePicker, showTimePicker) — one-liners from skal/renderer. Web escape hatches: HtmlEmbed and FlutterEmbed.