Skip to main content

shade-use-primitives

Replace bare divs that only carry flex/grid/gap utilities with Shade primitives (Stack, Inline, Box, Grid, Container, Text). Use semantic gap="md" instead of gap-4. Trigger when editing TSX in Shade-consuming apps.

Quellinformationen

Repository
TryGhost/Ghost
Letzte Quellaktivität
21. August 2026 um 15:11
Erkannte Sprache von SKILL.md
Englisch
Sterne
55.630
Forks
12.065

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 use primitives
description
Replace bare divs that only carry flex/grid/gap utilities with Shade primitives (Stack, Inline, Box, Grid, Container, Text). Use semantic gap="md" instead of gap-4. Trigger when editing TSX in Shade-consuming apps.
autoTrigger
[{"fileEdit":"apps/{shade,admin,admin-x-framework,activitypub}/**/*.tsx"}]
# Shade — use primitives, not flex divs A `<div>` whose className is only `flex / grid / gap / items-* / justify-*` utilities is a primitive call site. Use a Shade primitive instead so layouts read by **intent**, not by class string. ```ts import {Stack, Inline, Box, Grid, Container, Text} from '@tryghost/shade/primitives'; ``` ## Picking the primitive | You need | Use | Element | | ------------------------------- | ----------- | ------------------------------------- | | Column of children | `Stack` | flex-col | | Row of children | `Inline` | flex-row (with optional `wrap`, `as`) | | Padding / radius around content | `Box` | div with `padding`, `radius` props | | Two-dimensional layout | `Grid` | display: grid | | Width-constrained shell | `Container` | max-width wrapper | | Text with size/tone/weight | `Text` | `as`, `size`, `tone`, `weight` | ## Use the semantic gap scale, not raw numbers `gap="md"` reads as intent and resolves to the shared spacing scale. Mapping: | Step | Tailwind | Use for | | ------ | -------- | -------------------------- | | `none` | `gap-0` | flush | | `xs` | `gap-1` | inline icons-to-text | | `sm` | `gap-2` | dense lists, badges | | `md` | `gap-3` | default row/column spacing | | `lg` | `gap-5` | section spacing | | `xl` | `gap-6` | between major blocks | | `2xl` | `gap-8` | page-level rhythm | The same scale applies to `Box` padding (`padding="md"` → `p-3`). ## Correct ```tsx <Box padding="lg" radius="md" className="border border-border-default"> <Inline align="center" gap="md" justify="between"> <Stack gap="xs"> <Text weight="semibold">Email notifications</Text> <Text size="sm" tone="secondary">Get notified about engagement.</Text> </Stack> <Switch /> </Inline> </Box> ``` ## Incorrect ```tsx // BAD — bare div doing flex layout <div className="flex flex-col gap-2"> <div className="font-semibold">Title</div> <div className="text-sm text-gray-600">Hint</div> </div> // BAD — raw gap-4 instead of gap="md" <Stack className="gap-4"> ``` ## When NOT to reach for a primitive - A pattern already exists for the shape (page header → `PageHeader`, list page → `ListPage`). - The wrapper is starting to know about Ghost data — that's a Pattern, not a primitive composition. - You're inside a Shade primitive's own implementation. ## className still works Primitives forward `className` and merge with `cn()`. Use it for one-offs the prop API doesn't cover (e.g. `className="border border-border-default"`). Don't reach for `className` to set `flex`, `gap`, `align`, or `justify` — that's what the props are for.
Auf GitHub ansehen