Patterns

Page header

The band across the top of every app page — the app-side cousin of SectionHead. It answers "what is this, and what can you do with it?" One component, two jobs: it heads a collection (eyebrow · title · count + a primary action) and it is the identity hero of a record (eyebrow · title · status · a metadata row + record actions).

Collection header

The top of a list view: what you're looking at, how much of it there is, and the one thing you came here to do — create.

Record identity hero

The top of a detail view: who or what this record is, its live status, and the facts you check first — with the record's actions on the right.

Slots

Only the title is required — use the slots your page needs and skip the rest.

eyebrow
A gold uppercase kicker — the entity type or section.
title
The name or collection title. Required. Renders the page h1 (override with titleAs).
count
A muted, tabular number beside the title — the size of a collection.
status
A slot beside the title for a <Badge> — a record's live state.
meta
A muted row of facts below, auto-separated by middots. Pass spans.
actions
Right-aligned Buttons — the primary action (lists) or record actions (detail).

Materiality

Typographic, not a surface — a header is neither a card nor a control, so it gets no border or fill. The engraved heading belongs to the proposed system; here the title is simply the display face: bold slab type, flat on the page. The count is mono and tabular; the meta row is muted with middot separators.

frameless
No frame or fill. Set divider for a single hairline below — for a header that pins above scrolling content.
size
size="lg" (default) is the page h1 scale; md downsizes the title for a nested panel. The semantic level is separate — set titleAs to keep the heading outline correct.
count
Mono (--font-data), tabular, muted — it reads as a measure, not a heading.

Props

title / eyebrow / description
The required title and two optional text slots above and below it.
count / status
A collection count, or a record status node — beside the title.
meta?: ReactNode
The muted fact row below the title.
actions?: ReactNode
Right-aligned actions.
size / titleAs / divider
size 'lg' | 'md', titleAs the heading element (default h1), divider for a bottom hairline.

Usage

Collection headertsx
import { PageHeader, Button } from '@halo-compliance/ui'
import { Plus } from 'lucide-react'

<PageHeader
  eyebrow="Compliance"
  title="Officers"
  count={142}
  description="Loan officers across every branch."
  actions={
    <Button variant="primary" icon={<Plus />}>New officer</Button>
  }
/>
Record identity herotsx
import { PageHeader, Badge, Button } from '@halo-compliance/ui'
import { SquarePen } from 'lucide-react'

<PageHeader
  eyebrow="Loan officer"
  title="Tom Becker"
  status={<Badge tone="affirm" dot>Active</Badge>}
  meta={
    <>
      <span>Created by Dana Whitfield</span>
      <span>NMLS 1234567</span>
    </>
  }
  actions={<Button variant="secondary" icon={<SquarePen />}>Edit</Button>}
/>

When to use

  • The top of every list and detail view. It is the orientation band of a Collection and the identity region of a Record.
  • One per surface. It carries the page's h1; nested panels use a downsized header (size md) or plain headings.
  • Doc pages use SectionHead instead. PageHeader is the app analog — count, status, meta and actions are app concerns.

Anti-patterns

  • A toolbar in the header. Search and filters belong in the collection toolbar below, not in the actions slot — keep it to the primary action.
  • Framing it. A header is not a surface; wrapping it in a Card reads as a panel and competes with the content.
  • A wall of actions. One primary action, the rest behind a ⋯ menu — the header is for orientation, not a control panel.
  • /text-groups — the doc-page sibling; same three-part top composition.
  • /collection — the list view this heads.
  • /record — the detail view whose Identity region this is.
  • /badge — the status node in the hero.