Skip to content

Layout and views

PAM Native layout is reconciled by Rust and committed as native platform frames. View, Column, and Row do not introduce a browser layout engine; they become retained native containers.

use Pam\Native\SafeAreaMode;
use Pam\Native\Style;
use Pam\Native\UI\Column;
use Pam\Native\UI\Grid;
use Pam\Native\UI\Row;
use Pam\Native\UI\SafeAreaView;
use Pam\Native\UI\Screen;
use Pam\Native\UI\Spacer;
use Pam\Native\UI\Text;
use Pam\Native\UI\View;
$screen = Screen::make(
SafeAreaView::make(
Column::make(
Text::make('Dashboard'),
Row::make(
View::make(Text::make('Revenue')),
Spacer::make(12),
View::make(Text::make('Orders')),
),
Grid::make(
View::make(Text::make('Card A')),
View::make(Text::make('Card B')),
View::make(Text::make('Card C')),
)->columns(12)->gutter(16),
)->style(new Style(flexGrow: 1, padding: 24, gap: 16)),
)->mode(SafeAreaMode::Padding),
);
<Screen>
<SafeAreaView class="flex-1">
<Column class="flex-1 p-6 gap-4">
<Text fontSize="28">Dashboard</Text>
<Row class="gap-3">
<View class="flex-1 card"><Text>Revenue</Text></View>
<View class="flex-1 card"><Text>Orders</Text></View>
</Row>
<Grid columns="12" gutterX="16" gutterY="16">
<Column span="12" spanSm="6" spanMd="4">...</Column>
</Grid>
</Column>
</SafeAreaView>
</Screen>
  • Screen is the root screen surface.
  • View is the neutral native container.
  • Column and Row preset vertical or horizontal flex direction.
  • Grid provides responsive column spans, offsets, ordering and gutters.
  • SafeAreaView applies selected platform insets as padding or margin.
  • Spacer is an explicit fixed gap; prefer container gap for repeated sibling spacing.

PAM Native 0.5.63 implements flex-wrap inside the retained Rust layout engine. Wrapped rows and columns calculate their line breaks, gap, justification, alignment, and intrinsic cross-axis size before platform views receive final frames. PHP does not receive a callback per item or per frame.

<Row class="chip-list">
<View p-for="$chip in $chips" class="chip">
<Text>{{ $chip }}</Text>
</View>
</Row>
<style scoped>
.chip-list {
flex-wrap: wrap;
gap: 8px;
}
</style>

Use flex-wrap: nowrap to make the no-wrap contract explicit. Row wraps horizontally and Column wraps vertically; content-sized containers include all generated lines in their intrinsic cross-axis extent.

Combine border-radius and overflow: hidden when child content must follow the container shape:

<Pressable class="avatar">
<Image class="avatar-image" :source="$avatar" />
</Pressable>
<style scoped>
.avatar,
.avatar-image {
width: 38px;
height: 38px;
}
.avatar {
overflow: hidden;
border-radius: 19px;
}
</style>

This is a native compositor clip on Android and iOS. The clip path is updated only when the bounds or radii change, and removing overflow: hidden restores visible overflow immediately.

For breakpoints, spans, VirtualGrid, foldable posture and responsive examples, continue to Responsive layout.