Skip to content

Grida Canvas - Aspect Ratio#473

Merged
softmarshmallow merged 12 commits intomainfrom
canary
Dec 19, 2025
Merged

Grida Canvas - Aspect Ratio#473
softmarshmallow merged 12 commits intomainfrom
canary

Conversation

@softmarshmallow
Copy link
Copy Markdown
Member

@softmarshmallow softmarshmallow commented Dec 19, 2025

Summary by CodeRabbit

  • New Features

    • Aspect-ratio lock/unlock actions and a dashed aspect-ratio guide during constrained resizing.
    • Unified Width/Height control in the properties panel with a lock toggle.
  • Bug Fixes & Improvements

    • Layout sizing model refined to use explicit target/min/max dimensions and optional aspect-ratio hints.
    • Figma import and canvas layout honor preserve-ratio metadata.
    • Added numeric utilities for gcd/aspect-ratio approximation and related tests.
  • Style

    • Minor formatting and example code cleanups.

✏️ 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)
docs Ready Ready Preview, Comment Dec 19, 2025 0:48am
grida Ready Ready Preview, Comment Dec 19, 2025 0:48am
5 Skipped Deployments
Project Deployment Review Updated (UTC)
code Ignored Ignored Dec 19, 2025 0:48am
legacy Ignored Ignored Dec 19, 2025 0:48am
backgrounds Skipped Skipped Dec 19, 2025 0:48am
blog Skipped Skipped Dec 19, 2025 0:48am
viewer Skipped Skipped Dec 19, 2025 0:48am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 19, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This PR renames and extends layout fields across the codebase: width/heightlayout_target_width/layout_target_height, adds min/max layout constraints and layout_target_aspect_ratio, and wires aspect-ratio support through I/O, schema, layout conversion, editor UI/commands, snapping/resize logic, examples, tests, and utilities.

Changes

Cohort / File(s) Summary
Core Layout Schema & Types
crates/grida-canvas/src/node/schema.rs, crates/grida-canvas/src/node/factory.rs
Renamed layout fields and expanded UniformNodeLayout/LayoutDimensionStyle: added layout_target_*, layout_min_*/layout_max_*, layout_target_aspect_ratio, renamed positionlayout_position, updated constructors/builders and merge logic.
Layout Engine & Conversion
crates/grida-canvas/src/layout/into_taffy.rs, crates/grida-canvas/src/layout/engine.rs
Mapped new layout_... fields into Taffy Style (size/min/max/inset/position), added aspect-ratio handling (style.aspect_ratio) and updated size extraction logic/tests.
I/O: Figma / Grida
crates/grida-canvas/src/io/io_figma.rs, crates/grida-canvas/src/io/io_grida.rs, packages/grida-canvas-io-figma/lib.ts
Converted incoming size/constraint data to new layout_... fields; JSON node properties extended with layout min/max and aspect-ratio; introduced HasLayoutTraitIR in Figma IO to carry preserveRatio/targetAspectRatio.
Canvas Cache / SVG / Examples / Tests
crates/grida-canvas/src/cache/geometry.rs, crates/grida-canvas/src/svg/pack.rs, crates/grida-canvas/examples/*, crates/grida-canvas/tests/*, crates/grida-dev/examples/*
Updated fallback sizing, root/container sizing, and ~many examples/tests to use layout_target_width/layout_target_height. Minor formatting-only edits in some example files.
Editor: Commands, Reducers & UI
editor/grida-canvas/editor.i.ts, editor/grida-canvas/editor.ts, editor/grida-canvas/reducers/node.reducer.ts, editor/grida-canvas/reducers/scale.ts, editor/grida-canvas/reducers/node-transform.reducer.ts, editor/grida-canvas/reducers/tools/snap-resize.ts, editor/grida-canvas/reducers/tools/__tests__/snap-resize.test.ts
Added lockAspectRatio/unlockAspectRatio commands; exposed layout_target_aspect_ratio as a node property; extended scale/transform/snap code to accept and propagate a target aspect ratio (new action payload fields and adjusted signatures); updated tests to new snap API.
Editor Viewport & Controls
editor/grida-canvas-react/viewport/surface.tsx, editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx, editor/scaffolds/sidecontrol/controls/width-height.tsx, editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx, editor/scaffolds/sidecontrol/controls/ext-align.tsx
Added AspectRatioGuide component and integration into NodeOverlay for constrained-resize visuals; introduced WidthHeightControl with lock toggle wired to lock/unlock commands; small UI/test-id and styling tweaks.
Math Utilities & Tests
packages/grida-cmath/index.ts, packages/grida-cmath/__tests__/*
Added gcd, aspectRatio, and rational.approximateFraction implementations and tests (fraction approximation and aspect-ratio normalization).
Schema & Typings
packages/grida-canvas-schema/grida.ts
Added ILayoutTargetAspectRatio and mixed it into many public node interfaces and ICSSStylable so nodes can carry layout_target_aspect_ratio.
DB Draft / Packaging
supabase/drafts/20251214_grida_canvas_document_model.sql, editor/package.json, packages/grida-canvas-io-figma/package.json
Database draft updated to use layout_target_* columns and add layout constraint columns; removed @figma/rest-api-spec from editor devDeps; bumped figma rest spec version in io-figma package.json.
Minor Formatting
crates/csscascade/src/rcdom/mod.rs, crates/grida-canvas/src/shape/stroke_rect.rs, various formatting-only edits
Non-functional formatting tweaks (removed blank line, reflowed imports, multiline call formatting).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–75 minutes

Areas requiring extra attention:

  • crates/grida-canvas/src/node/schema.rs — broad public-type renames/additions; verify builders, Default impls, serialization, and backward compatibility.
  • crates/grida-canvas/src/layout/into_taffy.rs — aspect-ratio → Taffy mapping and min/max conversions.
  • editor/grida-canvas/reducers/tools/snap-resize.ts and editor/grida-canvas/reducers/node-transform.reducer.ts — signature changes and propagation of targetAspectRatio; ensure tests and callers updated consistently.
  • packages/grida-canvas-io-figma/lib.ts and crates/grida-canvas/src/io/* — consistent propagation of preserveRatio/targetAspectRatio across IR and JSON shapes.
  • Database draft and schema typings — ensure migrations and type consumers remain in sync.

Possibly related PRs

Suggested labels

canvas, ux, migration, breaking

"
🐇 I hopped through fields and gave them new names,
From width to target, the layout reclaims.
A dashed diagonal, a guide softly drawn,
Locking ratios steady from dusk until dawn.
✨📐
"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Grida Canvas - Aspect Ratio' directly reflects the main objective of this changeset, which introduces comprehensive aspect-ratio support throughout the Grida Canvas system.

📜 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 5c4f0a2 and ac7d650.

📒 Files selected for processing (2)
  • packages/grida-cmath/__tests__/cmath.test.ts (1 hunks)
  • packages/grida-cmath/index.ts (2 hunks)

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.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/grida-dev/examples/grida_blendmode.rs (1)

1-1: Address the FIXME comment - broken demo status needs verification.

The FIXME comment indicates this demo might be broken and should be renamed to use a golden_ prefix instead of grida_. Since this is an example file demonstrating blend mode functionality, having a potentially broken demo is problematic, especially when verifying that the layout field changes work correctly.

Would you like me to help verify whether this demo is actually broken and investigate the naming convention issue? I can generate scripts to check for similar examples and naming patterns.

supabase/drafts/20251214_grida_canvas_document_model.sql (1)

410-421: Update comments to reflect renamed fields.

The comments in the shape parity checklist still reference layout_width/layout_height instead of the new layout_target_width/layout_target_height field names. Update these comments for consistency.

Suggested fix for comment consistency
-  - Node::Rectangle        -> node_type='rectangle' + transform + layout_width/layout_height + rectangular_corner_radius_* + fill_paints/stroke_paints/effects
+  - Node::Rectangle        -> node_type='rectangle' + transform + layout_target_width/layout_target_height + rectangular_corner_radius_* + fill_paints/stroke_paints/effects

Apply similar changes to all other comments referencing the old field names on lines 410-421.

🧹 Nitpick comments (10)
editor/scaffolds/sidecontrol/controls/width-height.tsx (1)

31-42: Consider extracting magic numbers to constants.

The hardcoded positioning values (top: "0.5rem" and bottom: "0.5rem") could be extracted to named constants for better maintainability. This is a minor improvement and not required.

Optional refactor to use constants
+const BRACKET_OFFSET = "0.5rem";
+
 export function WidthHeightControl({
   ...
 }) {
   return (
     <div className="relative flex flex-col gap-2 py-1">
       <div className="absolute left-16 top-0 bottom-0 z-10 flex items-center justify-center">
         <div
           className="absolute left-1/2 -translate-x-1/2 w-2.5 h-2.5 border-0 border-l-2 border-t-2 border-border rounded-tl-sm"
-          style={{ top: "0.5rem" }}
+          style={{ top: BRACKET_OFFSET }}
         />
         <div
           className="absolute left-1/2 -translate-x-1/2 w-2.5 h-2.5 border-0 border-l-2 border-b-2 border-border rounded-bl-sm"
-          style={{ bottom: "0.5rem" }}
+          style={{ bottom: BRACKET_OFFSET }}
         />
packages/grida-cmath/index.ts (2)

38-68: Normalize max_denominator to a sensible integer bound in aspectRatio

aspectRatio relies on rational.approximateFraction’s max_denominator as an upper bound, but currently accepts arbitrary positive reals. Values like max_denominator = 0.5 lead to degenerate results (e.g. a positive aspect ratio producing [0, 1]). Coercing to an integer ≥ 1 at the boundary keeps the API predictable.

Proposed tweak: clamp & floor max_denominator before use
   export function aspectRatio(
     width: number,
     height: number,
     max_denominator: number = 1000
   ): [number, number] | undefined {
     if (
       !Number.isFinite(width) ||
       !Number.isFinite(height) ||
       width <= 0 ||
       height <= 0
     ) {
       return undefined;
     }
+    // Ensure we pass a sane integer bound to the rational helper.
+    max_denominator = Math.max(1, Math.floor(max_denominator));
+
     const r = width / height;
     const frac = rational.approximateFraction(r, max_denominator);

648-712: rational.approximateFraction looks solid for bounded‑denominator aspect‑ratio use

The continued‑fraction implementation with max_denominator clamp, input validation, and sign handling is well structured and matches how aspectRatio consumes it. With the gcd fix above in place, this should be robust for canvas/layout use cases.

If you ever want to harden it further, you could (a) explicitly clamp epsilon to a reasonable positive range, and/or (b) document that max_denominator is interpreted as an integer bound (then align it with the aspectRatio normalization above).

packages/grida-cmath/__tests__/cmath.rational.test.ts (1)

1-35: Good test coverage for core functionality.

The test suite covers the essential cases: exact fractions, zero, common rationals, max_denominator constraint, and invalid inputs. The tests are well-structured and clear.

Consider adding edge case tests for more comprehensive coverage:

Suggested additional test cases
test("should handle max_denominator boundary cases", () => {
  // Very small denominators
  const result1 = cmath.rational.approximateFraction(0.7, 1);
  expect(result1).toEqual([1, 1]); // closest to 0.7 with denom=1

  // Exact hit on max_denominator
  const result2 = cmath.rational.approximateFraction(0.5, 2);
  expect(result2).toEqual([1, 2]);
});

test("should handle floating point precision edge cases", () => {
  // Very large numbers
  const result = cmath.rational.approximateFraction(1e10 + 0.5);
  expect(result).toBeDefined();
  
  // Very small numbers
  const result2 = cmath.rational.approximateFraction(1e-10);
  expect(result2).toBeDefined();
});
editor/grida-canvas/reducers/methods/scale.ts (1)

245-258: Consider improving type safety for layout_target_aspect_ratio access.

The use of (first_node as any).layout_target_aspect_ratio bypasses TypeScript's type checking. If layout_target_aspect_ratio is a legitimate property on certain node types, consider adding it to the appropriate type definition or using a type guard.

🔎 Suggested improvement
-    const first_node = draft.document.nodes[
-      selection[0]
-    ] as grida.program.nodes.Node;
-    const target_ratio = (first_node as any).layout_target_aspect_ratio as
-      | [number, number]
-      | undefined;
+    const first_node = draft.document.nodes[
+      selection[0]
+    ] as grida.program.nodes.Node;
+    const target_ratio = 
+      "layout_target_aspect_ratio" in first_node
+        ? (first_node.layout_target_aspect_ratio as [number, number] | undefined)
+        : undefined;
editor/grida-canvas/reducers/node-transform.reducer.ts (1)

59-64: Aspect‑ratio scaling branch looks correct; consider a small defensive guard

The new targetAspectRatio handling in the preserveAspectRatio path correctly:

  • Picks a dominant axis from movement
  • Derives a (newWidth, newHeight) pair that matches the requested ratio
  • Converts back to scale factors relative to rect.width / rect.height
  • Falls back to the previous “use current rect aspect ratio” behavior when targetAspectRatio is absent.

Given targetAspectRatio is a free tuple, you might optionally add a simple validation (e.g. ignore or clamp if targetAspectRatio[1] <= 0) to make this reducer robust against bad upstream data, but functionally this change is sound.

Also applies to: 109-110, 121-151

editor/grida-canvas-react/viewport/surface.tsx (1)

93-93: Aspect‑ratio guide integration in NodeOverlay is sound; consider tightening visibility and reusing selection data

The new logic in NodeOverlay:

  • Correctly derives rect dimensions from useSingleSelection(node_id) and the current transform scale.
  • Shows the AspectRatioGuide only when:
    • A scale gesture is active,
    • The node is part of gesture.selection, and
    • Either the node has layout_target_aspect_ratio, the scale tool is in uniform mode (gesture.uniform_scale), or the preserve‑aspect‑ratio modifier is on.

This matches the intended semantics for aspect‑ratio‑constrained resizing, and the way you feed rect and direction into <AspectRatioGuide> is consistent with how the overlay is sized.

Two optional cleanups you might consider:

  1. Limit the guide to the “primary” interactive overlay

    Right now, show_aspect_ratio_guide ignores focused / readonly, so any overlay whose node is in gesture.selection can render the diagonal (e.g. per‑node overlays in multi‑selection). If you only want the main interactive overlay to show the guide, you could also require focused && !readonly in the predicate.

  2. Avoid recomputing useSingleSelection twice

    SingleSelectionOverlay and NodeOverlay both call useSingleSelection(node_id). For heavier scenes this doubles geometry queries. A small refactor would be to compute the selection data once in SingleSelectionOverlay and pass it into NodeOverlay as a prop, letting other callers (hover, remote cursors) keep using the hook directly.

These are polish‑level; the current implementation is functionally correct.

Also applies to: 1194-1202, 1238-1249, 1250-1259, 1461-1473

editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx (1)

16-57: Codify direction → diagonal mapping with small unit tests

The corner/edge → endpoints mapping is non-trivial but pure; a couple of focused tests around getDiagonalEndpoints (one case per CardinalDirection) would lock in the intended behavior and make future refactors safer.

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

756-771: New layout min/max and aspect-ratio fields are wired correctly; consider adding deserialization tests

The serde setup for layout_min_*/layout_max_* (with aliases like minWidth/maxWidth) and layout_target_aspect_ratio (alias aspectRatio) plus the mapping into LayoutDimensionStyle in From<JSONContainerNode> all look consistent with the updated layout model.

To avoid regressions, it would be worthwhile to add a small test that:

  • Deserializes a JSONContainerNode with these fields set (using both canonical names and aliases), and
  • Asserts the resulting ContainerNodeRec.layout_dimensions min/max and layout_target_aspect_ratio values.

Also applies to: 1368-1375

crates/grida-canvas/src/node/schema.rs (1)

324-405: UniformNodeLayout and LayoutDimensionStyle structure are coherent; consider a small API helper for aspect ratio

The expanded UniformNodeLayout/LayoutDimensionStyle surface (target size, min/max, aspect ratio, container + child properties, and an explicit layout_position) reads cleanly and lines up with how into_taffy.rs consumes it.

To keep callsites from having to construct raw (f32, f32) tuples and to centralize invariants (e.g., rejecting non‑positive or NaN values), you might consider adding a small builder-style helper like:

  • with_layout_aspect_ratio(width: f32, height: f32) -> Self

that normalizes/validates the pair before assigning layout_target_aspect_ratio.

Also applies to: 407-537, 808-817, 819-831

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84d9ea3 and 5c4f0a2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (65)
  • crates/csscascade/src/rcdom/mod.rs (0 hunks)
  • crates/grida-canvas/examples/golden_container_stroke.rs (1 hunks)
  • crates/grida-canvas/examples/golden_fe_noise.rs (1 hunks)
  • crates/grida-canvas/examples/golden_layout_flex.rs (1 hunks)
  • crates/grida-canvas/examples/golden_layout_flex_alignment.rs (1 hunks)
  • crates/grida-canvas/examples/golden_layout_flex_padding.rs (1 hunks)
  • crates/grida-canvas/examples/golden_layout_padding.rs (2 hunks)
  • crates/grida-canvas/examples/golden_pdf.rs (1 hunks)
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs (1 hunks)
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs (1 hunks)
  • crates/grida-canvas/examples/golden_svg.rs (1 hunks)
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs (1 hunks)
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs (1 hunks)
  • crates/grida-canvas/src/cache/geometry.rs (1 hunks)
  • crates/grida-canvas/src/io/io_figma.rs (5 hunks)
  • crates/grida-canvas/src/io/io_grida.rs (2 hunks)
  • crates/grida-canvas/src/layout/engine.rs (16 hunks)
  • crates/grida-canvas/src/layout/into_taffy.rs (4 hunks)
  • crates/grida-canvas/src/node/factory.rs (1 hunks)
  • crates/grida-canvas/src/node/schema.rs (6 hunks)
  • crates/grida-canvas/src/shape/stroke_rect.rs (1 hunks)
  • crates/grida-canvas/src/svg/pack.rs (1 hunks)
  • crates/grida-canvas/tests/geometry_cache.rs (1 hunks)
  • crates/grida-canvas/tests/hit_test.rs (2 hunks)
  • crates/grida-canvas/tests/scene_cache.rs (1 hunks)
  • crates/grida-dev/examples/grida_basic.rs (1 hunks)
  • crates/grida-dev/examples/grida_blendmode.rs (1 hunks)
  • crates/grida-dev/examples/grida_booleans.rs (1 hunks)
  • crates/grida-dev/examples/grida_container.rs (1 hunks)
  • crates/grida-dev/examples/grida_effects.rs (1 hunks)
  • crates/grida-dev/examples/grida_fills.rs (2 hunks)
  • crates/grida-dev/examples/grida_gradients.rs (1 hunks)
  • crates/grida-dev/examples/grida_image.rs (1 hunks)
  • crates/grida-dev/examples/grida_images.rs (1 hunks)
  • crates/grida-dev/examples/grida_lines.rs (1 hunks)
  • crates/grida-dev/examples/grida_mask.rs (2 hunks)
  • crates/grida-dev/examples/grida_nested.rs (1 hunks)
  • crates/grida-dev/examples/grida_paint.rs (1 hunks)
  • crates/grida-dev/examples/grida_shapes.rs (1 hunks)
  • crates/grida-dev/examples/grida_shapes_ellipse.rs (1 hunks)
  • crates/grida-dev/examples/grida_strokes.rs (1 hunks)
  • crates/grida-dev/examples/grida_texts.rs (1 hunks)
  • crates/grida-dev/examples/grida_vector.rs (1 hunks)
  • crates/grida-dev/examples/grida_webfonts.rs (1 hunks)
  • crates/grida-dev/examples/wd_windowed_mode.rs (3 hunks)
  • editor/grida-canvas-react/viewport/surface.tsx (5 hunks)
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx (1 hunks)
  • editor/grida-canvas/editor.i.ts (1 hunks)
  • editor/grida-canvas/editor.ts (1 hunks)
  • editor/grida-canvas/reducers/methods/scale.ts (4 hunks)
  • editor/grida-canvas/reducers/node-transform.reducer.ts (3 hunks)
  • editor/grida-canvas/reducers/node.reducer.ts (1 hunks)
  • editor/grida-canvas/reducers/tools/__tests__/snap-resize.test.ts (0 hunks)
  • editor/grida-canvas/reducers/tools/snap-resize.ts (9 hunks)
  • editor/package.json (0 hunks)
  • editor/scaffolds/sidecontrol/controls/ext-align.tsx (10 hunks)
  • editor/scaffolds/sidecontrol/controls/width-height.tsx (1 hunks)
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx (2 hunks)
  • packages/grida-canvas-io-figma/lib.ts (4 hunks)
  • packages/grida-canvas-io-figma/package.json (1 hunks)
  • packages/grida-canvas-schema/grida.ts (10 hunks)
  • packages/grida-cmath/__tests__/cmath.rational.test.ts (1 hunks)
  • packages/grida-cmath/__tests__/cmath.test.ts (1 hunks)
  • packages/grida-cmath/index.ts (2 hunks)
  • supabase/drafts/20251214_grida_canvas_document_model.sql (1 hunks)
💤 Files with no reviewable changes (3)
  • crates/csscascade/src/rcdom/mod.rs
  • editor/grida-canvas/reducers/tools/tests/snap-resize.test.ts
  • editor/package.json
🧰 Additional context used
📓 Path-based instructions (9)
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-dev/examples/grida_container.rs
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs
  • crates/grida-dev/examples/grida_images.rs
  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/node/factory.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-dev/examples/grida_effects.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/examples/golden_container_stroke.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-dev/examples/grida_vector.rs
  • crates/grida-canvas/examples/golden_fe_noise.rs
  • crates/grida-canvas/examples/golden_layout_flex.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-canvas/examples/golden_layout_flex_alignment.rs
  • crates/grida-canvas/examples/golden_layout_padding.rs
  • crates/grida-dev/examples/grida_fills.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-canvas/examples/golden_layout_flex_padding.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_image.rs
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-dev/examples/grida_nested.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-canvas/src/io/io_figma.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-canvas/src/svg/pack.rs
  • crates/grida-dev/examples/wd_windowed_mode.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.rs
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/examples/golden_vector_regions_fills.rs
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/node/factory.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-canvas/examples/golden_container_stroke.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-canvas/examples/golden_fe_noise.rs
  • crates/grida-canvas/examples/golden_layout_flex.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-canvas/examples/golden_layout_flex_alignment.rs
  • crates/grida-canvas/examples/golden_layout_padding.rs
  • crates/grida-canvas/examples/golden_layout_flex_padding.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-canvas/src/io/io_figma.rs
  • crates/grida-canvas/src/svg/pack.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
**/*.{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-cmath/__tests__/cmath.test.ts
  • editor/grida-canvas/reducers/node.reducer.ts
  • editor/scaffolds/sidecontrol/controls/ext-align.tsx
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/grida-canvas/reducers/methods/scale.ts
  • editor/scaffolds/sidecontrol/controls/width-height.tsx
  • editor/grida-canvas/reducers/node-transform.reducer.ts
  • editor/grida-canvas/editor.i.ts
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • packages/grida-cmath/__tests__/cmath.rational.test.ts
  • editor/grida-canvas/editor.ts
  • packages/grida-canvas-io-figma/lib.ts
  • packages/grida-canvas-schema/grida.ts
  • packages/grida-cmath/index.ts
  • editor/grida-canvas-react/viewport/surface.tsx
  • editor/grida-canvas/reducers/tools/snap-resize.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/reducers/node.reducer.ts
  • editor/scaffolds/sidecontrol/controls/ext-align.tsx
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/grida-canvas/reducers/methods/scale.ts
  • editor/scaffolds/sidecontrol/controls/width-height.tsx
  • editor/grida-canvas/reducers/node-transform.reducer.ts
  • editor/grida-canvas/editor.i.ts
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • editor/grida-canvas/editor.ts
  • packages/grida-canvas-io-figma/lib.ts
  • packages/grida-canvas-schema/grida.ts
  • editor/grida-canvas-react/viewport/surface.tsx
  • editor/grida-canvas/reducers/tools/snap-resize.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/reducers/node.reducer.ts
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/grida-canvas/reducers/methods/scale.ts
  • editor/grida-canvas/reducers/node-transform.reducer.ts
  • editor/grida-canvas/editor.i.ts
  • editor/grida-canvas/editor.ts
  • editor/grida-canvas-react/viewport/surface.tsx
  • editor/grida-canvas/reducers/tools/snap-resize.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use React.js 19 for web applications

Files:

  • editor/scaffolds/sidecontrol/controls/ext-align.tsx
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/scaffolds/sidecontrol/controls/width-height.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • editor/grida-canvas-react/viewport/surface.tsx
editor/scaffolds/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • editor/scaffolds/sidecontrol/controls/ext-align.tsx
  • editor/scaffolds/sidecontrol/controls/width-height.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
supabase/**/*.sql

📄 CodeRabbit inference engine (AGENTS.md)

Database heavily relies on Supabase (PostgreSQL); use Supabase for database, auth, and storage

Files:

  • supabase/drafts/20251214_grida_canvas_document_model.sql
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/lib.ts
  • packages/grida-canvas-schema/grida.ts
🧠 Learnings (32)
📓 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
📚 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-dev/examples/grida_container.rs
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs
  • crates/grida-dev/examples/grida_images.rs
  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/node/factory.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-dev/examples/grida_effects.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/examples/golden_container_stroke.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-dev/examples/grida_vector.rs
  • crates/grida-canvas/examples/golden_fe_noise.rs
  • crates/grida-canvas/examples/golden_layout_flex.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-canvas/examples/golden_layout_flex_alignment.rs
  • crates/grida-canvas/examples/golden_layout_padding.rs
  • crates/grida-dev/examples/grida_fills.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-canvas/examples/golden_layout_flex_padding.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_image.rs
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-dev/examples/grida_nested.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-canvas/src/io/io_figma.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-canvas/src/svg/pack.rs
  • crates/grida-dev/examples/wd_windowed_mode.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.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 `skia-safe` crate for all painting and rendering operations

Applied to files:

  • crates/grida-dev/examples/grida_container.rs
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs
  • crates/grida-dev/examples/grida_images.rs
  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/node/factory.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-dev/examples/grida_effects.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/examples/golden_container_stroke.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-dev/examples/grida_vector.rs
  • crates/grida-canvas/examples/golden_fe_noise.rs
  • crates/grida-canvas/examples/golden_layout_flex.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-canvas/examples/golden_layout_flex_alignment.rs
  • crates/grida-canvas/examples/golden_layout_padding.rs
  • crates/grida-dev/examples/grida_fills.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-canvas/examples/golden_layout_flex_padding.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_image.rs
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-dev/examples/grida_nested.rs
  • crates/grida-canvas/src/io/io_figma.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-canvas/src/svg/pack.rs
  • crates/grida-dev/examples/wd_windowed_mode.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.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 : Public APIs must accept and return `UserNodeId` (String) instead of `NodeId` for stability and serialization

Applied to files:

  • crates/grida-dev/examples/grida_container.rs
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs
  • crates/grida-dev/examples/grida_images.rs
  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/node/factory.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-dev/examples/grida_vector.rs
  • crates/grida-canvas/examples/golden_fe_noise.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_image.rs
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-dev/examples/grida_nested.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-canvas/src/io/io_figma.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-canvas/src/svg/pack.rs
  • crates/grida-dev/examples/wd_windowed_mode.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.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-dev/examples/grida_container.rs
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs
  • crates/grida-dev/examples/grida_images.rs
  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/node/factory.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-dev/examples/grida_effects.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/examples/golden_container_stroke.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-dev/examples/grida_vector.rs
  • crates/grida-canvas/examples/golden_fe_noise.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_image.rs
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-canvas/src/svg/pack.rs
  • crates/grida-dev/examples/wd_windowed_mode.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.rs
📚 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-dev/examples/grida_container.rs
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs
  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • packages/grida-canvas-io-figma/package.json
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • editor/grida-canvas/reducers/node.reducer.ts
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • supabase/drafts/20251214_grida_canvas_document_model.sql
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-canvas/examples/golden_fe_noise.rs
  • crates/grida-canvas/examples/golden_layout_flex.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-dev/examples/grida_fills.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_image.rs
  • editor/grida-canvas/editor.ts
  • packages/grida-canvas-io-figma/lib.ts
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-dev/examples/grida_nested.rs
  • packages/grida-canvas-schema/grida.ts
  • crates/grida-canvas/src/io/io_grida.rs
  • packages/grida-cmath/index.ts
  • crates/grida-canvas/src/io/io_figma.rs
  • crates/grida-dev/examples/grida_texts.rs
  • editor/grida-canvas/reducers/tools/snap-resize.ts
  • crates/grida-dev/examples/wd_windowed_mode.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.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 `IdConverter` to handle conversion between `NodeId` and `UserNodeId` during .grida file loading

Applied to files:

  • crates/grida-dev/examples/grida_container.rs
  • crates/grida-canvas/examples/golden_vector_regions_fills.rs
  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-dev/examples/grida_fills.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_image.rs
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.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-dev/examples/grida_container.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-dev/examples/grida_fills.rs
  • crates/grida-dev/examples/grida_mask.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-dev/examples/wd_windowed_mode.rs
  • crates/grida-canvas/src/layout/into_taffy.rs
  • crates/grida-dev/examples/grida_strokes.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-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/src/node/factory.rs
  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_basic.rs
  • crates/grida-canvas/examples/golden_pdf.rs
  • crates/grida-dev/examples/grida_shapes.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-canvas/src/io/io_grida.rs
  • crates/grida-dev/examples/grida_texts.rs
  • crates/grida-canvas/src/node/schema.rs
  • crates/grida-dev/examples/grida_strokes.rs
📚 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:

  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-dev/examples/grida_paint.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-dev/examples/grida_mask.rs
📚 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: Applies to crates/grida-dev/grida-dev/Cargo.toml : The `grida-dev` crate is marked `publish = false` and is intended solely for local development workflows and devtools

Applied to files:

  • crates/grida-dev/examples/grida_gradients.rs
  • crates/grida-dev/examples/grida_booleans.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-dev/examples/grida_blendmode.rs
  • crates/grida-dev/examples/grida_texts.rs
📚 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:

  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/grida-canvas-react/viewport/surface.tsx
📚 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:

  • crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
  • crates/grida-canvas/examples/golden_svg.rs
  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-dev/examples/grida_shapes_ellipse.rs
  • crates/grida-canvas/src/layout/engine.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-dev/examples/grida_fills.rs
  • crates/grida-dev/examples/grida_texts.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 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-io-figma/package.json
  • supabase/drafts/20251214_grida_canvas_document_model.sql
  • packages/grida-canvas-schema/grida.ts
  • editor/grida-canvas-react/viewport/surface.tsx
📚 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 crates/**/*.rs : Use Skia graphics backend for 2D graphics, bound with skia-safe

Applied to files:

  • crates/grida-canvas/src/cache/geometry.rs
  • crates/grida-canvas/examples/golden_sk_text_backdrop_blur_path.rs
  • crates/grida-canvas/src/shape/stroke_rect.rs
  • crates/grida-dev/examples/grida_lines.rs
  • crates/grida-canvas/examples/golden_vector_regions_strokes.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/**/scenario_*.rs : Scenario-specific comprehensive tests should be organized in files matching `scenario_*.rs`

Applied to files:

  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/tests/hit_test.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 : Run tests with serde feature using: `cargo test --features serde`

Applied to files:

  • crates/grida-canvas/tests/geometry_cache.rs
  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/tests/hit_test.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/tests/geometry_cache.rs
📚 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:

  • editor/scaffolds/sidecontrol/controls/ext-align.tsx
  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/grida-canvas-react/viewport/surface.tsx
📚 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 : Use `ttf-parser = "0.25"` as the required dependency for font parsing backend

Applied to files:

  • crates/grida-dev/examples/grida_webfonts.rs
  • crates/grida-canvas/src/layout/into_taffy.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-dev/examples/grida_webfonts.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/**/italic_level1.rs : Core font selection and italic detection tests should be organized in `italic_level1.rs`

Applied to files:

  • crates/grida-dev/examples/grida_webfonts.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 crates/**/*.rs : Use Rust 2024 edition for wasm builds and graphics core

Applied to files:

  • crates/grida-canvas/src/shape/stroke_rect.rs
📚 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:

  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.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/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • editor/grida-canvas-react/viewport/surface.tsx
📚 Learning: 2025-12-14T23:30:42.112Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T23:30:42.112Z
Learning: Applies to {editor/**/*.{ts,tsx},packages/grida-canvas-*/**/*.{ts,tsx}} : Use DOM (plain DOM as canvas) for website builder canvas, bound with React

Applied to files:

  • editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/grida-canvas-react/viewport/surface.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 : 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/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
📚 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/**/scenario_level2_*.rs : Level 2+ placeholder and limitation tests should be organized in files matching `scenario_level2_*.rs`

Applied to files:

  • crates/grida-canvas/tests/scene_cache.rs
  • crates/grida-canvas/tests/hit_test.rs
  • crates/grida-dev/examples/grida_fills.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 **/components/ui/**/*.{ts,tsx} : Use Shadcn UI for UI component library

Applied to files:

  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
📚 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/components/ui/**/*.{ts,tsx} : Use /editor/components/ui for shadcn UI components

Applied to files:

  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
📚 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 crates/**/*.rs : Rust crates in /crates directory are under rapid development and serve as the new rendering backend; ensure high quality implementations

Applied to files:

  • crates/grida-canvas/examples/golden_pdf.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 dev-dependency `serde_json = "1.0"` for JSON testing

Applied to files:

  • crates/grida-canvas/src/io/io_grida.rs
🧬 Code graph analysis (21)
crates/grida-dev/examples/grida_container.rs (1)
editor/grida-canvas-react-renderer-dom/nodes/index.ts (1)
  • container (18-18)
crates/grida-canvas/examples/golden_vector_regions_fills.rs (1)
crates/grida-canvas/src/cg/color.rs (1)
  • from_rgba (44-46)
crates/grida-canvas/src/node/factory.rs (1)
crates/grida-canvas/src/node/schema.rs (6)
  • default (130-138)
  • default (156-164)
  • default (540-542)
  • default (654-664)
  • default (803-805)
  • default (820-830)
crates/grida-canvas/src/shape/stroke_rect.rs (1)
.ref/canvaskit/canvaskit.d.ts (3)
  • PathEffect (3119-3119)
  • PathOp (5010-5010)
  • RRect (4806-4806)
editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx (1)
packages/grida-cmath/index.ts (1)
  • CardinalDirection (219-227)
editor/grida-canvas/reducers/methods/scale.ts (1)
editor/grida-canvas/reducers/node-transform.reducer.ts (1)
  • updateNodeTransform (77-230)
editor/scaffolds/sidecontrol/controls/width-height.tsx (3)
packages/grida-canvas-schema/grida.ts (1)
  • LengthPercentage (1004-1004)
editor/scaffolds/sidecontrol/ui/index.tsx (1)
  • PropertyLineLabel (43-59)
editor/scaffolds/sidecontrol/controls/length-percentage.tsx (1)
  • LengthPercentageControl (27-81)
editor/grida-canvas/reducers/node-transform.reducer.ts (1)
editor/grida-canvas/editor.ts (1)
  • scale (139-184)
crates/grida-canvas/examples/golden_vector_regions_strokes.rs (1)
crates/grida-canvas/src/cg/color.rs (1)
  • from_rgba (44-46)
crates/grida-canvas/examples/golden_fe_noise.rs (1)
crates/grida-canvas/src/cg/color.rs (1)
  • from_rgba (44-46)
editor/grida-canvas/editor.i.ts (1)
packages/grida-canvas-schema/grida.ts (1)
  • NodeID (1101-1101)
crates/grida-canvas/examples/golden_layout_flex.rs (1)
crates/grida-canvas/src/node/schema.rs (6)
  • default (130-138)
  • default (156-164)
  • default (540-542)
  • default (654-664)
  • default (803-805)
  • default (820-830)
crates/grida-canvas/examples/golden_layout_flex_alignment.rs (1)
crates/grida-canvas/src/node/schema.rs (6)
  • default (130-138)
  • default (156-164)
  • default (540-542)
  • default (654-664)
  • default (803-805)
  • default (820-830)
crates/grida-canvas/examples/golden_layout_padding.rs (1)
crates/grida-canvas/src/node/schema.rs (6)
  • default (130-138)
  • default (156-164)
  • default (540-542)
  • default (654-664)
  • default (803-805)
  • default (820-830)
crates/grida-canvas/examples/golden_layout_flex_padding.rs (1)
crates/grida-canvas/src/node/schema.rs (6)
  • default (130-138)
  • default (156-164)
  • default (540-542)
  • default (654-664)
  • default (803-805)
  • default (820-830)
editor/grida-canvas/editor.ts (2)
crates/grida-canvas/src/node/schema.rs (9)
  • rect (941-941)
  • rect (1003-1010)
  • rect (1183-1190)
  • rect (1340-1347)
  • rect (1472-1479)
  • rect (1680-1697)
  • rect (1760-1762)
  • rect (1874-1881)
  • rect (1997-2004)
editor/grida-canvas/backends/dom.ts (1)
  • rect (45-47)
editor/grida-canvas-react/viewport/surface.tsx (4)
editor/grida-canvas-react/viewport/surface-hooks.ts (1)
  • useSingleSelection (295-412)
editor/grida-canvas-react/provider.tsx (1)
  • useGestureState (614-632)
editor/grida-canvas-react/use-editor.tsx (1)
  • useEditorState (108-120)
editor/grida-canvas-react/viewport/ui/aspect-ratio-guide.tsx (1)
  • AspectRatioGuide (67-105)
editor/grida-canvas/reducers/tools/snap-resize.ts (2)
crates/math2/src/rect.rs (1)
  • aspect_ratio (575-577)
editor/app/(dev)/canvas/experimental/grid/core/state.ts (1)
  • initial (6-9)
crates/grida-canvas/src/svg/pack.rs (1)
crates/grida-canvas/examples/golden_container_stroke.rs (1)
  • scene (9-45)
crates/grida-canvas/src/layout/into_taffy.rs (2)
crates/grida-canvas/src/node/schema.rs (1)
  • layout (1071-1077)
crates/grida-canvas/src/io/io_css.rs (1)
  • length (76-81)
crates/grida-canvas/src/node/schema.rs (2)
packages/grida-canvas-cg/lib.ts (3)
  • Axis (561-561)
  • MainAxisAlignment (568-575)
  • CrossAxisAlignment (582-582)
crates/grida-canvas/src/cg/types.rs (12)
  • default (44-46)
  • default (82-84)
  • default (104-106)
  • default (236-238)
  • default (300-302)
  • default (314-316)
  • default (409-411)
  • default (516-518)
  • default (591-593)
  • default (617-619)
  • default (633-635)
  • default (663-665)

Comment thread packages/grida-canvas-io-figma/package.json
Comment thread packages/grida-cmath/index.ts
@vercel vercel Bot temporarily deployed to Preview – viewer December 19, 2025 12:44 Inactive
@vercel vercel Bot temporarily deployed to Preview – blog December 19, 2025 12:44 Inactive
@vercel vercel Bot temporarily deployed to Preview – backgrounds December 19, 2025 12:44 Inactive
@softmarshmallow softmarshmallow merged commit f3d3b90 into main Dec 19, 2025
8 of 11 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Dec 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant