alma-oss/spirit-design-system

spirit:figma-to-code

Implement production React UI from a Figma design using @alma-oss/spirit-web-react.

Voir la source

Mode d’emploi

  1. Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
  2. Consultez le document original pour les outils, identifiants et environnements requis.
  3. Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/alma-oss/spirit-design-system --skill spirit:figma-to-code

Avant de commencer

  • L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
  • Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Document Skill original

Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.

Figma to Code

Convert a Figma design into React with @alma-oss/spirit-web-react. Target this repository’s current main / latest APIs. Do not invent APIs, tokens, breakpoints, routes, data, or assets.

Do not use this skill for:

  • Design-system review or handoff reports — use /spirit:review-figma-design
  • Writing or updating Figma Code Connect mappings
  • Building or syncing designs in Figma from code
  • Vanilla packages/web markup or other non-React packages

References

Source Authority

Resolve conflicts in this order. A later source does not override an earlier one.

  1. Valid APIs, defaults, deprecations, composition — current Spirit source in this order:

implementation, public types, packages/web-react/DEPRECATIONS.md, then the component README. If those disagree, implementation and types win. Do not copy stale README examples.

  1. Component identity and variants — Figma Code Connect mappings (when present).
  2. Visual measurements, tokens, assets — Figma design context, variables, and exported assets.
  3. Behavior, copy, routing, and accessibility — product requirements and the surrounding app.

Normalize Code Connect and generated snippets to the current API: replace removed or deprecated props, omit values equal to current defaults, and keep design intent. Code Connect is not always complete or up to date. Nested CardLink is a common omission: a “Card Basic” snippet with a bare CardTitle is not proof the card is static if the title node uses a themed/link/… token. See Cards.

Never guess from screenshots. If Figma data, Code Connect, or product context is missing, stop, list the assumptions, and ask. Do not silently invent breakpoints, icon names, colors, spacing, accessible names, hrefs, or image sources.

Workflow

1. Acquire the Design

If a Figma design-to-code skill is available, follow it before calling get_design_context.

  1. Parse a Figma URL when provided (fileKey, nodeId from node-id with - → :). If the MCP

needs fileKey even for the current selection, ask for a node URL instead of guessing.

  1. Call get_design_context first. Treat the returned code as a reference, not paste-ready

output. Adapt it to Spirit React.

  1. Use supporting tools only when needed: metadata to pick a node, variable definitions for tokens,

screenshots for visual comparison, asset download for images/icons, motion context for animation.

  1. When the MCP lets you set client context, request React and TypeScript.

2. Map Structure, Not Figma’s Layer Count

Preserve reading order, visual grouping, max-width boundaries, and Spirit composition contracts. Figma frames often exist for editing, clipping, or naming — they are not 1:1 DOM nodes.

  • Use a Spirit component when it owns the needed semantics, behavior, or styling contract. Match

Figma names and layout patterns first, then search for an existing composite (PricingPlan + Matrix, ScrollView, Stack). See Component selection.

  • Use native semantic elements (p, ul/ol/li, article, form) when no Spirit component is

responsible, including inside Card body content.

  • Do not wrap extra layout components around Card, Dialog, Drawer, or other families that require a

flat, ordered composition.

  • Add Container only where a distinct width constraint exists. See Layout.
  • When the design is a form, wrap both the field area and the action buttons in a named native

<form>. See Forms.

3. Choose Components and Props

  1. Route from Figma component names, text styles, and Code Connect to Spirit components using

Component selection.

  1. Confirm props against current types and defaults. Omit props that match defaults.
  2. Heading and UNSTABLE_DisplayHeading elementType is always required. CardTitle already

defaults to h4. Map Figma Display/\* styles to UNSTABLE_DisplayHeading, not Heading.

  1. Keep exact icon identifiers from Figma: Icon uses name, IconBox uses iconName. Do not

replace placeholder with a “better” icon.

  1. Map Figma spacing tokens such as --global/spacing/space-1400 to spacing="space-1400".
  2. Map CSS alignment to Spirit alignmentX / alignmentY (flex-start → left/top,

flex-end → right/bottom). On vertical Flex, align-items is alignmentX. On horizontal Flex, justify-content is alignmentX.

  1. Prefer Box colorScheme for semantic surfaces. Use component-specific color dictionaries; do

not reuse Heading/Text colors on Box, Section, Link, or Button.

Deprecated or removed APIs must not appear in new code. Current traps:

  • emphasis → fontWeight and isItalic
  • Flex row / column → horizontal / vertical (plus horizontal-reversed when needed)
  • hideOnCollapse → isDisposable on UncontrolledCollapse
  • CardDescription, CardTitle headingProps, CardLink isExternal, Button variant

If Code Connect still emits those, tell the user and emit the current API.

4. Responsive Behavior

Spirit breakpoints are mobile from 0, tablet from 48rem, desktop from 80rem (typically 768px and 1280px). Do not infer a 1024px desktop breakpoint from frame width.

  • Encode only transitions supported by Figma frames, variables, or annotations.
  • A scalar applies at every breakpoint. Partial objects cascade forward

({ mobile: 'small', desktop: 'large' } keeps small on tablet).

  • If only one frame is provided, match that frame. Do not invent other breakpoints.
  • Figma layout guides (column counts, gutters) are often absent from MCP output. If the user

mentions them, implement with Grid and ask when the column count is unclear. Infer column counts from how the frame divides the parent (tokens and the 12-column system), not from a pixel formula. See Layout.

5. Accessibility

Apply /spirit:accessibility. This step is a semantics pass, not a prop re-check. Cover landmarks, heading outline, list markup, and role/elementType from meaning — not from the Figma component name.

  • Choose elementType from document outline, not from visual size. Visual style and semantics

are independent.

  • Prefer not to skip heading ranks; fix the outline rather than forcing a visual size onto the

wrong tag. Keep the page h1 out of an anonymous <section>. See Layout.

  • Repeating cards or items that are a list in meaning use ul/ol with li, not a bare Flex/Grid

of divs.

  • Preserve DOM source order. If Flex horizontal-reversed or similar changes visual order, keep

the accessible reading order correct.

  • Give controls accessible names, states, and relationships (label, description, error, required).
  • Decide decorative vs informative for images and icons; do not invent alt text from pixels.
  • Do not nest interactive elements. A stretched CardLink may coexist with footer buttons because

Card raises those controls; do not add extra wrapping links.

  • Honor reduced-motion and focus management for Dialog, Drawer, Dropdown, and similar overlays.
  • Personal-data autocomplete and checkbox-revealed field ARIA live in /spirit:accessibility.

6. Assets

  • Prefer Figma MCP assets, files already in the repo, or an explicit product image source.
  • MCP asset URLs expire; for committed code, download the bytes or wire the app’s image source.
  • Do not use picsum.photos or other random remote placeholders.
  • If no asset is available, use a clearly labeled local placeholder and flag it in the handoff.

Validation

Validation is required, not optional. After implementation:

  1. Confirm every Spirit prop against current types. Fix invalid token names and removed APIs.
  2. Run linters on edited files (ReadLints in this repo) and fix new issues.
  3. Run relevant unit tests when the change lives in this repository.
  4. Render and compare. In this repo: start Vite with make start or yarn start

(http://localhost:3456/packages/web-react/), inspect with Playwright MCP, then use Docker Make targets (make test-e2e, make test-e2e-a11y) for suite runs. Do not skip visual comparison silently.

  1. Re-fetch Figma context if the implementation drifted from tokens, icons, or composition.

If a gate cannot run, say so in the handoff (verified vs unverified) and list what was skipped.

Implementation Checklist

  • \[ \] Design acquired with get_design_context; missing data flagged, not guessed
  • \[ \] Code Connect intent kept; snippets normalized to current APIs and defaults
  • \[ \] Icon identifiers unchanged (Icon name, IconBox iconName)
  • \[ \] No deprecated or removed APIs (emphasis, row/column, hideOnCollapse, CardDescription)
  • \[ \] Semantic structure preserved; Figma-only wrapper frames not copied 1:1
  • \[ \] Existing composite used where one covers the pattern (PricingPlan, ScrollView, Stack)
  • \[ \] Widths expressed as Grid column spans or Container size tokens, not one-off pixel formulas
  • \[ \] Card vs Box decided by composition (artwork/title/footer/link), not Figma name
  • \[ \] Card titles with themed/link/… tokens use CardLink even if Code Connect omitted it
  • \[ \] Page h1 not nested in an anonymous Section; repeating cards use list markup
  • \[ \] Heading elementType set; Display/\* → UNSTABLE_DisplayHeading; typography mapped by text style, not by size alone
  • \[ \] Form wraps fields and actions; submit first in DOM; personal-data autocomplete per /spirit:accessibility
  • \[ \] Responsive values exist only where Figma supports them; breakpoints are Spirit tokens
  • \[ \] Assets are stable; alt/decorative decisions are explicit
  • \[ \] Accessibility, TypeScript, lint, render, and (when in this repo) tests/a11y checks ran — or the handoff is marked unverified
  • \[ \] Unclear patterns were asked about instead of improvised

Tâches connexes