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.

Datos de origen

Repositorio
TryGhost/Ghost
Última actividad en el origen
16 de septiembre de 2026 a las 12:45
Idioma detectado de SKILL.md
inglés
Estrellas
55.512
Forks
11.988

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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.
Ver en GitHub