Skip to content
CodeAtlas UI

Layout

PageShell

The standard page container with a title, a description and an actions slot.

<script>
  import { PageShell, Button } from "@codeatlasdev/ui";
</script>

<PageShell title="Dashboard" description="Overview of this month">
  {#snippet actions()}<Button size="sm">New report</Button>{/snippet}
  <!-- page content -->
</PageShell>

Below 900px the header stacks: the description leads and actions wrap onto their own row. Labeled buttons share that row full-width (large tap targets); icon-only controls (IconButton, ThemeToggle) keep their natural size and stay at the end of the row.

The shell renders title as the page <h1>; below 900px inside an AppShellLayout it is hidden visually because the mobile header already shows it. Inside a PageShell, EmptyState titles default to <h2> (under the page <h1>). Pass headingLevel to EmptyState or Card to pick the level explicitly.

Dashboard page

KPI cards and a content card inside a PageShell.

Dashboard

Overview of this month

Revenue

$118k
↑+23.4%

Users

24.8k
↑+8.1%

Growth

34%
↑+5.6%

Uptime

99.9%
↑+0.1%

Chart or data table goes here

Code
svelte
<script lang="ts">
  import { PageShell, KpiCard, KpiGrid, Card, Stack, Button } from '@codeatlasdev/ui';
  import { TrendingUp, Users, DollarSign, Activity } from '@lucide/svelte';
</script>

<Card material="glass" flush full>
  <PageShell title="Dashboard" description="Overview of this month">
    {#snippet actions()}<Button variant="filled" size="sm">New report</Button>{/snippet}

    <Stack gap="6">
      <KpiGrid>
        <KpiCard title="Revenue" value="$118k" trend={23.4} icon={DollarSign} />
        <KpiCard title="Users" value="24.8k" trend={8.1} icon={Users} />
        <KpiCard title="Growth" value="34%" trend={5.6} icon={TrendingUp} />
        <KpiCard title="Uptime" value="99.9%" trend={0.1} icon={Activity} />
      </KpiGrid>

      <Card material="glass" full>
        <p class="placeholder">Chart or data table goes here</p>
      </Card>
    </Stack>
  </PageShell>
</Card>

<style>
  .placeholder {
    margin: 0;
    height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ca-text-hint);
    font-size: var(--ca-font-size-body2);
  }
</style>

Props

PropTypeDefaultDescription
titlestring–Page title.
descriptionstring–Supporting text under the title.
gapnumberundefinedVertical gap between the header and the content, in px. Omit for `--ca-space-7` (28px at the default density).
maxWidthstringundefinedMaximum width of the content column, any CSS length. Omit for 80rem (1280px at the default 4px spacing unit).
actionsSnippet–Right side of the page header.
childrenSnippet–Page content.
classstring''Extra class names.