# Patterns

> Application recipes built from existing components — filter bars, inline calls to action, and an index of every recipe on the component pages.

URL: https://apogee.avaui.dev/docs/patterns
Last updated: 2026-10-15

Application recipes built from existing components — filter bars, inline calls to action, and an index of every recipe on the component pages.

Last updated October 15, 2026

Patterns are compositions, not components: copy the markup and change it. Each one uses only components you already have.

## Recipe index

| Recipe | Where |
| --- | --- |
| Page header (breadcrumbs, back link, actions, search) | [SectionHeader](https://apogee.avaui.dev/docs/section-header#examples) |
| Card header with actions and a menu | [Card](https://apogee.avaui.dev/docs/card#examples) |
| Table card (title, table, pagination footer) | [Table](https://apogee.avaui.dev/docs/table#examples) |
| Metric card | [Stat](https://apogee.avaui.dev/docs/stat#variants) |
| Dialog bodies (confirm, form, media, drawer) | [Dialog](https://apogee.avaui.dev/docs/dialog#examples) |
| Activity feed | [Timeline](https://apogee.avaui.dev/docs/timeline#examples) |
| Conversation and composers | [Message](https://apogee.avaui.dev/docs/message#examples) |
| Sidebar groups, headings, featured card | [Sidebar](https://apogee.avaui.dev/docs/sidebar#examples) |
| Table footer with page size | [Pagination](https://apogee.avaui.dev/docs/pagination#examples) |
| Date inputs | [Input](https://apogee.avaui.dev/docs/input#date-inputs) |
| Upload list | [FileUpload](https://apogee.avaui.dev/docs/file-upload#upload-list) |
| Tabbed install commands | [Code](https://apogee.avaui.dev/docs/code#examples) |
| Notification count on an icon button | [Button](https://apogee.avaui.dev/docs/button#notification-count) |
| Account switcher crumb | [Breadcrumbs](https://apogee.avaui.dev/docs/breadcrumbs#account-switcher) |

## Filter bar

Search, a period switch and a Filters popover holding a GET form: the filters submit with zero JS and the server renders the filtered page. Clear is a link to the unfiltered URL, not a reset button: a reset would restore the values the server just rendered. The badge on the trigger counts the applied filters.

```astro
<div class="flex flex-wrap items-end gap-3">
<div class="min-w-48 flex-1"><Input aria-label="Search projects" placeholder="Search"><Search slot="start" /></Input></div>
<SegmentedControl aria-label="Period" options={['7d', '30d', '12m']} value="30d" />
<Popover id="filters" width="20rem" placement="bottom-end">
  <Button slot="anchor" popovertarget="filters" variant="outline" color="neutral">
    <Filter slot="start" />Filters<Badge slot="end" size="small" rounded>2</Badge>
  </Button>
  <form method="get" class="flex flex-col gap-3">
    <Select label="Status" name="status">…</Select>
    <Select label="Owner" name="owner">…</Select>
    <div class="flex justify-end gap-2">
      <Button href="?" variant="ghost" color="neutral" size="small">Clear</Button>
      <Button type="submit" size="small">Apply</Button>
    </div>
  </form>
</Popover>
</div>
```

## Inline calls to action

Primary action on top on phones (`flex-col-reverse`), side by side from `sm`; a media card; an email capture whose button lines up with the field; a checklist.

```astro
<Card>
<Heading as="h3" size="h4">Upgrade to Pro</Heading>
<Text size="small" color="neutral-faded">Unlimited projects and priority support.</Text>
<div class="mt-4 flex flex-col-reverse gap-3 sm:flex-row sm:justify-end">
  <Button variant="outline" color="neutral">Compare plans</Button>
  <Button>Upgrade</Button>
</div>
</Card>
<Card mediaPosition="start">
<img slot="media" src="…" alt="" />
<Heading as="h3" size="h4">Invite your team</Heading>
<Text size="small" color="neutral-faded">Projects move faster with more hands.</Text>
<ul class="mt-3 flex flex-col gap-1.5 text-sm">
  <li class="flex items-center gap-2"><CircleCheck class="size-4 text-positive" aria-hidden="true" />Shared boards</li>
  …
</ul>
<Button class="mt-4" size="small">Send invites</Button>
</Card>
<Card>
<Heading as="h3" size="h4">Get the changelog</Heading>
<form class="mt-3 flex flex-col gap-3 sm:flex-row sm:items-end">
  <div class="flex-1"><Input label="Email" type="email" placeholder="you@example.com" /></div>
  <Button type="submit">Subscribe</Button>
</form>
</Card>
```

## Related

[

PopoverRich content on click, built on the native Popover API — top layer and light dismiss for free, anchored with CSS anchor positioning.

](https://apogee.avaui.dev/docs/popover)[

CardA surface container for grouped content. Compose freely inside — heading, text, button, an optional media block.

](https://apogee.avaui.dev/docs/card)[

SectionHeaderEyebrow, 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.

](https://apogee.avaui.dev/docs/section-header)[

TableA styled, horizontally-scrollable table. Write plain thead/tbody markup — Table only styles it.

](https://apogee.avaui.dev/docs/table)
