PageHeader
Organismbeta@macaw-ds/ui · since 0.1.0The page's own header under the TopBar: title, description, meta, actions and section tabs. Not the global header; that is TopBar.
Import
import { PageHeader } from '@macaw-ds/ui';Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title* | string | Invoices | The page title. |
| description | string | Every invoice across your customers, newest first. | One line under the title. |
| headingLevel | "h1" | "h2" | h1 | Heading element for the title. h1 unless the page already has one. Accessibility: Each page has exactly one h1; PageHeader's title is usually it. |
| meta | ReactNode | — | Small context next to the title: a status Badge, an ID. |
| actions | ReactNode | — | Page actions: one primary Button and its secondaries. |
| tabs | ReactNode | — | A TabNav for the page's sections. |
Slots
Named parts you pass content into.
- title
- description
- meta
- actions
- tabs
Tokens used
Every value this component renders comes from one of these tokens.
| Token | Light | Dark |
|---|---|---|
| color.surface.layer-1 semantic · color | oklch(1 0 0) | oklch(0.15 0.012 250) |
| color.line.default semantic · color | oklch(0.925 0.005 250) | oklch(0.29 0.012 250) |
| layout.margin semantic · dimension | 32px | 32px |
| layout.stack-lg semantic · dimension | 24px | 24px |
| layout.stack-sm semantic · dimension | 8px | 8px |
| size.topbar semantic · dimension | 56px | 56px |
| z.sticky primitive · number | 100 | 100 |
| text.size.heading-lg semantic · dimension | 1.25rem | 1.25rem |
Eject
Ejecting copies the source into your repo and records it in .macaw/ejected.json, so the fork stays visible. The same file is served as a shadcn-compatible registry item.
npx @macaw-ds/cli add page-header --ejectnpx shadcn@latest add https://macaw-design-system.vercel.app/r/page-header.jsonBundle budget: 1,500 bytes gzipped, enforced by size-limit in CI.
Manifest
registry/manifests/page-header.json, the contract the playground, CLI, plugin and MCP server read.
{
"name": "PageHeader",
"slug": "page-header",
"package": "@macaw-ds/ui",
"status": "beta",
"since": "0.1.0",
"level": "organism",
"category": "layout",
"purpose": "The page's own header under the TopBar: title, description, meta, actions and section tabs. Not the global header; that is TopBar.",
"description": "A compact secondary header on surface layer-1, full width at the top of the main area. The title is the page's h1. Actions sit on the right; the tabs slot takes a TabNav, which sticks below the TopBar for the whole page. Spacing follows the density mode.",
"exports": [
"PageHeader"
],
"props": {
"title": {
"type": "string",
"default": "Invoices",
"required": true,
"description": "The page title."
},
"description": {
"type": "string",
"default": "Every invoice across your customers, newest first.",
"required": false,
"description": "One line under the title."
},
"headingLevel": {
"type": "enum",
"values": [
"h1",
"h2"
],
"default": "h1",
"required": false,
"description": "Heading element for the title. h1 unless the page already has one.",
"a11y": "Each page has exactly one h1; PageHeader's title is usually it."
},
"meta": {
"type": "node",
"required": false,
"description": "Small context next to the title: a status Badge, an ID.",
"control": "none"
},
"actions": {
"type": "node",
"required": false,
"description": "Page actions: one primary Button and its secondaries.",
"control": "none"
},
"tabs": {
"type": "node",
"required": false,
"description": "A TabNav for the page's sections.",
"control": "none"
}
},
"slots": [
"title",
"description",
"meta",
"actions",
"tabs"
],
"tokens": [
"color.surface.layer-1",
"color.line.default",
"layout.margin",
"layout.stack-lg",
"layout.stack-sm",
"size.topbar",
"z.sticky",
"text.size.heading-lg"
],
"a11y": {
"role": "none (a plain region at the top of main; it never becomes a second banner landmark)",
"focusable": false,
"keyboard": [],
"name": "The title is the page's heading; the tabs landmark is named by TabNav's aria-label.",
"notes": [
"The title renders as h1 by default so every page has exactly one top-level heading.",
"The sticky tab row sits below the TopBar (top-topbar), so focused tabs are never hidden behind it.",
"Actions wrap under the title on narrow viewports; the tab row is sticky only at 1024px and wider."
]
},
"budget": {
"gzip": 1500
},
"rules": [
"One PageHeader per page, first inside main.",
"The title is the page's only h1.",
"At most one primary Button in actions; it is the page's primary action.",
"Use the tabs slot only with TabNav, and only when each section has its own URL."
],
"dos": [
"Put the record status in meta as a Badge: Invoices / INV-0041 [Overdue]."
],
"donts": [
"Do not stack two PageHeaders.",
"Do not put filters in the PageHeader; they belong to the content area."
],
"examples": [
{
"name": "Default",
"props": {
"title": "Invoices",
"description": "Every invoice across your customers, newest first."
}
},
{
"name": "Record",
"description": "Meta, actions and tabs.",
"props": {
"title": "INV-0041"
}
}
],
"registryDependencies": [
"text"
],
"dependencies": [],
"related": [
"tab-nav",
"top-bar",
"app-shell",
"button",
"badge"
]
}