Skip to content

PageContent

<PageContent> is the only scrollable region on a routed page. Everything else (PageHeader, ActionBar) sits outside the scroll. Use narrow for forms and settings; spaced to add space-y-6 between major sections.

import from "@na/ui/components/PageContent" ▶ Open in Storybook packages/ui/src/components/PageContent.tsx

When to use

Don’t use PageContent for: focus / wizard layouts (FocusLayout owns its own scroll), modal bodies (Dialog / Sheet manage their own scroll).

Default

Settings

Profile
How you appear to teammates.
<>
<PageHeader title="Settings" />
<PageContent>
<Card></Card>
<Card></Card>
</PageContent>
</>

Narrow (form-page width)

narrow constrains the body to max-w-2xl and centers it — the ergonomic width for read-and-edit forms.

Edit profile

Profile
Constrained to max-w-2xl, centered.
<PageContent narrow>
<Card>…form fields…</Card>
</PageContent>

API

Prop Type Default Description
children * ReactNode Page body.
spaced boolean false Adds space-y-6 between top-level children.
narrow boolean false Constrains to max-w-2xl, centered. For forms / settings.
className string Forwarded.

Design guidelines

✓ Do

  • Use narrow for any read-and-edit page — settings, profile, agent-edit. The width matches the spec.
  • Use spaced when the body is a vertical stack of ContentSections — replaces hand-rolled space-y-6.
  • Place exactly ONE PageContent per route. Two scroll regions = the user gets lost.

✗ Don't

  • Wrap the page in a custom div with overflow-auto. PageContent is the canonical scroller.
  • Use narrow for list / table pages. Tables want full width.
  • Add custom horizontal scroll inside PageContent. Use ScrollArea on a sized child if needed.

Accessibility

  • Plain <div> semantics. Pair with <main> in the surrounding layout for landmark navigation.
  • Browser scroll = native scroll = native keyboard support out of the box.

▶ Open PageContent stories in Storybook