# Oanarina Bridge for Figma

Local development plugin for exchanging **supported editable layers** through `.oui` JSON. This is an independent plugin using Figma's public Plugin API. It does not read or write binary `.fig` files.

1. In Figma **desktop**, open a design file, then Plugins → Development → Import plugin from manifest.
2. Choose `manifest.json` in this folder. Run **Oanarina Bridge** from Development plugins.
3. Export selection, current page, or all pages. Open the resulting `.oui` in Oanarina through File → Open project.
4. In Oanarina, save/export a `.oui`. In the plugin, choose that file to add editable pages to Figma.

Development conversion covers page structure, names/hierarchy, basic shapes, configurable polygons/stars/arcs, cubic vector paths, single-style text metadata, fill paint stacks, shared stroke geometry, supported shadows/blur, independent corners row/column layout metadata, ruler/layout guides, and supported prototype navigation/overlay/scroll links. Fonts fall back with a report. Import creates new pages and rolls them back if an operation fails. Both version-one and version-two `.oui` documents are accepted.

Page canvas backgrounds transfer through the public single-solid `PageNode.backgrounds` property, including opacity and visibility. Optional Forma page metadata is validated before import. Unsupported page paints are reported and omitted; theme-following pages without an explicit override use the destination's default. This path has API-contract mock coverage and still needs actual Figma desktop acceptance. It does not change frame or prototype backgrounds. See the public [canvas background guide](https://www.oanarinaldi.com/ui-tool-guide.html#canvas-backgrounds), including when reading this guide from the standalone plugin ZIP.

Limits: gradients and rotation origin alignment are approximate. Complex gradient scale/skew, crop/rotation edge cases, mixed stroke widths/dashes, some sizing combinations and rich text need further work. Vector contours are fitted to the layer bounds, so contour offsets need review. Groups and sections import as frames. Supported instances remain linked; unsupported structures become independent frames with reports. Boolean results become editable paths without operand linkage. Variables, annotations, comments, variable/condition/variant reactions, many input triggers and full grid layout are not maintained. Component limits are described below. Known reductions appear in the report, which is not an exhaustive loss detector. SVG assets embedded in `.oui` are rejected by editable import; export/place SVG separately.

Automated tests use an API mock to check interchange and rollback. Synthetic fixtures were also imported/exported through the connected Figma Plugin API on October 29, 2026: eight editable layers covered text, shapes, effects, vectors and auto layout, with a separate text auto-height regression check. That check fixed layout activation changing fixed dimensions and sizing assignments resetting text auto-height. The sanitized exported fixture is checked by the local document parser. This is not the desktop development-plugin UI path; a real desktop round-trip remains required before production compatibility can be claimed. Figma may restrict development plugins based on account/organization policy.

Public API references: https://developers.figma.com/docs/plugins/ and https://developers.figma.com/docs/plugins/api/properties/nodes-exportasync/.


The current bridge also transfers supported click/drag/hover/press/mouse/delay triggers and standard/cubic prototype transitions. Key/gamepad/scroll triggers, authored variables and conditions, variant actions, overlay appearance, flow metadata and fixed/sticky positioning are omitted with reports. Mixed text ranges, custom underline appearance and font axis/OpenType settings are reduced to base text properties. Diagonal/vertical line layers become editable vectors; horizontal lines remain native lines. A rectangle/image containing children becomes an editable frame to retain hierarchy.

A separate five-node real connected-API regression confirmed three stretch columns with gutter/margin, a page ruler guide, vertical overflow, click navigation/dissolve, text vertical alignment and diagonal geometry. A later read confirmed persistence. It exposed stricter alignment-specific grid keys than generic public typings; the bridge now emits those runtime-compatible keys. The sanitized returned document is in tests/fixtures/bridge-prototype-roundtrip.json. That harness reused an existing synthetic page and did not run the desktop plugin UI. The service's Starter-plan call limit blocked the final screenshot request. Full desktop round-trip acceptance remains pending.

## Linked component transfer (0.2.0-dev.7 preview)

- Selection/page exports include needed main components and variant sets on a separate dependency page, including available cross-page/nested/swap targets; unrelated pages are excluded. Export loads invisible instance children and restores the caller's traversal preference. Published library identity is localized.
- Instances carry explicit main-child source IDs, ownership and supported override metadata. Matching uses ordered typed trees, never layer names or undocumented ID strings. Ambiguous structure, nested swaps or missing mains produce detached editable appearance with a report. Equal-to-default overrides are retained where the API proves them; ambiguous equal-default property overrides are reported with inheritance retained.
- Import creates definitions before real `createInstance()` instances, maps the generated descendants and never appends copied artwork into an instance. It restores sibling painter order after dependency-first creation. Unoverridden inherited fields stay inherited; supported explicit text/font, paint/stroke, effects, size, position, opacity, corner, visibility and clipping overrides remain editable. Other authored override fields materialize that instance as a frame rather than silently dropping its supported appearance.
- Native variant sets use `combineAsVariants`. Combinations must be unique and complete. Spatial default selection can differ from Forma's chosen default; positions are retained and the difference is reported.
- Single-target text, boolean and instance-swap definitions use actual API-returned property IDs; available per-instance values use `setProperties`. Source property IDs stay distinct from display names. Root bindings, multi-target controls, slots, exposed nested controls, preferred-value suggestions, variable bindings, exact property descriptions and published libraries are outside this contract. Source artwork and property defaults can differ in Forma; native binding may materialize a default on the main, which is reported. Stale property values are reported and omitted.
- Imports validate global IDs, types, ownership, property targets and values, swap dependencies, cycles and variant membership before creating pages. Limits: 20,000 total layers, 256 hierarchy levels, 1,000 sets and up to 1,000 properties per definition. A failed native operation rolls back all newly created pages and restores the previous page. The UI input limit remains 50 MB.

The new component checks use a strict API-contract mock with live inheritance, opaque generated IDs, immutable instance structure, font-loading requirements and injected failures. They **are not real Figma component acceptance**. Existing connected-API fixtures cover older shape/text/prototype paths only. The component connected-API attempt on 2026-10-29 was blocked by the account's tool quota before any content operation; no component UI or real component round trip is claimed.

Reference: [Figma component properties](https://developers.figma.com/docs/plugins/working-with-component-properties/), [instances](https://developers.figma.com/docs/plugins/api/InstanceNode/) and [component sets](https://developers.figma.com/docs/plugins/api/ComponentSetNode/).
