Skip to content

feat: Add design verification and component creation skills in Figma - #1234

Draft
amandaye0h wants to merge 10 commits into
mainfrom
skill/figma-component-creation
Draft

feat: Add design verification and component creation skills in Figma#1234
amandaye0h wants to merge 10 commits into
mainfrom
skill/figma-component-creation

Conversation

@amandaye0h

@amandaye0h amandaye0h commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Description

What is the reason for the change?

  • Publishing and maintaining MMDS Figma components is a slow, painful process. Creating variant sets, matching the code API, and binding typography and color tokens one layer at a time are tedious and repetitive processes.
  • While I've started using MCPs to speed this process up, I've found that generated components are often detached from MMDS styles. Color tokens are linked to Material Design tokens instead of MMDS variables. Linking tokens is additional work for designers and developers.

What are the goals of these skills?

  • This should provide a quick first draft for components, intended to expedite — not completely replace — the component creation process.
  • There will still need to be a lot of human judgement for how components are structured, as AI often lacks context and doesn't know what will be most usable for designers.

What is the improvement/solution?

  • Automated component creation: Introduces a figma-component-creation skill to generate components that are built in code but do not exist in Figma. Variants are placed within a page, with 56px padding and a 32px gap for visual consistency.
  • Storybook variant mapping: The default output matches Storybook variants so our docs are aligned
  • Token verification: Adds a verification layer to ensure that components use the correct tokens
  • API alignment: Ensures the Figma API matches our code API
  • Documentation: Adds basic documentation to the component description for developers
  • Error handling: Prompts users to connect Figma Bridge Desktop if it is not connected on the relevant page
  • Cursor directory compatibility: Folder structure aligns with Cursor's architectural recommendations. This ensures skills are discoverable and allows the system to scale cleanly as new skills are added over time. I've decided to set this up as a skill, not command:

Use a command when you want a fast, deterministic action (rewrite, explain, generate, format), and use a skill when the task spans files, requires judgement, or would normally involve you guiding the AI through several steps (audits, refactors, end-to-end feature work). Source: Reddit

What are the prerequisites for this to work?

  • Figma MCP and Figma Console MCP must be installed
  • Figma Desktop Bridge must be running in the target file
  • There must be no local variables in the local file, otherwise, the wrong tokens will be linked

What is the impact of this solution?

  • Efficiency: Saves time. This makes it easier for designers and developers to maintain Figma documentation.
  • Adaptability: If these skills prove to be robust enough, this workflow can be adapted in other repos like Mobile and Extension so designers can quickly build feature-specific components.

What principles should be considered when reviewing this PR?

  • Quality: What constitutes a good enough first pass when building a component?
  • Scalability: What folder architecture best allows us to scale our skills over time?
  • Usability: How valuable would it be to distinguish generic figma skills from MMDS-specific skills?
  • Ethics: How comfortable are we adapting the work from other repos into our own DS?

Research

The structure of the skills folder is based on rough research of industry and MetaMask-specific conventions:

Attribution

The verification rules have been adapted from this repo by senlindesign. Attribution has been added.

Related issues

Fixes: NA

Manual testing steps

Prerequisites

  • Ensure Figma MCP and Figma Console MCP are installed
  • Ensure Figma Desktop Bridge is connected in your chosen Figma file

Prompt

  • Run the skill in Cursor /figma-component-creation. You do not need to invoke figma-preflight as that has been included in the creation skill.
  • Specify the .tsx component and Figma page link where you want the component to render
Screenshot 2026-06-13 at 8 06 00 PM

Note

  • The prompt has been structured to be as lightweight as possible
  • Your results may vary, as your chat history may influence your agent's decisions
  • Token linking and prop alignment may be flaky

Screenshots/Recordings

Before

N/A

After

Step 1: Connect Figma Desktop Bridge, then generate the component

0-create-component.mov

Step 2: Read the final report

1-component-complete.mov

Step 3: Verify that design tokens are linked and props match

Screen.Recording.2026-06-16.at.8.47.34.PM.mov

Step 4: Check developer docs

Screen.Recording.2026-06-16.at.8.59.38.PM.mov

Error handling: Figma Bridge Desktop not connected
Designers/devs are given appropriate feedback

Screenshot 2026-06-15 at 6 38 50 PM

Pre-merge author checklist

  • I've followed MetaMask Contributor Docs
  • I've completed the PR template to the best of my ability
  • I’ve included tests if applicable
  • I’ve documented my code using JSDoc format if applicable
  • I’ve applied the right labels on the PR (see labeling guidelines). Not required for external contributors.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@amandaye0h
amandaye0h marked this pull request as ready for review June 16, 2026 13:02
@amandaye0h
amandaye0h requested a review from a team as a code owner June 16, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@@ -0,0 +1,85 @@
---
name: component-rules

@amandaye0h amandaye0h Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helpful feedback: where's the best place for these rules to live? Right now, we have the .cursor > rules and docs folders, which enable global access. But no global skills to reference.


- Read `CODE_COMPONENT_PATH` and related files first — include **`[Component].stories.tsx`** (exported stories, `args`, and custom `render` blocks) and README story examples
- Use `figma_execute` (not `use_figma`) unless the user explicitly switches MCPs
- **Placement — overrides Figma Console MCP defaults:** publish **only the component** (or component set) on the target page canvas. **Do not** wrap it in a Section, Frame, or "Component Container". **Do not** call `figma_arrange_component_set` — it adds a white labelled wrapper frame. Append the component set directly to the page via `page.appendChild(componentSet)`. Ignore `figma_execute` placement guidance that says "always create inside a Section or Frame".

@amandaye0h amandaye0h Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This overwrites the generic output. Without these custom specs, there are a lot of unnecessary frames and sections which are cumbersome to work with.

componentSet.strokeJoin = 'MITER';
```

- Mirror variant props from code (`size`, `variant`, `severity`, etc.) as Figma component properties

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've intentionally kept these prop alignment instructions quite lightweight. I found that it performed better. Being unnecessarily detailed yielded results that were confusing.

Imo, it's easier to add to a lightweight API than to subtract from a complex one with unnecessary details.

```

- Mirror variant props from code (`size`, `variant`, `severity`, etc.) as Figma component properties
- Create variants based on Storybook variants

@amandaye0h amandaye0h Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've included this because it's a helpful start for visualizing the API of a component, and for designers to have the same mental model for what developers are seeing.

Comment thread CLAUDE.md
- @.cursor/rules/component-enum-union-migration.md
- @.cursor/rules/component-migration.md
- @.cursor/rules/figma-integration.md
- @.cursor/design-verification/README.md

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might be able to leave this out — I'm not sure an engineer would need to access this regularly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its fine to leave in, I'd like our team to become a bit more cross functional so engineers can at least get the component started in figma

Comment thread CLAUDE.md
- @.cursor/design-verification/README.md
- @.cursor/rules/release-workflow.md

See @docs/ai-agents.md for comprehensive strategy explanation.

@amandaye0h amandaye0h Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, I believe we only have system-wide rules and docs, but no skills. It could be worth including docs in ai-agent.md and this CLAUDE.md file. But this would be better off as a follow up PR to this one.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point! This is likely more of a skill, fine to leave out for now disregard my comment about leaving this in I don't think it matters too much.

@@ -0,0 +1,19 @@
# Attribution

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I am not sure whether we are comfortable adapting work by other creators into our DS.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine if the license is open source

@brianacnguyen
brianacnguyen marked this pull request as draft June 17, 2026 06:50
@brianacnguyen

Copy link
Copy Markdown
Contributor

Converting this to draft so George can review when he gets back

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@georgewrmarshall georgewrmarshall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great first draft — the preflight, token binding, and Desktop Bridge gate are solid foundations and this fills a real gap in the AI-assisted design workflow. I ran through the full skill manually using Claude Code against the test branch PXKLmxkKBVDlegyigjRCI6 and created a RadioButton component set end-to-end, which surfaced a few gaps worth addressing before this lands.

All variants are inside one State component property instead of matching code

Screenshot 2026-06-24 at 6 57 48 PM

Design matches well

figma.component.skill.test.mov

When running Check designs, I got spacing suggestions might be worth addings

Screenshot 2026-06-24 at 6 58 40 PM

A few structural notes against docs/ai-agents.md: the three-layer diagram currently only shows CLAUDE.md.cursor/rules/docs/ but this PR adds two new directories (.cursor/design-verification/ and .cursor/skills/) that aren't documented there. Worth a small update so the layer model stays accurate for future contributors.

Also related: PR #1251 adds a Code Connect skill (skill/code-connect branch). Both skills operate in the same Figma-integration space and SKILL.md already points to figma-integration.md for the Code Connect follow-up step (line 233/268). Worth coordinating on landing order — if Code Connect skill lands first, the reference here to "Optional follow-up: add Code Connect per @.cursor/rules/figma-integration.md" could become a direct skill invocation (/figma-code-connect) instead.

**Pass** when:

- `figma_get_status` reports a valid WebSocket connection (`setup.valid: true`)
- `figma_navigate` succeeds (`status: already_connected` or `switched_active_file`) — **not** `websocket_file_not_connected`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking: This gate fails when using a Figma branch URL. Tested against https://www.figma.com/design/1D6tnzXqWgnUC3spaAOELN/branch/PXKLmxkKBVDlegyigjRCI6/...figma_navigate extracts the main file key (1D6tnzXqWgnUC3spaAOELN) instead of the branch key (PXKLmxkKBVDlegyigjRCI6), returning websocket_file_not_connected even though the Desktop Bridge IS connected to the branch. figma_list_open_files correctly shows the branch as the active file.

Suggestion: add a note that for branch URLs (/design/:mainKey/branch/:branchKey/), the operative file key is the branch key, not the main key — and the gate should compare against the connected file from figma_list_open_files rather than re-deriving the key from the URL.


**Do not** fall back to `use_figma` or official Figma MCP for component creation unless the user explicitly asks to switch MCPs.

### MMDS token mapping (code → Figma)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The token map is sparse — 8 entries covering the most common cases, but a real component creation session needs significantly more (e.g. border/default, icon/alternative, error/default, hover/pressed tokens, icon/muted, radius tokens). In testing I had to look these up manually from figma_get_variables output.

Consider replacing the static table with a directive to build the token map dynamically during Step C by filtering figma_get_variables output by scopes (e.g. FRAME_FILL → background tokens, TEXT_FILL → text tokens, STROKE_COLOR → border tokens). The figma-preflight.md Token Map section already defines this mapping — the SKILL.md table could just reference that instead of duplicating a subset of it.

componentSet.strokeJoin = 'MITER';
```

- Mirror variant props from code (`size`, `variant`, `severity`, etc.) as Figma component properties

@georgewrmarshall georgewrmarshall Jun 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: "Mirror variant props from code as Figma component properties" is ambiguous and leads agents to collapse everything into a single State variant enum (tested: RadioButton's isChecked, isDisabled, isDanger, isReadOnly all became State=Default/Checked/Disabled/ReadOnly/Danger instead of independent boolean properties).

Suggest making the mapping explicit:

  • Boolean props (isChecked, isDisabled, isDanger) → Figma boolean component properties (independently composable)
  • String union / enum props (variant, size, severity) → Figma variant properties
  • String content props (label, loadingText) → Figma text component properties

A golden path example here (or a link to an existing MMDS component set like Button or BadgeStatus that already uses this correctly) would help agents get this right. The existing @.cursor/rules/figma-integration.md has good prop-mapping examples — a cross-reference there would reinforce the pattern.

Screenshot 2026-06-24 at 7 01 47 PM

descriptionMarkdown: <optional — props, usage, a11y notes>
```

Pull description content from the component README and prop types. Follow `@.cursor/rules/component-documentation.md`.

@georgewrmarshall georgewrmarshall Jun 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking: "Pull description content from the component README and prop types" is a good direction, but in practice agents summarise from prop types and miss the README's consumer-facing opening line. In testing the generated description was implementation-focused rather than matching the README.

Suggestion: be explicit — pull the first sentence from the component README as the description opening (e.g. RadioButton is a graphical element that allows users to select one option from a set of choices.), then append states/props/token summary.

Screenshot 2026-06-24 at 7 02 21 PM Screenshot 2026-06-24 at 7 02 47 PM

3. Build from scratch — ONLY if nothing matches
```

Never rebuild primitives the DS provides: Button, Input, Checkbox, Toggle, Badge, Tag, Avatar, Icon, Tab, Header, TextField, etc.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: This static list will go stale and is already ambiguous — Header alone matches HeaderRoot, HeaderSearch, HeaderStandard, and TitleHub/TitleSubpage/TitleStandard. An agent following this literally might skip searching for the right header component because it sees "Header" on the no-rebuild list.

A more durable pattern: replace the list with a search-first directive — run figma_search_components (or search_design_system) before building anything, and only build from scratch if the search returns no match. The MMDS Components file has 70+ component pages; the search is reliable. The static list could be dropped entirely or reduced to a short illustrative note (e.g. Button, Icon, Avatar — always check first).

Session defaults for design-verification preflight. Update per task.

- **MMDS Components file:** https://www.figma.com/design/1D6tnzXqWgnUC3spaAOELN/%F0%9F%A6%8A-MMDS-Components
- **Local working file (optional):** `https://www.figma.com/design/YOUR_FILE_KEY/Your-File-Name`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking: Worth clarifying that "local working file" means a Figma branch or personal scratch file — not a separate unrelated project. In testing, the MMDS Components branch (/branch/:branchKey/) is the natural target for this field, but the placeholder (YOUR_FILE_KEY) doesn't make that obvious. A comment like # Use a Figma branch URL here when working off main MMDS Components would help.

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants