openpencil/packages/scene-graph/src
Danila Poyarkov 7ee621ec41
feat: import and export W3C design tokens (#964)
* feat(core): read and write W3C design tokens

Variables export as DTCG 2025.10 token files, one per collection mode in the shape Figma imports, with text and effect styles as typography and shadow tokens and a resolver document that combines them. OpenPencil's own token fields ride in a dev.openpencil extension, so an export reads back as it was.

Import reads plain mode files, resolver documents, and Tokens Studio themes, plans what it would add, update, or skip against the document without changing it, and applies the plan as one undo step: values merge into variables by name, nothing is deleted, and an updated style updates the layers that use it.

* feat: import and export design tokens from the variables dialog

The stylesheet menu exports the document's variables and styles as a zip of W3C design tokens, and Import design tokens reads token files, folders, or a zip into a dialog that shows where each collection and mode goes, what would be added, updated, or skipped and why, before applying it as one undo step.

* feat: import and export design tokens from tools and the CLI

openpencil tokens --format dtcg --out <folder> writes the token files, design_to_tokens takes the same format, and import_design_tokens imports token files into a document for AI, MCP, and openpencil tool call. The editor and these paths share one apply step behind a target interface: the editor makes each change undoable, a headless document takes them directly.

Re-importing an export changes nothing it does not need to: values that match are left alone, layers that use an updated style are changed only outside instances, where they follow their component, and collections that share a name keep their own files apart.

* perf(core): index token lookups when planning an import

Resolving each reference scanned every token and variable, which made importing a large design system quadratic. A resolver now also finds files picked without their folders by name.

* docs: document design token import and export

* test: type the design token result in the tokens command test

* fix: lay out the design token import dialog as a mapping list

Each collection and mode sits beside the picker for where it goes, in one bordered list, so the pickers no longer read as headings. Skipped tokens use AppCollapsible, file problems AppAlert, and the counts move to the footer.

* fix: keep durations, variable metadata, and style edits through design token import

A duration Figma's format writes in seconds goes back into a variable that holds milliseconds. Tokens without OpenPencil's extension leave an updated variable's unit, scopes, and code syntax as they are. A style token whose value was edited in another tool takes that edit instead of the stale exact fields its extension still carries. Aliases to a repeated collection name resolve within one collection, a collection named Styles no longer collides with the resolver's styles set, and the dialog plans again when the document changes and right before applying. The editor imports the apply step directly rather than the whole format barrel.

* fix: keep effect order and explicit alias targets in design token import

Edited shadows take the places of the shadows they replace, so blurs keep their positions. An alias whose Figma data names a collection that is left out or absent is missing rather than bound to the same path in another collection. The resolver reserves the Styles set name only when there is a styles file.

* perf(cli): print token stylesheets without loading every page

A CSS or Tailwind stylesheet reads only variables, which load with the document, so tokens skips populating and laying out every page as variables already does. On an 85 MB design kit this takes the command from about seven minutes to seconds.
2026-10-08 16:53:46 +00:00
..
behaviours refactor: share behaviour control roles through dom-css (#960) 2026-10-07 20:06:16 +00:00
color feat: import and export W3C design tokens (#964) 2026-10-08 16:53:46 +00:00
components feat(scene-graph)!: let a SceneGraph take its ID generator (#887) 2026-10-05 08:21:22 +00:00
css fix: share CSS value parsing between dom-css and design JSX (#910) 2026-10-05 17:02:43 +00:00
fields feat(fig): occurrence-scoped instance interpretation as the single .fig reader 2026-10-01 11:20:27 +04:00
instances feat(collab)!: sync layer trees as a CRDT and open each room in its own tab (#902) 2026-10-06 10:40:25 +00:00
plugin-data feat: behaviours and preview mode (#893) 2026-10-06 13:23:05 +00:00
scaling fix: match Figma's transforms, strokes, booleans, sections, and names (#931) 2026-10-07 08:36:50 +00:00
slots feat: create, fill, and edit slots (#862) 2026-10-04 17:02:28 +00:00
transfer fix(fig): keep variable metadata, plugin data and default mode on save (#848) 2026-10-04 12:53:04 +04:00
variables fix: keep bound text and visibility in step with their variables (#954) 2026-10-07 18:37:15 +00:00
arrow-caps.ts feat(canvas): render arrow stroke caps on lines and open vectors 2026-08-31 21:25:38 +03:00
bindings.ts feat(editor): add shared style bindings 2026-07-17 20:28:22 +03:00
buffered-events.ts feat(fig): occurrence-scoped instance interpretation as the single .fig reader 2026-10-01 11:20:27 +04:00
checkpoint.ts fix(tools): guard checkpoint identities and share input schemas 2026-09-15 19:45:30 +03:00
constants.ts fix: meet WCAG AA contrast and name controls for screen readers (#952) 2026-10-07 17:51:24 +00:00
coordinate.ts fix: share Figma's creation and grouping between editor and plugin API (#919) 2026-10-06 12:28:52 +00:00
copy.ts feat(scene-graph)!: make a stroke a paint (#864) 2026-10-04 13:38:05 +04:00
events.ts feat: split SceneGraph and Pen packages 2026-06-30 10:54:32 +03:00
export-format.ts refactor(export): derive export format lists from the IO registry (#755) 2026-09-25 15:42:42 +04:00
export-scale.ts feat: split SceneGraph and Pen packages 2026-06-30 10:54:32 +03:00
font-style.ts fix(deps): patch collaboration websocket driver 2026-07-18 02:49:22 +03:00
geometry.ts fix(canvas): include arrow caps in bounds and controls 2026-08-31 21:25:38 +03:00
group-bounds.ts fix: match Figma's transforms, strokes, booleans, sections, and names (#931) 2026-10-07 08:36:50 +00:00
guides.ts perf: speed up opening large pages (#953) 2026-10-07 20:57:57 +00:00
hit-test.ts feat(canvas): select auto layout frames by their gaps and dot their children, as in Figma (#943) 2026-10-07 11:29:52 +00:00
images.ts fix(fig): use hex image hashes 2026-06-30 10:55:20 +03:00
index.ts fix(fig): keep the sizes Figma derived for instance layers when a page loads (#951) 2026-10-07 20:57:55 +00:00
instance-overrides.ts feat(fig): occurrence-scoped instance interpretation as the single .fig reader 2026-10-01 11:20:27 +04:00
instances.ts fix(fig): keep the sizes Figma derived for instance layers when a page loads (#951) 2026-10-07 20:57:55 +00:00
layout-guides.ts fix(editor): harden snapping edge cases 2026-08-19 12:33:32 +03:00
layout-sizing.ts fix(layout): size each axis on its own and lay out before geometry reads (#942) 2026-10-07 11:52:08 +00:00
matrix.ts feat: split SceneGraph and Pen packages 2026-06-30 10:54:32 +03:00
mutation-impact.ts fix(layout): size each axis on its own and lay out before geometry reads (#942) 2026-10-07 11:52:08 +00:00
node-defaults.ts fix: match Figma's transforms, strokes, booleans, sections, and names (#931) 2026-10-07 08:36:50 +00:00
order-keys.ts feat(collab)!: sync layer trees as a CRDT and open each room in its own tab (#902) 2026-10-06 10:40:25 +00:00
parse-path.ts fix(core): fill open subpaths of filled SVG paths (#876) 2026-10-04 13:25:23 +00:00
preview.ts feat(editor): checkpoint live interaction improvements 2026-09-15 11:36:17 +03:00
primitives.ts refactor: standardize acronym casing 2026-08-10 15:48:16 +03:00
random.ts feat(scene-graph)!: let a SceneGraph take its ID generator (#887) 2026-10-05 08:21:22 +00:00
resize.ts fix(fig): write text glyphs from the layout the renderer draws (#928) 2026-10-06 11:37:02 +00:00
shared-styles.ts feat(text): deepen typography controls 2026-07-17 22:40:52 +03:00
snap.ts feat(editor): add configurable snapping and guides 2026-08-18 19:11:48 +03:00
source-metadata.ts refactor(fig): own raw metadata invalidation 2026-07-18 02:22:01 +03:00
text-direction.ts refactor!: move shared primitives below dom-css and core (#771) 2026-09-26 11:39:11 +04:00
text-picture.ts feat(fig): occurrence-scoped instance interpretation as the single .fig reader 2026-10-01 11:20:27 +04:00
types.ts feat: show controls in a prebuilt demo and fix what saving it to .fig lost (#938) 2026-10-07 18:37:05 +00:00
undo.ts feat(ai): revert, regenerate, and edit chat turns (#844) 2026-10-06 09:54:42 +00:00
variables.ts fix: keep bound text and visibility in step with their variables (#954) 2026-10-07 18:37:15 +00:00
variant-name.ts feat: split SceneGraph and Pen packages 2026-06-30 10:54:32 +03:00
variant-properties.ts feat: behaviours and preview mode (#893) 2026-10-06 13:23:05 +00:00
vector-network.ts fix(figma-api): match Figma vector editing (#444) 2026-08-02 22:32:16 +03:00