PageHeader

The top of a page: breadcrumbs, title, subtitle, actions and tabs.

Overview

The first block of every page; it puts the page's first content at the same y on every page.

Slots

Do

Build 412

main · 3 changed

import { Breadcrumbs, Button, NavTabs, PageHeader } from "@hackcove/ui";

<PageHeader
  breadcrumbs={
    <Breadcrumbs
      crumbs={[
        { label: "Hack Cove", href: "#project" },
        { label: "Builds", href: "#builds" },
        "Build 412",
      ]}
    />
  }
  title="Build 412"
  subtitle="main · 3 changed"
  actions={
    <>
      <Button variant="outline">Reject</Button>
      <Button>Accept all</Button>
    </>
  }
  tabs={
    <NavTabs
      label="Build"
      items={[
        { label: "Changed", href: "#changed", active: true },
        { label: "New", href: "#new" },
      ]}
    />
  }
/>
Breadcrumbs, title, subtitle, actions and tabs are slots of one PageHeader; each is optional.
Don't

Build 412

main · 3 changed

import { Button, Cluster, PageHeading, Stack, Subtitle } from "@hackcove/ui";

<Cluster justify="between">
  <Stack gap="xs">
    <PageHeading>Build 412</PageHeading>
    <Subtitle>main · 3 changed</Subtitle>
  </Stack>
  <Button>Accept all</Button>
</Cluster>
A title row built from a heading, a subtitle and a Cluster is a second header that drifts from every other page's. Use PageHeader.

In stack

Do

Members

Who can see this project.

Active

3 members
import { Body, Card, PageHeader, Stack } from "@hackcove/ui";

<Stack gap="lg">
  <PageHeader title="Members" subtitle="Who can see this project." />
  <Card title="Active">
    <Body>3 members</Body>
  </Card>
</Stack>
As a direct child of a Stack, the header drops its own bottom margin, so the Stack's gap is the only space under it.
Don't

Members

Who can see this project.

Active

3 members
import { Body, Card, PageHeader, Stack } from "@hackcove/ui";

<Stack gap="lg">
  <div>
    <PageHeader title="Members" subtitle="Who can see this project." />
  </div>
  <Card title="Active">
    <Body>3 members</Body>
  </Card>
</Stack>
Wrapped in a div, the header is no longer a direct child of the Stack, keeps its margin and doubles the space.

Usage

  • Pass title, and subtitle, breadcrumbs, actions and tabs as needed; never build a title row from a heading and a Cluster.
  • actions sit beside the title from sm up and under it on a phone: a Button or two, one primary.
  • breadcrumbs take a Breadcrumbs; tabs take a NavTabs (links to pages).
  • Its fixed bottom margin gives every page the same first-block position. As a direct child of a Stack it has none and the Stack's gap is the only space, so do not wrap it in another element.
  • One PageHeader per page: it holds the page's <h1>.

Accessibility

  • The title is the page's <h1>; the subtitle is a paragraph.
  • Breadcrumbs is a <nav> named Breadcrumb, with the last crumb marked aria-current="page". Give NavTabs a label.
  • On a narrow screen the actions move below the title.

API

PageHeader

The top of a page: breadcrumbs, title, subtitle, actions and tabs. Its fixed bottom margin puts every page's first block at the same y; as a direct child of a Stack it has none, so the Stack's gap is the only space under it.


actions

Right of the title on sm and up, below it on a phone.

Type
ReactNode

breadcrumbs

A Breadcrumbs above the title.

Type
ReactNode

subtitle
Type
ReactNode

tabs

A NavTabs (or similar) under the title.

Type
ReactNode

title required
Type
ReactNode