Skip to content

feat: add component, variant, and prototype reaction tools - #48

Open
phss-henrique wants to merge 1 commit into
gethopp:mainfrom
phss-henrique:feat/components-variants-reactions
Open

feat: add component, variant, and prototype reaction tools#48
phss-henrique wants to merge 1 commit into
gethopp:mainfrom
phss-henrique:feat/components-variants-reactions

Conversation

@phss-henrique

@phss-henrique phss-henrique commented Aug 27, 2026

Copy link
Copy Markdown

Adds three tools covering Plugin API surface the bridge doesn't currently expose: creating real Components, combining them into Variant sets, and setting prototype reactions.

I hit these gaps building a multi-screen prototype through the bridge — frames could be created and styled, but there was no way to promote them to Components or wire up click-through navigation without dropping out to the Figma UI.

Tools

  • create_component_from_node — converts an existing frame into a Component in place via figma.createComponentFromNode. Returns the new node id, since conversion changes it.
  • combine_as_variants — combines Components into a Component Set via figma.combineAsVariants. Figma stacks the children at (0,0), so this lays them out along a configurable axis/gap and resizes the set to fit.
  • set_reactions — sets prototype reactions (on-click / on-hover navigation) via setReactionsAsync, which is required rather than the .reactions setter because the manifest uses documentAccess: "dynamic-page".

All three are registered in EDIT_REQUEST_TYPES, so they respect the existing Dev Mode read-only guard.

Testing

No automated tests, since the repo doesn't have a suite. Verified manually against a real file: converted 9 screens to Components and applied 54 navigation reactions across them, with every call accepted by Figma's own destination validation (which does reject invalid targets — it caught a Component Set destination during development). Both server and plugin build clean.

Two things I'd like your call on

  1. set_reactions takes the reactions array untyped (z.array(z.record(z.unknown())), passed straight through to setReactionsAsync). It works, but callers get no schema help and only find out about a malformed Trigger/Action from Figma's runtime error. Happy to write proper Zod schemas for the reaction shapes if you'd prefer that.
  2. combine_as_variants does opinionated layout. Laying out the children and resizing the set isn't strictly part of the API call — without it you get an unreadable pile at (0,0) — but it is a product decision rather than a thin wrapper. Easy to drop or put behind a flag if you'd rather keep it neutral.

Summary by CodeRabbit

  • New Features
    • Create components from eligible design nodes, with optional naming.
    • Combine multiple components into organized variant sets with configurable layout and spacing.
    • Replace prototype interactions with a complete set of reactions.
    • Clear validation and error reporting are provided for unsupported nodes or invalid inputs.

Adds three tools covering Plugin API surface the bridge did not expose:

- create_component_from_node: converts an existing frame into a real
  Component in place via figma.createComponentFromNode. Returns the new
  node id, since converting changes it.
- combine_as_variants: combines Components into a Component Set via
  figma.combineAsVariants. Figma stacks the children at (0,0), so this
  lays them out along a configurable axis/gap and resizes the set to fit.
- set_reactions: sets prototype reactions (on-click/on-hover navigation)
  via setReactionsAsync, which is required because the plugin manifest
  uses documentAccess: dynamic-page, making .reactions read-only.

All three are registered in EDIT_REQUEST_TYPES so they respect the
existing Dev Mode read-only guard.
Copilot AI lite review requested due to automatic review settings August 27, 2026 23:02
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ad8c975-20a1-4e06-b4e4-2e7b70d81e0e

📥 Commits

Reviewing files that changed from the base of the PR and between 734d4c1 and d771bea.

📒 Files selected for processing (4)
  • plugin/src/main/code.ts
  • plugin/src/ui/App.tsx
  • server/src/schema.ts
  • server/src/tools.ts

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

Changes

The PR adds MCP tools and plugin handlers for creating components, combining components into variants, and replacing prototype reactions. The new mutations use schema validation and are restricted to editor mode.

Component and reaction mutations

Layer / File(s) Summary
Tool contracts and registration
server/src/schema.ts, server/src/tools.ts
Defines schemas and RPC mappings for the three tools. Registers tool handlers that forward component, variant, and reaction parameters.
Editor mutation handling
plugin/src/main/code.ts, plugin/src/ui/App.tsx
Adds editor-only request types and handlers. Creates components, lays out component variants, and applies validated reaction arrays. Extends the UI request union.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🔵 Low · up to d771b

The new tools enable component conversion, variant-set creation, layout changes, and full prototype-reaction replacement. A timeout or partial variant-layout failure could leave the document in an ambiguous state, and malformed reaction inputs may fail only at runtime. The PR is mergeable with explicit owner awareness and follow-up on mutation recovery and reaction schemas.

Sequence Diagram(s)

sequenceDiagram
  participant MCPClient
  participant ServerTools
  participant RPCMapper
  participant Plugin
  participant FigmaEditor
  MCPClient->>ServerTools: call component or reaction mutation
  ServerTools->>RPCMapper: validate and map arguments
  RPCMapper->>Plugin: send editor mutation request
  Plugin->>FigmaEditor: create, combine, or update nodes
  FigmaEditor-->>Plugin: return node details or reaction count
  Plugin-->>MCPClient: return mutation result
Loading

Suggested reviewers: konsalex, jeinjang, julioservan

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the three main changes: component creation, variant combination, and prototype reaction tools.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 4 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the bridge’s exposed Figma Plugin API surface by adding three new editing tools: converting nodes into Components, combining Components into Variant sets, and setting prototype reactions.

Changes:

  • Registers create_component_from_node, combine_as_variants, and set_reactions as server tools and wires them through RPC.
  • Adds Zod input schemas and RPC argument mapping for the new tools.
  • Implements the corresponding plugin-side request handlers and includes them in the edit-mode (non–Dev Mode) guard.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
server/src/tools.ts Registers the three new tools and forwards calls to the plugin via RPC.
server/src/schema.ts Adds input schemas for the new tools and maps RPC wire format to tool args.
plugin/src/ui/App.tsx Extends the UI-side RequestType union to include the new tool request types.
plugin/src/main/code.ts Adds edit-guard coverage and implements handlers for component creation, variant combining, and reaction setting.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread plugin/src/main/code.ts
Comment on lines +1625 to +1630
const node = await getSceneNodeById(nodeId);
if (node.type === "COMPONENT" || node.type === "COMPONENT_SET") {
throw new Error(`Node is already a ${node.type}: ${nodeId}`);
}

const component = figma.createComponentFromNode(node);
Comment thread plugin/src/main/code.ts
Comment on lines +1707 to +1709
const setWidth = layout === "ROW" ? cursor + 40 : maxCross + 40;
const setHeight = layout === "ROW" ? maxCross + 40 : cursor + 40;
set.resizeWithoutConstraints(Math.max(setWidth, 1), Math.max(setHeight, 1));
@konsalex

Copy link
Copy Markdown
Contributor

Hey @phss-henrique before I dive into the code could you sign the CLA? 🙏

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.

4 participants