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.

Datos de origen

Repositorio
TryGhost/Ghost
Última actividad en el origen
21 de agosto de 2026 a las 15:11
Idioma detectado de SKILL.md
inglés
Estrellas
55.544
Forks
11.995

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 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.
Ver en GitHub