Skip to content

0.89.0-beta#474

Merged
softmarshmallow merged 15 commits intomainfrom
canary
Dec 20, 2025
Merged

0.89.0-beta#474
softmarshmallow merged 15 commits intomainfrom
canary

Conversation

@softmarshmallow
Copy link
Copy Markdown
Member

@softmarshmallow softmarshmallow commented Dec 19, 2025

  • padding -> padding_top, padding_right, padding_bottom, padding_left
  • rm SVGPathNode
  • vector data as LUT

Summary by CodeRabbit

Release Notes

  • New Features

    • Improved Figma vector geometry handling with fill and stroke path support
  • Bug Fixes

    • Enhanced vector network conversion from Figma REST API responses
  • Refactor

    • Removed legacy SVGPath node type; vectors now use unified representation
    • Padding properties restructured as individual directional fields (top, right, bottom, left)
    • Test framework migrated from Jest to Vitest
  • Documentation

    • Updated naming conventions and schema documentation for new padding structure

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 19, 2025

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

Project Deployment Review Updated (UTC)
backgrounds Ready Ready Preview, Comment Dec 20, 2025 8:09am
blog Ready Ready Preview, Comment Dec 20, 2025 8:09am
docs Ready Ready Preview, Comment Dec 20, 2025 8:09am
grida Ready Ready Preview, Comment Dec 20, 2025 8:09am
viewer Ready Ready Preview, Comment Dec 20, 2025 8:09am
2 Skipped Deployments
Project Deployment Review Updated (UTC)
code Ignored Ignored Dec 20, 2025 8:09am
legacy Ignored Ignored Dec 20, 2025 8:09am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 19, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Comprehensive refactoring removing the SVGPath node type, transitioning container padding from a uniform value to per-side fields (padding_top/right/bottom/left), updating Figma REST API handling to use VectorNode with geometry traits instead of SVGPath, and migrating test infrastructure from Jest to Vitest. Schema version updated from 0.0.4-beta to 0.89.0-beta.

Changes

Cohort / File(s) Change Summary
SVGPath node type removal
packages/grida-canvas-schema/grida.ts, crates/grida-canvas/src/io/io_grida.rs, crates/grida-canvas/src/io/id_converter.rs, editor/grida-canvas-react-renderer-dom/nodes/svg-path.tsx, editor/grida-canvas-react-renderer-dom/nodes/index.ts, editor/grida-canvas-react-renderer-dom/nodes/node.tsx, editor/grida-canvas-react-starter-kit/starterkit-icons/node-type-icon.tsx, editor/grida-canvas/policy.ts, editor/grida-canvas/utils/supports.ts, crates/grida-canvas/examples/tool_convert_svgpath.rs, crates/grida-canvas/examples/tool_io_grida.rs
Removed SVGPathNode type from schema, eliminated dedicated SVGPath variant from JSONNode and Node unions, deleted SVGPath rendering component and example tools, removed svgpath from policy leaf-node constraints and fill support mappings.
Padding structure refactor
packages/grida-canvas-schema/grida.ts, crates/grida-canvas/src/io/io_grida.rs, editor/grida-canvas/editor.i.ts, editor/grida-canvas/editor.ts, editor/grida-canvas/reducers/node.reducer.ts, editor/grida-canvas/reducers/surface.reducer.ts, editor/grida-canvas/reducers/event-target.reducer.ts, editor/grida-canvas/reducers/schema/schema.ts, editor/grida-canvas/reducers/tools/initial-node.ts, editor/grida-canvas-react/provider.tsx, editor/grida-canvas-react/viewport/surface.tsx, editor/grida-canvas-utils/css.ts, editor/scaffolds/sidecontrol/controls/padding.tsx, editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
Replaced uniform padding property with four explicit per-side fields (padding_top, padding_right, padding_bottom, padding_left) across schema, IO, reducers, and UI controls; updated padding computation logic and CSS serialization.
Figma geometry handling upgrade
packages/grida-canvas-io-figma/lib.ts, packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.ts, packages/grida-canvas-io-figma/package.json
Added geometry-material trait detection and processing; replaced SVGPath-based node construction with VectorNode creation from fillGeometry/strokeGeometry paths; added @grida/vn dependency.
Example canvas files
editor/public/examples/canvas/slides-01.grida, editor/public/examples/canvas/instagram-post-01.grida, editor/public/examples/canvas/poster-01.grida, editor/public/examples/canvas/resume-01.grida, editor/public/examples/canvas/event-page-01.grida
Deleted five predefined canvas example files; remaining examples updated to new padding and version format.
Canvas example references
editor/grida-canvas-hosted/playground/examples.ts, editor/grida-canvas-hosted/playground/widgets/index.ts, crates/grida-canvas/AGENTS.md
Removed example entries and usage documentation; updated widget padding declarations to per-side format.
Version and schema updates
crates/grida-canvas-wasm/example/rectangle.grida, crates/grida-canvas-wasm/package.json, editor/public/examples/canvas/*, fixtures/test-grida/README.md, editor/scaffolds/editor/editor.tsx, editor/scaffolds/editor/init.ts, editor/scaffolds/editor/sync/agent-startpage.sync.tsx, packages/grida-canvas-io/__tests__/archive.test.ts
Updated version strings from 0.0.4-beta+20251209 to 0.89.0-beta+20251219 across manifests, fixtures, and test data.
Documentation and fixtures
docs/wg/feat-fig/glossary/fig.kiwi.md, docs/wg/feat-schema/naming-conventions.md, fixtures/test-figma/rest-api/L0/vector-frame.md, fixtures/test-figma/rest-api/L0/vector-frame.response.json
Added vector geometry documentation; updated naming conventions with padding fields; added Figma vector frame fixture.
Test infrastructure migration
packages/grida-canvas-color/jest.config.ts, packages/grida-canvas-io-figma/jest.config.ts, packages/grida-canvas-color/package.json, packages/grida-canvas-io/package.json, packages/grida-canvas-io/README.md, packages/grida-canvas-color/vitest.config.ts, packages/grida-canvas-io-figma/vitest.config.ts, packages/grida-canvas-io/vitest.config.ts, package.json
Removed Jest configurations; added Vitest configurations with globals enabled; updated test scripts from jest to vitest run; added vitest devDependency.
TypeScript configuration
packages/grida-canvas-color/tsconfig.json, packages/grida-canvas-io-figma/tsconfig.json, packages/grida-canvas-io/tsconfig.json
Added skipLibCheck: true to suppress library type-checking overhead.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Key areas requiring attention:

  • SVGPath removal completeness: Verify all rendering paths, type guards, and node factories correctly exclude svgpath; check that no stale references remain in switch statements or type unions.
  • Padding refactor consistency: Ensure all padding accessors, setters, and calculations correctly use per-side fields; validate CSS serialization and layout calculation logic properly handle the four-value representation.
  • Figma geometry conversion logic: Review the new geometry-material trait detection and VectorNode creation pipeline; verify fillGeometry and strokeGeometry paths are correctly transformed and positioned.
  • Test migration: Confirm Vitest configuration matches Jest feature parity (globals, timeouts); validate test suite structure and import paths are compatible with new runner.
  • Cross-file coordation: Verify schema changes propagate correctly through IO, reducers, React components, and utilities; check type safety across the padding-carrying call chain.

Possibly related PRs

  • Grida Canvas - Flex layout #437: Directly related—both refactor layout/flex system and padding representation (per-side padding on IPadding/JSONContainerNode, layout_wrap APIs) across overlapping files.
  • Daily RC #461: Both modify packages/grida-canvas-io-figma/lib.ts Figma import pipeline; main PR adds geometry→VectorNode conversion while related PR adds ID-generation and clipboard plumbing.
  • [Grida Canvas] Vector Network & Object Edit Mode #408: Related—both introduce/modify VectorNetwork rendering surface and remove SVG path node variants; add WASM bindings and stroke-overlay APIs.

Suggested labels

canvas, vector, schema, refactor

Poem

🐰 Hop along, the paths depart!
Per-side padding steals the chart,
SVGPath bids its last goodbye,
Vector networks rise and fly.
Jest gives way to Vitest's spring—
Schema's dancing, hear it ring! 🌸

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.17% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title '0.89.0-beta' is a version number that corresponds to the PR's main objective of bumping the schema version and implementing structural changes, but it is overly broad and vague. While it references a real change in the PR (version updates from 0.0.4-beta to 0.89.0-beta throughout), it does not clearly convey the primary technical changes: removal of SVGPathNode and the refactoring of padding properties from a single field to four directional fields. Consider a more descriptive title like 'Refactor padding to explicit properties and remove SVGPathNode' or 'Schema v0.89.0: flatten padding and deprecate SVGPath' to better communicate the main architectural changes to future readers.
✅ 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

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8425bba and db5309f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • fixtures/test-grida/README.md (2 hunks)
  • package.json (1 hunks)
  • packages/grida-canvas-color/jest.config.ts (0 hunks)
  • packages/grida-canvas-color/package.json (1 hunks)
  • packages/grida-canvas-color/tsconfig.json (1 hunks)
  • packages/grida-canvas-color/vitest.config.ts (1 hunks)
  • packages/grida-canvas-io-figma/jest.config.ts (0 hunks)
  • packages/grida-canvas-io-figma/package.json (1 hunks)
  • packages/grida-canvas-io-figma/tsconfig.json (1 hunks)
  • packages/grida-canvas-io-figma/vitest.config.ts (1 hunks)
  • packages/grida-canvas-io/__tests__/README.md (0 hunks)
  • packages/grida-canvas-io/package.json (1 hunks)
  • packages/grida-canvas-io/tsconfig.json (1 hunks)
  • packages/grida-canvas-io/vitest.config.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • packages/grida-canvas-io/tests/README.md
  • packages/grida-canvas-color/jest.config.ts
  • packages/grida-canvas-io-figma/jest.config.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/vitest.config.ts
  • packages/grida-canvas-io/vitest.config.ts
  • packages/grida-canvas-color/vitest.config.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/vitest.config.ts
  • packages/grida-canvas-io/vitest.config.ts
  • packages/grida-canvas-color/vitest.config.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/vitest.config.ts
  • packages/grida-canvas-io/vitest.config.ts
  • packages/grida-canvas-color/vitest.config.ts
{package.json,.nvmrc,.node-version}

📄 CodeRabbit inference engine (AGENTS.md)

Use Node.js 22 as the main runtime for most apps

Files:

  • package.json
🧠 Learnings (14)
📓 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: 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
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.)
📚 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:

  • packages/grida-canvas-color/tsconfig.json
  • packages/grida-canvas-io/tsconfig.json
  • packages/grida-canvas-io-figma/tsconfig.json
  • packages/grida-canvas-io/vitest.config.ts
  • packages/grida-canvas-io-figma/package.json
  • packages/grida-canvas-io/package.json
  • packages/grida-canvas-color/vitest.config.ts
  • packages/grida-canvas-color/package.json
📚 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:

  • packages/grida-canvas-color/tsconfig.json
  • packages/grida-canvas-io/tsconfig.json
  • packages/grida-canvas-io-figma/tsconfig.json
  • packages/grida-canvas-io-figma/vitest.config.ts
  • packages/grida-canvas-io/vitest.config.ts
  • packages/grida-canvas-io-figma/package.json
  • packages/grida-canvas-io/package.json
  • packages/grida-canvas-color/vitest.config.ts
  • packages/grida-canvas-color/package.json
  • fixtures/test-grida/README.md
📚 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/grida-*/**/*.{ts,tsx} : Use /editor/grida-* directories to isolate domain-specific modules; promote well-defined modules to <root>/packages

Applied to files:

  • packages/grida-canvas-color/tsconfig.json
  • packages/grida-canvas-io/tsconfig.json
  • packages/grida-canvas-io-figma/tsconfig.json
  • packages/grida-canvas-io/package.json
  • packages/grida-canvas-color/package.json
📚 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:

  • packages/grida-canvas-color/tsconfig.json
  • packages/grida-canvas-io/tsconfig.json
📚 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/**/+(grida-canvas-wasm.js|grida-canvas-wasm.wasm) : Include WASM artifacts (`grida-canvas-wasm.js` and `grida-canvas-wasm.wasm`) in git for faster CI builds

Applied to files:

  • packages/grida-canvas-color/tsconfig.json
  • packages/grida-canvas-io/tsconfig.json
  • packages/grida-canvas-io-figma/package.json
  • packages/grida-canvas-color/package.json
📚 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/**/*.{js,ts,jsx,tsx} : Use Web Workers for heavy graphics operations to improve performance and responsiveness

Applied to files:

  • packages/grida-canvas-color/tsconfig.json
  • packages/grida-canvas-io/tsconfig.json
  • packages/grida-canvas-io-figma/package.json
📚 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/lib/**/*.{ts,tsx} : Use /editor/lib for core, strictly designed modules with non-opinionated, reusable, and stable implementations

Applied to files:

  • packages/grida-canvas-io/tsconfig.json
📚 Learning: 2025-12-01T00:22:41.045Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:41.045Z
Learning: Applies to editor/**/next-env.d.ts : Include `next-env.d.ts` file in git for the project to avoid requiring dev/build runs for typechecking in CI environments

Applied to files:

  • packages/grida-canvas-io/tsconfig.json
  • packages/grida-canvas-io-figma/tsconfig.json
  • package.json
  • packages/grida-canvas-io/package.json
  • packages/grida-canvas-color/package.json
📚 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 **/*.{ts,tsx} : Use TypeScript 5 as the main language for most apps

Applied to files:

  • packages/grida-canvas-io/tsconfig.json
  • packages/grida-canvas-io-figma/tsconfig.json
  • package.json
  • packages/grida-canvas-color/package.json
📚 Learning: 2025-12-01T00:22:06.800Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-fonts/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:06.800Z
Learning: Applies to crates/grida-canvas-fonts/**/*.rs : Run all tests with: `cargo test`

Applied to files:

  • packages/grida-canvas-io-figma/package.json
📚 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: Run turbo typecheck to verify TypeScript types across the project

Applied to files:

  • package.json
📚 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 desktop/**/*.{ts,tsx,js,jsx} : Use Electron with electron-forge and Vite for desktop application

Applied to files:

  • packages/grida-canvas-io/package.json
  • packages/grida-canvas-color/package.json
📚 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 {jobs/**/*.ts,jobs/**/deno.json,jobs/**/deno.lock} : Use Deno for tasks and jobs that share the codebase (e.g., /jobs directory)

Applied to files:

  • packages/grida-canvas-color/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: cargo test
  • GitHub Check: test
🔇 Additional comments (13)
fixtures/test-grida/README.md (1)

9-9: Version specifier and current version correctly updated.

The schema version bump is properly reflected: the example on line 9 correctly demonstrates that schema version 0.89.0-beta+20251219 maps to version specifier 20251219 (matching the build metadata date), and line 18 reflects the current version with the corresponding last-updated date. This resolves the version specifier mismatch flagged in the previous review.

Also applies to: 18-18

packages/grida-canvas-io/tsconfig.json (1)

5-6: Verify whether skipLibCheck is intentional or temporary.

Adding skipLibCheck: true improves build performance by skipping type-checking of declaration files from dependencies, but it can mask real type issues in those dependencies.

Given the context of this PR's major type refactoring (SVGPath removal, padding schema changes), please confirm:

  • Is this a permanent decision for build performance?
  • Or a temporary workaround for dependency type conflicts during the refactor?

If temporary, consider tracking its removal once the refactor stabilizes.

packages/grida-canvas-color/vitest.config.ts (1)

1-7: LGTM! Clean Vitest configuration.

The configuration is straightforward and enables global test APIs, which aligns well with the migration from Jest (where globals are the default).

package.json (1)

28-29: LGTM! Vitest dependency added for test migration.

The addition of Vitest as a dev dependency supports the repository-wide migration from Jest to Vitest.

packages/grida-canvas-io-figma/vitest.config.ts (1)

1-7: LGTM! Consistent Vitest configuration.

The configuration matches the pattern used in other packages and appropriately enables global test APIs.

packages/grida-canvas-io/vitest.config.ts (1)

1-8: LGTM! Appropriate timeout for I/O tests.

The configuration enables global test APIs and sets a generous 120-second timeout, which is well-suited for I/O operations that may involve file processing or external data handling.

packages/grida-canvas-io/package.json (1)

8-8: LGTM! Test runner migrated to Vitest.

The script correctly uses vitest run for non-watch mode execution, suitable for CI pipelines.

packages/grida-canvas-color/package.json (2)

18-18: LGTM! Test runner migrated to Vitest.

The test script correctly uses vitest run for non-watch mode execution.


23-29: LGTM! Proper module exports for ESM/CJS interoperability.

The exports field follows Node.js conventions and ensures proper resolution for:

  • TypeScript types (types)
  • ES modules (import)
  • CommonJS (require)

This is a best practice for published packages and improves compatibility across different module systems.

packages/grida-canvas-io-figma/package.json (2)

6-7: LGTM! Test runner migrated to Vitest.

The test script correctly uses vitest run for non-watch mode execution. The script order change (typecheck before test) is cosmetic but logical.


12-12: LGTM! Added vector geometry support.

The @grida/vn dependency addition aligns with the PR objectives around vector data handling and the broader refactoring to replace SVGPath-based processing with vector representations.

packages/grida-canvas-io-figma/tsconfig.json (1)

10-10: Ensure skipLibCheck doesn't mask integration issues from new dependencies.

skipLibCheck: true is a standard optimization in TypeScript projects, especially monorepos. However, given this PR adds new dependencies (@grida/vn, @grida/cg, @grida/schema) alongside major refactoring, verify that type integration is sound by confirming monorepo-level typecheck passes cleanly (via turbo typecheck or equivalent CI verification).

packages/grida-canvas-color/tsconfig.json (1)

6-7: skipLibCheck is a standard monorepo pattern—verify it's not masking real issues.

skipLibCheck does not work well under monorepo projects, but it's a standard practice in Turborepo monorepos paired with strict type checking. TypeScript still checks your code against types in declaration files even with skipLibCheck enabled. Since this package is published to npm, run turbo typecheck or pnpm typecheck to confirm type safety is maintained and no real errors are being suppressed.


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.

@vercel vercel Bot temporarily deployed to Preview – blog December 20, 2025 07:12 Inactive
@vercel vercel Bot temporarily deployed to Preview – backgrounds December 20, 2025 07:12 Inactive
@vercel vercel Bot temporarily deployed to Preview – viewer December 20, 2025 07:12 Inactive
@softmarshmallow softmarshmallow marked this pull request as ready for review December 20, 2025 07:13
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 1172 to +1176
id: gridaId,
...base_node_trait(node),
...positioning_trait(node),
...fills_trait(node.fills),
...effects_trait(node.effects),
type: "svgpath",
paths: [
...(node.fillGeometry?.map((p) => ({
d: p.path ?? "",
fill_rule: map.windingRuleMap[p.windingRule],
fill: "fill" as const,
})) ?? []),
...(node.strokeGeometry?.map((p) => ({
d: p.path ?? "",
fill_rule: map.windingRuleMap[p.windingRule],
fill: "stroke" as const,
})) ?? []),
],
} satisfies grida.program.nodes.SVGPathNode;
type: "group",
expanded: false,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Vector REST nodes converted to unsupported group type

The REST import now turns VECTOR/STAR/REGULAR_POLYGON nodes into group nodes (rather than the previous svgpath), but the DOM renderer still has no group case and throws Unknown node type (see editor/grida-canvas-react-renderer-dom/nodes/node.tsx lines 86-103). Any Figma REST export with geometry=paths that includes a vector will now fail to render because the root of the imported shape is of an unsupported type.

Useful? React with 👍 / 👎.

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: 2

🧹 Nitpick comments (3)
editor/scaffolds/sidecontrol/controls/padding.tsx (1)

31-34: Consider using CSS shorthand order for placeholder.

The placeholder displays values in [left, top, right, bottom] order, but CSS shorthand convention is top, right, bottom, left (clockwise from top). This could cause confusion for users familiar with CSS.

🔎 Suggested fix to use CSS convention order
   const placeholder =
     uniformValue !== undefined
       ? String(uniformValue)
-      : [left, top, right, bottom].join(", ");
+      : [top, right, bottom, left].join(", ");
editor/grida-canvas-react/viewport/surface.tsx (1)

943-948: Redundant null coalescing operators.

The ?? operators on lines 944-947 are redundant since the padding object constructed on lines 898-901 already defaults all properties to 0. The additional coalescing provides no functional benefit.

🔎 Optional simplification
 padding={{
-  top: padding.padding_top ?? 0,
-  right: padding.padding_right ?? 0,
-  bottom: padding.padding_bottom ?? 0,
-  left: padding.padding_left ?? 0,
+  top: padding.padding_top,
+  right: padding.padding_right,
+  bottom: padding.padding_bottom,
+  left: padding.padding_left,
 }}
packages/grida-canvas-io-figma/lib.ts (1)

779-847: Consider consolidating duplicated geometry processing logic.

Both processFillGeometries and processStrokeGeometries follow nearly identical patterns, differing only in:

  • Property accessed (fillGeometry vs strokeGeometry)
  • Child ID suffix and naming
  • Options flags (useFill vs useStroke)

While the current implementation is functionally correct, consolidating into a single generic function would reduce duplication and improve maintainability.

💡 Proposed refactor to generic function
+function processGeometries(
+  node: InputNode & figrest.HasGeometryTrait,
+  parentGridaId: string,
+  nodeTypeName: string,
+  type: 'fill' | 'stroke'
+): string[] {
+  const geometries = type === 'fill' ? node.fillGeometry : node.strokeGeometry;
+  if (!geometries?.length) return [];
+
+  const childIds: string[] = [];
+  geometries.forEach((geometry, idx) => {
+    const childId = `${parentGridaId}_${type}_${idx}`;
+    const name = `${node.name || nodeTypeName} ${type === 'fill' ? 'Fill' : 'Stroke'} ${idx + 1}`;
+
+    const childNode = createVectorNodeFromPath(
+      geometry.path ?? "",
+      geometry,
+      node,
+      childId,
+      name,
+      { useFill: type === 'fill', useStroke: type === 'stroke' }
+    );
+
+    if (childNode) {
+      nodes[childId] = childNode;
+      childIds.push(childId);
+    }
+  });
+
+  return childIds;
+}

-function processFillGeometries(...) { ... }
+function processFillGeometries(node, parentGridaId, nodeTypeName) {
+  return processGeometries(node, parentGridaId, nodeTypeName, 'fill');
+}

-function processStrokeGeometries(...) { ... }
+function processStrokeGeometries(node, parentGridaId, nodeTypeName) {
+  return processGeometries(node, parentGridaId, nodeTypeName, 'stroke');
+}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3d3b90 and 8425bba.

⛔ Files ignored due to path filters (3)
  • crates/grida-canvas-wasm/lib/bin/grida_canvas_wasm.wasm is excluded by !**/*.wasm
  • fixtures/test-figma/rest-api/L0/vector-frame.png is excluded by !**/*.png
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (53)
  • crates/grida-canvas-wasm/example/rectangle.grida (1 hunks)
  • crates/grida-canvas-wasm/package.json (1 hunks)
  • crates/grida-canvas/AGENTS.md (0 hunks)
  • crates/grida-canvas/examples/tool_convert_svgpath.rs (0 hunks)
  • crates/grida-canvas/examples/tool_io_grida.rs (0 hunks)
  • crates/grida-canvas/src/io/id_converter.rs (1 hunks)
  • crates/grida-canvas/src/io/io_grida.rs (15 hunks)
  • docs/wg/feat-fig/glossary/fig.kiwi.md (1 hunks)
  • docs/wg/feat-schema/naming-conventions.md (2 hunks)
  • editor/grida-canvas-hosted/playground/examples.ts (0 hunks)
  • editor/grida-canvas-hosted/playground/widgets/index.ts (3 hunks)
  • editor/grida-canvas-react-renderer-dom/nodes/index.ts (0 hunks)
  • editor/grida-canvas-react-renderer-dom/nodes/node.tsx (0 hunks)
  • editor/grida-canvas-react-renderer-dom/nodes/svg-path.tsx (0 hunks)
  • editor/grida-canvas-react-starter-kit/starterkit-icons/node-type-icon.tsx (0 hunks)
  • editor/grida-canvas-react/provider.tsx (1 hunks)
  • editor/grida-canvas-react/viewport/surface.tsx (2 hunks)
  • editor/grida-canvas-utils/css.ts (3 hunks)
  • editor/grida-canvas/editor.i.ts (1 hunks)
  • editor/grida-canvas/editor.ts (3 hunks)
  • editor/grida-canvas/policy.ts (0 hunks)
  • editor/grida-canvas/reducers/document.reducer.ts (1 hunks)
  • editor/grida-canvas/reducers/event-target.reducer.ts (2 hunks)
  • editor/grida-canvas/reducers/node.reducer.ts (3 hunks)
  • editor/grida-canvas/reducers/schema/schema.ts (1 hunks)
  • editor/grida-canvas/reducers/surface.reducer.ts (1 hunks)
  • editor/grida-canvas/reducers/tools/initial-node.ts (1 hunks)
  • editor/grida-canvas/utils/supports.ts (0 hunks)
  • editor/public/examples/canvas/blank.grida (1 hunks)
  • editor/public/examples/canvas/component-01.grida (4 hunks)
  • editor/public/examples/canvas/event-page-01.grida (0 hunks)
  • editor/public/examples/canvas/globals-01.grida (1 hunks)
  • editor/public/examples/canvas/helloworld.grida (4 hunks)
  • editor/public/examples/canvas/instagram-post-01.grida (0 hunks)
  • editor/public/examples/canvas/layout-01.grida (4 hunks)
  • editor/public/examples/canvas/poster-01.grida (0 hunks)
  • editor/public/examples/canvas/resume-01.grida (0 hunks)
  • editor/public/examples/canvas/slides-01.grida (0 hunks)
  • editor/scaffolds/editor/editor.tsx (1 hunks)
  • editor/scaffolds/editor/init.ts (2 hunks)
  • editor/scaffolds/editor/sync/agent-startpage.sync.tsx (1 hunks)
  • editor/scaffolds/sidecontrol/controls/padding.tsx (1 hunks)
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx (2 hunks)
  • fixtures/test-figma/rest-api/L0/vector-frame.md (1 hunks)
  • fixtures/test-figma/rest-api/L0/vector-frame.response.json (1 hunks)
  • fixtures/test-grida/README.md (2 hunks)
  • packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.ts (1 hunks)
  • packages/grida-canvas-io-figma/jest.config.ts (1 hunks)
  • packages/grida-canvas-io-figma/jest.setup.ts (1 hunks)
  • packages/grida-canvas-io-figma/lib.ts (4 hunks)
  • packages/grida-canvas-io-figma/package.json (1 hunks)
  • packages/grida-canvas-io/__tests__/archive.test.ts (2 hunks)
  • packages/grida-canvas-schema/grida.ts (5 hunks)
💤 Files with no reviewable changes (15)
  • editor/grida-canvas-react-renderer-dom/nodes/index.ts
  • editor/grida-canvas/utils/supports.ts
  • editor/grida-canvas/policy.ts
  • editor/grida-canvas-hosted/playground/examples.ts
  • editor/public/examples/canvas/slides-01.grida
  • editor/public/examples/canvas/resume-01.grida
  • editor/grida-canvas-react-renderer-dom/nodes/svg-path.tsx
  • crates/grida-canvas/AGENTS.md
  • editor/grida-canvas-react-renderer-dom/nodes/node.tsx
  • editor/grida-canvas-react-starter-kit/starterkit-icons/node-type-icon.tsx
  • editor/public/examples/canvas/poster-01.grida
  • crates/grida-canvas/examples/tool_convert_svgpath.rs
  • editor/public/examples/canvas/event-page-01.grida
  • crates/grida-canvas/examples/tool_io_grida.rs
  • editor/public/examples/canvas/instagram-post-01.grida
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{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:

  • editor/grida-canvas/editor.i.ts
  • packages/grida-canvas-io-figma/jest.config.ts
  • editor/grida-canvas/reducers/tools/initial-node.ts
  • editor/grida-canvas-hosted/playground/widgets/index.ts
  • editor/grida-canvas/reducers/document.reducer.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.ts
  • packages/grida-canvas-io/__tests__/archive.test.ts
  • editor/scaffolds/editor/editor.tsx
  • editor/scaffolds/editor/sync/agent-startpage.sync.tsx
  • editor/scaffolds/editor/init.ts
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/grida-canvas/reducers/schema/schema.ts
  • editor/grida-canvas-react/viewport/surface.tsx
  • packages/grida-canvas-io-figma/lib.ts
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • editor/grida-canvas/editor.ts
  • packages/grida-canvas-schema/grida.ts
  • editor/scaffolds/sidecontrol/controls/padding.tsx
  • editor/grida-canvas/reducers/node.reducer.ts
  • editor/grida-canvas/reducers/event-target.reducer.ts
  • editor/grida-canvas-utils/css.ts
  • packages/grida-canvas-io-figma/jest.setup.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:

  • editor/grida-canvas/editor.i.ts
  • packages/grida-canvas-io-figma/jest.config.ts
  • editor/grida-canvas/reducers/tools/initial-node.ts
  • editor/grida-canvas-hosted/playground/widgets/index.ts
  • editor/grida-canvas/reducers/document.reducer.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.ts
  • packages/grida-canvas-io/__tests__/archive.test.ts
  • editor/scaffolds/editor/editor.tsx
  • editor/scaffolds/editor/sync/agent-startpage.sync.tsx
  • editor/scaffolds/editor/init.ts
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/grida-canvas/reducers/schema/schema.ts
  • editor/grida-canvas-react/viewport/surface.tsx
  • packages/grida-canvas-io-figma/lib.ts
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • editor/grida-canvas/editor.ts
  • packages/grida-canvas-schema/grida.ts
  • editor/scaffolds/sidecontrol/controls/padding.tsx
  • editor/grida-canvas/reducers/node.reducer.ts
  • editor/grida-canvas/reducers/event-target.reducer.ts
  • editor/grida-canvas-utils/css.ts
  • packages/grida-canvas-io-figma/jest.setup.ts
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/editor.i.ts
  • editor/grida-canvas/reducers/tools/initial-node.ts
  • editor/grida-canvas-hosted/playground/widgets/index.ts
  • editor/grida-canvas/reducers/document.reducer.ts
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/grida-canvas/reducers/schema/schema.ts
  • editor/grida-canvas-react/viewport/surface.tsx
  • editor/grida-canvas/editor.ts
  • editor/grida-canvas/reducers/node.reducer.ts
  • editor/grida-canvas/reducers/event-target.reducer.ts
  • editor/grida-canvas-utils/css.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/jest.config.ts
  • packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.ts
  • packages/grida-canvas-io/__tests__/archive.test.ts
  • packages/grida-canvas-io-figma/lib.ts
  • packages/grida-canvas-schema/grida.ts
  • packages/grida-canvas-io-figma/jest.setup.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use React.js 19 for web applications

Files:

  • editor/scaffolds/editor/editor.tsx
  • editor/scaffolds/editor/sync/agent-startpage.sync.tsx
  • editor/grida-canvas-react/provider.tsx
  • editor/grida-canvas-react/viewport/surface.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • editor/scaffolds/sidecontrol/controls/padding.tsx
editor/scaffolds/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use /editor/scaffolds for feature-specific larger components, pages, and editors

Files:

  • editor/scaffolds/editor/editor.tsx
  • editor/scaffolds/editor/sync/agent-startpage.sync.tsx
  • editor/scaffolds/editor/init.ts
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • editor/scaffolds/sidecontrol/controls/padding.tsx
crates/grida-canvas/**/*.rs

📄 CodeRabbit inference engine (crates/grida-canvas/AGENTS.md)

crates/grida-canvas/**/*.rs: All internal structs (NodeRecs, SceneGraph, caches) must use NodeId (u64) for high-performance counter-based IDs in the rendering engine
Public APIs must accept and return UserNodeId (String) instead of NodeId for stability and serialization
Use IdConverter to handle conversion between NodeId and UserNodeId during .grida file loading
NodeRepository must auto-generate IDs for factory-created nodes, assigning ID=0 as the default
Use skia-safe crate for all painting and rendering operations
Use math2 crate for all geometry and common math operations

Files:

  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Use Rust 2024 edition for wasm builds and graphics core
Use Skia graphics backend for 2D graphics, bound with skia-safe
Rust crates in /crates directory are under rapid development and serve as the new rendering backend; ensure high quality implementations

Files:

  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
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/feat-schema/naming-conventions.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
  • docs/wg/feat-schema/naming-conventions.md
🧠 Learnings (28)
📓 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-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`
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
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.)
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
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
📚 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:

  • crates/grida-canvas-wasm/package.json
  • packages/grida-canvas-io-figma/jest.config.ts
  • editor/public/examples/canvas/helloworld.grida
  • editor/public/examples/canvas/component-01.grida
  • packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.ts
  • packages/grida-canvas-io/__tests__/archive.test.ts
  • editor/scaffolds/editor/editor.tsx
  • editor/scaffolds/editor/init.ts
  • crates/grida-canvas/src/io/id_converter.rs
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/public/examples/canvas/layout-01.grida
  • crates/grida-canvas/src/io/io_grida.rs
  • editor/grida-canvas/reducers/schema/schema.ts
  • packages/grida-canvas-io-figma/lib.ts
  • crates/grida-canvas-wasm/example/rectangle.grida
  • editor/public/examples/canvas/globals-01.grida
  • packages/grida-canvas-schema/grida.ts
  • editor/public/examples/canvas/blank.grida
  • editor/grida-canvas-utils/css.ts
  • packages/grida-canvas-io-figma/jest.setup.ts
📚 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/**/+(grida-canvas-wasm.js|grida-canvas-wasm.wasm) : Include WASM artifacts (`grida-canvas-wasm.js` and `grida-canvas-wasm.wasm`) in git for faster CI builds

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • packages/grida-canvas-io-figma/package.json
  • crates/grida-canvas-wasm/example/rectangle.grida
📚 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:

  • crates/grida-canvas-wasm/package.json
  • packages/grida-canvas-io-figma/package.json
  • packages/grida-canvas-io-figma/jest.config.ts
  • editor/public/examples/canvas/helloworld.grida
  • editor/public/examples/canvas/component-01.grida
  • packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.ts
  • packages/grida-canvas-io/__tests__/archive.test.ts
  • editor/scaffolds/editor/editor.tsx
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/public/examples/canvas/layout-01.grida
  • editor/grida-canvas/reducers/schema/schema.ts
  • editor/grida-canvas-react/viewport/surface.tsx
  • packages/grida-canvas-io-figma/lib.ts
  • crates/grida-canvas-wasm/example/rectangle.grida
  • editor/public/examples/canvas/globals-01.grida
  • docs/wg/feat-schema/naming-conventions.md
  • packages/grida-canvas-schema/grida.ts
  • editor/public/examples/canvas/blank.grida
  • editor/grida-canvas-utils/css.ts
  • packages/grida-canvas-io-figma/jest.setup.ts
📚 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/**/*.{js,ts,jsx,tsx} : Use Web Workers for heavy graphics operations to improve performance and responsiveness

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • packages/grida-canvas-io-figma/package.json
  • crates/grida-canvas-wasm/example/rectangle.grida
📚 Learning: 2025-12-01T00:22:28.164Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:28.164Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `skia-safe` crate for all painting and rendering operations

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-canvas-wasm/example/rectangle.grida
📚 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/**/Cargo.toml : Use the target `wasm32-unknown-emscripten` when building Rust code for WebAssembly compilation

Applied to files:

  • crates/grida-canvas-wasm/package.json
📚 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/**/Cargo.toml : Set environment variables `CC=emcc`, `CXX=em++`, and `AR=emar` when building Rust code for WebAssembly targets

Applied to files:

  • crates/grida-canvas-wasm/package.json
📚 Learning: 2025-12-01T00:22:28.164Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:28.164Z
Learning: Applies to crates/grida-canvas/**/*.rs : Public APIs must accept and return `UserNodeId` (String) instead of `NodeId` for stability and serialization

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
📚 Learning: 2025-12-01T00:22:28.164Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:28.164Z
Learning: Applies to crates/grida-canvas/**/*.rs : NodeRepository must auto-generate IDs for factory-created nodes, assigning ID=0 as the default

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/io/id_converter.rs
📚 Learning: 2025-12-01T00:22:28.164Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:28.164Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `math2` crate for all geometry and common math operations

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-canvas-wasm/example/rectangle.grida
📚 Learning: 2025-12-01T00:22:06.800Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-fonts/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:06.800Z
Learning: Applies to crates/grida-canvas-fonts/**/Cargo.toml : Include dev-dependency `serde_json = "1.0"` for JSON testing

Applied to files:

  • packages/grida-canvas-io-figma/package.json
  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
📚 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/grida-*/**/*.{ts,tsx} : Use /editor/grida-* directories to isolate domain-specific modules; promote well-defined modules to <root>/packages

Applied to files:

  • packages/grida-canvas-io-figma/package.json
📚 Learning: 2025-12-01T00:22:41.045Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:41.045Z
Learning: Applies to editor/**/next-env.d.ts : Include `next-env.d.ts` file in git for the project to avoid requiring dev/build runs for typechecking in CI environments

Applied to files:

  • packages/grida-canvas-io-figma/jest.config.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/public/examples/canvas/helloworld.grida
  • editor/grida-canvas/reducers/document.reducer.ts
  • editor/public/examples/canvas/component-01.grida
  • editor/scaffolds/editor/editor.tsx
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/public/examples/canvas/layout-01.grida
  • editor/grida-canvas-react/viewport/surface.tsx
  • packages/grida-canvas-schema/grida.ts
  • editor/grida-canvas/reducers/event-target.reducer.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/__tests__/iofigma.rest-api.vector.test.ts
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas/reducers/schema/schema.ts
  • packages/grida-canvas-io-figma/lib.ts
  • packages/grida-canvas-schema/grida.ts
  • editor/grida-canvas/reducers/node.reducer.ts
  • packages/grida-canvas-io-figma/jest.setup.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/__tests__/iofigma.rest-api.vector.test.ts
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas/reducers/schema/schema.ts
  • packages/grida-canvas-io-figma/lib.ts
  • packages/grida-canvas-schema/grida.ts
  • editor/grida-canvas/reducers/node.reducer.ts
  • packages/grida-canvas-io-figma/jest.setup.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/__tests__/iofigma.rest-api.vector.test.ts
  • editor/grida-canvas/reducers/surface.reducer.ts
  • editor/grida-canvas/reducers/schema/schema.ts
  • packages/grida-canvas-io-figma/lib.ts
  • editor/grida-canvas/reducers/node.reducer.ts
  • packages/grida-canvas-io-figma/jest.setup.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/scaffolds/**/*.{ts,tsx} : Use /editor/scaffolds for feature-specific larger components, pages, and editors

Applied to files:

  • editor/scaffolds/editor/init.ts
📚 Learning: 2025-12-01T00:22:28.164Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:28.164Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `IdConverter` to handle conversion between `NodeId` and `UserNodeId` during .grida file loading

Applied to files:

  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
📚 Learning: 2025-12-01T00:22:28.164Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:28.164Z
Learning: Applies to crates/grida-canvas/**/*.rs : All internal structs (NodeRecs, SceneGraph, caches) must use `NodeId` (u64) for high-performance counter-based IDs in the rendering engine

Applied to files:

  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
📚 Learning: 2025-12-01T00:22:06.800Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-fonts/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:06.800Z
Learning: Applies to crates/grida-canvas-fonts/**/serde_test.rs : JSON serialization tests should be organized in `serde_test.rs`

Applied to files:

  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
📚 Learning: 2025-12-01T00:22:06.800Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-fonts/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:06.800Z
Learning: Applies to crates/grida-canvas-fonts/**/Cargo.toml : Include optional `serde = "1.0"` with `derive` feature for JSON serialization support

Applied to files:

  • crates/grida-canvas/src/io/id_converter.rs
  • crates/grida-canvas/src/io/io_grida.rs
📚 Learning: 2025-12-01T00:22:06.800Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-fonts/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:06.800Z
Learning: Applies to crates/grida-canvas-fonts/**/ui_parser_test.rs : High-level UI API tests should use `parse_ui` and be organized in `ui_parser_test.rs`

Applied to files:

  • crates/grida-canvas/src/io/io_grida.rs
📚 Learning: 2025-12-01T00:22:28.164Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:28.164Z
Learning: Validate `.grida` files using the `tool_io_grida` CLI tool for debugging parsing issues and structure verification

Applied to files:

  • crates/grida-canvas/src/io/io_grida.rs
  • docs/wg/feat-schema/naming-conventions.md
📚 Learning: 2025-12-01T00:22:36.510Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-dev/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:36.510Z
Learning: The `cg` crate must remain platform-agnostic; all winit/glutin integration code must live in the `grida-dev` crate

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 : When adding new parameters to the halftone tool, add state with useState, include in useEffect dependency array, pass to renderHalftone() function, use in rendering logic, and add UI control

Applied to files:

  • editor/scaffolds/sidecontrol/controls/padding.tsx
📚 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 React hooks for state management (imageSrc, shape, grid, maxRadius, gamma, jitter, opacity, color, customShapeImage, imageDataRef, sizeRef)

Applied to files:

  • editor/scaffolds/sidecontrol/controls/padding.tsx
🧬 Code graph analysis (7)
editor/grida-canvas/editor.i.ts (1)
packages/grida-canvas-schema/grida.ts (1)
  • IPadding (1486-1507)
editor/grida-canvas/reducers/surface.reducer.ts (1)
editor/grida-canvas-react-renderer-dom/nodes/index.ts (1)
  • container (17-17)
packages/grida-canvas-io-figma/lib.ts (1)
packages/grida-canvas-schema/grida.ts (3)
  • VectorNode (2302-2325)
  • GroupNode (2066-2074)
  • Node (1104-1123)
editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx (3)
editor/grida-canvas-react/provider.tsx (1)
  • useNodeActions (78-281)
editor/scaffolds/sidecontrol/ui/index.tsx (2)
  • PropertyLine (19-41)
  • PropertyLineLabel (43-59)
editor/scaffolds/sidecontrol/controls/padding.tsx (1)
  • PaddingControl (11-164)
editor/grida-canvas/editor.ts (1)
packages/grida-canvas-schema/grida.ts (1)
  • IPadding (1486-1507)
editor/scaffolds/sidecontrol/controls/padding.tsx (1)
packages/grida-canvas-schema/grida.ts (1)
  • IPadding (1486-1507)
editor/grida-canvas/reducers/event-target.reducer.ts (3)
packages/grida-canvas-schema/grida.ts (2)
  • ContainerNode (2196-2211)
  • ComponentNode (2446-2459)
editor/grida-canvas/reducers/node.reducer.ts (1)
  • nodeReducer (900-981)
editor/grida-canvas/action.ts (1)
  • NodeChangeAction (931-943)
🪛 LanguageTool
fixtures/test-figma/rest-api/L0/vector-frame.md

[grammar] ~24-~24: Ensure spelling is correct
Context: ... - Stroke: Black solid (rgb(0, 0, 0), 1px weight, center aligned) ## Key Charact...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
fixtures/test-figma/rest-api/L0/vector-frame.md

11-11: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: cargo test
  • GitHub Check: test
🔇 Additional comments (66)
packages/grida-canvas-io/__tests__/archive.test.ts (3)

72-72: Version updates align with PR schema migration.

The version field updates to 0.89.0-beta+20251219 are correctly reflected in both mockDocumentData and complexDocumentData. These changes are consistent with the PR's schema version bump.

Also applies to: 99-99


112-132: Verify schema compatibility: rectangle node lacks padding properties.

The rectangle node in complexDocumentData omits the new explicit padding properties (padding_top, padding_right, padding_bottom, padding_left) introduced by the PR. Confirm whether:

  • The schema makes these properties optional/defaultable (acceptable as-is), or
  • Test nodes should include explicit padding properties for schema completeness (to validate migrations)

If padding properties are required or recommended in the test data for validating the schema migration, consider adding them with zero or typical values.


1-61: FIXTURE_IMAGES pattern is well-structured for integration testing.

The fixture image loading pattern is maintainable and supports comprehensive integration testing with real files (PNG, JPG, up to 8K resolution). This enables robust round-trip and data-integrity verification.

crates/grida-canvas-wasm/package.json (1)

4-4: Version bump to 0.89.0-canary.0 is correct and complete.

TypeScript definitions and WASM artifacts are properly tracked in git. The version change aligns with the 0.89.0 release cycle.

docs/wg/feat-schema/naming-conventions.md (2)

7-9: ✓ PR table updated correctly.

The feature tracking table now documents PR #474 alongside existing related PRs, maintaining the schema migration history.


96-98: ✓ Layout pattern examples now complete.

The addition of padding_right, padding_bottom, and padding_left completes the set of directional padding properties and aligns with the schema migration. All four edge-specific properties are now documented consistently in the naming convention examples. The schema, UI controls, and serializers uniformly implement all four directional padding properties with no legacy shorthand present.

editor/public/examples/canvas/globals-01.grida (1)

2-2: Version bump aligns with schema migration.

The version update to "0.89.0-beta+20251219" is consistent with the PR's schema migration objectives.

crates/grida-canvas-wasm/example/rectangle.grida (1)

2-2: LGTM!

Version update is consistent with the schema migration.

editor/public/examples/canvas/blank.grida (1)

2-2: Version update looks good.

The schema version is correctly updated to match the migration.

editor/scaffolds/editor/sync/agent-startpage.sync.tsx (1)

24-44: Schema version update is consistent.

The version update aligns with the canvas document editor changes. The same backward compatibility considerations mentioned in editor/scaffolds/editor/editor.tsx apply here.

editor/scaffolds/editor/init.ts (2)

344-378: Form start page validation mirrors canvas validation.

The validation logic is consistent with the canvas validation. The same error handling considerations apply.


310-342: Schema validation correctly rejects mismatched versions.

The version check properly flags documents with incompatible schema versions by setting __schema_valid: false. Verify that:

  1. The error handling path for invalid schemas is user-friendly
  2. Users are guided to migrate or upgrade old documents
  3. The ErrorInvalidSchema component (referenced in editor.tsx line 182) provides clear instructions
editor/public/examples/canvas/component-01.grida (2)

2-2: Schema version correctly updated.


20-49: Padding refactor successfully implemented.

The migration from shorthand padding style property to explicit padding_top, padding_right, padding_bottom, padding_left properties is correctly implemented. The values are equivalent (all 0.0), maintaining the same visual appearance while conforming to the new schema structure.

editor/public/examples/canvas/helloworld.grida (2)

2-2: Version update is consistent.


20-39: Padding migration correctly applied.

The conversion from shorthand padding to per-edge padding properties is consistent with other example files. All values remain equivalent (0.0), ensuring no visual changes.

editor/scaffolds/editor/editor.tsx (1)

151-168: Verify schema migration handling for existing documents.

The hardcoded schema version means all document saves will use the new version. Ensure that:

  1. Existing documents with the old schema version ("0.0.4-beta+20251209") can still be loaded
  2. A migration path exists to upgrade old documents to the new schema
  3. The validation logic in __init_canvas properly handles version mismatches
editor/public/examples/canvas/layout-01.grida (1)

2-2: LGTM! Schema version and padding migration are consistent.

The version bump to 0.89.0-beta+20251219 and the migration from shorthand padding to explicit per-edge padding fields (padding_top, padding_right, padding_bottom, padding_left) are correctly applied across all container nodes in this fixture.

Also applies to: 24-27, 64-67, 173-176

editor/scaffolds/sidecontrol/controls/padding.tsx (1)

1-1: LGTM! Clean refactor to per-edge padding structure.

The type changes and value handling are well-implemented:

  • Proper defaults with ?? 0 for each side
  • handleUniformChange correctly emits a complete IPadding object
  • handleIndividualChange properly preserves existing values for unchanged sides

Also applies to: 9-9, 12-16, 20-29, 36-57

editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx (2)

1653-1687: LGTM! Clean component extraction for padding control.

The PropertyPaddingLine component is well-structured:

  • Self-contained state management via useNodeState
  • Proper gating behind is_flex_container check
  • Correctly binds to the updated actions.padding handler expecting IPadding

The component reads its own node state independently, which is a good pattern for isolation and potential reuse.


1118-1118: LGTM!

Clean replacement of inline padding UI with the extracted PropertyPaddingLine component.

packages/grida-canvas-schema/grida.ts (4)

533-533: LGTM! Version bump aligns with breaking schema changes.

The version bump to 0.89.0-beta+20251219 appropriately signals the breaking changes (padding shorthand removal, SVGPathNode removal).


1482-1507: LGTM! Well-documented IPadding interface.

The per-edge padding fields are clearly defined with appropriate JSDoc comments and default values. This flat structure is more explicit than the previous shorthand approach.


2207-2208: LGTM! Correct use of Partial<i.IPadding> for container types.

Using Partial<i.IPadding> on ContainerNode and ComponentNode allows padding fields to be optional, which is appropriate since padding is only meaningful for flex containers and defaults to 0 when unspecified.

Also applies to: 2455-2457


2795-2798: LGTM! Factory correctly initializes per-edge padding.

The createContainerNode factory properly initializes all four padding fields to 0, ensuring consistent defaults for new container nodes.

editor/grida-canvas-react/provider.tsx (1)

238-239: LGTM! Padding action type correctly updated.

The type change from IPadding["padding"] (single value) to IPadding (per-edge object) aligns with the schema refactor and matches the updated PaddingControl.onValueCommit signature.

editor/grida-canvas/reducers/event-target.reducer.ts (1)

806-848: LGTM! Per-edge padding implementation is correct.

The refactored padding handling correctly:

  • Supports both container and component node types
  • Implements per-edge padding updates (padding_top, padding_right, padding_bottom, padding_left)
  • Preserves mirroring behavior when enabled
  • Uses an incremental updates object pattern

The type cast on line 848 is acceptable given that the updates object is built from the same properties defined in the node types. The Partial type ensures flexibility while nodeReducer validates the actual node compatibility.

editor/grida-canvas/reducers/document.reducer.ts (1)

1446-1449: LGTM! Per-edge padding correctly applied in autolayout container creation.

The change correctly replaces the single padding property with four explicit per-edge fields. The logic preserves the original behavior where containers with a single child get 16px padding on all sides, while others get 0.

editor/grida-canvas/reducers/surface.reducer.ts (2)

836-852: LGTM! Per-edge padding correctly read in gesture initialization.

The padding gesture initialization now correctly reads the flat per-edge padding properties (padding_top, padding_right, padding_bottom, padding_left) directly from the container node, with appropriate fallback to 0 when undefined.


262-292: Unable to verify complete removal of svgpath content edit mode handling.

Repository access was unavailable to run the verification script checking for remaining svgpath references in the codebase.

editor/grida-canvas/reducers/schema/schema.ts (1)

247-251: LGTM! Parametric scaling correctly updated for per-edge padding.

The parametric scaling logic now correctly scales each padding edge independently using scale_number_in_place. This ensures that when users scale nodes with the Scale tool (K), padding values scale proportionally on all four sides.

editor/grida-canvas/reducers/tools/initial-node.ts (1)

135-138: LGTM! Initial container node correctly uses per-edge padding.

The initial container node template now correctly uses four explicit per-edge padding fields instead of a single padding property. All edges are initialized to 0, preserving the original default behavior.

crates/grida-canvas/src/io/id_converter.rs (1)

140-140: Verify complete removal of Path variant across the codebase.

The Path variant handling has been removed from the match statement. Ensure that the JSONNode::Path variant itself has been removed from the JSONNode enum definition, and that no other code paths still reference it.

Run the following script to verify complete removal of Path-related code:

#!/bin/bash
# Description: Verify that JSONNode::Path variant and related Path handling have been completely removed from the codebase.

# Search for JSONNode::Path references
echo "=== Checking for JSONNode::Path references ==="
rg -n "JSONNode::Path" --type rust

# Search for Path variant in JSONNode enum definition
echo "=== Checking for Path in JSONNode enum ==="
rg -n -A5 "enum JSONNode" crates/grida-canvas/src/io/io_grida.rs

# Search for any remaining path-related node handling
echo "=== Checking for other Path node type references ==="
rg -n "Node::Path" --type rust
editor/grida-canvas-react/viewport/surface.tsx (1)

896-903: LGTM!

The padding object construction correctly extracts per-side padding values from container and component nodes, with appropriate default values of 0 for undefined properties.

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

24-27: LGTM!

The widget prototypes have been correctly updated to use explicit per-side padding properties (padding_top, padding_right, padding_bottom, padding_left) instead of the shorthand padding property. The values maintain visual equivalence with the previous schema.

Also applies to: 157-160, 212-215

editor/grida-canvas/editor.i.ts (1)

3229-3232: All call sites updated to pass complete IPadding object structure.

The changeContainerNodePadding signature change from a single padding value to the full IPadding object (containing padding_top, padding_right, padding_bottom, padding_left) has been properly implemented. The only call site found in the codebase (editor/grida-canvas-react/provider.tsx) correctly passes an IPadding object, and the implementation in editor.ts matches the interface.

editor/grida-canvas/editor.ts (3)

2654-2654: LGTM! Version bump is consistent with PR objectives.

The archive version string correctly reflects the 0.89.0-beta release mentioned in the PR description.


2816-2816: LGTM! Version string consistent with archive method.

The syncDocument version matches the archive version, ensuring proper document serialization consistency.


2232-2241: Verify all callers updated to new padding signature.

The method signature changed from accepting a single padding value (or sub-property) to accepting a full IPadding object with per-edge properties. Ensure all call sites have been updated to pass the complete object structure.

Run the following script to verify all usages of changeContainerNodePadding are updated:

#!/bin/bash
# Description: Find all calls to changeContainerNodePadding and verify they pass IPadding object

# Search for method calls
rg -n -A 3 'changeContainerNodePadding\s*\(' --type ts --type tsx
editor/grida-canvas-utils/css.ts (3)

88-91: LGTM! Padding destructuring updated correctly.

The destructuring properly extracts all four per-edge padding properties, aligning with the schema migration.


141-146: LGTM! Safe defaults for padding values.

The call correctly provides default values of 0 for each padding side when undefined, ensuring valid CSS output.


439-462: LGTM! Padding CSS conversion handles per-edge values correctly.

The function properly:

  • Handles null/undefined by returning "0"
  • Provides safe defaults using ?? 0 for each side
  • Optimizes to single value when all sides are equal
  • Returns standard CSS four-value format (top right bottom left) otherwise
editor/grida-canvas/reducers/node.reducer.ts (5)

273-282: LGTM! SVGPathNode removed from fill eligibility.

The assertion correctly removes svgpath from the list of node types that support the fill property, aligning with the PR objective to remove SVGPathNode.


316-339: LGTM! Formatting-only change.

The rectangular corner radius properties were reformatted without any functional changes. The logic remains identical.


429-472: LGTM! Formatting-only change with consistent validation.

The rectangular stroke width properties were reformatted without functional changes. Type assertions and range validation remain properly applied.


499-509: LGTM! SVGPathNode removed from stroke_dash_array eligibility.

The assertion correctly removes svgpath from the list of node types that support stroke_dash_array, consistent with the global SVGPathNode removal.


658-681: LGTM! Padding split into per-edge properties.

The padding property has been correctly split into four directional properties (padding_top, padding_right, padding_bottom, padding_left). Each property:

  • Is properly constrained to container or component nodes
  • Has its own handler that updates the specific field
  • Aligns with the global padding migration across the codebase
crates/grida-canvas/src/io/io_grida.rs (6)

948-956: LGTM! Clean migration to explicit per-edge padding fields.

The flat padding structure with serde aliases for both snake_case (padding_top) and camelCase (paddingTop) provides good backward compatibility during migration. The #[serde(default)] ensures missing fields default to 0.0.


1937-1937: LGTM!

The JSONNode::Vector conversion is clean and consistent with the removal of the separate Path node type mentioned in the PR objectives.


2137-2228: Good test coverage for the new per-edge padding format.

The tests comprehensively cover:

  1. Full padding specification with all four edges
  2. Partial padding with missing fields defaulting to 0
  3. No padding resulting in None for layout_padding

This ensures the migration from shorthand padding to explicit properties is well-tested.


3087-3087: Version strings updated consistently.

Test fixtures correctly reflect the new schema version 0.89.0-beta+20251219.


3805-3834: Tests properly updated for the new flat padding format.

The container deserialization tests now correctly use explicit padding_top, padding_right, padding_bottom, and padding_left properties, with appropriate assertions verifying both the raw fields and the converted EdgeInsets values.


1308-1320: Padding conversion logic with zero-check optimization is correct.

The code properly constructs EdgeInsets from the four explicit padding fields and returns None when all edges are zero, avoiding unnecessary allocations. The EdgeInsets::is_zero() method is correctly implemented in crates/grida-canvas/src/cg/types.rs and checks all four fields against 0.0.

packages/grida-canvas-io-figma/package.json (1)

12-12: LGTM! Dependency addition supports vector network processing.

The addition of @grida/vn as a workspace dependency enables the new vector network handling functionality introduced in this PR.

fixtures/test-figma/rest-api/L0/vector-frame.response.json (1)

1-166: LGTM! Well-structured test fixture for HasGeometryTrait testing.

This fixture provides a comprehensive REST API response structure with fillGeometry and strokeGeometry data, properly supporting the new HasGeometryTrait conversion tests.

packages/grida-canvas-io-figma/jest.config.ts (1)

8-8: LGTM! Jest configuration correctly references setup file.

The setupFilesAfterEnv configuration properly loads the test setup shim needed for mocking ESM-only dependencies.

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

1-166: LGTM! Comprehensive test coverage for HasGeometryTrait conversion.

The test suite thoroughly validates:

  • Conversion of VECTOR nodes with fillGeometry/strokeGeometry to GroupNode + VectorNode children
  • Proper naming and typing of converted nodes
  • Presence of fill and stroke child nodes with correct properties
  • Positioning logic for child nodes relative to parent GroupNode

The tests are well-structured with clear assertions and helpful comments explaining behavior in the mocked test environment.

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

3-3: LGTM! Import updated to support runtime vector network processing.

The change from type-only import to runtime import enables the new vn.fromSVGPathData() and vn.getBBox() calls introduced in the HasGeometryTrait processing functions.


690-698: LGTM! Clean type guard implementation.

The hasGeometryTrait type guard correctly identifies nodes with fillGeometry or strokeGeometry properties, enabling proper handling of REST API nodes with the HasGeometryTrait.


700-777: LGTM! Well-designed vector node creation with proper coordinate space handling.

The function correctly converts SVG path data to VectorNode using the @grida/vn library. Key strengths:

  • Preserves spatial relationships by positioning children at their bbox origin
  • Proper error handling with fallback to null
  • Clear comments explaining the coordinate space strategy
  • Flexible fill/stroke control via options parameter

The positioning logic (lines 747-752) correctly maintains the original coordinate space by using the bbox origin, ensuring fill and stroke geometries align properly.


849-895: LGTM! Well-structured geometry processing coordination.

The functions properly orchestrate HasGeometryTrait processing:

  • processNodeWithGeometryTrait coordinates fill and stroke conversion and updates the graph
  • attachGeometryChildrenIfPresent provides proper guards and delegates appropriately
  • Early returns make the logic clear and avoid unnecessary processing
  • Graph links are correctly updated to maintain parent-child relationships

918-918: LGTM! Geometry processing correctly integrated into node creation flow.

The call to attachGeometryChildrenIfPresent is properly placed after node creation, ensuring geometry children are added when appropriate.


1165-1177: VECTOR/STAR/REGULAR_POLYGON now return GroupNode with child VectorNodes

REST API nodes with HasGeometryTrait (geometry=paths parameter) now return a parent GroupNode instead of VectorNode directly. The processNode implementation creates child VectorNodes from fillGeometry and strokeGeometry—each is a separate SVG path per the REST API model, unlike the unified vector network used by X_VECTOR (Kiwi/Plugin).

This aligns with how fillGeometry and strokeGeometry are returned as separate arrays of paths when geometry=paths is used. Tests validate the pattern: GroupNode parent with children filtered by type === "vector". Code properly type-guards children, so no breaking impact expected.

fixtures/test-figma/rest-api/L0/vector-frame.md (1)

1-109: LGTM! Comprehensive fixture documentation.

The documentation clearly explains:

  • The fixture structure and API requirements
  • HasGeometryTrait implementation details
  • Self-intersecting path behavior and resulting geometry differences
  • Relationship to other Figma APIs (Plugin API, .fig format)

This provides valuable context for understanding the test fixture and the HasGeometryTrait conversion logic.

packages/grida-canvas-io-figma/jest.setup.ts (1)

1-57: LGTM! Well-designed minimal mock for ESM-only dependency.

The Jest setup mock provides:

  • Minimal encodeSVGPath implementation supporting basic path commands (MOVE_TO, LINE_TO, CURVE_TO, CLOSE_PATH)
  • SVGPathData class with all required static constants (including those used by @grida/vn)
  • Proper ESM module marking with __esModule: true

The mock is intentionally minimal (no-op constructor, toAbs returns this) which is appropriate for unit tests that don't depend on exact SVG path parsing behavior. This allows the test suite to run in a CommonJS Jest environment while still loading modules that import the ESM-only svg-pathdata package.

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

266-357: The Vector section at lines 266-357 is not duplicated in the document. A search confirms only one "### Vector" heading exists, followed by the External Resources section. The documentation does not require any modifications for duplication removal.

Likely an incorrect or invalid review comment.

Comment thread fixtures/test-figma/rest-api/L0/vector-frame.md
Comment thread fixtures/test-grida/README.md Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant