Skip to content

Conversation

@mdroidian
Copy link
Contributor

@mdroidian mdroidian commented Oct 17, 2025

Add an icon button to the TLdraw canvas to open the canvas drawer.

https://www.loom.com/share/7d61087e52d5447cb971830b2fb2ce42

Co-authored-by: mclicks <mclicks@gmail.com>
@cursor
Copy link

cursor bot commented Oct 17, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@linear
Copy link

linear bot commented Oct 17, 2025

@supabase
Copy link

supabase bot commented Oct 17, 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 ↗︎.

cursoragent and others added 3 commits October 17, 2025 18:08
Co-authored-by: mclicks <mclicks@gmail.com>
Co-authored-by: mclicks <mclicks@gmail.com>
Co-authored-by: mclicks <mclicks@gmail.com>
@mdroidian
Copy link
Contributor Author

@CodeRabbit full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

✅ Actions performed

Full review triggered.

- Added CanvasDrawerProvider to manage the canvas drawer's lifecycle and allow it to be called from non-React contexts.
- Updated openCanvasDrawer function to utilize the new provider for better state handling.
- Refactored CanvasDrawer component to accept unmountRef as a prop.
- Enhanced CanvasDrawerButton styling for improved UI consistency.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

📝 Walkthrough

Walkthrough

This PR introduces external control for the canvas drawer component, enabling it to be triggered from non-React contexts like the command palette. It adds a CanvasDrawerProvider context, an openCanvasDrawer function for external invocation, a new CanvasDrawerButton UI component, and integrates these into the main Tldraw canvas wrapper.

Changes

Cohort / File(s) Summary
Canvas Drawer Management
apps/roam/src/components/canvas/CanvasDrawer.tsx
Introduces CanvasDrawerProvider context and openCanvasDrawer function to enable drawer control from non-React contexts. Adds module-level drawerUnmountRef to manage lifecycle, updates CanvasDrawer component to accept unmountRef prop, implements validation with toast notifications, and supports toggle-off behavior when drawer is already open.
Drawer UI Button
apps/roam/src/components/canvas/CanvasDrawerButton.tsx
New component that renders a positioned button with add-column-left icon, triggering openCanvasDrawer on click. Includes inline shadow styling.
Canvas Integration
apps/roam/src/components/canvas/Tldraw.tsx
Wraps TldrawCanvas with CanvasDrawerProvider context and adds CanvasDrawerButton component to the canvas UI, enabling drawer access throughout the rendering flow.

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as CanvasDrawerButton
    participant Fn as openCanvasDrawer()
    participant Provider as CanvasDrawerProvider
    participant Overlay as renderOverlay
    participant Drawer as CanvasDrawer

    User->>UI: Click button
    UI->>Fn: Call openCanvasDrawer()
    
    Fn->>Provider: Check provider exists
    alt Provider exists
        Fn->>Fn: Compute page & shapes
        Fn->>Overlay: renderOverlay with CanvasDrawer
        Overlay->>Drawer: Mount with unmountRef
        Drawer->>User: Display drawer
        User->>Drawer: Interact or close
        Drawer->>Overlay: Call unmountRef.current()
        Overlay->>Provider: Cleanup
    else Provider missing
        Fn->>UI: Show error toast
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The changes introduce new external control patterns with context management and error handling, requiring careful verification of the provider lifecycle, unmount flow, and integration points. However, the individual components are straightforward with limited interplay between them.

Possibly related PRs

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "ENG-977 Create icon button for canvas drawer" clearly and specifically describes the primary user-facing change introduced in this pull request. The raw summary confirms that a new CanvasDrawerButton component was created with an icon that triggers drawer functionality, which is exactly what the title conveys. While the changeset also includes infrastructure changes such as CanvasDrawerProvider and openCanvasDrawer function, these are implementation enablers rather than the main deliverable. The title appropriately captures the most important change from the developer's perspective without unnecessary detail, and it is specific enough that a teammate reviewing the commit history would understand the primary objective.

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/CanvasDrawerButton.tsx (1)

7-14: Consider using tldraw's CSS variable directly instead of hardcoding shadow values.

The inline boxShadow duplicates tldraw's --shadow-2 variable with hardcoded values. This creates a maintenance burden—if tldraw updates their shadow, this component won't automatically match.

Additionally, the z-index: 250 might conflict with other UI elements. Consider coordinating z-index values across components or using a centralized z-index system.

Apply this diff to use the CSS variable directly:

     <div
       className="pointer-events-auto absolute top-11 m-2 rounded-lg"
       style={{
         zIndex: 250,
-        // copying tldraw var(--shadow-2)
-        boxShadow:
-          "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%)",
+        boxShadow: "var(--shadow-2)",
       }}
     >
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e96f02 and 2fb3cea.

📒 Files selected for processing (3)
  • apps/roam/src/components/canvas/CanvasDrawer.tsx (5 hunks)
  • apps/roam/src/components/canvas/CanvasDrawerButton.tsx (1 hunks)
  • apps/roam/src/components/canvas/Tldraw.tsx (3 hunks)
🔇 Additional comments (11)
apps/roam/src/components/canvas/CanvasDrawerButton.tsx (2)

1-3: LGTM!

The imports are correct and all necessary for the component functionality.


16-21: LGTM!

The Button implementation is correct. The openCanvasDrawer function handles errors internally (via toast notifications), so no additional error handling is needed here.

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

87-88: LGTM!

The imports are correct and properly structured.


712-712: LGTM!

The button placement is correct—it renders after the canvas loads and inside the container where absolute positioning will work properly. The CanvasDrawerProvider (added at lines 996-998) ensures the drawer context is available when the button is clicked.


996-998: LGTM!

The CanvasDrawerProvider correctly wraps TldrawCanvas, ensuring the drawer context is available for both main window and sidebar renders. This enables the external control pattern introduced in CanvasDrawer.tsx.

apps/roam/src/components/canvas/CanvasDrawer.tsx (6)

1-1: LGTM!

Added useRef import is necessary for the new CanvasDrawerProvider component.


12-12: LGTM!

Importing render as renderToast is necessary for the error notification in openCanvasDrawer.


51-51: LGTM!

Making pageTitle reactive to pageUid via useMemo is the correct approach.


172-190: LGTM!

The handleClose wrapper correctly clears unmountRef.current before calling onClose(), preventing stale references during unmount.


192-211: LGTM!

The provider validation and toggle behavior are implemented correctly. The error handling provides clear feedback to users if the provider is not mounted, and the toggle-off logic properly unmounts and clears the ref.


213-241: LGTM!

The data fetching and rendering logic is correct. The function properly extracts shapes from the tldraw store, groups them by UID, and renders the drawer via renderOverlay. The ref management enables proper cleanup and toggle behavior.

@mdroidian mdroidian changed the title Create icon button for canvas drawer ENG-977 Create icon button for canvas drawer Oct 17, 2025
@mdroidian mdroidian marked this pull request as ready for review October 17, 2025 20:50
@mdroidian mdroidian merged commit e29c8fa into main Oct 17, 2025
5 checks passed
@github-project-automation github-project-automation bot moved this to Done in General Oct 17, 2025
@mdroidian mdroidian deleted the cursor/ENG-977-create-icon-button-for-canvas-drawer-6357 branch October 17, 2025 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants