diff --git a/package-lock.json b/package-lock.json index 66fb7c1..2b167f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23037,7 +23037,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, diff --git a/src/components/features/SkillTreeVisualizer.tsx b/src/components/features/SkillTreeVisualizer.tsx index ae30808..e0d39b5 100644 --- a/src/components/features/SkillTreeVisualizer.tsx +++ b/src/components/features/SkillTreeVisualizer.tsx @@ -149,6 +149,31 @@ export default function SkillTreeVisualizer({ window.removeEventListener('close-all-overlays', handleCloseAll); }, []); + // Bind local arrow key shortcuts for node selection cycling + useKeyboardShortcuts({ + arrowright: () => { + if (nodes.length === 0) return; + const currentIndex = selectedNode ? nodes.findIndex((n) => n.id === selectedNode.id) : -1; + const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % nodes.length; + setSelectedNode(nodes[nextIndex]); + }, + arrowleft: () => { + if (nodes.length === 0) return; + const currentIndex = selectedNode ? nodes.findIndex((n) => n.id === selectedNode.id) : -1; + const prevIndex = currentIndex === -1 ? nodes.length - 1 : (currentIndex - 1 + nodes.length) % nodes.length; + setSelectedNode(nodes[prevIndex]); + }, + }); + + // Listen for the escape close-all-overlays event to close the side drawer + useEffect(() => { + const handleCloseAll = () => { + setSelectedNode(null); + }; + window.addEventListener('close-all-overlays', handleCloseAll); + return () => window.removeEventListener('close-all-overlays', handleCloseAll); + }, []); + return (