fix: preserve Figma frame dimensions for editable clipboard copy - #36
Merged
Conversation
Copy for Figma (editable) produced a tiny empty rectangle in Figma when the Satori HTML lacked inline width/height on the outer element. The regex-based parseHtmlViewport fell back to defaults or zeros, collapsing the root frame so no child nodes were visible. - Persist frame width/height as first-class screen fields at paste time - Resolve viewport from stored dimensions first, regex as fallback for older screens - Clamp root frame size to a 100x100 minimum in the DOM traversal to keep pasted content selectable even when dimensions are missing - Backfill sourceWidth/sourceHeight for older .drawd files in importFlow
After the dimension fix, the pasted frame was the correct size but most content was invisible: text rendered as empty and inline SVG icons produced empty FRAME subtrees. Two blind spots in the DOM traversal: - makeTextNode forwarded the first token of the CSS font-family stack (e.g. "-apple-system") straight into Figma. That is a CSS system keyword, not a registered Figma font, so Figma rendered the text blank. Added sanitizeFontFamily to skip system keywords and generic families, falling back to Inter. - Inline <svg> icons paint via SVG fill/stroke attributes, which the container path ignores (it only reads CSS background/border). Every path/circle became an empty FRAME. <svg> is now collapsed into a single colored RECTANGLE placeholder derived from stroke/fill/ currentColor, with a circular corner radius when the SVG contains a <circle> at a square aspect.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
width:...px/height:...pxon the outer element. The root frame collapsed to default or zero dimensions and hid all children.sourceWidth,sourceHeight) at Figma paste time, resolve them preferentially over regex-parsing the HTML, and clamp the DOM-traversal root frame to a 100x100 minimum so pasted content is always visible/selectable.-apple-system,system-ui, ...) and generic families never reach Figma, falling back toInter.<svg>icons into a single coloredRECTANGLEplaceholder at the SVG's bounding box (color derived fromstroke/fill/currentColor; circular corner radius when the SVG contains a<circle>at a square aspect).sourceWidth/sourceHeightinimportFlow.jsfor older.drawdfiles so existing documents continue to open cleanly.Changes
src/hooks/useFigmaPaste.js– captureframe.width/frame.heightfromconvertFigmaBufferalongsidesourceHtmlwhen creating the screen.src/hooks/useScreenManager.js– addsourceWidth/sourceHeightto themakeScreenfactory defaults.src/utils/copyToFigma.js– addresolveViewport(screen)that prefers stored dimensions and falls back to the existingparseHtmlViewportregex; replace allparseHtmlViewportcall sites in the editable-copy path.src/utils/importFlow.js– defaultsourceWidth/sourceHeighttonullfor pre-existing flows.mcp-server/src/figma-export/dom-traversal.js– clamp root framewidth/heightto a 100x100 minimum; addsanitizeFontFamilyhelper and swap the three text-node call sites to use it; special-case<svg>to emit a visible colored placeholder instead of recursing.Test plan
npm run lintcleannpm test– 648/648 passingfontRequirements).drawdfile, run the same copy: regex fallback keeps working for screens without stored dimensionsFollow-ups (out of scope)
vectorNetwork(non-trivial reverse ofvectorNetworkToSvgPathinfigmaToHtml.js).NODE_CHANGESmessage so Figma pre-resolves them before render; eliminates the "blank text until reload" behavior.figmaToHtml.js'sresolveFontFamilyso designer-chosen families survive instead of always landing onInter.