From 3eb3f1f599e54056354cff19f9b095303fde6c12 Mon Sep 17 00:00:00 2001 From: sid597 Date: Fri, 10 Apr 2026 21:29:42 +0530 Subject: [PATCH 1/2] ENG-1552: Add per-user canvas keyboard shortcut overrides Allow users to customize discourse node shortcuts in the canvas via a new "Canvas shortcuts" tab in personal settings. --- .../src/components/canvas/uiOverrides.tsx | 7 +++- .../settings/CanvasShortcutSettings.tsx | 36 +++++++++++++++++++ .../roam/src/components/settings/Settings.tsx | 7 ++++ .../settings/utils/zodSchema.example.ts | 2 ++ .../components/settings/utils/zodSchema.ts | 1 + 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 apps/roam/src/components/settings/CanvasShortcutSettings.tsx diff --git a/apps/roam/src/components/canvas/uiOverrides.tsx b/apps/roam/src/components/canvas/uiOverrides.tsx index c503ae44d..110de884f 100644 --- a/apps/roam/src/components/canvas/uiOverrides.tsx +++ b/apps/roam/src/components/canvas/uiOverrides.tsx @@ -53,6 +53,7 @@ import { getRelationColor } from "./DiscourseRelationShape/DiscourseRelationUtil import DiscourseGraphPanel from "./DiscourseToolPanel"; import { DISCOURSE_TOOL_SHORTCUT_KEY } from "~/data/userSettings"; import { getSetting } from "~/utils/extensionSettings"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; import { CustomDefaultToolbar } from "./CustomDefaultToolbar"; import { renderModifyNodeDialog } from "~/components/ModifyNodeDialog"; import { CanvasSyncMode } from "./canvasSyncMode"; @@ -396,13 +397,17 @@ export const createUiOverrides = ({ editor.setCurrentTool("discourse-tool"); }, }; + const canvasNodeShortcuts = + getPersonalSetting>(["Canvas node shortcuts"]) ?? + {}; + allNodes.forEach((node, index) => { const nodeId = node.type; tools[nodeId] = { id: nodeId, icon: "color", label: `shape.node.${node.type}` as TLUiTranslationKey, - kbd: node.shortcut, + kbd: canvasNodeShortcuts[nodeId] ?? node.shortcut, onSelect: () => { editor.setCurrentTool(nodeId); }, diff --git a/apps/roam/src/components/settings/CanvasShortcutSettings.tsx b/apps/roam/src/components/settings/CanvasShortcutSettings.tsx new file mode 100644 index 000000000..1f9b2a662 --- /dev/null +++ b/apps/roam/src/components/settings/CanvasShortcutSettings.tsx @@ -0,0 +1,36 @@ +import React, { useMemo } from "react"; +import getDiscourseNodes, { + excludeDefaultNodes, +} from "~/utils/getDiscourseNodes"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; +import { PersonalTextPanel } from "./components/BlockPropSettingPanels"; + +const CANVAS_NODE_SHORTCUTS_KEY = "Canvas node shortcuts"; + +const CanvasShortcutSettings = () => { + const nodes = useMemo( + () => getDiscourseNodes().filter(excludeDefaultNodes), + [], + ); + + return ( +
+ {nodes.map((node) => ( + ([ + CANVAS_NODE_SHORTCUTS_KEY, + node.type, + ]) || node.shortcut + } + /> + ))} +
+ ); +}; + +export default CanvasShortcutSettings; diff --git a/apps/roam/src/components/settings/Settings.tsx b/apps/roam/src/components/settings/Settings.tsx index 3e836328b..ccfa93469 100644 --- a/apps/roam/src/components/settings/Settings.tsx +++ b/apps/roam/src/components/settings/Settings.tsx @@ -23,6 +23,7 @@ import getDiscourseNodes, { } from "~/utils/getDiscourseNodes"; import NodeConfig from "./NodeConfig"; import HomePersonalSettings from "./HomePersonalSettings"; +import CanvasShortcutSettings from "./CanvasShortcutSettings"; import refreshConfigTree from "~/utils/refreshConfigTree"; import { FeedbackWidget } from "~/components/BirdEatsBugs"; import { getVersionWithDate } from "~/utils/getVersion"; @@ -170,6 +171,12 @@ export const SettingsDialog = ({ className="overflow-y-auto" panel={} /> + } + /> Date: Fri, 10 Apr 2026 21:42:27 +0530 Subject: [PATCH 2/2] ENG-1552: Rename tab to Canvas, fix empty shortcut fallback --- apps/roam/src/components/canvas/uiOverrides.tsx | 2 +- apps/roam/src/components/settings/CanvasShortcutSettings.tsx | 1 + apps/roam/src/components/settings/Settings.tsx | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/roam/src/components/canvas/uiOverrides.tsx b/apps/roam/src/components/canvas/uiOverrides.tsx index 110de884f..521becdce 100644 --- a/apps/roam/src/components/canvas/uiOverrides.tsx +++ b/apps/roam/src/components/canvas/uiOverrides.tsx @@ -407,7 +407,7 @@ export const createUiOverrides = ({ id: nodeId, icon: "color", label: `shape.node.${node.type}` as TLUiTranslationKey, - kbd: canvasNodeShortcuts[nodeId] ?? node.shortcut, + kbd: canvasNodeShortcuts[nodeId] || node.shortcut, onSelect: () => { editor.setCurrentTool(nodeId); }, diff --git a/apps/roam/src/components/settings/CanvasShortcutSettings.tsx b/apps/roam/src/components/settings/CanvasShortcutSettings.tsx index 1f9b2a662..02a0a9c3d 100644 --- a/apps/roam/src/components/settings/CanvasShortcutSettings.tsx +++ b/apps/roam/src/components/settings/CanvasShortcutSettings.tsx @@ -27,6 +27,7 @@ const CanvasShortcutSettings = () => { node.type, ]) || node.shortcut } + placeholder={node.shortcut} /> ))} diff --git a/apps/roam/src/components/settings/Settings.tsx b/apps/roam/src/components/settings/Settings.tsx index ccfa93469..f5c472744 100644 --- a/apps/roam/src/components/settings/Settings.tsx +++ b/apps/roam/src/components/settings/Settings.tsx @@ -173,7 +173,7 @@ export const SettingsDialog = ({ /> } />