Skip to main content

shade-page-templates

Pick the right Shade page template (ListPage, PageHeader) for a new admin page instead of inventing chrome. Trigger when creating new admin pages or routes in apps/admin or apps/activitypub.

Quellinformationen

Repository
TryGhost/Ghost
Letzte Quellaktivität
16. September 2026 um 12:45
Erkannte Sprache von SKILL.md
Englisch
Sterne
55.544
Forks
11.995

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
Shade page templates
description
Pick the right Shade page template (ListPage, PageHeader) for a new admin page instead of inventing chrome. Trigger when creating new admin pages or routes in apps/admin or apps/activitypub.
autoTrigger
[{"fileEdit":"apps/{admin,activitypub}/src/**/*.tsx"}]
# Shade — page templates When building a new admin page, the first question is **what page type is this?** — then reach for the matching pattern instead of inventing chrome. ## Page type taxonomy ### List page Browsing or scanning a collection of items. - **Live examples**: Members, Tags, Comments, Automations, ActivityPub. - **Chrome shape**: `PageHeader` (title + count + search/filter/actions) → table or list → empty state → pagination. - **Pattern**: `ListPage` (composes `PageHeader`). Heavy filter UI uses `Filters`. ### Detail page Working with a single item — viewing, editing, or both. - **Live examples**: Post editor. - **Chrome shape**: `PageHeader` with breadcrumb + title + meta, a primary action area, and a content area dedicated to the item. - **Pattern**: not built this milestone. Use `PageHeader` directly and lay out the body yourself. ### Settings Out of scope for the current page-template milestone. Don't force a settings page into `ListPage` or `PageHeader`. ### Workflow / multi-step flows No standard yet — too few examples. Don't standardise prematurely. When constructing or changing header controls, follow [Shade page header](../shade-page-header/SKILL.md) and its linked Storybook contract. ## Canonical list page skeleton ```tsx import {ListPage} from '@tryghost/shade/page-templates'; import {PageHeader, ViewBar, FilterBar} from '@tryghost/shade/patterns'; import {EmptyIndicator, Table} from '@tryghost/shade/components'; import {LucideIcon} from '@tryghost/shade/utils'; <ListPage> <ListPage.Header> {/* sticky={false} — ListPage.Header owns stickiness and blur */} <PageHeader sticky={false} blurredBackground={false}> <PageHeader.Left> <PageHeader.Title> Members<PageHeader.Count>{count}</PageHeader.Count> </PageHeader.Title> </PageHeader.Left> <PageHeader.Actions> <PageHeader.ActionGroup> <PageHeader.ActionGroup.Primary> <PageHeader.Action label="Add member"><LucideIcon.Plus />Add member</PageHeader.Action> </PageHeader.ActionGroup.Primary> </PageHeader.ActionGroup> </PageHeader.Actions> </PageHeader> <ViewBar>{/* optional */}</ViewBar> <FilterBar>{/* optional — auto-collapses when empty */}</FilterBar> </ListPage.Header> <ListPage.Body> {items.length === 0 ? <EmptyIndicator title='No members yet' /> : <Table>...</Table>} </ListPage.Body> </ListPage> ``` ## Gotchas - **`sticky={false}` on `PageHeader` inside `ListPage.Header`.** The wrapper handles stickiness and blur — leaving `PageHeader` sticky stacks two sticky containers and breaks scroll. - **Don't put `useQuery` inside a pattern.** State lives in the consumer. Patterns are layout/composition contracts. - **`PageHeader` is slot-based** (`.Left`, `.Title`, `.Count`, `.Description`, `.Meta`, `.Actions`, `.ActionGroup`, `.Breadcrumb`) — don't pass a prop bag. - **`FilterBar` auto-collapses when empty** — render it unconditionally; no need to conditionally mount. ## Subcomponent inventory (PageHeader) - `PageHeader.Left` — title block container - `PageHeader.Breadcrumb` — small muted breadcrumb above the title - `PageHeader.Title` — H1, accepts inline `Count` - `PageHeader.Count` — inline secondary count next to the title - `PageHeader.Description` — paragraph below the title - `PageHeader.Meta` — small muted metadata line below - `PageHeader.Actions` — right-side action area - `PageHeader.ActionGroup` — grouping for buttons ## When ListPage doesn't fit - The page is a **Detail page** → use `PageHeader` directly; build the body from primitives + components. - The page is **Settings** → out of scope; use whatever the surrounding settings shell uses. - The page is a **multi-step flow** → no pattern yet; assemble from primitives. If you're tempted to force a non-list shape into `ListPage`, stop and check whether you're actually building one of those three other shapes. ## Source of truth Storybook → Page Templates / Page Types and the `ListPage` and `PageHeader` stories.
Auf GitHub ansehen