TopBar
Organismbeta@macaw-ds/ui · since 0.1.0The application's global header: brand, optional centre content and actions. Not a page title; that is PageHeader.
Import
import { TopBar } from '@macaw-ds/ui';Props
| Prop | Type | Default | Description |
|---|---|---|---|
| brand* | ReactNode | — | Product mark and name, usually a link to home. |
| children | ReactNode | — | Centre content such as a search field or an environment switcher. |
| actions | ReactNode | — | Right-aligned actions: help, notifications, theme toggle, account. Use ghost icon-only Buttons. |
Slots
Named parts you pass content into.
- brand
- children
- actions
Tokens used
Every value this component renders comes from one of these tokens.
| Token | Light | Dark |
|---|---|---|
| size.topbar semantic · dimension | 56px | 56px |
| 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) |
| z.sticky primitive · number | 100 | 100 |
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 top-bar --ejectnpx shadcn@latest add https://macaw-design-system.vercel.app/r/top-bar.jsonBundle budget: 1,000 bytes gzipped, enforced by size-limit in CI.
Manifest
registry/manifests/top-bar.json, the contract the playground, CLI, plugin and MCP server read.
{
"name": "TopBar",
"slug": "top-bar",
"package": "@macaw-ds/ui",
"status": "beta",
"since": "0.1.0",
"level": "organism",
"category": "layout",
"purpose": "The application's global header: brand, optional centre content and actions. Not a page title; that is PageHeader.",
"description": "A sticky banner landmark on surface layer-1 with a bottom border. Its height is size.topbar (56px comfortable, 48px compact), which sticky elements below it use as their offset. Content is passed through three slots.",
"exports": [
"TopBar"
],
"props": {
"brand": {
"type": "node",
"required": true,
"description": "Product mark and name, usually a link to home.",
"control": "none"
},
"children": {
"type": "node",
"required": false,
"description": "Centre content such as a search field or an environment switcher.",
"control": "none"
},
"actions": {
"type": "node",
"required": false,
"description": "Right-aligned actions: help, notifications, theme toggle, account. Use ghost icon-only Buttons.",
"control": "none"
}
},
"slots": [
"brand",
"children",
"actions"
],
"tokens": [
"size.topbar",
"color.surface.layer-1",
"color.line.default",
"z.sticky"
],
"a11y": {
"role": "banner (header element at the top level)",
"focusable": false,
"keyboard": [],
"name": "Not named; there is one banner per page.",
"notes": [
"The TopBar is not focusable itself; its brand link and action buttons are.",
"Sticky content below it offsets by top-topbar so it is never obscured (WCAG 2.2 SC 2.4.11).",
"Sticky only at 1024px and wider; below that it scrolls away so a zoomed or narrow viewport keeps its height for content."
]
},
"budget": {
"gzip": 1000
},
"rules": [
"One TopBar per page, placed in AppShell's topBar slot.",
"Actions are ghost Buttons; icon-only actions need aria-label.",
"Never put the page title in the TopBar; that belongs to PageHeader."
],
"dos": [
"Link the brand to the product home."
],
"donts": [
"Do not add a primary Button to the TopBar; primary actions belong to the page."
],
"examples": [
{
"name": "Default",
"props": {}
}
],
"registryDependencies": [],
"dependencies": [],
"related": [
"app-shell",
"side-nav",
"page-header"
]
}