Maquettes de spécifications
Cette compétence explique comment dessiner. lw-spec-write indique où va le cahier des charges et comment la page s'affiche.
Informations produit
Le dossier d'adaptation provient de la configuration. Lisez-le d'abord :
ah config get harness.adapterDir
Lisez ensuite <adapterDir>/spec-mockup/. Le projet en est propriétaire. Il nomme :
| Information | Exemple |
|---|---|
| Les fichiers de tokens de chaque application, dans l'ordre | apps/console/src/styles/tokens.css |
| Les sélecteurs des valeurs claires et sombres | :root, .dark |
| Le dossier des icônes lucide | node_modules/lucide-react/dist/esm/icons |
| La navigation de chaque application avec une barre latérale, et d'où elle vient | la table de routes de la console |
| La source du texte réel | le catalogue i18n de l'application |
Lorsque l'adaptateur est manquant, demandez à l'utilisateur le fichier de tokens avant de dessiner. N'inventez jamais de couleur.
Le format
SVG généré, dessiné avec une seule bibliothèque : boards.py à côté de ce fichier. Chaque spécification a un script, docs/specs/assets/<date>-<sujet>-boards.py. Il importe la bibliothèque et écrit dans docs/specs/assets/<date>-<sujet>/. Ne modifiez jamais un SVG généré à la main : changez le script et exécutez-le à nouveau. Lorsque la bibliothèque manque d'un élément, ajoutez-le au module d'aide du projet à côté du script, afin que la spécification suivante en bénéficie aussi.
example.py est une planche fonctionnelle : une page sur ordinateur de bureau et sur téléphone, avec des repères et une légende. Exécutez-la pour voir la forme :
python3 .claude/skills/lw-spec-mockup/example.py <scratchpad>/mock --render
Un script de spécification commence comme ceci :
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
sys.path.insert(0, str(ROOT / ".claude/skills/lw-spec-mockup"))
from boards import GUTTER, Board, render, tokens
t = tokens("apps/console/src/styles/tokens.css", "light")
b = Board(1440 + 2 * GUTTER, 1200, icons="node_modules/lucide-react/dist/esm/icons")
b.title("Tableau de bord : état vide")
f = b.sidebar_app(
GUTTER,
160,
t["bg"],
t["sidebar"],
t["ink"],
t["muted"],
t["active"],
["Tableau de bord"],
"Tableau de bord",
"Console",
)
b.pin(f.x + f.left + 24, f.top + 30, 1)
b.legend(
GUTTER, 1100, [(1, "L'état vide", "Aucun widget tant que le produit n'en nomme pas un.", "R1")], 1440
)
b.save("docs/specs/assets/<date>-<sujet>/desktop-empty.svg")
| Appel | Dessine |
|---|---|
tokens(fichiers, theme, base=, dark=, overlay=) | Les valeurs --* résolues des fichiers de tokens. t["accent"]. Un token manquant déclenche une erreur. overlay est une proposition de restylage |
phone(x, y, bg, ink, surface, url), desktop(x, y, bg, url) | Un téléphone (web ou app), une fenêtre de navigateur |
sidebar_app(x, y, ...) | Une application avec une barre latérale gauche, comme une console. Copiez nav depuis la table de routes de l'application |
screenshot(chemin, x, y), crop(chemin, ...) | Une capture réelle de l'écran livré, ou une région de celui-ci, pour la colonne Aujourd'hui |
icon(nom, x, y, taille, couleur) | Un glyphe lucide depuis le dossier icons de la planche |
image(chemin, ...), embed_font(famille, chemin) | Un art réel et une police de marque depuis le dépôt |
pin, legend, caption, column_head, row_label, title | Les notes. Une note de légende de plus de deux lignes déclenche une erreur |
render(svg, png, w, h) | La capture d'écran par Chrome sans tête pour la vérification ci-dessous |
Fidélité
- Les couleurs sont des tokens, via
tokens(). Une valeur hexadécimale dans un script de spécification est incorrecte, sauf pour un art que le fichier de tokens ne contient pas. - Le texte est réel. Utilisez la chaîne du catalogue de l'application lorsqu'elle existe. Une nouvelle chaîne est courte : un libellé, une valeur, un état vide, une erreur ou une indication d'une ligne.
- Les données sont réalistes. Utilisez des valeurs plausibles, et une valeur longue là où elle peut se produire.
Toile
| Surface | Cadre |
|---|---|
| Téléphone | 390 x 844, marges de 48 px |
| Bureau | 1440 x 900 |
| Planche | aussi large que ses cadres, aussi haute que ses rangées le nécessitent |
Ce que dessine une spécification
- Aujourd'hui, puis cible. « Aujourd'hui » est une capture d'écran réelle de l'écran livré (
today-*.png). « Cible » est le SVG. Placez-les côte à côte dans un tableau Markdown. - Une ligne par état concerné : par défaut, vide, chargement, erreur, texte long, le contenu le plus petit et le plus grand.
- Repères et légende. Un repère numéroté sur chaque élément qui change. Sous le cadre, une légende numérotée : un titre en gras, deux lignes au maximum, et l'ID de spécification qu'elle sert.
- Une liste de composants dans la spécification à côté des planches : chaque élément, le composant qu'il réutilise, et chaque nouveau composant avec sa raison.
Noms
docs/specs/assets/<AAAA-MM-JJ>-<sujet>-boards.py
docs/specs/assets/<AAAA-MM-JJ>-<sujet>/<surface>-<état>.svg
docs/specs/assets/<AAAA-MM-JJ>-<sujet>/today-<surface>-<état>.png
La spécification nomme le nom de base de chaque fichier qu'elle contient dans assets/.
Examinez chaque planche avant de la valider
Un défaut d'une planche est invisible dans sa source et évident dans l'image. Affichez chaque planche et lisez le PNG avec l'outil de lecture. Écrivez le PNG dans le bloc-notes, pas dans docs/.
- Aucun texte ne dépasse de son cadre, et aucun repère ne couvre une valeur.
- Chaque chaîne dans l'interface utilisée dessinée est un libellé, une valeur, un état vide, une erreur ou une indication.
- Pas d'art de substitution, et aucune couleur choisie à l'œil.
- Chaque état et surface que la spécification touche a son cadre.
- Aujourd'hui et cible sont côte à côte.
render nécessite google-chrome ou chromium dans le PATH.
Après la construction
La construction doit correspondre à la planche approuvée. Capturez l'écran construit et placez-le à côté de la planche. Une différence est un défaut de la construction, pas une raison de redessiner la planche.