Skip to content

Conversation

@mdroidian
Copy link
Contributor

@mdroidian mdroidian commented Nov 25, 2025

URL: https://discoursegraphs.com/releases/roam/eng-994-move-canvas-drawer-into-tldraw-component

https://www.loom.com/share/75f329a5c39943ce81d45124880624ea

Summary by CodeRabbit

  • Refactor

    • Restructured Canvas Drawer component architecture for improved maintainability.
    • Updated camera control to use native editor API for enhanced reliability.
  • Bug Fixes

    • Improved shape selection and camera positioning behavior.
  • Removals

    • Removed Canvas Drawer command from command palette.
    • Removed Canvas Drawer option from context menu.

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

…mproved UI. Remove CanvasDrawerButton and update related imports. Simplify state management for grouped shapes in Tldraw component.
…tion. Move grouped shapes logic from Tldraw to CanvasDrawerPanel, simplifying component structure and improving maintainability.
…tate management. Remove unnecessary props and simplify integration in Tldraw component.
…ent functionality. Refactor moveCameraToShape logic and update CanvasDrawerPanel to pass editor instance, streamlining component interactions.
Copy link
Contributor Author

@supabase
Copy link

supabase bot commented Nov 25, 2025

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@mdroidian mdroidian requested a review from jsmorabito November 25, 2025 03:37
@mdroidian
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

📝 Walkthrough

Walkthrough

The Canvas Drawer component architecture is refactored from a provider/custom-event-based pattern to a self-contained CanvasDrawerPanel component. The CanvasDrawerButton component is removed, command palette registration and context menu options for opening the drawer are eliminated, and integration points are updated to use the new panel component directly.

Changes

Cohort / File(s) Summary
Core CanvasDrawer Refactor
apps/roam/src/components/canvas/CanvasDrawer.tsx
Replaced overlay/provider architecture with self-contained CanvasDrawerPanel managing local state and lifecycle. Updated CanvasDrawerContent to accept editor prop for direct camera control. Changed moveCameraToShape logic from custom DOM events to Editor API. Exported CanvasDrawerPanel and CanvasDrawerContent; removed CanvasDrawer, CanvasDrawerProvider, and openCanvasDrawer. Added Editor, useEditor, TLShapeId imports.
UI Integration Update
apps/roam/src/components/canvas/Tldraw.tsx
Replaced CanvasDrawerButton and CanvasDrawerProvider usage with new CanvasDrawerPanelWrapper component rendering CanvasDrawerPanel. Removed move-camera-to-shape global action listener. Updated component mounting to eliminate provider wrapping.
Removed Components
apps/roam/src/components/canvas/CanvasDrawerButton.tsx
File deleted; removed UI trigger button component for opening canvas drawer.
UI Option Removal
apps/roam/src/components/canvas/uiOverrides.tsx
Removed Open Canvas Drawer menu option from DefaultContextMenu when no shape is selected.
Command Registry Cleanup
apps/roam/src/utils/registerCommandPaletteCommands.ts
Removed openCanvasDrawer import and "DG: Open - Canvas Drawer" command registration.

Sequence Diagram

sequenceDiagram
    actor User
    participant UI as Tldraw UI
    participant Panel as CanvasDrawerPanel
    participant Content as CanvasDrawerContent
    participant Editor as Editor API
    
    rect rgb(220, 240, 250)
    Note over Panel,Content: New Self-Contained Architecture
    User->>UI: Interact with Tldraw
    UI->>Panel: Render CanvasDrawerPanel
    Panel->>Panel: Manage isOpen state
    Panel->>Editor: Get editor instance (useEditor)
    Panel->>Content: Pass editor + groupedShapes
    end
    
    rect rgb(245, 230, 255)
    Note over Content,Editor: Camera Movement (via Editor API)
    User->>Content: Click shape in drawer
    Content->>Editor: moveCameraToShape(editor, shapeId)
    Editor->>Editor: Center on shape & select
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Key attention areas:
    • Logic transition in moveCameraToShape: verify custom event removal and correct Editor API usage for camera centering and shape selection
    • State management changes in CanvasDrawerPanel: ensure isOpen state and groupedShapes computation from editor store are correctly implemented
    • Integration verification in Tldraw.tsx: confirm CanvasDrawerPanelWrapper properly wraps and renders CanvasDrawerPanel; verify removal of provider does not break component lifecycle
    • Public API surface changes: validate that all removal of openCanvasDrawer references across the codebase are accounted for in command palette and UI override files

Possibly related PRs

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main architectural change: moving the canvas drawer component from a provider-based pattern into the tldraw component itself.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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
Contributor

@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: 1

🧹 Nitpick comments (1)
apps/roam/src/components/canvas/CanvasDrawer.tsx (1)

436-441: Consider extracting duplicate boxShadow to a constant.

The same complex boxShadow value appears twice (lines 439-441 and 458-459). Extracting it to a constant would reduce duplication and make maintenance easier.

const TLDRAW_SHADOW = "0px 0px 2px hsl(0, 0%, 0%, 16%), 0px 2px 3px hsl(0, 0%, 0%, 24%), 0px 2px 6px hsl(0, 0%, 0%, 0.1), inset 0px 0px 0px 1px hsl(0, 0%, 100%)";

// Then use: style={{ zIndex: 250, boxShadow: TLDRAW_SHADOW, ... }}

Also applies to: 454-460

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3e7fc5 and 05ee6c6.

📒 Files selected for processing (5)
  • apps/roam/src/components/canvas/CanvasDrawer.tsx (6 hunks)
  • apps/roam/src/components/canvas/CanvasDrawerButton.tsx (0 hunks)
  • apps/roam/src/components/canvas/Tldraw.tsx (4 hunks)
  • apps/roam/src/components/canvas/uiOverrides.tsx (0 hunks)
  • apps/roam/src/utils/registerCommandPaletteCommands.ts (0 hunks)
💤 Files with no reviewable changes (3)
  • apps/roam/src/components/canvas/CanvasDrawerButton.tsx
  • apps/roam/src/utils/registerCommandPaletteCommands.ts
  • apps/roam/src/components/canvas/uiOverrides.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/main.mdc)

**/*.{ts,tsx}: Use Tailwind CSS for styling where possible
When refactoring inline styles, use tailwind classes
Prefer type over interface in TypeScript
Use explicit return types for functions
Avoid any types when possible
Prefer arrow functions over regular function declarations
Use named parameters (object destructuring) when a function has more than 2 parameters
Use PascalCase for components and types
Use camelCase for variables and functions
Use UPPERCASE for constants
Function names should describe their purpose clearly
Prefer early returns over nested conditionals for better readability

Files:

  • apps/roam/src/components/canvas/Tldraw.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
apps/roam/**/*.{js,ts,tsx,jsx,json}

📄 CodeRabbit inference engine (.cursor/rules/roam.mdc)

Prefer existing dependencies from package.json when working on the Roam Research extension

Files:

  • apps/roam/src/components/canvas/Tldraw.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
apps/roam/**/*.{ts,tsx,jsx,js,css,scss}

📄 CodeRabbit inference engine (.cursor/rules/roam.mdc)

Use BlueprintJS 3 components and Tailwind CSS for platform-native UI in the Roam Research extension

Files:

  • apps/roam/src/components/canvas/Tldraw.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
apps/roam/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/roam.mdc)

apps/roam/**/*.{ts,tsx,js,jsx}: Use the roamAlphaApi docs from https://roamresearch.com/#/app/developer-documentation/page/tIaOPdXCj when implementing Roam functionality
Use Roam Depot/Extension API docs from https://roamresearch.com/#/app/developer-documentation/page/y31lhjIqU when implementing extension functionality

Files:

  • apps/roam/src/components/canvas/Tldraw.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
apps/roam/**

📄 CodeRabbit inference engine (.cursor/rules/roam.mdc)

Implement the Discourse Graph protocol in the Roam Research extension

Files:

  • apps/roam/src/components/canvas/Tldraw.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
🧠 Learnings (3)
📚 Learning: 2025-11-25T00:52:41.909Z
Learnt from: CR
Repo: DiscourseGraphs/discourse-graph PR: 0
File: .cursor/rules/roam.mdc:0-0
Timestamp: 2025-11-25T00:52:41.909Z
Learning: Applies to apps/roam/**/*.{ts,tsx,js,jsx} : Use the roamAlphaApi docs from https://roamresearch.com/#/app/developer-documentation/page/tIaOPdXCj when implementing Roam functionality

Applied to files:

  • apps/roam/src/components/canvas/Tldraw.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
📚 Learning: 2025-11-25T00:52:41.909Z
Learnt from: CR
Repo: DiscourseGraphs/discourse-graph PR: 0
File: .cursor/rules/roam.mdc:0-0
Timestamp: 2025-11-25T00:52:41.909Z
Learning: Applies to apps/roam/**/*.{ts,tsx,jsx,js,css,scss} : Use BlueprintJS 3 components and Tailwind CSS for platform-native UI in the Roam Research extension

Applied to files:

  • apps/roam/src/components/canvas/Tldraw.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
📚 Learning: 2025-08-11T19:09:58.252Z
Learnt from: maparent
Repo: DiscourseGraphs/discourse-graph PR: 337
File: apps/roam/src/components/DiscourseFloatingMenu.tsx:43-43
Timestamp: 2025-08-11T19:09:58.252Z
Learning: The roam subdirectory (apps/roam) is constrained to React 17 and cannot use React 18+ features like createRoot API. ReactDOM.render should be used instead of createRoot in this subdirectory.

Applied to files:

  • apps/roam/src/components/canvas/CanvasDrawer.tsx
🧬 Code graph analysis (2)
apps/roam/src/components/canvas/Tldraw.tsx (1)
apps/roam/src/components/canvas/CanvasDrawer.tsx (1)
  • CanvasDrawerPanel (393-487)
apps/roam/src/components/canvas/CanvasDrawer.tsx (3)
apps/roam/src/components/LivePreview.tsx (1)
  • Props (86-93)
packages/ui/src/components/ui/card.tsx (1)
  • Card (82-82)
apps/roam/src/components/canvas/DiscourseNodeUtil.tsx (1)
  • DiscourseNodeShape (158-170)
🪛 Biome (2.1.2)
apps/roam/src/components/canvas/Tldraw.tsx

[error] 934-934: Unexpected empty object pattern.

(lint/correctness/noEmptyPattern)

🔇 Additional comments (5)
apps/roam/src/components/canvas/CanvasDrawer.tsx (3)

36-40: LGTM!

Props type definition correctly uses type over interface and includes the new editor prop needed for direct camera control.


147-159: LGTM!

Clean refactor of camera control logic using the Editor API directly instead of custom events. The implementation properly handles the shape lookup and provides smooth animation.


393-400: Critical: Hook ordering bug - setIsOpen is referenced before it's defined.

toggleDrawer callback (lines 395-397) references setIsOpen, but useState is declared on line 398. When useCallback executes, setIsOpen is undefined in the closure, causing the toggle button to fail.

Apply this diff to fix the hook ordering:

 export const CanvasDrawerPanel = () => {
   const editor = useEditor();
+  const [isOpen, setIsOpen] = useState(false);
+  const pageUid = getCurrentPageUid();
+  const [groupedShapes, setGroupedShapes] = useState<GroupedShapes>({});
+
   const toggleDrawer = useCallback(() => {
     setIsOpen((prev) => !prev);
   }, []);
-  const [isOpen, setIsOpen] = useState(false);
-  const pageUid = getCurrentPageUid();
-  const [groupedShapes, setGroupedShapes] = useState<GroupedShapes>({});

Likely an incorrect or invalid review comment.

apps/roam/src/components/canvas/Tldraw.tsx (2)

87-87: LGTM!

Import correctly updated to use the new CanvasDrawerPanel component.


685-685: LGTM!

Correct placement inside TldrawUi ensures the panel has access to the editor context via useEditor().

…divs for improved layout consistency. Adjust styles and structure in CanvasDrawerPanel for better responsiveness and visual clarity.
Copy link
Collaborator

@jsmorabito jsmorabito left a comment

Choose a reason for hiding this comment

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

Fantastic! Let's merge!!

@mdroidian mdroidian merged commit ecbbe46 into main Nov 25, 2025
5 checks passed
@mdroidian mdroidian deleted the eng-994-move-canvas-drawer-into-tldraw-component branch November 25, 2025 16:32
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.

3 participants