Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Layout

Perry provides layout containers that arrange child widgets using the platform’s native layout system.

VStack

Arranges children vertically (top to bottom).

import { VStack, Text, Button } from "perry/ui";

VStack([
  Text("First"),
  Text("Second"),
  Text("Third"),
]);

Methods:

  • setPadding(padding: number) — Set padding around all edges
  • setSpacing(spacing: number) — Set spacing between children

HStack

Arranges children horizontally (left to right).

import { HStack, Text, Button } from "perry/ui";

HStack([
  Button("Cancel", () => {}),
  Spacer(),
  Button("OK", () => {}),
]);

ZStack

Layers children on top of each other (back to front).

import { ZStack, Text, Image } from "perry/ui";

ZStack([
  Image("background.png"),
  Text("Overlay text"),
]);

ScrollView

A scrollable container.

import { ScrollView, VStack, Text } from "perry/ui";

ScrollView(
  VStack(
    Array.from({ length: 100 }, (_, i) => Text(`Row ${i}`))
  )
);

Methods:

  • setRefreshControl(callback: () => void) — Add pull-to-refresh (calls callback on pull)
  • endRefreshing() — Stop the refresh indicator

LazyVStack

A vertically scrolling list that lazily renders items. More efficient than ScrollView + VStack for large lists.

import { LazyVStack, Text } from "perry/ui";

LazyVStack(1000, (index) => {
  return Text(`Row ${index}`);
});

A navigation container that supports push/pop navigation.

import { NavigationStack, Text, Button } from "perry/ui";

NavigationStack([
  Text("Home Screen"),
  Button("Go to Details", () => {
    // Push a new view
  }),
]);

Spacer

A flexible space that expands to fill available room.

import { HStack, Text, Spacer } from "perry/ui";

HStack([
  Text("Left"),
  Spacer(),
  Text("Right"),
]);

Use Spacer() inside HStack or VStack to push widgets apart.

Divider

A visual separator line.

import { VStack, Text, Divider } from "perry/ui";

VStack([
  Text("Section 1"),
  Divider(),
  Text("Section 2"),
]);

Nesting Layouts

Layouts can be nested freely:

import { App, VStack, HStack, Text, Button, Spacer, Divider } from "perry/ui";

App("Layout Example", () =>
  VStack([
    // Header
    HStack([
      Text("My App"),
      Spacer(),
      Button("Settings", () => {}),
    ]),
    Divider(),
    // Content
    VStack([
      Text("Welcome!"),
      HStack([
        Button("Action 1", () => {}),
        Button("Action 2", () => {}),
      ]),
    ]),
    Spacer(),
    // Footer
    Text("v1.0.0"),
  ])
);

Child Management

Containers support dynamic child management:

const stack = VStack([]);
// Add children dynamically
stack.addChild(Text("New child"));
stack.addChildAt(0, Text("Prepended"));
stack.removeChild(someWidget);
stack.reorderChild(widget, 2);
stack.clearChildren();

Methods:

  • addChild(widget) — Append a child widget
  • addChildAt(index, widget) — Insert a child at a specific position
  • removeChild(widget) — Remove a child widget
  • reorderChild(widget, newIndex) — Move a child to a new position
  • clearChildren() — Remove all children

Next Steps