* 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. |
||
|---|---|---|
| .. | ||
| docs | ||
| scripts | ||
| src | ||
| tests | ||
| AGENTS.md | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsconfig.test.json | ||
| tsdown.config.ts | ||
@open-pencil/fig
.fig file-format package for OpenPencil.
The package owns the outer .fig archive boundary and is the staged home for Figma-specific
SceneGraph conversion policy. Production SceneGraph read/write remains available through
@open-pencil/core/io while conversion modules move behind this package's public API.
Current ownership:
- Complete
.figarchive parsing throughparseFigBuffer() .figarchive assembly throughwriteFigArchive()- Canvas payload and image resource handling
readFigContainer()/writeFigContainer()helpers for rawfig-kiwipayloads.figsource and archive result types- NodeChange-to-SceneGraph property conversion, including styles, plugin metadata, text, paint, vector, and font policy, through
@open-pencil/fig/node-change - Component-property, symbol-override, derived-symbol-data, and instance synchronization policy through
@open-pencil/fig/instance-overrides - Effective raw-metadata precedence and invalidation over SceneGraph's format-neutral edited-field tracking
- SceneGraph-to-
NodeChangeexport conversion with an explicit text-shaping runtime service for saved glyphs - Package-local archive, conversion, instance, export, and dist smoke tests
Architecture documentation
Start with the package docs for the source model, instance evaluation, materialization, document sessions, export, and validation contracts.
Planned ownership:
- Oracle-backed
.figfixtures
Non-goals:
- Generic Kiwi schema/runtime internals — use
@open-pencil/kiwi - Format-neutral IO registration, export targeting, CanvasKit thumbnails, or browser workers — use
@open-pencil/core/io - Editor actions, renderer behavior, Vue/app UI, CLI formatting, or MCP transport
This follows the existing @open-pencil/pen pattern: a format package owns its source model/parser
and SceneGraph policy, while core registers it in the shared IO system.
Checks
cd packages/fig
bun run check