From f7bfcf2b75e075eb581ba3ca119b955307ce355d Mon Sep 17 00:00:00 2001 From: Jesper Ordrup Date: Mon, 16 Feb 2026 15:10:13 +0100 Subject: [PATCH] fix(app): add mouse and touch subfolder navigation in open project dialog --- .../components/dialog-select-directory.tsx | 58 +++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/packages/app/src/components/dialog-select-directory.tsx b/packages/app/src/components/dialog-select-directory.tsx index 515e640c9fab..c628da781fa5 100644 --- a/packages/app/src/components/dialog-select-directory.tsx +++ b/packages/app/src/components/dialog-select-directory.tsx @@ -1,6 +1,7 @@ import { useDialog } from "@opencode-ai/ui/context/dialog" import { Dialog } from "@opencode-ai/ui/dialog" import { FileIcon } from "@opencode-ai/ui/file-icon" +import { Icon } from "@opencode-ai/ui/icon" import { List } from "@opencode-ai/ui/list" import type { ListRef } from "@opencode-ai/ui/list" import { getDirectory, getFilename } from "@opencode-ai/util/path" @@ -271,6 +272,11 @@ export function DialogSelectDirectory(props: DialogSelectDirectoryProps) { return results.map((absolute) => toRow(absolute, home())) } + const descend = (absolute: string) => { + const value = displayPath(absolute, filter(), home()) + list?.setFilter(value.endsWith("/") ? value : value + "/") + } + function resolve(absolute: string) { props.onSelect(props.multiple ? [absolute] : absolute) dialog.close() @@ -288,15 +294,13 @@ export function DialogSelectDirectory(props: DialogSelectDirectoryProps) { ref={(r) => (list = r)} onFilter={(value) => setFilter(cleanInput(value))} onKeyEvent={(e, item) => { - if (e.key !== "Tab") return + if (e.key !== "Tab" && e.key !== "ArrowRight") return if (e.shiftKey) return if (!item) return e.preventDefault() e.stopPropagation() - - const value = displayPath(item.absolute, filter(), home()) - list?.setFilter(value.endsWith("/") ? value : value + "/") + descend(item.absolute) }} onSelect={(path) => { if (!path) return @@ -315,6 +319,29 @@ export function DialogSelectDirectory(props: DialogSelectDirectoryProps) { / + { + e.preventDefault() + e.stopPropagation() + }} + onClick={(e) => { + e.preventDefault() + e.stopPropagation() + descend(item.absolute) + }} + onKeyDown={(e) => { + if (e.key !== "Enter" && e.key !== " ") return + e.preventDefault() + e.stopPropagation() + descend(item.absolute) + }} + aria-label="Open subfolder" + > + + ) } @@ -330,6 +357,29 @@ export function DialogSelectDirectory(props: DialogSelectDirectoryProps) { / + { + e.preventDefault() + e.stopPropagation() + }} + onClick={(e) => { + e.preventDefault() + e.stopPropagation() + descend(item.absolute) + }} + onKeyDown={(e) => { + if (e.key !== "Enter" && e.key !== " ") return + e.preventDefault() + e.stopPropagation() + descend(item.absolute) + }} + aria-label="Open subfolder" + > + + ) }}