/// Layout
Stack
A flex container that stacks children on one axis with a token-scale gap, plus align/justify shorthands.
import { Stack, HStack, VStack } from "@protocore/pds";Basics
A vertical Stack (the default) spaces children evenly using a step on the --pds-space-* scale. gap takes a scale number, not pixels.
HStack and VStack presets
HStack and VStack are direction-locked presets. Combine them with align and justify — here a spread action row and a run of status badges.
Wrapping rows
Set wrap on a row Stack to let children flow onto multiple lines — the gap applies on both axes.
When to use it
Stack is the default one-dimensional layout tool: a row or column of items separated by a consistent gap. Use HStack/VStack when the axis is fixed and you want the intent to read at a glance. Reach for Grid instead when you need a two-dimensional layout — equal columns, an auto-fit card wall, or aligned rows *and* columns. Use a Spacer for a single one-off gap or a push, and a Divider when the separation needs a visible rule. Gaps are token steps (1–16 on the space scale), never raw pixels — this is what keeps rhythm consistent across the system.
Usage
Do
- Use gap for spacing between children instead of margins on the children themselves.
- Pick HStack/VStack when the direction is fixed — it documents intent.
- Add wrap to row Stacks of chips or tags so they reflow on narrow viewports.
Don't
- Use Stack for a two-axis card grid — that is Grid.
- Pass raw pixel gaps; gap is a step on the token scale (e.g. gap={4}).
- Nest deep Stacks to fake a grid; the columns won't align across rows.
Accessibility
- Stack is a presentational flex `<div>` with no role of its own.
- Visual order follows DOM order, so keyboard and reading order stay in sync — avoid reordering with CSS in ways that diverge from the DOM.
Mobile (React Native)
Preview. @protocore/pds-mobile ships the React Native sibling of Stack. It mirrors the web API where React Native allows; the package is a preview with no device-level QA yet, so pin it and expect small changes.
Import it from the mobile package (not @protocore/pds), inside a <PdsProvider> — there is no stylesheet, so style (a ViewStyle) replaces className and every value comes from the theme:
import { Stack, HStack, VStack } from "@protocore/pds-mobile";Parity with web. The flexbox layout primitive; the mobile package also exports the HStack / VStack presets.
gapmaps to thetheme.spacing[n]scale (web uses CSSgaptokens);align/justify/wraptake the same shorthand vocabulary.
<VStack gap={4} align="stretch">
<Heading size="h3">Region</Heading>
<Text color="secondary">eu-central-1</Text>
</VStack>Stack props
| Prop | Type | Default | Description |
|---|---|---|---|
align | enum | — | `align-items` shorthand. |
className | string | — | |
direction | enum | column | Main-axis direction. |
gap | enum | 4 | Gap between children, mapped to `--pds-space-<n>`. |
justify | enum | — | `justify-content` shorthand. |
style | CSSProperties | — | |
wrap | boolean | false | Allow children to wrap onto multiple lines. |
HStack props
| Prop | Type | Default | Description |
|---|---|---|---|
align | enum | — | `align-items` shorthand. |
className | string | — | |
gap | enum | 4 | Gap between children, mapped to `--pds-space-<n>`. |
justify | enum | — | `justify-content` shorthand. |
style | CSSProperties | — | |
wrap | boolean | false | Allow children to wrap onto multiple lines. |
VStack props
| Prop | Type | Default | Description |
|---|---|---|---|
align | enum | — | `align-items` shorthand. |
className | string | — | |
gap | enum | 4 | Gap between children, mapped to `--pds-space-<n>`. |
justify | enum | — | `justify-content` shorthand. |
style | CSSProperties | — | |
wrap | boolean | false | Allow children to wrap onto multiple lines. |