* fix(fig): keep filled frames fixed along the axis they fill Figma stores fill on the child and keeps that axis fixed in the frame's own sizing; a hugging value there wins over the stretch or grow. A row filled across a vertical card, or an instance stretched to the card's width, was written with its own sizing still hugging, so in Figma the row shrank and pushed its badge against the title, and the button shrank to its label. The .fig and clipboard writer now writes a filled axis as FIXED, both on the frame's own record and in an instance's sizing override, which Figma applies over the record. Unedited imported layers keep their stored sizing, since Figma's own files also hold hugging axes on stretched children. * fix(clipboard): keep how text resizes when copying to Figma The Figma clipboard writer forced every text record to a fixed size and layout version 5. Figma then kept the width OpenPencil measured instead of laying the text out in its own font, so labels it draws wider overflowed or wrapped: a pricing card's title ran under its badge and its button label broke onto two lines. Text now keeps the auto-resize and layout version the .fig writer gives it, as Figma's own files store them, and a paste into Figma 126 grows each label to fit. |
||
|---|---|---|
| .. | ||
| assets | ||
| src | ||
| tests | ||
| AGENTS.md | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsconfig.test.json | ||
| tsdown.config.ts | ||
@open-pencil/core
Editor engine for OpenPencil: the CanvasKit (Skia WASM) renderer, Yoga layout, the framework-agnostic editor with undo and selection, the Figma Plugin API compatibility layer, the AI/MCP tool definitions, clipboard and vector conversion, and format-neutral document I/O.
It depends on @open-pencil/scene-graph, @open-pencil/pen, @open-pencil/kiwi, and @open-pencil/fig, and keeps browser DOM out so it runs in the app, the CLI, the MCP server, and headless scripts alike.
Import the root barrel or the targeted subpaths listed in package.json exports, for example @open-pencil/core/io, @open-pencil/core/geometry, and @open-pencil/core/canvaskit.
Scripts get two globals through compileScript from @open-pencil/core/tools: figma, the Figma Plugin API over a document, and openpencil (OpenPencilAPI from @open-pencil/core/openpencil-api), what OpenPencil adds to it in the same style, such as making a component behave as a Reka UI control:
import { FigmaAPI } from '@open-pencil/core/figma-api'
import { compileScript } from '@open-pencil/core/tools'
await compileScript(`
const set = figma.currentPage.findOne((n) => n.name === 'Switch')
openpencil.setBehaviour(set, { kind: 'switch', values: { value: 'State' } })
`)(new FigmaAPI(graph))
- Programmable overview and SDK docs: https://openpencil.dev/programmable/
- Source and issues: https://github.com/open-pencil/open-pencil
MIT License.