Editor has no right-click context menu on a path or node — the right-click affordance for duplicate, delete, fit-to-view, change-color, etc. only lives in the right panel and keyboard shortcuts #236

Closed
opened 2026-10-04 02:32:10 +00:00 by Mark · 0 comments
Owner

Finding

src/components/editor/EditorCanvas.tsx has no onContextMenu handler. grep -n 'onContextMenu' src/components/editor/ returns 0 hits. Right-clicking on a path or node does nothing (the browser's default context menu appears, but it's not customized).

src/components/editor/EditorRightPanel.tsx's path list rows have the per-row actions (Duplicate, Delete, Fit to View, Change Color, Toggle Visibility). All the same actions also have keyboard shortcuts (per the various #176/#178 family). But the canvas itself — where the user is actively drawing/editing — has no right-click menu.

A user right-clicking a path:

  • Sees the browser's default context menu ("Back", "Reload", "View Page Source", etc.)
  • Doesn't see a "Duplicate this path" or "Delete this path" or "Fit to View" option
  • Has to move the mouse to the right panel to find the action

The right-click is the standard "I'm doing something specific to this thing" affordance in any vector editor. Figma, Illustrator, Inkscape all have it.

Where

  • Editor canvas: src/components/editor/EditorCanvas.tsx (no onContextMenu)
  • Right panel: src/components/editor/EditorRightPanel.tsx (has the actions, but requires mouse movement)
  • Keyboard shortcuts: src/components/editor/useKeyboardShortcuts.ts (has Cmd+D, etc., per the kanban landings)

Suggested fix shape

Add an onContextMenu handler to the canvas that:

  1. Detects what was right-clicked (a path? a node? empty canvas? a control handle?).
  2. Opens a context menu at the cursor position with the relevant actions.
onContextMenu={(e) => {
  e.preventDefault();
  const hit = hitTest(e.clientX, e.clientY);
  if (hit?.node) {
    showContextMenu('node', hit.node);
  } else if (hit?.path) {
    showContextMenu('path', hit.path);
  } else {
    showContextMenu('canvas');
  }
}}

showContextMenu(type, target) opens a <ContextMenu> (shadcn) at e.clientX, e.clientY with the actions:

  • On a path: Duplicate, Delete, Fit to View, Toggle Visibility, Change Color (opens the picker)
  • On a node: Convert to Corner/Smooth/Symmetric, Add Node (after), Delete Node
  • On empty canvas: Paste (if a path is in the clipboard), Cancel current path drawing
  • On a control handle: Symmetric / Asymmetric / Free handle

The menu items dispatch the same actions as the right panel buttons and keyboard shortcuts. The menu is dismissable on click-outside or Esc.

Severity

Low. The user can use the right panel or keyboard shortcuts. Right-click is a power-user affordance.

Discovered by

Gap analysis (2026-10-02) of editor right-click affordances.

  • #176 (open) — Workspace's context menu shows shortcut hints that don't work. The editor's missing menu is the parallel concern.
  • The right panel's per-row actions are the actions to surface in the context menu.
  • Figma/Illustrator/Inkscape all have right-click context menus on the canvas; this is a standard affordance.
## Finding `src/components/editor/EditorCanvas.tsx` has no `onContextMenu` handler. `grep -n 'onContextMenu' src/components/editor/` returns 0 hits. Right-clicking on a path or node does nothing (the browser's default context menu appears, but it's not customized). `src/components/editor/EditorRightPanel.tsx`'s path list rows have the per-row actions (Duplicate, Delete, Fit to View, Change Color, Toggle Visibility). All the same actions also have keyboard shortcuts (per the various #176/#178 family). But the canvas itself — where the user is actively drawing/editing — has no right-click menu. A user right-clicking a path: - Sees the browser's default context menu ("Back", "Reload", "View Page Source", etc.) - Doesn't see a "Duplicate this path" or "Delete this path" or "Fit to View" option - Has to move the mouse to the right panel to find the action The right-click is the standard "I'm doing something specific to this thing" affordance in any vector editor. Figma, Illustrator, Inkscape all have it. ## Where - Editor canvas: `src/components/editor/EditorCanvas.tsx` (no `onContextMenu`) - Right panel: `src/components/editor/EditorRightPanel.tsx` (has the actions, but requires mouse movement) - Keyboard shortcuts: `src/components/editor/useKeyboardShortcuts.ts` (has Cmd+D, etc., per the kanban landings) ## Suggested fix shape Add an `onContextMenu` handler to the canvas that: 1. Detects what was right-clicked (a path? a node? empty canvas? a control handle?). 2. Opens a context menu at the cursor position with the relevant actions. ```tsx onContextMenu={(e) => { e.preventDefault(); const hit = hitTest(e.clientX, e.clientY); if (hit?.node) { showContextMenu('node', hit.node); } else if (hit?.path) { showContextMenu('path', hit.path); } else { showContextMenu('canvas'); } }} ``` `showContextMenu(type, target)` opens a `<ContextMenu>` (shadcn) at `e.clientX, e.clientY` with the actions: - **On a path**: Duplicate, Delete, Fit to View, Toggle Visibility, Change Color (opens the picker) - **On a node**: Convert to Corner/Smooth/Symmetric, Add Node (after), Delete Node - **On empty canvas**: Paste (if a path is in the clipboard), Cancel current path drawing - **On a control handle**: Symmetric / Asymmetric / Free handle The menu items dispatch the same actions as the right panel buttons and keyboard shortcuts. The menu is dismissable on click-outside or Esc. ## Severity Low. The user can use the right panel or keyboard shortcuts. Right-click is a power-user affordance. ## Discovered by Gap analysis (2026-10-02) of editor right-click affordances. ## Related - #176 (open) — Workspace's context menu shows shortcut hints that don't work. The editor's missing menu is the parallel concern. - The right panel's per-row actions are the actions to surface in the context menu. - Figma/Illustrator/Inkscape all have right-click context menus on the canvas; this is a standard affordance.
Sign in to join this conversation.
No description provided.