Skip to content

Commit ddebdc1

Browse files
authored
Merge pull request #223 from beNative/codex/enable-arrow-key-navigation-in-search-results
Allow arrow down to focus document tree from search
2 parents 19b8133 + 69026f2 commit ddebdc1

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

components/Sidebar.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const findNodeAndSiblings = (nodes: DocumentNode[], id: string): {node: Document
8787
};
8888

8989
const Sidebar: React.FC<SidebarProps> = (props) => {
90+
const { documentTree, navigableItems, searchTerm, setSearchTerm, setSelectedIds, lastClickedId, setLastClickedId, onContextMenu, renamingNodeId, onRenameComplete, onExpandAll, onCollapseAll, commands, pendingRevealId, onRevealHandled, onNewFromClipboard, customShortcuts, onSelectTemplate, onSelectNode } = props;
9091
const { documentTree, navigableItems, searchTerm, setSearchTerm, setSelectedIds, lastClickedId, setLastClickedId, onContextMenu, renamingNodeId, onRenameComplete, onExpandAll, onCollapseAll, commands, pendingRevealId, onRevealHandled, onNewFromClipboard, customShortcuts, searchInputRef } = props;
9192
const [focusedItemId, setFocusedItemId] = useState<string | null>(null);
9293
const [isTemplatesCollapsed, setIsTemplatesCollapsed] = useState(false);
@@ -105,6 +106,38 @@ const Sidebar: React.FC<SidebarProps> = (props) => {
105106

106107

107108
const sidebarRef = useRef<HTMLDivElement>(null);
109+
const handleSearchKeyDown = useCallback(
110+
(event: React.KeyboardEvent<HTMLInputElement>) => {
111+
if (event.key !== 'ArrowDown') {
112+
return;
113+
}
114+
115+
const firstNavigableItem = navigableItems[0];
116+
if (!firstNavigableItem) {
117+
return;
118+
}
119+
120+
event.preventDefault();
121+
event.currentTarget.blur();
122+
setFocusedItemId(firstNavigableItem.id);
123+
setSelectedIds(new Set([firstNavigableItem.id]));
124+
setLastClickedId(firstNavigableItem.id);
125+
126+
if (firstNavigableItem.type === 'template') {
127+
onSelectTemplate(firstNavigableItem.id);
128+
} else {
129+
const syntheticEvent = {
130+
shiftKey: false,
131+
ctrlKey: false,
132+
metaKey: false,
133+
} as React.MouseEvent;
134+
onSelectNode(firstNavigableItem.id, syntheticEvent);
135+
}
136+
137+
sidebarRef.current?.focus();
138+
},
139+
[navigableItems, onSelectNode, onSelectTemplate, setLastClickedId, setSelectedIds]
140+
);
108141
const isResizingTemplates = useRef(false);
109142

110143
// Effect to manage focus state
@@ -446,6 +479,7 @@ const Sidebar: React.FC<SidebarProps> = (props) => {
446479
placeholder="Search..."
447480
value={searchTerm}
448481
onChange={(e) => setSearchTerm(e.target.value)}
482+
onKeyDown={handleSearchKeyDown}
449483
className="w-full bg-background border border-border-color rounded-md pl-9 pr-9 py-1 text-xs text-text-main focus:ring-2 focus:ring-primary focus:outline-none placeholder:text-text-secondary"
450484
/>
451485
{searchTerm.trim() && (

0 commit comments

Comments
 (0)