# Variant Component Setup

> Create a multi-variant Figma component correctly. Use when the designer asks to "make this a variant", "add size/state variants", "build a button with primary/secondary/ghost", "turn this into a component set", or any task that needs VARIANT properties. Covers the full promote → clone → combine → add properties sequence and avoids the "variant properties require component set" trap.

- Skill: `egoisutolabs/variant-component-setup` (Agent Skill)
- Install (CLI): `npx skillmds@latest add egoisutolabs/variant-component-setup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/egoisutolabs/variant-component-setup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: egoisutolabs (https://skillmd.com/u/egoisutolabs)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/egoisutolabs/variant-component-setup

---


# Variant Component Setup (Mercury)

Figma's variant system has a hard rule that trips every first-time MCP caller:
**variant properties can only be added to a COMPONENT_SET, never to a plain
COMPONENT.** If you try, you get "Can only add variant property to a component
set" and the call fails.

The correct sequence is: promote → clone once per variant combination → move
off-canvas → combine-variants → then add-property.

## The full procedure

### 1. Plan the variant axes

Ask (or infer from the designer's request) the axes and values. Examples:

- 1 axis: `state = [default, hover, pressed, disabled]` → 4 variants
- 2 axes: `size = [sm, md, lg]` × `variant = [primary, secondary]` → 6 variants
- 3 axes: multiply. Be honest when the matrix gets large; >12 variants usually
  means one axis is wrong.

### 2. Promote the source frame to a component

If the node is still a FRAME or GROUP, call
`mcp__mercury__component op:"create"` with its id. It becomes a COMPONENT
(singular).

### 3. Move the source component off the working screen

**Gotcha:** If the source component sits on a screen frame, the combine step
in `mcp__mercury__component op:"combine-variants"` will relocate the whole
component set and the screen loses the original placement. Before combining,
use `mcp__mercury__nodes op:"move"` to park the source somewhere off-canvas
(e.g., x: −2000). Better: put it on a separate "Components" page via
`mcp__mercury__page op:"create"` and `op:"set-current"`.

### 4. Clone one component per variant combination

For each combination (cartesian product of axis values), call
`mcp__mercury__nodes op:"clone"` on the source component. You now have N
COMPONENT nodes — still plain components, not yet a set.

### 5. Name each clone with the variant property syntax

Figma uses `Property=Value, Property=Value` naming on COMPONENTs for the
combine step to infer the variant axes. Rename each clone via
`mcp__mercury__patch`:

- `state=default`
- `state=hover, size=md`
- `variant=primary, size=lg`

No quotes, no spaces around `=`. Comma-separated for multi-axis.

### 6. Style each clone to match its variant

Apply the per-variant differences (fills, strokes, text, opacity, instance
swaps of child icons). Batch with `mcp__mercury__batch` to keep it atomic.

### 7. Combine into a COMPONENT_SET

Call `mcp__mercury__component op:"combine-variants"` with the array of clone
ids. This returns a single COMPONENT_SET id. The axis names and values are
inferred from the clone names set in step 5.

### 8. Rename the set

The combined set's default name is something like "Property 1". Rename via
`mcp__mercury__patch` to the semantic name ("Button", "Input", "Card").

### 9. (Optional) Add bound properties

For non-variant properties (TEXT, BOOLEAN, INSTANCE_SWAP), now call
`mcp__mercury__component op:"add-property"` on the COMPONENT_SET:

- `type: "TEXT"` — e.g., `label` for a button string
- `type: "BOOLEAN"` — e.g., `showIcon`
- `type: "INSTANCE_SWAP"` — e.g., `icon` for icon-swappable slots.
  **Gotcha:** `preferredValues` rejects string IDs. Either omit the field or
  pass objects of the form `{ type: "COMPONENT", key: "..." }`.

Then `op: "bind-property"` to wire each property to the specific child
node/field inside each variant.

## Why not shortcut by adding properties to the source component first?

You can't. `type: VARIANT` on a plain COMPONENT returns
"Can only add variant property to a component set". Non-variant property
types (TEXT/BOOLEAN/INSTANCE_SWAP) *are* allowed on plain components, but you
still need the set for variant axes, so the order above is the only order
that works.

## Workflow summary (happy path)

```
ping
query { op: "selection" }                    # confirm source id
component { op: "create", id: <source> }     # promote to COMPONENT
page { op: "create", name: "Components" }    # optional, recommended
page { op: "set-current", id: <componentsPage> }
nodes { op: "clone", id: <source> }          # repeat per variant
batch {
  ops: [
    { tool: "patch", params: { id: <clone1>, name: "state=default" } },
    { tool: "patch", params: { id: <clone2>, name: "state=hover" } },
    # ...style tweaks as additional patch/paint ops...
  ]
}
component { op: "combine-variants", ids: [...] }   # → COMPONENT_SET id
patch { id: <set>, name: "Button" }
component { op: "add-property", setId: <set>, propertyType: "TEXT", name: "label" }
component { op: "bind-property", ... }
```

## When things go wrong

- **"Can only add variant property to a component set"** — You called
  `add-property type:VARIANT` on a COMPONENT. Combine first.
- **Source screen lost its button** — You combined variants while the source
  was still on the screen. Undo, move source off-canvas, retry.
- **`preferredValues` rejected** — You passed string IDs. Use object form or
  omit the field.
- **Variant axes are wrong in the set** — Clone naming in step 5 was wrong.
  Figma infers axes from the `Property=Value` format. Fix names and
  re-combine.

