0.89.0-beta#474
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughComprehensive 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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Key areas requiring attention:
Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (14)
💤 Files with no reviewable changes (3)
🧰 Additional context used📓 Path-based instructions (4)**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
{editor/**/*.{ts,tsx},packages/grida-canvas-*/**/*.{ts,tsx}}📄 CodeRabbit inference engine (AGENTS.md)
Files:
packages/grida-canvas-*/**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
{package.json,.nvmrc,.node-version}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (14)📓 Common learnings📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
📚 Learning: 2025-12-01T00:22:19.083ZApplied to files:
📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
📚 Learning: 2025-12-01T00:22:19.083ZApplied to files:
📚 Learning: 2025-12-01T00:22:19.083ZApplied to files:
📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
📚 Learning: 2025-12-01T00:22:41.045ZApplied to files:
📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
📚 Learning: 2025-12-01T00:22:06.800ZApplied to files:
📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
📚 Learning: 2025-12-14T23:30:42.112ZApplied to files:
⏰ 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)
🔇 Additional comments (13)
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. Comment |
There was a problem hiding this comment.
💡 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".
| 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, |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
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 istop, 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 thepaddingobject constructed on lines 898-901 already defaults all properties to0. 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
processFillGeometriesandprocessStrokeGeometriesfollow 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
⛔ Files ignored due to path filters (3)
crates/grida-canvas-wasm/lib/bin/grida_canvas_wasm.wasmis excluded by!**/*.wasmfixtures/test-figma/rest-api/L0/vector-frame.pngis excluded by!**/*.pngpnpm-lock.yamlis 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.tspackages/grida-canvas-io-figma/jest.config.tseditor/grida-canvas/reducers/tools/initial-node.tseditor/grida-canvas-hosted/playground/widgets/index.tseditor/grida-canvas/reducers/document.reducer.tspackages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.tspackages/grida-canvas-io/__tests__/archive.test.tseditor/scaffolds/editor/editor.tsxeditor/scaffolds/editor/sync/agent-startpage.sync.tsxeditor/scaffolds/editor/init.tseditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas-react/provider.tsxeditor/grida-canvas/reducers/schema/schema.tseditor/grida-canvas-react/viewport/surface.tsxpackages/grida-canvas-io-figma/lib.tseditor/scaffolds/sidecontrol/sidecontrol-node-selection.tsxeditor/grida-canvas/editor.tspackages/grida-canvas-schema/grida.tseditor/scaffolds/sidecontrol/controls/padding.tsxeditor/grida-canvas/reducers/node.reducer.tseditor/grida-canvas/reducers/event-target.reducer.tseditor/grida-canvas-utils/css.tspackages/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.tspackages/grida-canvas-io-figma/jest.config.tseditor/grida-canvas/reducers/tools/initial-node.tseditor/grida-canvas-hosted/playground/widgets/index.tseditor/grida-canvas/reducers/document.reducer.tspackages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.tspackages/grida-canvas-io/__tests__/archive.test.tseditor/scaffolds/editor/editor.tsxeditor/scaffolds/editor/sync/agent-startpage.sync.tsxeditor/scaffolds/editor/init.tseditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas-react/provider.tsxeditor/grida-canvas/reducers/schema/schema.tseditor/grida-canvas-react/viewport/surface.tsxpackages/grida-canvas-io-figma/lib.tseditor/scaffolds/sidecontrol/sidecontrol-node-selection.tsxeditor/grida-canvas/editor.tspackages/grida-canvas-schema/grida.tseditor/scaffolds/sidecontrol/controls/padding.tsxeditor/grida-canvas/reducers/node.reducer.tseditor/grida-canvas/reducers/event-target.reducer.tseditor/grida-canvas-utils/css.tspackages/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.tseditor/grida-canvas/reducers/tools/initial-node.tseditor/grida-canvas-hosted/playground/widgets/index.tseditor/grida-canvas/reducers/document.reducer.tseditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas-react/provider.tsxeditor/grida-canvas/reducers/schema/schema.tseditor/grida-canvas-react/viewport/surface.tsxeditor/grida-canvas/editor.tseditor/grida-canvas/reducers/node.reducer.tseditor/grida-canvas/reducers/event-target.reducer.tseditor/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.tspackages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.tspackages/grida-canvas-io/__tests__/archive.test.tspackages/grida-canvas-io-figma/lib.tspackages/grida-canvas-schema/grida.tspackages/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.tsxeditor/scaffolds/editor/sync/agent-startpage.sync.tsxeditor/grida-canvas-react/provider.tsxeditor/grida-canvas-react/viewport/surface.tsxeditor/scaffolds/sidecontrol/sidecontrol-node-selection.tsxeditor/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.tsxeditor/scaffolds/editor/sync/agent-startpage.sync.tsxeditor/scaffolds/editor/init.tseditor/scaffolds/sidecontrol/sidecontrol-node-selection.tsxeditor/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 useNodeId(u64) for high-performance counter-based IDs in the rendering engine
Public APIs must accept and returnUserNodeId(String) instead ofNodeIdfor stability and serialization
UseIdConverterto handle conversion betweenNodeIdandUserNodeIdduring .grida file loading
NodeRepository must auto-generate IDs for factory-created nodes, assigning ID=0 as the default
Useskia-safecrate for all painting and rendering operations
Usemath2crate for all geometry and common math operations
Files:
crates/grida-canvas/src/io/id_converter.rscrates/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.rscrates/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.mddocs/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.mddocs/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.jsonpackages/grida-canvas-io-figma/jest.config.tseditor/public/examples/canvas/helloworld.gridaeditor/public/examples/canvas/component-01.gridapackages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.tspackages/grida-canvas-io/__tests__/archive.test.tseditor/scaffolds/editor/editor.tsxeditor/scaffolds/editor/init.tscrates/grida-canvas/src/io/id_converter.rseditor/grida-canvas/reducers/surface.reducer.tseditor/public/examples/canvas/layout-01.gridacrates/grida-canvas/src/io/io_grida.rseditor/grida-canvas/reducers/schema/schema.tspackages/grida-canvas-io-figma/lib.tscrates/grida-canvas-wasm/example/rectangle.gridaeditor/public/examples/canvas/globals-01.gridapackages/grida-canvas-schema/grida.tseditor/public/examples/canvas/blank.gridaeditor/grida-canvas-utils/css.tspackages/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.jsonpackages/grida-canvas-io-figma/package.jsoncrates/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.jsonpackages/grida-canvas-io-figma/package.jsonpackages/grida-canvas-io-figma/jest.config.tseditor/public/examples/canvas/helloworld.gridaeditor/public/examples/canvas/component-01.gridapackages/grida-canvas-io-figma/__tests__/iofigma.rest-api.vector.test.tspackages/grida-canvas-io/__tests__/archive.test.tseditor/scaffolds/editor/editor.tsxeditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas-react/provider.tsxeditor/public/examples/canvas/layout-01.gridaeditor/grida-canvas/reducers/schema/schema.tseditor/grida-canvas-react/viewport/surface.tsxpackages/grida-canvas-io-figma/lib.tscrates/grida-canvas-wasm/example/rectangle.gridaeditor/public/examples/canvas/globals-01.gridadocs/wg/feat-schema/naming-conventions.mdpackages/grida-canvas-schema/grida.tseditor/public/examples/canvas/blank.gridaeditor/grida-canvas-utils/css.tspackages/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.jsonpackages/grida-canvas-io-figma/package.jsoncrates/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.jsoncrates/grida-canvas/src/io/io_grida.rscrates/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.jsoncrates/grida-canvas/src/io/id_converter.rscrates/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.jsoncrates/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.jsoncrates/grida-canvas/src/io/id_converter.rscrates/grida-canvas/src/io/io_grida.rscrates/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.jsoncrates/grida-canvas/src/io/id_converter.rscrates/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.gridaeditor/grida-canvas/reducers/document.reducer.tseditor/public/examples/canvas/component-01.gridaeditor/scaffolds/editor/editor.tsxeditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas-react/provider.tsxeditor/public/examples/canvas/layout-01.gridaeditor/grida-canvas-react/viewport/surface.tsxpackages/grida-canvas-schema/grida.tseditor/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.tseditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas/reducers/schema/schema.tspackages/grida-canvas-io-figma/lib.tspackages/grida-canvas-schema/grida.tseditor/grida-canvas/reducers/node.reducer.tspackages/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.tseditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas/reducers/schema/schema.tspackages/grida-canvas-io-figma/lib.tspackages/grida-canvas-schema/grida.tseditor/grida-canvas/reducers/node.reducer.tspackages/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.tseditor/grida-canvas/reducers/surface.reducer.tseditor/grida-canvas/reducers/schema/schema.tspackages/grida-canvas-io-figma/lib.tseditor/grida-canvas/reducers/node.reducer.tspackages/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.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rsdocs/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+20251219are correctly reflected in bothmockDocumentDataandcomplexDocumentData. 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
rectanglenode incomplexDocumentDataomits 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, andpadding_leftcompletes 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.tsxapply 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:
- The error handling path for invalid schemas is user-friendly
- Users are guided to migrate or upgrade old documents
- The
ErrorInvalidSchemacomponent (referenced in editor.tsx line 182) provides clear instructionseditor/public/examples/canvas/component-01.grida (2)
2-2: Schema version correctly updated.
20-49: Padding refactor successfully implemented.The migration from shorthand
paddingstyle property to explicitpadding_top,padding_right,padding_bottom,padding_leftproperties 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:
- Existing documents with the old schema version ("0.0.4-beta+20251209") can still be loaded
- A migration path exists to upgrade old documents to the new schema
- The validation logic in
__init_canvasproperly handles version mismatcheseditor/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+20251219and the migration from shorthandpaddingto 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
?? 0for each sidehandleUniformChangecorrectly emits a completeIPaddingobjecthandleIndividualChangeproperly preserves existing values for unchanged sidesAlso 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
PropertyPaddingLinecomponent is well-structured:
- Self-contained state management via
useNodeState- Proper gating behind
is_flex_containercheck- Correctly binds to the updated
actions.paddinghandler expectingIPaddingThe 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
PropertyPaddingLinecomponent.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+20251219appropriately 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 ofPartial<i.IPadding>for container types.Using
Partial<i.IPadding>onContainerNodeandComponentNodeallows 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
createContainerNodefactory 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) toIPadding(per-edge object) aligns with the schema refactor and matches the updatedPaddingControl.onValueCommitsignature.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
paddingproperty 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
paddingproperty. 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::Pathvariant itself has been removed from theJSONNodeenum 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 rusteditor/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 shorthandpaddingproperty. 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
changeContainerNodePaddingsignature change from a single padding value to the fullIPaddingobject (containingpadding_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 anIPaddingobject, 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
IPaddingobject 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
changeContainerNodePaddingare 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 tsxeditor/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
?? 0for 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
svgpathfrom the list of node types that support thefillproperty, 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
svgpathfrom the list of node types that supportstroke_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 to0.0.
1937-1937: LGTM!The
JSONNode::Vectorconversion is clean and consistent with the removal of the separatePathnode type mentioned in the PR objectives.
2137-2228: Good test coverage for the new per-edge padding format.The tests comprehensively cover:
- Full padding specification with all four edges
- Partial padding with missing fields defaulting to 0
- No padding resulting in
Noneforlayout_paddingThis 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, andpadding_leftproperties, with appropriate assertions verifying both the raw fields and the convertedEdgeInsetsvalues.
1308-1320: Padding conversion logic with zero-check optimization is correct.The code properly constructs
EdgeInsetsfrom the four explicit padding fields and returnsNonewhen all edges are zero, avoiding unnecessary allocations. TheEdgeInsets::is_zero()method is correctly implemented incrates/grida-canvas/src/cg/types.rsand 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/vnas 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()andvn.getBBox()calls introduced in the HasGeometryTrait processing functions.
690-698: LGTM! Clean type guard implementation.The
hasGeometryTraittype 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:
processNodeWithGeometryTraitcoordinates fill and stroke conversion and updates the graphattachGeometryChildrenIfPresentprovides 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
attachGeometryChildrenIfPresentis properly placed after node creation, ensuring geometry children are added when appropriate.
1165-1177: VECTOR/STAR/REGULAR_POLYGON now return GroupNode with child VectorNodesREST 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
encodeSVGPathimplementation supporting basic path commands (MOVE_TO, LINE_TO, CURVE_TO, CLOSE_PATH)SVGPathDataclass with all required static constants (including those used by @grida/vn)- Proper ESM module marking with
__esModule: trueThe 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.
padding->padding_top,padding_right,padding_bottom,padding_leftSVGPathNodevector data as LUTSummary by CodeRabbit
Release Notes
New Features
Bug Fixes
Refactor
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.