(e: KeyboardEvent, state: ReturnType<typeof useStore.getState>)
| 1055 | // ---- Key handlers (called from the single persistent handler) -------- |
| 1056 | |
| 1057 | function handleSidebarKey(e: KeyboardEvent, state: ReturnType<typeof useStore.getState>): void { |
| 1058 | const key = e.key |
| 1059 | const overrides = state.keymapOverrides |
| 1060 | if (state.focusedPanel !== 'sidebar') state.setFocusedPanel('sidebar') |
| 1061 | const items = getIndexedElements('[data-sidebar-idx]', 'sidebarIdx') |
| 1062 | const count = items.length |
| 1063 | const max = count - 1 |
| 1064 | const currentPos = findPositionByIndex(items, 'sidebarIdx', state.sidebarCursorIndex) |
| 1065 | const wantsContextMenu = |
| 1066 | matchesSequenceToken(e, overrides, 'nav.contextMenu') || |
| 1067 | key === 'ContextMenu' || |
| 1068 | (e.shiftKey && key === 'F10') |
| 1069 | |
| 1070 | // Always consume single-char nav keys when sidebar is focused, |
| 1071 | // even if the sidebar is empty — prevents them leaking to the editor. |
| 1072 | const wantsHandledKey = |
| 1073 | matchesSequenceToken(e, overrides, 'nav.moveDown') || |
| 1074 | matchesSequenceToken(e, overrides, 'nav.moveUp') || |
| 1075 | matchesSequenceToken(e, overrides, 'nav.jumpBottom') || |
| 1076 | sequenceTokenFromEvent(e) === getSequenceTokens(overrides, 'nav.jumpTop')[0] || |
| 1077 | matchesSequenceToken(e, overrides, 'nav.openSideItem') || |
| 1078 | matchesSequenceToken(e, overrides, 'nav.back') || |
| 1079 | matchesSequenceToken(e, overrides, 'nav.toggleFolder') || |
| 1080 | matchesSequenceToken(e, overrides, 'nav.filter') || |
| 1081 | key === 'Enter' || |
| 1082 | key === 'Escape' || |
| 1083 | key === 'ArrowDown' || |
| 1084 | key === 'ArrowUp' || |
| 1085 | key === 'ArrowLeft' || |
| 1086 | key === 'ArrowRight' || |
| 1087 | wantsContextMenu |
| 1088 | if (wantsHandledKey) { |
| 1089 | e.preventDefault() |
| 1090 | e.stopImmediatePropagation() |
| 1091 | } else { |
| 1092 | return // not a nav key, let it through |
| 1093 | } |
| 1094 | |
| 1095 | if (count === 0) return // nothing to navigate |
| 1096 | |
| 1097 | if (matchesSequenceToken(e, overrides, 'nav.moveDown') || key === 'ArrowDown') { |
| 1098 | scrollToIndexedElement(items[Math.min(currentPos + 1, max)], 'sidebarIdx', state.setSidebarCursorIndex) |
| 1099 | return |
| 1100 | } |
| 1101 | if (matchesSequenceToken(e, overrides, 'nav.moveUp') || key === 'ArrowUp') { |
| 1102 | scrollToIndexedElement(items[Math.max(currentPos - 1, 0)], 'sidebarIdx', state.setSidebarCursorIndex) |
| 1103 | return |
| 1104 | } |
| 1105 | if (matchesSequenceToken(e, overrides, 'nav.jumpBottom')) { |
| 1106 | scrollToIndexedElement(items[max], 'sidebarIdx', state.setSidebarCursorIndex) |
| 1107 | return |
| 1108 | } |
| 1109 | if ( |
| 1110 | advanceSequence( |
| 1111 | e, |
| 1112 | getKeymapBinding(overrides, 'nav.jumpTop'), |
| 1113 | jumpTopPending, |
| 1114 | jumpTopTimer, |
no test coverage detected