apps/shade/src/docs/patterns-guide.mdx
import { Meta } from '@storybook/addon-docs/blocks';
<Meta title="Patterns / Patterns Guide" /> <div className="sb-doc">| Do | Don't |
|---|---|
Expose 3–6 named subcomponents (.Title, .Actions, .Body) | Take a prop bag (title, onAdd, columns, emptyText …) |
| Compose components, primitives, recipes | Fetch data, own routing, read app context |
Carry generic names (PageHeader, KpiCard) | Carry surface-specific names (MembersFilterBar) |
| Stay stable across consumers | Add a prop every time a new consumer needs something |
If you find useQuery inside a pattern, the boundary is wrong — bring-your-own state.
Promotion rules and the full decision flow: Layers. Agent rules: apps/shade/AGENTS.md.
import {PageHeader, ListPage} from '@tryghost/shade/patterns';
import {Button, Table} from '@tryghost/shade/components';
<ListPage>
<PageHeader>
<PageHeader.Left>
<PageHeader.Title>Members<PageHeader.Count>{count}</PageHeader.Count></PageHeader.Title>
</PageHeader.Left>
<PageHeader.Actions>
<PageHeader.ActionGroup>
<Button>Add member</Button>
</PageHeader.ActionGroup>
</PageHeader.Actions>
</PageHeader>
<ListPage.Body>
<Table>...</Table>
</ListPage.Body>
</ListPage>
Browse the sidebar for the live list of patterns.
</div>