Eyebrow, heading and description at the top of a section or an app page, with actions, a divider and the level, alignment and colours every section shares.

Last updated

Features

Everything a page needs

Composable sections built from the same tokens as every component.

Show code
<SectionHeader eyebrow="Features" heading="Everything a page needs" description="Composable sections built from the same tokens as every component." />

Add

npx @ava-ui/apogee add section-header

Depends on Eyebrow, Heading, Text. Slot actions takes buttons.

Usage

---
import SectionHeader from '@/components/apogee/SectionHeader/SectionHeader.astro'
---
<section aria-labelledby="pricing-heading">
  <SectionHeader id="pricing-heading" eyebrow="Pricing" heading="Simple plans" align="center" />
</section>

API

@composable. Any other native attribute passes through to the wrapper.

Prop Type Default Description
eyebrow string — Small label above the heading.
heading string — Required.
description string — One or two sentences under the heading.
headingLevel 1 | 2 | 3 | 4 2 Semantic level of the heading element.
align 'start' | 'center' 'start' Alignment; center also centres the block.
background 'page' | 'neutral-faded' | 'primary-faded' | 'primary' | 'inverted' 'page' The surrounding section’s background, so eyebrow and description colours stay readable.
size 'small' | 'medium' | 'large' 'medium' small is the in-app size (h4 visual, small text, tight gap); large uses the display size (Hero).
divider boolean false A rule under the header.
id string — Id on the heading for aria-labelledby.
class string — Extra classes on the wrapper.

Variants

Eyebrow

Start aligned

The default. Text wraps at a comfortable measure.

Eyebrow

Centred

Centred text and a centred block.

Eyebrow

Large, level one

Hero size.

Show code
<SectionHeader heading="Start aligned" description="…" />
<SectionHeader heading="Centred" description="…" align="center" />
<SectionHeader heading="Large" size="large" headingLevel={1} description="…" />

The in-app size, with actions and a divider. Actions sit beside the text from md and under it on phones:

Team members

Manage who has access to this project and what they can do.

Show code
<SectionHeader size="small" heading="Team members" description="Manage who has access." divider>
<Button slot="actions" size="small" variant="outline" color="neutral">Export</Button>
<Button slot="actions" size="small">Invite</Button>
</SectionHeader>

Every size:

Small, for app pages and card tops

An h4 visual with small text.

Medium, the default

Medium text at a prose measure.

Large, for heroes

Display heading and large text.

Show code
<SectionHeader size="small" heading="Small" description="…" />
<SectionHeader size="medium" heading="Medium" description="…" />
<SectionHeader size="large" heading="Large" description="…" />

Centred with actions:

Ready to start?

Create a project in under a minute.

Show code
<SectionHeader align="center" heading="Ready to start?" description="…">
<Button slot="actions">Get started</Button>
</SectionHeader>

On each section background:

Neutral faded

Readable on a tint

Eyebrow stays primary.

Primary faded

Readable on the brand tint

Eyebrow stays primary.

Primary

On the brand fill

Everything inherits the on-colour.

Inverted

On the inverted surface

Everything inherits the on-colour.

Show code
<Section background="primary"><SectionHeader background="primary" … /></Section>

States

Static: no interactive states. Buttons in actions keep their own states.

Examples

A page header: breadcrumbs on desktop, a back link on phones, the title with actions, and a search box with a shortcut hint.

Back

Spring launch

Updated two hours ago by Ana.

⌘K
Show code
<div class="flex flex-col gap-5">
<Breadcrumbs class="max-lg:hidden" items={[{ label: 'Projects', href: '#' }, { label: 'Spring launch' }]} />
<Button variant="link" color="neutral" size="small" href="#" class="lg:hidden"><ArrowLeft slot="start" />Back</Button>
<SectionHeader headingLevel={1} size="small" heading="Spring launch" description="Updated two hours ago by Ana." divider>
  <Input slot="actions" size="small" placeholder="Search" aria-label="Search"><Search slot="start" /><Kbd slot="end">⌘K</Kbd></Input>
  <Button slot="actions" size="small">New task</Button>
</SectionHeader>
</div>

Inside a card, the small size is the card title row:

Recent activity

The last seven days.

List goes here.

Show code
<Card>
<SectionHeader slot="header" size="small" heading="Recent activity" description="The last seven days." class="flex-1" />
<Button slot="header" size="small" variant="link">View all</Button>
…
</Card>

Accessibility

  • The heading is a real h1–h4; keep the page’s heading order and point the section’s aria-labelledby at id.
  • Colours per background keep AA in both themes; solid fills inherit the on-colour.

Tokens

Token Used for
--foreground-primary Eyebrow on page and tinted backgrounds
--foreground-neutral-faded Description on page and tinted backgrounds
--on-primary, --on-inverted Everything on the solid fills (inherited)
--border-neutral The divider rule

Do / Don’t

  • Do use one per section, at the top, with the heading level that fits the page outline.
  • Do keep actions to one or two buttons.
  • Don’t stack two SectionHeaders with nothing between them; merge them or add the content.

Content

  • Eyebrow: one or two words naming the area (“Pricing”, “Changelog”).
  • Title: what the section gives the reader, in sentence case.
  • Description: one sentence. Cut it if it repeats the title.