Skip to content

feat: let create_component componentize an existing node (fromNodeId)#5

Merged
awdr74100 merged 1 commit into
mainfrom
feat/componentize-from-node
Jun 24, 2026
Merged

feat: let create_component componentize an existing node (fromNodeId)#5
awdr74100 merged 1 commit into
mainfrom
feat/componentize-from-node

Conversation

@awdr74100

Copy link
Copy Markdown
Owner

What

create_component gains an optional fromNodeId: convert an existing node into a reusable main component (figma.createComponentFromNode) instead of only creating an empty one.

create_component({ fromNodeId?, parentId?, name?, x?, y?, width?, height? }) -> { ok, nodeId, name, type }

Tool count unchanged (enhancement, not a new tool).

Why

Discovered while exploring import_svg: it drops a frame of raw vectors, but there was no way to turn that (or any built frame) into a reusable componentcreate_component only made an empty one. This closes the loop: import_svgcreate_component (fromNodeId) → create_instance = the same structure as the file's own icon components (a COMPONENT + linked instances).

Behaviour

  • fromNodeId given → createComponentFromNode replaces the node in place, keeping its parent/position unless parentId is passed. Rejects PAGE/DOCUMENT/COMPONENT/COMPONENT_SET with a clear error.
  • fromNodeId omitted → empty component, exactly as before (no regression).

Batch faithfulness (the correctness bit)

create_component stays batchable as an empty create, but fromNodeId is rejected inside a batch: componentizing consumes the source node, so the generic "undo = remove the created node" would destroy the original — no faithful inverse. Same principle that already excludes delete_* / swap_component from batch. Rejected at validate time (capture phase), before any mutation.

Verification

  • pnpm typecheck && pnpm lint && pnpm format:check && pnpm knip && pnpm build && pnpm test — green (681 tests / 131 files).
  • New tests: handler fromNodeId (componentizes in place, no reparent; not-found / non-componentizable throw) + batch rejects create_component {fromNodeId} at validate time.
  • Live round-trip pending (needs MCP reconnect): import_svgcreate_component fromNodeIdcreate_instance → confirm the instance links back to the new component; confirm a batch with fromNodeId is rejected.

Pass fromNodeId to convert an existing node — e.g. the vectors from an
import_svg logo/icon, or a built frame — into a reusable component via
figma.createComponentFromNode, then create_instance it. That completes
the SVG-to-reusable-icon path: import_svg -> create_component fromNodeId
-> create_instance. Omit fromNodeId to create an empty component
(behaviour unchanged).

createComponentFromNode replaces the node in place, so the component
keeps the node's parent/position unless parentId is given. Guarded in
batch: fromNodeId consumes the source node and has no faithful inverse,
so it is rejected at batch validate time (an empty create stays
batchable).

Enhancement to an existing tool — tool count unchanged. Full gate green
(681 tests).
@awdr74100 awdr74100 merged commit bfca6ec into main Jun 24, 2026
2 checks passed
@awdr74100 awdr74100 deleted the feat/componentize-from-node branch June 24, 2026 19:58
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.

1 participant