Grace
Guides

Développer les composants avec Storybook

Consulter, documenter et prévisualiser le design system Grace depuis Storybook et son serveur MCP local.

Storybook expose les composants visuels de Grace dans un catalogue local. Son addon MCP permet aux agents de code de découvrir leurs props et leurs stories au lieu de les déduire du nom ou du code source.

Le catalogue est un outil de développement du frontend. Il n'ajoute aucune route à l'application Grace et n'est pas déployé avec elle.

Scope et nomenclature

Le catalogue couvre obligatoirement chaque composant React rendu ré-exporté publiquement par platform/frontend/src/components/ui/index.ts, y compris les icônes ré-exportées depuis Icon.tsx. Il peut aussi documenter un composant visuel local à une feature lorsqu'il est isolé, déterministe et utile pour comprendre l'assemblage du système. Les hooks, helpers, types, fonctions de style, containers de routing et pages branchées aux données restent hors scope.

La barre latérale suit une taxonomie Atomic Design explicite :

  1. Design System/Atoms/<Composant> ;
  2. Design System/Molecules/<Domaine>/<Composant> ;
  3. Design System/Organisms/<Domaine>/<Composant> ;
  4. puis Templates et Pages si ces niveaux apparaissent.

Le tri du catalogue conserve cet ordre, indépendamment de l'ordre alphabétique. Le nom du composant décrit la responsabilité visuelle ; le domaine parent porte le contexte métier, donc les feuilles évitent les préfixes redondants.

Au 2026-08-21, le catalogue documente les 32 entrées visuelles du design system : chaque composant rendu ré-exporté par components/ui/index.ts, la galerie de toutes les icônes publiques, les quatre composants Catalog et le template PageContainer. La suite Storybook exécute 74 scénarios dans Chromium avec axe bloquant.

shadcn comme implémentation interne

Grace utilise des sources shadcn générées dans platform/frontend/src/components/shadcn/. Ces fichiers sont du code possédé par le dépôt, pas une bibliothèque de composants exposée aux features :

  • les pages et features importent uniquement la surface publique components/ui ;
  • les adapters Grace conservent leurs props, leur vocabulaire, leurs icônes publiques et leurs classes/tokens issus de src/index.css ;
  • components.json configure Vite, TypeScript et les chemins de génération ; le CLI shadcn reste ponctuel et doit être appelé avec une version exacte ;
  • toute mise à jour d'une recette se contrôle avec view, --dry-run ou --diff avant écriture, puis repasse par Storybook, axe, les tests frontend et la revue visuelle ;
  • les classes de couleur générées sont remappées vers la palette Grace, sans seconde palette.

Les primitives actuellement adaptées sont Alert, Badge, Button, Card, Checkbox, Dialog, Input, Label, Popover, ScrollArea, Sheet, Skeleton, Slider, Switch et Textarea. Select reste natif pour préserver <option> et ChangeEvent<HTMLSelectElement>. ActionMenu, SegmentedControl, Tooltip et Toast gardent leur mécanique Grace parce que les recettes disponibles changent respectivement le contrat disabled/focus, les rôles aria-pressed, le positionnement du portail et le timing des live regions. Ces exceptions restent documentées dans leurs stories ; elles ne créent pas une seconde API publique.

Démarrer le catalogue et le MCP

Depuis la racine :

mise run storybook

Le script npm reste l'équivalent package-local et le propriétaire des options de sécurité :

cd platform/frontend
npm ci
npm run storybook

Le serveur écoute uniquement sur la boucle locale, à l'adresse http://127.0.0.1:6006. Le catalogue est aussi ouvrable via http://localhost:6006.

Le script impose le port 6006 : s'il est occupé, Storybook s'arrête au lieu de choisir un autre port qui rendrait la configuration MCP incorrecte.

Consulter les composants documentés

La hiérarchie actuelle est consultable directement à http://localhost:6006 et couvre :

  • Atoms — Button, Card, Chip, DocsLink, Icon, Input, SectionLabel, Select, Skeleton, Slider, Stat, Switch et Textarea ;
  • Molecules — ActionMenu, Alert, DangerZone, Drawer, EmptyState, ErrorState, Field, Modal, MultiSelectDropdown, ScrollableRegion, SearchInput, SegmentedControl, Toast et Tooltip ;
  • Molecules / Catalog — Card Skeleton et Talent Card ;
  • Organisms / Catalog — Filters et Header ;
  • Templates — PageContainer.

Chaque entrée expose ses variantes et états observables ; les overlays, menus, sélections, formulaires et feedbacks portent des scénarios play lorsque le clavier, le focus, une action ou une live region font partie du contrat.

Dans une story ouverte, l'onglet Accessibility affiche les violations, passes et résultats inconclusifs détectés par axe. Ce contrôle automatique complète les tests et la revue clavier ; il ne prouve pas à lui seul une conformité WCAG AA.

Utiliser Storybook depuis un agent

La racine du dépôt déclare le serveur storybook dans .mcp.json :

{
  "storybook": {
    "type": "http",
    "url": "http://127.0.0.1:6006/mcp"
  }
}

Démarre Storybook avant la session de l'agent ou recharge ses serveurs MCP après le démarrage. Le MCP est un conseil de reconnaissance, jamais une autorité : avant d'utiliser un composant du catalogue, l'agent appelle dans cet ordre :

  1. list-all-documentation pour découvrir les composants et les story IDs disponibles ;
  2. get-documentation pour lire les props et exemples du composant choisi ;
  3. get-storybook-story-instructions avant de créer ou modifier une story ;
  4. preview-stories après une modification visuelle pour obtenir l'URL de contrôle.

Les manifestes viennent des stories CSF/MDX et du docgen : leurs props, descriptions et exemples doivent rester fidèles au code. Une fixture invalide ou seulement pédagogique porte !manifest. Si Storybook est arrêté, l'appel MCP doit échouer explicitement : l'agent signale la limitation, il n'invente ni prop ni état pour la contourner.

Adapter l'import proposé

Le manifeste expérimental déduit actuellement @grace/frontend depuis le nom du package privé. Ce package n'est pas publié et ne définit pas d'export public : dans le frontend, conserve les imports relatifs existants via components/ui.

Ajouter ou maintenir une story

Les stories ordinaires vivent à côté du composant et portent le suffixe .stories.tsx. Elles utilisent CSF3 typé (Meta/StoryObj et satisfies), le composant réel et les tokens chargés par src/index.css. Leur title suit Design System/<Niveau>/<Domaine?>/<Composant>. Les exports UpperCamelCase nomment un scénario observable (LoadingResults, ProjectWithoutName) plutôt qu'un terme générique comme Default.

La meta porte autodocs et exactement un tag de cycle de vie : experimental, stable ou deprecated. Une story couvre le défaut, les variantes et les états publics qui changent une décision ou une interaction — notamment les états disabled, loading, empty, error ou denied quand le composant les expose. args est le moyen par défaut ; render ne sert qu'à une composition nécessaire ; un play prouve une interaction, un clavier ou un focus observable.

Une story reste déterministe : pas de requête ou service live, secret, routing, store, règle métier, date courante ou hasard. Si un composant promu dans ce scope exige ultérieurement un transport, utiliser des fixtures fixes et des handlers MSW par story pour les cas success/error/loading ; ne pas installer MSW avant ce besoin réel. Une modification ou suppression du composant met à jour ou retire sa story dans le même changement ; une story deprecated nomme son remplacement.

La couverture obligatoire progresse lorsqu'un composant public du scope est créé ou modifié. Un composant local peut être ajouté lorsqu'il apporte une guidance d'assemblage réelle, jamais pour remplir artificiellement le catalogue.

Construire le catalogue statique

npm run storybook:build

La commande produit platform/frontend/dist/storybook. Cet artefact permet une revue humaine, mais ne lance aucun processus MCP : /mcp n'existe que pendant npm run storybook.

Le job frontend de CI exécute ce build pour détecter une story ou une configuration cassée.

Interactions et accessibilité

L'addon Vitest transforme les stories en tests de composants dans Chromium. Les fonctions play exercent les interactions via des rôles et noms accessibles ; l'addon a11y exécute axe avec parameters.a11y.test: "error", ce qui rend les violations bloquantes.

npm run test:storybook exécute cette couche isolément. npm test enchaîne les tests unitaires, les tests Storybook puis les helpers navigateur ; le job frontend de CI appelle cet agrégat et constitue donc le gate des interactions et de l'accessibilité.

Sécurité et limites

  • Le serveur écoute exclusivement sur 127.0.0.1, impose le port 6006 et ne doit pas être exposé sur le LAN ou Internet.
  • N'injecte aucun secret dans une variable destinée à Storybook, une story, une fixture ou un manifeste ; ne publie pas le catalogue sans décision séparée sur l'accès, les secrets et les dépendances.
  • L'addon MCP et les manifestes sont en preview : leurs APIs et schémas ne sont pas des contrats stables.
  • platform/frontend/package-lock.json résout valibot@1.2.0 via @storybook/addon-mcp. L'avis de sécurité GitHub sur le comportement record()/flatten() de Valibot affecte les versions <=1.4.1 et est corrigé en 1.4.2. Cette dépendance demande une remédiation sécurité séparée ; la frontière locale reste obligatoire, mais ne constitue pas un correctif.

Contrôles avant livraison

Pour contrôler uniquement les stories depuis platform/frontend :

npm run test:storybook

Pour la livraison frontend :

npx eslint .storybook "src/**/*.stories.tsx"
npm run storybook:build
npm run build
npm test

Depuis la racine :

mise run docs:check

Le dépôt ne définit actuellement aucune tâche mise run check; utilise les tâches canoniques ci-dessus sans créer un second agrégateur implicite.

Sources officielles (vérifiées le 2026-08-21)

On this page