Skip to content

Grida Canvas - Export Settings (313)#484

Merged
softmarshmallow merged 10 commits intomainfrom
canary
Dec 29, 2025
Merged

Grida Canvas - Export Settings (313)#484
softmarshmallow merged 10 commits intomainfrom
canary

Conversation

@softmarshmallow
Copy link
Copy Markdown
Member

@softmarshmallow softmarshmallow commented Dec 28, 2025

Manage Export Settings per node & export at once.

  • formats: PNG, JPEG, WEBP, PDF, SVG
  • supported constraints: scale, scale-to-fit-width, scale-to-fit-height
  • supported color profile: srgb only
  • quality for webp, jpeg
day-313-grida-canvas-export-settings.mp4

Summary by CodeRabbit

  • New Features

    • Added WEBP and BMP export formats
    • Per-format quality controls for JPEG and WEBP
    • Export constraints: none, scale, fit-to-width, fit-to-height
    • Per-node export configuration UI and batch ZIP export for multiple configs
  • Improvements

    • Unified node userdata into a metadata system with editor-side metadata management
    • Export flow and UI reorganized for clearer single/multi-file exports and feedback

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

@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 28, 2025

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

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 28, 2025

Walkthrough

Refactors the export type system and runtime to add WEBP/BMP, per-format quality and constraint-based scaling; introduces per-node metadata (export_settings, userdata) with storage and reducer support; updates editor export API to a generic, typed form; adjusts UI for section-based exports and ZIP multi-file flow.

Changes

Cohort / File(s) Summary
Export types (wasm + schema)
crates/grida-canvas-wasm/lib/index.ts, crates/grida-canvas/src/export/types.rs, packages/grida-canvas-schema/grida.ts
Redefined ExportConstraints tags and introduced per-format export types (ExportAsPNG/JPEG/WEBP/BMP) with optional quality fields; added NodeExportSettings and INodeMetadata schema types; renamed serde tags to lowercase descriptors.
Image exporters & renderer
crates/grida-canvas/src/export/export_as_image.rs, crates/grida-canvas/src/export/export_as_pdf.rs, crates/grida-canvas/src/export/export_as_svg.rs, crates/grida-canvas/src/export/mod.rs
Add world-space camera scaling to render at target resolution; Renderer::new_with_store signature now accepts Camera2D; exporters accept ImageRepository; per-format quality propagated to encoders; render snapshot freed earlier.
Editor API & interfaces (types + backends)
editor/grida-canvas/editor.i.ts, editor/grida-canvas/editor.ts, editor/grida-canvas/backends/wasm.ts, editor/grida-canvas/backends/dom-export.ts, editor/grida-canvas/backends/noop.ts
exportNodeAs made generic over formats with conditional return type (SVG → string, images → Uint8Array); added ExportConfigOf mapping; backends updated to accept config and support WEBP/BMP (wasm), and to restrict/validate formats (dom/noop); signatures updated to use grida.program.document.NodeExportSettings["format"].
Metadata actions & reducers
editor/grida-canvas/action.ts, editor/grida-canvas/reducers/metadata.reducer.ts, editor/grida-canvas/reducers/document.reducer.ts
Added MetadataAction and metadataReducer to manage per-node metadata namespaces (export_settings, userdata); document reducer routes metadata actions and initializes metadata map when needed.
Runtime metadata plumbing
editor/grida-canvas/plugins/yjs/y-document.ts, supabase/drafts/20251214_grida_canvas_document_model.sql
Include document.metadata in remote sync payload; added DB table grida_canvas.canvas_node_metadata for per-node metadata with indexes.
Editor internals & public actions
editor/grida-canvas/editor.ts, editor/grida-canvas/editor.i.ts
Added INodeMetadataActions and IExportConfigActions to editor surface; removed changeNodeUserData public helper; Editor.exportNodeAs signature updated to generic form and delegates validated exports to exporter.
UI: export controls & userdata
editor/scaffolds/sidecontrol/controls/export.tsx, editor/scaffolds/sidecontrol/controls/x-userdata.tsx, editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx, editor/scaffolds/sidecontrol/sidecontrol-document-properties.tsx
Replaced modal export UI with ExportSection, ExportNodeControl, ExportMultipleLayers; multi-config exports ZIP multiple files; UserDataControl now reads/writes via useNodeMetadata and editor.setUserData (props simplified).
Mixed properties & node shape changes
editor/grida-canvas-react/provider.tsx, editor/grida-canvas-react/index.ts, editor/grida-canvas-react/use-mixed-properties.ts, editor/grida-canvas/reducers/node.reducer.ts, editor/grida-canvas/reducers/tools/initial-node.ts, packages/grida-canvas-schema/grida.ts
Exposed useNodeMetadata hook; removed userdata from mixed properties ignore list; removed userdata property from safe_properties, initialNode, and IBaseNode (migrated to metadata).
WASM package bump & IO utilities
crates/grida-canvas-wasm/package.json, packages/grida-canvas-io/index.ts
Bumped wasm package version; io.zip utilities added (ensureUint8Array, create ZIP); JSON document parsing retains document.metadata; PNG data normalization to Uint8ClampedArray.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Editor
    participant MetadataStore
    participant Exporter
    participant Renderer
    participant ImageRepo

    Client->>Editor: exportNodeAs(node_id, format, config?)
    Editor->>Editor: validate format supported
    Editor->>MetadataStore: getNodeMetadata(node_id, "export_settings")
    MetadataStore-->>Editor: NodeExportSettings[]?
    Editor->>Editor: build runtime ExportConfig (constraints, quality)
    alt format == "SVG"
        Editor->>Exporter: exportNodeAs(node_id, "SVG", config)
        Exporter->>Renderer: render to SVG
        Renderer-->>Exporter: SVG string
        Exporter-->>Editor: Promise<string>
        Editor-->>Client: Promise<string>
    else image format (PNG/JPEG/WEBP/BMP)
        Editor->>Exporter: exportNodeAs(node_id, format, config)
        Exporter->>Exporter: compute camera scale & target resolution
        Exporter->>ImageRepo: fetch images
        Exporter->>Renderer: new_with_store(scene, fonts, images, camera)
        Renderer->>Renderer: render at target resolution
        Renderer-->>Exporter: snapshot
        Exporter->>Exporter: encode (apply quality if provided)
        Exporter-->>Editor: Promise<Uint8Array>
        Editor-->>Client: Promise<Uint8Array>
    else
        Editor-->>Client: throw Error("Non supported format: <format>")
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

breaking, canvas/io, migration

Poem

🐰 I hopped through code both neat and spry,

Added formats, zipped files high,
Metadata burrows left userdata's nest,
Camera scales to make pixels best,
Hooray — exports now jump and fly!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.84% 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 - Export Settings (313)' directly describes the main feature being added: export settings management for Grida Canvas, which is corroborated by the comprehensive changes across export-related modules, new metadata infrastructure, and UI controls.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch canary

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

❤️ Share

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

… improved data handling and ZIP file creation
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: 4

Caution

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

⚠️ Outside diff range comments (1)
editor/scaffolds/sidecontrol/controls/x-userdata.tsx (1)

16-29: User data editor is broken due to incorrect binding and validation logic

The code has two critical coupled issues that make the editor effectively read-only:

  1. Monaco editor isn't bound to txt state

    Line 88 binds the editor to value (from metadata) instead of txt:

    <MonacoEditor
      language="json"
      value={JSON.stringify(value, null, 2)}  // should be {txt}
      onChange={(value) => { setTxt(value); }}
    />

    User edits update txt, but React continuously re-renders the editor with the metadata value, causing all edits to be discarded.

  2. Validation treats empty input as invalid

    • validate("") returns undefined (line 20)
    • setValid(validate(txt) !== false) evaluates to true when empty (line 52, since undefined !== false)
    • But onSaveClick treats undefined as an error and shows a toast (line 58, if (res) is falsy for undefined)
    • Users cannot clear userdata via the UI

Fix by binding the editor to txt and using undefined explicitly for "clear" semantics:

<MonacoEditor
  language="json"
  value={txt}
  onChange={(v) => setTxt(v ?? "")}
/>

function validate(value: string | undefined): any | false {
  if (value == null || value.trim() === "") return undefined; // clear
  try {
    const parsed = JSON.parse(value);
    assert(parsed && typeof parsed === "object" && !Array.isArray(parsed));
    return parsed;
  } catch {
    return false;
  }
}

const onSaveClick = () => {
  const res = validate(txt);
  if (res === false) {
    toast.error("Invalid User Data Format");
    return;
  }
  editor.setUserData(node_id, (res ?? null) as Record<string, unknown> | null);
};
🧹 Nitpick comments (7)
editor/scaffolds/sidecontrol/controls/export.tsx (2)

222-313: Consider enhancing error handling for partial export failures.

The export logic correctly handles single vs. multi-file exports and provides good UX with spinner and toast feedback. However, if an individual export in the multi-file flow fails, the entire export may fail silently.

Consider wrapping individual exports in try-catch to handle partial failures gracefully:

🔎 Proposed enhancement for partial failure handling
       const tasks = exportConfigs.map(async (config, index) => {
+        try {
           if (!config?.format) return null;
 
           const format = config.format;
           if (
             !editorTypes.internal.export_settings.ALL_FORMATS.includes(format)
           ) {
             return null;
           }
 
           // Build export config from stored settings
           const exportConfig = buildExportConfig(config);
           const editorApi: editorTypes.api.IDocumentExportPluginActions = editor;
           const data = await editorApi.exportNodeAs(
             node_id,
             format,
             exportConfig
           );
 
           const suffix = config.suffix ? `-${config.suffix}` : "";
           const filename = `${name}${suffix}.${editorTypes.internal.export_settings.getFileExtension(format)}`;
 
           // Convert to Uint8Array for zip
           const bytes = io.zip.ensureUint8Array(data);
 
           files[filename] = bytes;
           return { filename, data };
+        } catch (error) {
+          console.error(`Failed to export ${config.format}:`, error);
+          return null;
+        }
       });

This ensures that one failing export doesn't break the entire multi-file export flow.


410-442: Consider validation for scale input bounds.

The scale input allows values from 0.1 to 10, but the handleScaleChange function doesn't validate the parsed value falls within this range. Invalid values could be set if users manually type values outside the allowed range.

🔎 Proposed validation enhancement
   const handleScaleChange = (newScale: string) => {
     const oldScale = scaleValue;
-    const scale = parseFloat(newScale) || 1;
+    let scale = parseFloat(newScale) || 1;
+    // Clamp to min/max bounds
+    scale = Math.max(0.1, Math.min(10, scale));
 
     // If suffix matches the auto pattern for old scale, update it for new scale
     const currentSuffix = config.suffix;
     const shouldUpdateSuffix = isAutoSuffix(currentSuffix, oldScale);
 
     // Only image configs can have constraints
     if (
       config.format === "PNG" ||
       config.format === "JPEG" ||
       config.format === "WEBP" ||
       config.format === "BMP"
     ) {
       const updates: {
         constraints: { type: "scale"; value: number };
         suffix?: string;
       } = {
         constraints: { type: "scale", value: scale },
       };
 
       if (shouldUpdateSuffix) {
         const newSuffix = getAutoSuffix(scale);
         if (newSuffix !== undefined) {
           updates.suffix = newSuffix;
         }
         // If scale is 1, we omit suffix (don't set it to undefined)
       }
 
       onUpdate(updates as Partial<grida.program.document.NodeExportSettings>);
     }
   };

This ensures scale values stay within the defined 0.1-10 range specified by the input's min/max attributes.

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

2038-2050: Implementation looks correct; consider metadata cleanup on node deletion.

The metadata action handling correctly initializes draft.document.metadata when absent and delegates to metadataReducer. The pattern follows the established reducer composition approach.

One consideration for future improvement: when nodes are deleted (in self_try_remove_node), their associated metadata entries in document.metadata are not cleaned up. This won't cause functional issues but may lead to orphaned metadata accumulating over time.

editor/grida-canvas/backends/noop.ts (1)

2-3: Generic exportNodeAs signature correctly aligned with editor API

The new generic exportNodeAs<F extends grida.program.document.NodeExportSettings["format"]>(...) and conditional return type match the updated ExportConfigOf<F> and editor-facing API; this keeps the noop backend type-safe while remaining a simple stub.

If you want stricter consistency with the other exporters, you could also widen canExportNodeAs’s format parameter to grida.program.document.NodeExportSettings["format"] | (string & {}) so the class perfectly mirrors the shared interface, but that’s optional given it always returns false.

Also applies to: 37-43

crates/grida-canvas/src/export/types.rs (1)

6-13: Serde tag/value alignment and per-format quality look correct; consider clamping

The updated serde rename values for ExportConstraints ("none" | "scale" | "scale-to-fit-width" | "scale-to-fit-height") match the TS side and should round‑trip cleanly. Adding quality: Option<u32> with #[serde(default)] for JPEG/WEBP also lines up with the new WASM bindings.

One follow‑up you might want to add later: defensively clamp quality into [0, 100] (either in this constructor or where you pass it to Skia), so malformed JSON or buggy callers can’t feed obviously out‑of‑range values into the encoder.

Also applies to: 29-36, 38-45, 117-122

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

3651-3658: Node metadata and export-config APIs are clean and encapsulated

The new INodeMetadataActions / IExportConfigActions implementations look well-structured:

  • Metadata is stored under document.metadata[node_id] and namespaced by "export_settings" and "userdata", so the core node schema stays untouched.
  • getNodeMetadata/setNodeMetadata/removeNodeMetadata provide a single, typed entry point for both namespaces, which is what the React hooks (useNodeMetadata) are now consuming.
  • Export-config helpers (getExportConfigs, addExportConfig, updateExportConfig, removeExportConfig, clearExportConfigs) manage arrays of NodeExportSettings per node and correctly remove the metadata entirely when the last config is deleted.

If you want to trim a bit of type noise, you could later replace the ReturnType<typeof this.getNodeMetadata<NS>> casts with a small internal helper or explicit type alias, but that’s purely ergonomic and doesn’t affect correctness.

Also applies to: 3670-3757, 3765-3807

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

4161-4286: LGTM!

Well-organized centralization of export-related types and utilities. The type guards, format arrays, and MIME type mapping provide a solid foundation for the export system.

Minor observation: The falsy checks in getFileExtension (line 4271) and getMimeType (line 4281) are defensive against runtime values that bypass TypeScript, which is reasonable. However, if you trust the type system, these branches are unreachable. Consider whether to keep them for defensive programming or remove for stricter type reliance.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9e39c9 and 215ae31.

⛔ Files ignored due to path filters (1)
  • crates/grida-canvas-wasm/lib/bin/grida_canvas_wasm.wasm is excluded by !**/*.wasm
📒 Files selected for processing (27)
  • crates/grida-canvas-wasm/lib/index.ts
  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_pdf.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/types.rs
  • editor/grida-canvas-react/index.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/grida-canvas-react/use-mixed-properties.ts
  • editor/grida-canvas/action.ts
  • editor/grida-canvas/backends/dom-export.ts
  • editor/grida-canvas/backends/noop.ts
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/editor.i.ts
  • editor/grida-canvas/editor.ts
  • editor/grida-canvas/plugins/yjs/y-document.ts
  • editor/grida-canvas/reducers/document.reducer.ts
  • editor/grida-canvas/reducers/metadata.reducer.ts
  • editor/grida-canvas/reducers/node.reducer.ts
  • editor/grida-canvas/reducers/tools/initial-node.ts
  • editor/scaffolds/sidecontrol/controls/export.tsx
  • editor/scaffolds/sidecontrol/controls/x-userdata.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-document-properties.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
  • packages/grida-canvas-io/index.ts
  • packages/grida-canvas-schema/grida.ts
💤 Files with no reviewable changes (2)
  • editor/grida-canvas/reducers/node.reducer.ts
  • editor/grida-canvas/reducers/tools/initial-node.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/plugins/yjs/y-document.ts
  • editor/grida-canvas-react/index.ts
  • editor/grida-canvas-react/use-mixed-properties.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-document-properties.tsx
  • editor/grida-canvas/reducers/document.reducer.ts
  • packages/grida-canvas-io/index.ts
  • editor/grida-canvas/reducers/metadata.reducer.ts
  • crates/grida-canvas-wasm/lib/index.ts
  • editor/grida-canvas/backends/noop.ts
  • editor/grida-canvas/editor.ts
  • editor/scaffolds/sidecontrol/controls/x-userdata.tsx
  • editor/grida-canvas/action.ts
  • editor/scaffolds/sidecontrol/controls/export.tsx
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/backends/dom-export.ts
  • packages/grida-canvas-schema/grida.ts
  • editor/grida-canvas/editor.i.ts
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
{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/plugins/yjs/y-document.ts
  • editor/grida-canvas-react/index.ts
  • editor/grida-canvas-react/use-mixed-properties.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-document-properties.tsx
  • editor/grida-canvas/reducers/document.reducer.ts
  • packages/grida-canvas-io/index.ts
  • editor/grida-canvas/reducers/metadata.reducer.ts
  • editor/grida-canvas/backends/noop.ts
  • editor/grida-canvas/editor.ts
  • editor/scaffolds/sidecontrol/controls/x-userdata.tsx
  • editor/grida-canvas/action.ts
  • editor/scaffolds/sidecontrol/controls/export.tsx
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/backends/dom-export.ts
  • packages/grida-canvas-schema/grida.ts
  • editor/grida-canvas/editor.i.ts
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
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/plugins/yjs/y-document.ts
  • editor/grida-canvas-react/index.ts
  • editor/grida-canvas-react/use-mixed-properties.ts
  • editor/grida-canvas-react/provider.tsx
  • editor/grida-canvas/reducers/document.reducer.ts
  • editor/grida-canvas/reducers/metadata.reducer.ts
  • editor/grida-canvas/backends/noop.ts
  • editor/grida-canvas/editor.ts
  • editor/grida-canvas/action.ts
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/backends/dom-export.ts
  • editor/grida-canvas/editor.i.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use React.js 19 for web applications

Files:

  • editor/grida-canvas-react/provider.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-document-properties.tsx
  • editor/scaffolds/sidecontrol/controls/x-userdata.tsx
  • editor/scaffolds/sidecontrol/controls/export.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.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/sidecontrol-document-properties.tsx
  • editor/scaffolds/sidecontrol/controls/x-userdata.tsx
  • editor/scaffolds/sidecontrol/controls/export.tsx
  • editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx
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/export/types.rs
  • crates/grida-canvas/src/export/export_as_pdf.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
crates/grida-canvas/**/*.rs

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

crates/grida-canvas/**/*.rs: Use NodeId (u64) for internal structs (NodeRecs, SceneGraph, caches) in the rendering engine for high-performance operations
Use UserNodeId (String) for public APIs that accept or return node IDs for stability and serialization
Handle NodeId to UserNodeId conversion via IdConverter during .grida file loading
Auto-generate IDs (ID=0) in NodeRepository for factory-created nodes
Maintain bidirectional mapping between NodeId and UserNodeId at the application layer for API boundary management
Use skia-safe crate for painting operations in the rendering engine
Use math2 crate for geometry and common math operations
Run cargo fmt to maintain code formatting standards
Run cargo clippy --no-deps --all-targets --all-features for linting to check style, performance, and correctness suggestions

Files:

  • crates/grida-canvas/src/export/types.rs
  • crates/grida-canvas/src/export/export_as_pdf.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
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/index.ts
  • packages/grida-canvas-schema/grida.ts
crates/grida-canvas-wasm/**/*.{js,ts,jsx,tsx}

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

Use Web Workers for heavy graphics operations to improve performance and responsiveness

Files:

  • crates/grida-canvas-wasm/lib/index.ts
🧠 Learnings (36)
📓 Common learnings
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 : Cache ImageData and dimensions in refs (imageDataRef, sizeRef) for efficient exports
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/**/+(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
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: Export options should support both PNG (rasterized at working resolution) and SVG (vector output not available for custom images)
📚 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/index.ts
  • editor/grida-canvas-react/use-mixed-properties.ts
  • editor/scaffolds/sidecontrol/controls/x-userdata.tsx
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/backends/dom-export.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/**/main.rs : Update `grida-canvas-wasm.d.ts` TypeScript definitions file when new APIs are introduced via `main.rs`

Applied to files:

  • editor/grida-canvas-react/index.ts
  • crates/grida-canvas/src/export/types.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/export/export_as_image.rs
  • packages/grida-canvas-io/index.ts
  • crates/grida-canvas-wasm/lib/index.ts
  • editor/grida-canvas/backends/noop.ts
  • editor/grida-canvas/editor.ts
  • crates/grida-canvas/src/export/export_as_svg.rs
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/backends/dom-export.ts
  • packages/grida-canvas-schema/grida.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/grida-*/**/*.{ts,tsx} : Use /editor/grida-* directories to isolate domain-specific modules; promote well-defined modules to <root>/packages

Applied to files:

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

Applied to files:

  • editor/grida-canvas-react/index.ts
  • crates/grida-canvas-wasm/package.json
  • packages/grida-canvas-io/index.ts
  • crates/grida-canvas-wasm/lib/index.ts
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/backends/dom-export.ts
  • packages/grida-canvas-schema/grida.ts
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Run `cargo fmt` to maintain code formatting standards

Applied to files:

  • crates/grida-canvas/src/export/types.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas-wasm/lib/index.ts
  • crates/grida-canvas/src/export/export_as_svg.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/export/types.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/export/types.rs
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `UserNodeId` (String) for public APIs that accept or return node IDs for stability and serialization

Applied to files:

  • crates/grida-canvas/src/export/types.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
  • packages/grida-canvas-schema/grida.ts
📚 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/export/types.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 : 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/src/export/types.rs
  • crates/grida-canvas/src/export/export_as_image.rs
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Run `cargo clippy --no-deps --all-targets --all-features` for linting to check style, performance, and correctness suggestions

Applied to files:

  • crates/grida-canvas/src/export/types.rs
  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/export/export_as_image.rs
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `skia-safe` crate for painting operations in the rendering engine

Applied to files:

  • crates/grida-canvas/src/export/types.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_svg.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 Skia graphics backend for 2D graphics, bound with skia-safe

Applied to files:

  • crates/grida-canvas/src/export/types.rs
  • crates/grida-canvas/src/export/export_as_image.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 React hooks for state management (imageSrc, shape, grid, maxRadius, gamma, jitter, opacity, color, customShapeImage, imageDataRef, sizeRef)

Applied to files:

  • editor/grida-canvas/reducers/document.reducer.ts
  • editor/scaffolds/sidecontrol/controls/x-userdata.tsx
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Auto-generate IDs (ID=0) in `NodeRepository` for factory-created nodes

Applied to files:

  • crates/grida-canvas/src/export/export_as_pdf.rs
  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `NodeId` (u64) for internal structs (NodeRecs, SceneGraph, caches) in the rendering engine for high-performance operations

Applied to files:

  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Handle NodeId to UserNodeId conversion via `IdConverter` during .grida file loading

Applied to files:

  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
  • editor/grida-canvas/backends/dom-export.ts
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Maintain bidirectional mapping between NodeId and UserNodeId at the application layer for API boundary management

Applied to files:

  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_svg.rs
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `math2` crate for geometry and common math operations

Applied to files:

  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas/src/export/export_as_image.rs
  • crates/grida-canvas/src/export/export_as_svg.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 : Cache ImageData and dimensions in refs (imageDataRef, sizeRef) for efficient exports

Applied to files:

  • crates/grida-canvas/src/export/mod.rs
  • crates/grida-canvas-wasm/lib/index.ts
  • editor/grida-canvas/editor.ts
  • editor/scaffolds/sidecontrol/controls/export.tsx
  • editor/grida-canvas/backends/dom-export.ts
  • editor/grida-canvas/editor.i.ts
📚 Learning: 2025-12-01T00:22:19.083Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-wasm/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:19.083Z
Learning: Applies to crates/grida-canvas-wasm/**/+(grida-canvas-wasm.js|grida-canvas-wasm.wasm) : Include WASM artifacts (`grida-canvas-wasm.js` and `grida-canvas-wasm.wasm`) in git for faster CI builds

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas-wasm/lib/index.ts
  • editor/grida-canvas/backends/wasm.ts
📚 Learning: 2025-12-01T00:22:19.083Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-wasm/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:19.083Z
Learning: Applies to crates/grida-canvas-wasm/**/*.{js,ts,jsx,tsx} : Use Web Workers for heavy graphics operations to improve performance and responsiveness

Applied to files:

  • crates/grida-canvas-wasm/package.json
  • crates/grida-canvas-wasm/lib/index.ts
  • editor/grida-canvas/backends/wasm.ts
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.grida : Validate .grida files using the `tool_io_grida` CLI tool to check file structure, parse all nodes, and detect parsing errors

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: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: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: Export options should support both PNG (rasterized at working resolution) and SVG (vector output not available for custom images)

Applied to files:

  • crates/grida-canvas/src/export/export_as_image.rs
  • editor/grida-canvas/backends/wasm.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:

  • editor/grida-canvas/editor.ts
  • editor/scaffolds/sidecontrol/controls/export.tsx
  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/backends/dom-export.ts
  • editor/grida-canvas/editor.i.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/sidecontrol/controls/export.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: Ensure WASM-ready JSON serialization for web integration

Applied to files:

  • editor/grida-canvas/backends/wasm.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/lib/**/*.{ts,tsx} : Use /editor/lib for core, strictly designed modules with non-opinionated, reusable, and stable implementations

Applied to files:

  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/editor.i.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:

  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/editor.i.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:

  • editor/grida-canvas/backends/wasm.ts
  • editor/grida-canvas/editor.i.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/components/ui/**/*.{ts,tsx} : Use /editor/components/ui for shadcn UI components

Applied to files:

  • editor/grida-canvas/backends/wasm.ts
  • 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/**/*.{ts,tsx} : Use /editor/components for generally reusable components

Applied to files:

  • editor/grida-canvas/backends/wasm.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 : Custom images used as halftone shapes should be loaded as HTMLImageElement for efficient canvas rendering and preserve original image colors in as-is mode

Applied to files:

  • editor/grida-canvas/backends/dom-export.ts
  • editor/grida-canvas/editor.i.ts
🧬 Code graph analysis (15)
editor/grida-canvas-react/provider.tsx (1)
editor/grida-canvas-react/use-editor.tsx (2)
  • useCurrentEditor (98-106)
  • useEditorState (108-120)
editor/scaffolds/sidecontrol/sidecontrol-document-properties.tsx (1)
editor/scaffolds/sidecontrol/controls/x-userdata.tsx (1)
  • UserDataControl (31-108)
crates/grida-canvas/src/export/types.rs (1)
crates/grida-canvas-wasm/lib/index.ts (3)
  • ExportAsWEBP (73-82)
  • ExportConstraints (41-55)
  • ExportAsJPEG (64-72)
editor/grida-canvas/reducers/document.reducer.ts (2)
editor/grida-canvas/reducers/utils/immer.ts (1)
  • updateState (3-13)
editor/grida-canvas/reducers/metadata.reducer.ts (1)
  • metadataReducer (4-33)
crates/grida-canvas/src/export/mod.rs (2)
crates/grida-canvas/src/export/export_as_pdf.rs (1)
  • export_node_as_pdf (15-71)
crates/grida-canvas/src/export/export_as_svg.rs (1)
  • export_node_as_svg (14-52)
editor/grida-canvas/reducers/metadata.reducer.ts (2)
packages/grida-canvas-schema/grida.ts (1)
  • INodeMetadata (655-671)
editor/grida-canvas/action.ts (1)
  • MetadataAction (1058-1076)
editor/grida-canvas/editor.ts (2)
editor/grida-canvas/editor.i.ts (3)
  • INodeMetadataActions (4030-4103)
  • IExportConfigActions (4110-4147)
  • ExportConfigOf (2558-2578)
packages/grida-canvas-schema/grida.ts (2)
  • NodeExportSettings (607-610)
  • format (126-133)
editor/scaffolds/sidecontrol/controls/x-userdata.tsx (2)
editor/grida-canvas-react/index.ts (2)
  • useCurrentEditor (1-1)
  • useNodeMetadata (8-8)
editor/grida-canvas-react/provider.tsx (1)
  • useNodeMetadata (867-880)
editor/grida-canvas/action.ts (1)
packages/grida-canvas-schema/grida.ts (1)
  • NodeExportSettings (607-610)
editor/scaffolds/sidecontrol/controls/export.tsx (9)
editor/grida-canvas/index.ts (1)
  • editor (4-4)
editor/grida-canvas-react/index.ts (2)
  • useCurrentEditor (1-1)
  • useNodeMetadata (8-8)
editor/grida-canvas-react/use-editor.tsx (1)
  • useCurrentEditor (98-106)
editor/components/sidebar/index.tsx (4)
  • SidebarSection (290-302)
  • SidebarSectionHeaderItem (313-332)
  • SidebarSectionHeaderLabel (334-348)
  • SidebarSectionHeaderActions (350-369)
editor/scaffolds/sidecontrol/ui/index.tsx (1)
  • PropertyLine (19-41)
editor/components/ui/spinner.tsx (1)
  • Spinner (16-16)
editor/components/ui-editor/popover.tsx (3)
  • Popover (62-62)
  • PopoverTrigger (62-62)
  • PopoverContent (62-62)
editor/components/ui/select.tsx (3)
  • Select (177-177)
  • SelectContent (178-178)
  • SelectItem (180-180)
editor/components/ui/input.tsx (1)
  • Input (21-21)
editor/grida-canvas/backends/wasm.ts (1)
editor/grida-canvas/editor.i.ts (1)
  • ExportConfigOf (2558-2578)
editor/grida-canvas/backends/dom-export.ts (2)
packages/grida-canvas-schema/grida.ts (2)
  • NodeExportSettings (607-610)
  • format (126-133)
editor/grida-canvas/editor.i.ts (1)
  • ExportConfigOf (2558-2578)
packages/grida-canvas-schema/grida.ts (2)
editor/grida-canvas/query/index.ts (1)
  • nodes (590-592)
editor/grida-canvas/editor.i.ts (1)
  • NodeID (136-136)
editor/grida-canvas/editor.i.ts (1)
packages/grida-canvas-schema/grida.ts (6)
  • NodeExportSettings (607-610)
  • NodeExportSettings_Image (628-636)
  • NodeExportSettingsConstraints (612-626)
  • NodeExportSettings_PDF (638-641)
  • NodeExportSettings_SVG (643-646)
  • format (126-133)
editor/scaffolds/sidecontrol/sidecontrol-node-selection.tsx (4)
editor/scaffolds/sidecontrol/controls/export.tsx (2)
  • ExportMultipleLayers (713-849)
  • ExportSection (150-200)
editor/components/sidebar/index.tsx (3)
  • SidebarSection (290-302)
  • SidebarSectionHeaderItem (313-332)
  • SidebarSectionHeaderLabel (334-348)
editor/scaffolds/sidecontrol/ui/index.tsx (1)
  • PropertyLine (19-41)
editor/scaffolds/sidecontrol/controls/x-userdata.tsx (1)
  • UserDataControl (31-108)
🪛 Biome (2.1.2)
editor/grida-canvas/reducers/metadata.reducer.ts

[error] 18-19: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 20-20: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 28-28: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🔇 Additional comments (26)
crates/grida-canvas-wasm/package.json (1)

4-4: LGTM! Version bump aligns with the PR's wasm toolchain update.

The version increment to 0.89.0-canary.3 is consistent with the PR description and the expanded export feature set.

packages/grida-canvas-io/index.ts (2)

864-909: LGTM! Well-designed ZIP utilities for multi-file exports.

The new io.zip namespace provides clean abstractions for the multi-file export feature:

  • ensureUint8Array handles both string (SVG) and binary (PNG/JPEG) export data
  • create wraps zipSync with type safety
  • Documentation is clear and includes examples

771-771: LGTM! Metadata propagation preserves per-node export settings.

Adding metadata: json.document.metadata ensures that per-node export configurations and userdata are correctly preserved during document parsing.

crates/grida-canvas-wasm/lib/index.ts (1)

41-91: LGTM! Well-structured per-format export type system.

The expanded export type system provides:

  • Clear constraint type documentation with examples
  • Separate types for each image format (PNG, JPEG, WEBP, BMP)
  • Quality settings for lossy formats with documented defaults
  • Type-safe discriminated union via format field

This is a breaking change from the previous ExportAsImage interface, but the new structure is more maintainable and extensible.

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

535-545: Consider whether undefined should be allowed in JSONValue.

The JSONValue type includes undefined in object values ({ [key: string]: JSONValue | undefined }), but undefined is not valid JSON according to the JSON specification. This might cause serialization issues when using JSON.stringify(), which omits undefined values.

If undefined values are intentional for sparse objects, this is acceptable. Otherwise, consider:

🔎 Strict JSON type alternative
export type JSONValue =
  | string
  | number
  | boolean
  | null
  | { [key: string]: JSONValue }
  | JSONValue[];

Please confirm whether undefined values in objects are intentionally supported for the metadata use case.


604-671: LGTM! Well-designed export configuration type system.

The new export settings types provide:

  • Clear separation between image, PDF, and SVG export configurations
  • Documented constraint types for image scaling
  • Quality settings for lossy formats (JPEG, WEBP)
  • Type-safe readonly properties

The structure supports the PR's expanded export capabilities while maintaining type safety.


866-866: LGTM! Document schema correctly extended for metadata support.

The changes properly support the metadata migration:

  • Document now extends INodeMetadata to include the metadata map
  • userdata removed from __base_scene_node_properties since it's now in metadata

This maintains backward compatibility while enabling the new per-node metadata system.

Also applies to: 1374-1374

crates/grida-canvas/src/export/export_as_pdf.rs (1)

7-7: LGTM! ImageRepository integration for PDF image rendering.

The changes correctly add image repository support to PDF export:

  • Import added for ImageRepository
  • Parameter added to function signature
  • Images cloned into renderer before scene loading

This parallels the SVG export implementation and enables proper image rendering in exported PDFs.

Also applies to: 18-18, 50-50

editor/grida-canvas-react/use-mixed-properties.ts (1)

38-38: Verify whether userdata has been fully removed from node serialization.

Removing "userdata" from ignoredKey means userdata values will now be included in the mixed property analysis. This is safe only if userdata is no longer serialized on node objects at runtime. The codebase shows userdata is now accessed through the metadata system (e.g., useNodeMetadata(node_id, "userdata")), but it's unclear whether the property was fully removed from nodes or remains for backward compatibility.

Confirm whether node objects still carry the userdata property at runtime, or verify that the metadata migration is complete and userdata is exclusively stored in the separate metadata layer.

editor/grida-canvas/plugins/yjs/y-document.ts (1)

117-130: LGTM!

The addition of metadata to the initial sync payload ensures that per-node export settings and userdata are properly synchronized in collaborative sessions. This is consistent with the document structure changes.

editor/grida-canvas-react/index.ts (1)

2-15: LGTM!

The useNodeMetadata hook is properly exported from the provider module, extending the public API surface consistently with the existing export pattern.

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

26-27: LGTM!

The imports for metadataReducer and schemaReducer are correctly added to support the new node metadata management system.

editor/grida-canvas/action.ts (2)

76-78: LGTM!

The DocumentAction union is properly extended to include MetadataAction, maintaining the established action composition pattern.


1057-1076: Well-structured discriminated union type.

The MetadataAction type uses proper TypeScript discriminated unions with namespace-based discrimination, allowing type-safe payloads:

  • "export_settings"NodeExportSettings[]
  • "userdata"Record<string, unknown> | null

The variants for set, remove, and remove-all cover the necessary operations for metadata management.

crates/grida-canvas/src/export/export_as_svg.rs (1)

14-52: LGTM!

The ImageRepository integration follows the same pattern as PDF export. Cloning the repository into the renderer before load_scene ensures image assets are available during SVG rendering. The implementation correctly uses skia-safe for the canvas operations as per coding guidelines.

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

103-104: LGTM!

The API call updated from instance.commands.changeNodeUserData to instance.setUserData aligns with the new metadata management approach.


860-880: Well-designed hook with proper type discrimination.

The useNodeMetadata hook provides type-safe access to node metadata with namespace-based return type inference. The conditional return type correctly discriminates between NodeExportSettings[] for export_settings and Record<string, unknown> | null for userdata.

The as any cast on line 879 is a pragmatic workaround for TypeScript's limitations with complex conditional type inference in function returns. The type safety is preserved at the call site through the generic constraint and conditional return type.

crates/grida-canvas/src/export/mod.rs (1)

99-116: LGTM!

The images parameter is correctly propagated to both export_node_as_pdf and export_node_as_svg calls, ensuring image assets are available during vector format exports. The implementation is consistent with the updated function signatures.

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

32-32: Export and userdata controls are wired consistently with new APIs

  • Importing and using ExportSection and ExportMultipleLayers behind config.export !== "off" matches the new export configuration model and keeps single vs multi‑selection exports separate.
  • UserDataControl is now invoked with just node_id, which is consistent with its updated implementation that reads/writes via useNodeMetadata and editor.setUserData.

The integration points in this file look correct and cohesive with the new export/metadata architecture.

Also applies to: 931-932, 1332-1340

editor/grida-canvas/backends/dom-export.ts (1)

5-5: DOM exporter generics and unsupported-format handling look solid

The DOM exporter’s type surface now matches the shared interface:

  • formats is typed from NodeExportSettings["format"][] and only lists ["PNG", "JPEG", "SVG"], which is consistent with using html‑to‑image.
  • canExportNodeAs and generic exportNodeAs<F>() cooperate with the editor’s validation to only route supported formats here.
  • Explicit branches for "PDF", "WEBP", and "BMP" throwing descriptive errors provide a clear failure mode even if this is called outside the usual guarded path.

No issues from this refactor on the DOM backend side.

Also applies to: 103-107, 117-122, 124-158

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

3645-3662: Generic exportNodeAs and clipboard helpers are correctly wired to the new exporter API

  • exportNodeAs<F>() validates both format support and canExportNodeAs before delegating to this.exporter.exportNodeAs, which is exactly what you want now that backends differ (DOM vs WASM).

  • The conditional return type Promise<F extends "SVG" ? string : Uint8Array> matches backend implementations and usage sites.

  • Clipboard helpers now call the typed export surface with explicit configs:

    • PNG: { format: "PNG", constraints: { type: "scale", value: 1 } }.
    • SVG: { format: "SVG" }.

    This keeps behavior explicit and in sync with ExportConfigOf<F>.

All of this looks consistent and should make future formats/config extensions much easier to manage.

Also applies to: 4533-4537, 4552-4553

editor/grida-canvas/backends/wasm.ts (1)

6-8: Fix incorrect export format mapping for WEBP and BMP in WASM backend

The exportNodeAsImage method (lines 83–101) incorrectly maps requested formats to export payloads:

switch (format) {
  case "BMP":
  case "PNG":
    exportFormat = { format: "PNG", constraints };
    break;
  case "JPEG":
  case "WEBP":
    exportFormat = {
      format: "JPEG",
      constraints,
      quality: config?.quality,
    };
    break;
}

This causes WEBP requests to be encoded as JPEG and BMP requests as PNG, creating a mismatch between the requested format and the actual binary output. The TypeScript types and Rust side both support distinct "PNG" | "JPEG" | "WEBP" | "BMP" formats with serde serialization mapping each format to its respective encoder.

Use direct format assignment instead:

switch (format) {
  case "PNG":
  case "BMP":
    exportFormat = { format, constraints };
    break;
  case "JPEG":
  case "WEBP":
    exportFormat = {
      format,
      constraints,
      quality: config?.quality,
    };
    break;
  default:
    throw new Error(`Unsupported image format: ${format}`);
}
⛔ Skipped due to learnings
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 : Custom images used as halftone shapes should be loaded as HTMLImageElement for efficient canvas rendering and preserve original image colors in as-is mode
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 : Cache ImageData and dimensions in refs (imageDataRef, sizeRef) for efficient exports
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
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: 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
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
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.grida : Validate .grida files using the `tool_io_grida` CLI tool to check file structure, parse all nodes, and detect parsing errors
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `skia-safe` crate for painting operations in the rendering engine
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
editor/grida-canvas/editor.i.ts (4)

2580-2593: LGTM!

The generic signature with conditional return type is well-designed. The optional config parameter allows export with sensible defaults while providing full control when needed.


4016-4021: LGTM!

The plugin action signature is consistent with the provider interface. Making config required for plugin actions ensures explicit export configuration.


4023-4103: LGTM!

The metadata interface is well-designed with a flexible namespace-based approach. The conditional return types provide excellent type safety, and the convenience methods for export settings and userdata reduce boilerplate for the common use cases.


4105-4147: LGTM!

Clean semantic API for managing multiple export configurations per node. The index-based operations align well with the array-based storage model.

Comment thread crates/grida-canvas/src/export/export_as_image.rs
Comment thread editor/grida-canvas/editor.i.ts
Comment thread editor/grida-canvas/reducers/metadata.reducer.ts
Comment thread editor/scaffolds/sidecontrol/sidecontrol-document-properties.tsx
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
editor/grida-canvas/editor.i.ts (1)

4194-4201: Remove redundant NonNullable wrapper.

The Format type is already a union of string literals ("PNG" | "JPEG" | "PDF" | "SVG" | "WEBP" | "BMP"), which is non-nullable by definition. The NonNullable<Format> wrapper on line 4194 is redundant.

🔎 Proposed simplification
-  export const MIME_TYPES: Record<NonNullable<Format>, string> = {
+  export const MIME_TYPES: Record<Format, string> = {
     PNG: "image/png",
     JPEG: "image/jpeg",
     PDF: "application/pdf",
     SVG: "image/svg+xml",
     WEBP: "image/webp",
     BMP: "image/bmp",
   } as const;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 215ae31 and b3b2ef1.

📒 Files selected for processing (2)
  • editor/grida-canvas/editor.i.ts
  • supabase/drafts/20251214_grida_canvas_document_model.sql
🧰 Additional context used
📓 Path-based instructions (4)
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
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • editor/grida-canvas/editor.i.ts
{editor/**/*.{ts,tsx},packages/grida-canvas-*/**/*.{ts,tsx}}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • editor/grida-canvas/editor.i.ts
editor/grida-*/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • editor/grida-canvas/editor.i.ts
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T23:30:42.112Z
Learning: Applies to packages/grida-canvas-*/**/*.{ts,tsx,js,jsx} : Packages under /packages/grida-canvas-* power the canvas; some are published to npm, refer to individual package README
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : Cache ImageData and dimensions in refs (imageDataRef, sizeRef) for efficient exports
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: Export options should support both PNG (rasterized at working resolution) and SVG (vector output not available for custom images)
📚 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:

  • supabase/drafts/20251214_grida_canvas_document_model.sql
  • editor/grida-canvas/editor.i.ts
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Auto-generate IDs (ID=0) in `NodeRepository` for factory-created nodes

Applied to files:

  • supabase/drafts/20251214_grida_canvas_document_model.sql
📚 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:

  • supabase/drafts/20251214_grida_canvas_document_model.sql
  • editor/grida-canvas/editor.i.ts
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Maintain bidirectional mapping between NodeId and UserNodeId at the application layer for API boundary management

Applied to files:

  • supabase/drafts/20251214_grida_canvas_document_model.sql
📚 Learning: 2025-12-20T08:11:16.220Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas/AGENTS.md:0-0
Timestamp: 2025-12-20T08:11:16.220Z
Learning: Applies to crates/grida-canvas/**/*.rs : Use `NodeId` (u64) for internal structs (NodeRecs, SceneGraph, caches) in the rendering engine for high-performance operations

Applied to files:

  • supabase/drafts/20251214_grida_canvas_document_model.sql
📚 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 : Cache ImageData and dimensions in refs (imageDataRef, sizeRef) for efficient exports

Applied to files:

  • editor/grida-canvas/editor.i.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:

  • editor/grida-canvas/editor.i.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:

  • editor/grida-canvas/editor.i.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/lib/**/*.{ts,tsx} : Use /editor/lib for core, strictly designed modules with non-opinionated, reusable, and stable implementations

Applied to files:

  • editor/grida-canvas/editor.i.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:

  • editor/grida-canvas/editor.i.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 : Custom images used as halftone shapes should be loaded as HTMLImageElement for efficient canvas rendering and preserve original image colors in as-is mode

Applied to files:

  • editor/grida-canvas/editor.i.ts
⏰ 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). (1)
  • GitHub Check: test

Comment thread editor/grida-canvas/editor.i.ts
Comment thread supabase/drafts/20251214_grida_canvas_document_model.sql
@softmarshmallow softmarshmallow changed the title Grida Canvas - Export Settings Grida Canvas - Export Settings (313) Dec 29, 2025
@softmarshmallow softmarshmallow merged commit 2267c1e into main Dec 29, 2025
10 checks passed
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