Skip to content

Grida Canvas - IO Figma Fixes & Improvements#481

Merged
softmarshmallow merged 9 commits intomainfrom
canary
Dec 24, 2025
Merged

Grida Canvas - IO Figma Fixes & Improvements#481
softmarshmallow merged 9 commits intomainfrom
canary

Conversation

@softmarshmallow
Copy link
Copy Markdown
Member

@softmarshmallow softmarshmallow commented Dec 24, 2025

Release Notes

  • New Features

    • Improved component and instance copying from Figma with enhanced payload handling
    • Support for component instance flattening
  • Bug Fixes

    • Fixed vector coordinate mapping for proper size normalization scaling
    • Enhanced root-level property overrides for copied instances
  • Documentation

    • Expanded clipboard payload structure documentation for components and variants
    • Added vector network coordinate mapping guidance
  • Tests

    • Comprehensive clipboard tests for components, instances, and variant scenarios
    • Vector scaling and override preservation verification tests

@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 24, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs Ready Ready Preview, Comment Dec 24, 2025 7:11am
grida Ready Ready Preview, Comment Dec 24, 2025 7:11am
5 Skipped Deployments
Project Deployment Review Updated (UTC)
code Ignored Ignored Dec 24, 2025 7:11am
legacy Ignored Ignored Dec 24, 2025 7:11am
backgrounds Skipped Skipped Dec 24, 2025 7:11am
blog Skipped Skipped Dec 24, 2025 7:11am
viewer Skipped Skipped Dec 24, 2025 7:11am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 24, 2025

Walkthrough

This PR enhances the Figma clipboard import pipeline by introducing buildClipboardRootNodes to streamline clipboard-to-root node conversion, adds vector network scaling for normalizedSize coordinate space mapping, and implements instance flattening via a new BuildTreeOptions configuration. Includes stroke support for instances and frames, root-level symbol overrides handling, and comprehensive fixture-based tests for clipboard scenarios.

Changes

Cohort / File(s) Summary
Documentation
docs/wg/feat-fig/glossary/fig.kiwi.md
Adds observed patterns for component sets in clipboard payloads (frame structure, variant copying behavior), detailed notes on vector node coordinate mapping from vectorData.normalizedSize space to node space, and documented VectorNetwork structure.
Documentation
fixtures/test-fig/clipboard/README.md
Expands clipboard fixtures README with component/instance payload structure documentation, component set representation rules, copy scenarios for container/component/instance variants, and group-to-frame behavior detection logic.
Examples
editor/grida-canvas-hosted/playground/examples.ts
Adds new canvas example entry for "Happy New Year 2026" poster.
Canvas Data Transfer
editor/grida-canvas-react/use-data-transfer.ts
Refactors clipboard conversion pipeline to use single iofigma.kiwi.buildClipboardRootNodes call instead of manual NodeChanges reconstruction; updates error messaging for unsupported nodes.
Core Library - Figma IO
packages/grida-canvas-io-figma/lib.ts
Introduces BuildTreeOptions type with flattenInstances flag; adds buildClipboardRootNodes function for streamlined root extraction; implements vector network scaling via scaleVectorNetworkFromNormalizedSize; adds stroke trait support for instances/frames; handles root-level symbol overrides; extends parseFile signatures to accept options; updates convertPageToScene with shared node_id_generator for collision avoidance.
Tests - Clipboard Components
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-components.test.ts
Tests root resolution for component definitions and instances, verifying correct node types and exclusion of internal SYMBOL masters.
Tests - Clipboard Overrides
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-overrides.test.ts
Tests symbol override extraction and preservation on root instances; validates fill/stroke paint counts match override specifications.
Tests - Clipboard Text Overrides
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts
Tests TEXT node overrides within instance symbol overrides; verifies text content replacement when flattenInstances is enabled.
Tests - Vector Network
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.vector-network.test.ts
Regression test for vector network scaling; validates bounding box alignment when mapping from normalizedSize space to node size space.
Tests - Root Merging
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.fig.test.ts
Regression test ensuring multiple root frames are preserved during scene conversion without node ID collisions.
Clipboard Fixtures
fixtures/test-fig/components.fig
Updated git-lfs pointer (oid and size changed).
Clipboard Fixtures
fixtures/test-fig/clipboard/component-*\*.clipboard.html (13 files)
HTML clipboard fixture files for testing component definitions, instances, and component set variants in blue/red scenarios with and without overrides.

Sequence Diagram

sequenceDiagram
    participant User
    participant Canvas as Canvas UI
    participant Transfer as use-data-transfer
    participant Kiwi as iofigma.kiwi
    participant Factory as factory.node
    participant Scene as Insertable Scene

    User->>Canvas: Paste component/instance
    Canvas->>Transfer: onDataTransfer (HTML clipboard)
    Transfer->>Transfer: readHTMLMessage()
    Transfer->>Kiwi: buildClipboardRootNodes({<br/>  nodeChanges,<br/>  message,<br/>  options: {flattenInstances}})
    
    rect rgb(200, 220, 240)
        Note over Kiwi,Factory: Root Building Process
        Kiwi->>Kiwi: Build GUID maps
        Kiwi->>Kiwi: Attach children by parentIndex
        alt flattenInstances = true
            Kiwi->>Kiwi: Inline SYMBOL subtrees
            Kiwi->>Factory: Create flattened instances
            Factory->>Factory: Apply symbol overrides
            Factory->>Factory: Scale vector networks<br/>(normalizedSize → node space)
            Factory-->>Kiwi: Return processed nodes
        else flattenInstances = false
            Kiwi-->>Kiwi: Return root structure as-is
        end
    end
    
    Kiwi-->>Transfer: rootNodes[]
    Transfer->>Transfer: Validate roots found
    Transfer->>Scene: Insert root nodes
    Scene-->>Canvas: Nodes added to scene
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

The PR introduces substantial new functionality across the Figma IO library with heterogeneous changes: core library refactoring with new types and functions, vector scaling logic, instance flattening implementation, clipboard conversion pipeline changes, and an extensive fixture/test suite. Logic density is moderate-to-high in lib.ts, spanning symbol overrides, vector network transformations, and tree building with multiple configuration options.

Possibly related PRs

Suggested labels

canvas/io

Poem

🐰 A Kiwi clipboard now flows so clean,
Building roots through the Figma scene,
Instances flatten, vectors scale true,
Overrides nested, all symbols pass through!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.90% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Grida Canvas - IO Figma Fixes & Improvements' is vague and generic, using non-descriptive terms like 'Fixes & Improvements' that don't convey meaningful information about the specific changeset. Use a more specific title that highlights the primary change, such as 'Add clipboard root node building and vector network scaling' or 'Implement instance flattening and vector network support for clipboard operations'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch canary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…including support for root-level overrides and flattening instances
@vercel vercel Bot temporarily deployed to Preview – viewer December 24, 2025 07:07 Inactive
@vercel vercel Bot temporarily deployed to Preview – backgrounds December 24, 2025 07:07 Inactive
@vercel vercel Bot temporarily deployed to Preview – blog December 24, 2025 07:07 Inactive
@softmarshmallow softmarshmallow marked this pull request as ready for review December 24, 2025 07:08
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
packages/grida-canvas-io-figma/lib.ts (3)

1952-2025: Root-level symbolOverrides patching for instances is minimal but well-scoped

The new instance construction:

  • Builds a full InstanceNode once and then conditionally applies a “root patch” when the first symbolOverrides entry lacks guid/type/parentIndex, which matches the clipboard payloads you’re targeting.
  • Avoids touching targeted overrides (with guid), which are instead consumed later by flattenInstancesInPlace via symbolOverrideByGuid.

This strikes a good balance between fixing real clipboard cases and not over-implementing the full override system prematurely. The inline TODO(kiwi-overrides) is accurate and keeps expectations clear.


2057-2117: Vector network scaling hook in vectorNode is correct and matches the new tests

Wiring parseVectorNetworkBlob through scaleVectorNetworkFromNormalizedSize before emitting an X_VECTOR node:

  • Uses normalizedSize and size to compute per-axis scale factors and applies them uniformly to vertices and tangents.
  • Falls back to scale 1 when either dimension is missing or zero, which is safe and predictable.
  • Preserves the old VECTOR fallback path (with empty path strings) when no blob is available, so existing behavior is unchanged there.

The new vector-network test exercises this path and should catch regressions in the coordinate-space mapping.


2298-2637: Instance flattening and clipboard/page tree builders are thoughtfully structured

The new BuildTreeOptions + helpers (buildGuidToKiwiMap, buildFlatFigmaNodes, buildChildrenRelationsInPlace, flattenInstancesInPlace, buildClipboardRootNodes, buildCanvasRootNodes) form a coherent pipeline:

  • Building flat REST/IR nodes once and reusing guidToNode / guidToKiwi avoids repeated conversion.
  • Child attachment via parentIndex.guid + lexicographic position sorting mirrors Figma’s ordering model.
  • flattenInstancesInPlace + cloneTreeWithNewIdsAndFlattenInstances properly:
    • Inline component trees for INSTANCEs when flattenInstances is enabled.
    • Guard against component cycles via componentStack.
    • Apply targeted overrides by guid during cloning, while preserving root-level patches applied in instance().

The clipboard builder also correctly excludes children of internal-only canvases from the roots, treating those canvases as a component repository.

If you later need full override semantics (swaps, nested instance overrides, non-paint fields), you already have clear extension points and TODOs.

editor/grida-canvas-react/use-data-transfer.ts (1)

177-183: Centralized clipboard root-building looks correct and simplifies this path

Using iofigma.kiwi.buildClipboardRootNodes with { nodeChanges, message: parsed.message, options: { flattenInstances: true } } cleanly replaces the bespoke root-detection logic, and the updated error message gives much better feedback (total nodes vs insertable roots). No functional issues spotted; this should also keep behavior aligned with the shared iofigma build pipeline going forward.

Also applies to: 185-189

packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts (1)

5-8: Consider tracking the fixture replacement as technical debt.

The comment correctly identifies that this test uses handcrafted/mocked data instead of a real Figma clipboard fixture. While the test validates the override logic in isolation, it would be more robust with a real-world fixture.

Do you want me to open an issue to track adding a real clipboard fixture with text overrides? This would ensure the test validates against actual Figma clipboard format.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30f479c and 27d12d2.

📒 Files selected for processing (26)
  • docs/wg/feat-fig/glossary/fig.kiwi.md
  • editor/grida-canvas-hosted/playground/examples.ts
  • editor/grida-canvas-react/use-data-transfer.ts
  • editor/public/examples/canvas/poster-happy-new-year-2026.grida
  • fixtures/test-fig/L0/components.fig
  • fixtures/test-fig/clipboard/README.md
  • fixtures/test-fig/clipboard/component-component-blue.clipboard.html
  • fixtures/test-fig/clipboard/component-component-instance-blue-with-overrides.clipboard.html
  • fixtures/test-fig/clipboard/component-component-instance-blue.clipboard.html
  • fixtures/test-fig/clipboard/component-component-instance-red-with-overrides.clipboard.html
  • fixtures/test-fig/clipboard/component-component-instance-red.clipboard.html
  • fixtures/test-fig/clipboard/component-component-red.clipboard.html
  • fixtures/test-fig/clipboard/component-component-set-component-blue.clipboard.html
  • fixtures/test-fig/clipboard/component-component-set-component-instance-blue-with-overrides.clipboard.html
  • fixtures/test-fig/clipboard/component-component-set-component-instance-blue.clipboard.html
  • fixtures/test-fig/clipboard/component-component-set-component-instance-red-with-overrides.clipboard.html
  • fixtures/test-fig/clipboard/component-component-set-component-instance-red.clipboard.html
  • fixtures/test-fig/clipboard/component-component-set-component-red.clipboard.html
  • fixtures/test-fig/clipboard/component-component-set.clipboard.html
  • fixtures/test-fig/clipboard/frame-with-stroke.clipboard.html
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-components.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-overrides.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.fig.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.vector-network.test.ts
  • packages/grida-canvas-io-figma/lib.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript 5 as the main language for most apps
Use Lucide or Radix Icons for icons

Files:

  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.vector-network.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-overrides.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts
  • editor/grida-canvas-hosted/playground/examples.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-components.test.ts
  • editor/grida-canvas-react/use-data-transfer.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.fig.test.ts
  • packages/grida-canvas-io-figma/lib.ts
{editor/**/*.{ts,tsx},packages/grida-canvas-*/**/*.{ts,tsx}}

📄 CodeRabbit inference engine (AGENTS.md)

Use DOM (plain DOM as canvas) for website builder canvas, bound with React

Files:

  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.vector-network.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-overrides.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts
  • editor/grida-canvas-hosted/playground/examples.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-components.test.ts
  • editor/grida-canvas-react/use-data-transfer.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.fig.test.ts
  • packages/grida-canvas-io-figma/lib.ts
packages/grida-canvas-*/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Packages under /packages/grida-canvas-* power the canvas; some are published to npm, refer to individual package README

Files:

  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.vector-network.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-overrides.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-components.test.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.fig.test.ts
  • packages/grida-canvas-io-figma/lib.ts
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Documentation source of truth is in the ./docs directory; deployment is handled by apps/docs

Files:

  • docs/wg/feat-fig/glossary/fig.kiwi.md
docs/{wg,reference}/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Only actively maintain docs/wg/** and docs/reference/** directories; see docs/AGENTS.md for contribution scope

Files:

  • docs/wg/feat-fig/glossary/fig.kiwi.md
editor/grida-*/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use /editor/grida-* directories to isolate domain-specific modules; promote well-defined modules to /packages

Files:

  • editor/grida-canvas-hosted/playground/examples.ts
  • editor/grida-canvas-react/use-data-transfer.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T23:30:42.112Z
Learning: Applies to packages/grida-canvas-*/**/*.{ts,tsx,js,jsx} : Packages under /packages/grida-canvas-* power the canvas; some are published to npm, refer to individual package README
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.201Z
Learning: Applies to crates/grida-canvas/**/*.grida : Validate .grida files using the `tool_io_grida` CLI tool to check file structure, parse all nodes, and detect parsing errors
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.201Z
Learning: Applies to crates/grida-canvas/**/*.rs : Run `cargo fmt` to maintain code formatting standards
📚 Learning: 2025-12-01T00:22:19.083Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-wasm/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:19.083Z
Learning: Applies to crates/grida-canvas-wasm/**/main.rs : Update `grida-canvas-wasm.d.ts` TypeScript definitions file when new APIs are introduced via `main.rs`

Applied to files:

  • editor/grida-canvas-hosted/playground/examples.ts
  • packages/grida-canvas-io-figma/lib.ts
📚 Learning: 2025-12-14T23:30:42.112Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T23:30:42.112Z
Learning: Applies to packages/grida-canvas-*/**/*.{ts,tsx,js,jsx} : Packages under /packages/grida-canvas-* power the canvas; some are published to npm, refer to individual package README

Applied to files:

  • editor/grida-canvas-hosted/playground/examples.ts
  • packages/grida-canvas-io-figma/lib.ts
📚 Learning: 2025-12-14T23:30:42.112Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T23:30:42.112Z
Learning: Applies to {editor/**/*.{ts,tsx},packages/grida-canvas-*/**/*.{ts,tsx}} : Use DOM (plain DOM as canvas) for website builder canvas, bound with React

Applied to files:

  • editor/grida-canvas-react/use-data-transfer.ts
📚 Learning: 2025-12-01T00:22:56.899Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : When adding new shape types, update the Shape type union, add cases in drawShape() function, add cases in shapeToSVG() function, and add SelectItem in UI

Applied to files:

  • packages/grida-canvas-io-figma/lib.ts
📚 Learning: 2025-12-01T00:22:56.899Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : Use Canvas 2D API with path commands for rendering geometric shapes (circle, square, triangle, etc.)

Applied to files:

  • packages/grida-canvas-io-figma/lib.ts
📚 Learning: 2025-12-01T00:22:56.899Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : For SVG export, convert circles to <circle> elements, rectangles to <rect> elements, and polygons to <polygon> elements with calculated points

Applied to files:

  • packages/grida-canvas-io-figma/lib.ts
🧬 Code graph analysis (5)
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.vector-network.test.ts (2)
packages/grida-canvas-io-figma/fig-kiwi/index.ts (2)
  • readFigFile (250-283)
  • getBlobBytes (344-351)
packages/grida-canvas-io-figma/index.ts (1)
  • iofigma (7-7)
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-overrides.test.ts (3)
editor/eslint.config.mjs (1)
  • __dirname (6-6)
packages/grida-canvas-io-figma/index.ts (1)
  • iofigma (7-7)
crates/grida-canvas/src/node/scene_graph.rs (1)
  • roots (206-208)
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts (2)
crates/grida-canvas/src/node/scene_graph.rs (1)
  • roots (206-208)
packages/grida-canvas-io-figma/index.ts (1)
  • iofigma (7-7)
packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-components.test.ts (3)
editor/eslint.config.mjs (1)
  • __dirname (6-6)
crates/grida-canvas/src/node/scene_graph.rs (1)
  • roots (206-208)
packages/grida-canvas-io-figma/index.ts (1)
  • iofigma (7-7)
packages/grida-canvas-io-figma/lib.ts (3)
packages/grida-canvas-schema/grida.ts (1)
  • NodeChange (1319-1319)
crates/grida-canvas/src/painter/layer.rs (1)
  • paints (220-224)
packages/grida-canvas-io-figma/fig-kiwi/index.ts (2)
  • readFigFile (250-283)
  • ParsedFigmaArchive (82-85)
🪛 Gitleaks (8.30.0)
fixtures/test-fig/clipboard/component-component-set-component-blue.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-instance-blue-with-overrides.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-instance-blue.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-set-component-instance-blue.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-set-component-instance-red-with-overrides.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-set-component-instance-red.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-instance-red.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-instance-red-with-overrides.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-set.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-blue.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-set-component-red.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/frame-with-stroke.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

fixtures/test-fig/clipboard/component-component-set-component-instance-blue-with-overrides.clipboard.html

[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (35)
fixtures/test-fig/L0/components.fig (1)

1-3: Git LFS pointer update is valid.

The Figma fixture file has been updated with a new object ID and increased size (28,343 → 29,545 bytes), which aligns with the PR's introduction of expanded clipboard test fixtures. The Git LFS pointer format is correct and valid.

editor/grida-canvas-hosted/playground/examples.ts (1)

32-36: Entry is correctly structured and the referenced file exists.

The new example entry at lines 32-36 follows the established pattern perfectly, with the .grida file already present at editor/public/examples/canvas/poster-happy-new-year-2026.grida. The id, name, and url properties are consistent with all other entries in the array.

fixtures/test-fig/clipboard/README.md (2)

65-127: Excellent payload structure documentation with clear verification.

The detailed documentation of Component/Instance and Component set payload structures is technically accurate and well-organized. The distinction between user-facing canvas and internal-only canvas is clearly explained, and the fixture verification sections provide specific references for validation.

Particularly strong points:

  • Clear explanation of INSTANCE-to-SYMBOL linkage via symbolData.symbolID
  • Practical patterns covering all three clipboard scenarios (container, variant, instance)
  • Systematic documentation of both component sets (FRAME) and variants (SYMBOL)
  • Verification sections cite specific fixtures for reproducibility

43-64: Comprehensive and well-structured fixture table.

The expanded Contents table clearly documents all clipboard fixture scenarios with appropriate categorization by source and usage. The systematic naming convention (blue/red variants, with/without overrides) makes the fixture coverage easy to understand. All referenced fixture files exist at the expected paths.

docs/wg/feat-fig/glossary/fig.kiwi.md (3)

266-292: Clear documentation of component-set clipboard patterns with fixture references.

The new subsection documenting how component sets appear in clipboard payloads is well-structured and practical. The three scenarios (container copy, variant copy, instance copy) are clearly differentiated, and the fixture references are specific and helpful for verification.


293-336: Comprehensive guide to components and instances in clipboard payloads.

The new "Components & Instances (clipboard payloads)" section effectively bridges glossary documentation and practical clipboard handling. The structure (node types → internal-only canvas → observed patterns) flows logically, and the four distinct scenarios are clearly explained with specific fixture references.

Strengths:

  • Explains the role of internal-only canvas for non-user-facing definitions
  • Clarifies the INSTANCE-to-SYMBOL linkage across all scenarios
  • Fixture references are comprehensive and specific

343-358: Technically sound explanation of vector coordinate space mapping.

The new subsection on vector network coordinate space clearly documents the normalizedSize vs. size distinction and provides practical scaling guidance with proper mathematical notation. This directly supports the PR's vector scaling improvements.

The explanation effectively conveys:

  • Why the coordinate space matters (avoiding mis-positioned/mis-sized vectors)
  • How to apply scaling to both vertex positions and segment tangents
  • The caveat about potential bbox origin translations

All referenced fixture files exist at their documented paths.

packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.fig.test.ts (1)

193-276: Good, focused regression coverage for root merge / ID-collision bug

The mock FigPage and assertions accurately exercise the multi-root merge path without node_id_generator, and will catch regressions in the shared ID generator logic in convertPageToScene.

fixtures/test-fig/clipboard/component-component-set-component-red.clipboard.html (1)

1-5: Static Figma clipboard fixture looks fine

Structure matches existing clipboard fixtures (charset + figmeta + figma buffer), and the large base64 payload is expected binary scene data. The reported “generic API key” here is a typical false positive on opaque fixture blobs rather than an actual secret.

fixtures/test-fig/clipboard/component-component-set-component-instance-blue.clipboard.html (1)

1-5: Clipboard instance (blue) fixture is consistent and self-contained

The markup follows the established clipboard-fixture pattern and safely encapsulates the binary payload for tests.

fixtures/test-fig/clipboard/frame-with-stroke.clipboard.html (1)

1-5: Frame-with-stroke fixture correctly follows existing clipboard format

Looks appropriate for exercising stroke handling on clipboard-imported frames; no issues.

fixtures/test-fig/clipboard/component-component-set-component-blue.clipboard.html (1)

1-5: Component-set (blue) clipboard fixture is well-formed

Static data-only fixture, consistent with other component/component-set clipboard assets.

fixtures/test-fig/clipboard/component-component-blue.clipboard.html (1)

1-5: Component (blue) clipboard fixture matches the rest of the test corpus

No issues; this extends coverage for component clipboard scenarios.

packages/grida-canvas-io-figma/lib.ts (5)

1007-1023: Stroke trait inclusion for FRAME / COMPONENT / INSTANCE is a sensible extension

Adding ...stroke_trait(node) to these container types ensures stroke metadata is preserved consistently for frames, components, and instances, aligning them with shapes like rectangles/ellipses. Downstream Grida nodes now get a uniform stroke representation without special-casing these node types.


2139-2199: scaleVectorNetworkFromNormalizedSize implementation looks mathematically sound

The scaler:

  • Computes sx / sy as size / normalizedSize with robust guards against zero/undefined.
  • Returns the original network when both scales are 1, avoiding unnecessary allocations.
  • Scales both vertex positions and segment tangents, leaving region topology untouched, which is exactly what’s needed.

Given the surrounding comments and test coverage, this is a solid, self-contained utility.


2667-2733: Propagating BuildTreeOptions through parseFile / extractPages / buildPageTree is clean

The updated signatures:

  • Keep options optional with a default {} on both parseFile and FigImporter.parseFile, so all existing call sites remain valid.
  • Plumb those options down into buildPageTreebuildCanvasRootNodes, unifying the tree-building behavior between .fig imports and clipboard handling.

This is a straightforward and backwards-compatible extension of the API.


2738-2793: Shared node_id_generator in convertPageToScene correctly fixes root-merge collisions

The new logic:

  • Creates a sharedNodeIdGenerator (either the caller’s generator or a Date.now() + counter fallback) and injects it into a derived sharedContext.
  • Ensures every restful.factory.document invocation in the loop uses this shared generator instead of per-call fallbacks, avoiding ID collisions when multiple roots are converted and then merged.
  • Leaves gradient_id_generator and other context fields untouched.

This directly addresses the regression covered by the new “should not drop roots when merging” test.


2800-2813: FigImporter static API remains backwards compatible while exposing options

The class wrapper now simply forwards options to the underlying functions:

  • FigImporter.parseFile(fileData, options)kiwi.parseFile(fileData, options)
  • FigImporter.convertPageToScene(page, context)kiwi.convertPageToScene(page, context)

Callers not passing an options object still get the same behavior, while newer callers can opt into flattenInstances and related behaviors without touching existing code.

packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.vector-network.test.ts (1)

1-93: Strong regression test for vectorNetwork scaling from normalizedSize to size

This test:

  • Carefully selects a VECTOR candidate with meaningful normalizedSize vs size differences.
  • Validates the bbox of the raw parsed network against the bbox of the scaled network produced by iofigma.kiwi.factory.node.
  • Asserts both dimensions and origin within a tight tolerance, which will catch subtle mistakes in the scaling logic.

The explicit guards and fixture-based approach make this a solid, low-noise regression test.

fixtures/test-fig/clipboard/component-component-red.clipboard.html (1)

1-5: Clipboard fixture structure LGTM

HTML markup (figmeta metadata, figma buffer, and whitespace span) is consistent with the existing clipboard fixtures and suitable for automated tests.

fixtures/test-fig/clipboard/component-component-instance-red.clipboard.html (1)

1-5: Instance clipboard fixture looks valid

Follows the same figmeta + figma buffer pattern as the other fixtures; appropriate for exercising component-instance clipboard scenarios in tests.

fixtures/test-fig/clipboard/component-component-set-component-instance-red.clipboard.html (1)

1-5: Component‑set/instance clipboard fixture LGTM

Well-formed clipboard HTML fixture (charset, figmeta, figma buffer, whitespace span) matching the expected structure for component‑set + instance tests.

fixtures/test-fig/clipboard/component-component-set.clipboard.html (1)

1-5: Component‑set clipboard fixture is consistent with the suite

Matches the other fixtures’ structure and is appropriate for testing component‑set root construction.

fixtures/test-fig/clipboard/component-component-instance-blue.clipboard.html (1)

1-5: Blue instance clipboard fixture looks good

Structurally identical to the red instance fixture with different payload, which is useful for variant coverage in tests.

fixtures/test-fig/clipboard/component-component-instance-red-with-overrides.clipboard.html (1)

1-5: Overrides-focused instance fixture is well-formed

This clipboard HTML follows the established figmeta/figma-buffer pattern and is appropriate for exercising symbol override behavior in tests.

fixtures/test-fig/clipboard/component-component-instance-blue-with-overrides.clipboard.html (1)

1-5: Blue instance + overrides fixture LGTM

Consistent HTML/clipboard structure with the other fixtures; suitable for override-related clipboard tests.

fixtures/test-fig/clipboard/component-component-set-component-instance-red-with-overrides.clipboard.html (1)

1-5: LGTM! Valid test fixture with false positive security warning.

This HTML fixture file contains base64-encoded Figma clipboard data for testing component-set instance scenarios with overrides. The static analysis warning about a "Generic API Key" is a false positive—this is legitimate test data, not sensitive credentials.

fixtures/test-fig/clipboard/component-component-set-component-instance-blue-with-overrides.clipboard.html (1)

1-5: LGTM! Valid test fixture with false positive security warning.

This HTML fixture file contains base64-encoded Figma clipboard data for testing the blue variant of component-set instance scenarios with overrides. The static analysis warning is a false positive—this is test fixture data, not sensitive credentials.

packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-components.test.ts (3)

1-12: LGTM! Clean imports and fixture path setup.

The imports and fixture path constants are well-organized and follow project conventions. Using __dirname for relative fixture paths is appropriate.


14-41: LGTM! Component definition tests are well-structured.

The tests for component definition copies follow a clear pattern and correctly validate that:

  • A single COMPONENT root is returned
  • The flattenInstances: true option is properly applied

The parallel blue/red test structure provides good coverage.


43-74: LGTM! Instance copy tests correctly validate flattening behavior.

The tests for instance copies properly validate that:

  • A single INSTANCE root is returned
  • Internal SYMBOL masters are excluded from roots
  • The helpful comment on lines 55-57 explains the expected behavior regarding internal-only canvas nodes

The negative assertion expect(roots.some((n) => n.type === "COMPONENT")).toBe(false) is particularly valuable for ensuring internal masters don't leak into the root set.

packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-text-overrides.test.ts (1)

70-87: LGTM! Test logic correctly validates text override behavior.

Despite using mocked data, the test effectively validates that:

  • buildClipboardRootNodes returns a single INSTANCE root with flattenInstances: true
  • TEXT node overrides from symbolOverrides are correctly applied
  • The overridden text characters are present in the final structure

The test assertions are clear and appropriate.

packages/grida-canvas-io-figma/__tests__/iofigma.kiwi.clipboard-overrides.test.ts (3)

1-16: LGTM! Clean setup with helpful utility function.

The imports, fixture paths, and findInstanceNc helper function are well-organized. The FILES array provides good coverage across blue/red and component/component-set variants.


18-45: LGTM! Comprehensive validation of paint override application.

The test correctly validates that symbolData.symbolOverrides are applied to INSTANCE nodes by:

  • Testing all fixture variants in a loop
  • Checking that override paints (fills/strokes) are present when defined
  • Using conditional assertions to handle cases where paints may be absent

The pattern of only asserting on fills/strokes when the override defines them is appropriate.


47-76: LGTM! Excellent validation of override preservation during flattening.

This test ensures that paint overrides are not lost when buildClipboardRootNodes flattens instances. The test:

  • Validates the expected single INSTANCE root structure
  • Confirms internal master nodes are excluded (comment on line 58 helpfully explains why)
  • Verifies override-produced paints survive the flattening process

The pattern of re-checking overrides after flattening provides strong confidence in the implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant