diff options
| author | adamelmore <[email protected]> | 2026-01-26 07:14:37 -0600 |
|---|---|---|
| committer | adamelmore <[email protected]> | 2026-01-26 09:33:42 -0600 |
| commit | ff35db0360fa7e10644b475f05266d4f4b97d05e (patch) | |
| tree | 89981fe8d514081a9bc5ab23f9b7ebff7ee8d5dc | |
| parent | af3d8c383e5fe2feba79ace5bb2e1082195a459d (diff) | |
| download | opencode-ff35db0360fa7e10644b475f05266d4f4b97d05e.tar.gz opencode-ff35db0360fa7e10644b475f05266d4f4b97d05e.zip | |
wip(app): full-height sidebar
| -rw-r--r-- | packages/app/src/pages/layout.tsx | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index a14b4a8e5..d12a81611 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -137,6 +137,8 @@ export default function Layout(props: ParentProps) { const [hoverSession, setHoverSession] = createSignal<string | undefined>() const [hoverProject, setHoverProject] = createSignal<string | undefined>() + const navRef = { current: undefined as HTMLElement | undefined } + const sidebarHovering = createMemo(() => !layout.sidebar.opened() && hoverProject() !== undefined) const sidebarExpanded = createMemo(() => layout.sidebar.opened() || sidebarHovering()) @@ -151,6 +153,19 @@ export default function Layout(props: ParentProps) { setHoverProject(undefined) }) + createEffect( + on( + () => ({ dir: params.dir, id: params.id }), + () => { + if (layout.sidebar.opened()) return + if (!hoverProject()) return + setHoverSession(undefined) + setHoverProject(undefined) + }, + { defer: true }, + ), + ) + const autoselecting = createMemo(() => { if (params.dir) return false if (initialDir) return false @@ -1044,6 +1059,10 @@ export default function Layout(props: ParentProps) { function navigateToProject(directory: string | undefined) { if (!directory) return + if (!layout.sidebar.opened()) { + setHoverSession(undefined) + setHoverProject(undefined) + } server.projects.touch(directory) const lastSession = store.lastSession[directory] navigate(`/${base64Encode(directory)}${lastSession ? `/session/${lastSession}` : ""}`) @@ -1052,6 +1071,10 @@ export default function Layout(props: ParentProps) { function navigateToSession(session: Session | undefined) { if (!session) return + if (!layout.sidebar.opened()) { + setHoverSession(undefined) + setHoverProject(undefined) + } navigate(`/${base64Encode(session.directory)}/session/${session.id}`) layout.mobileSidebar.hide() } @@ -1730,7 +1753,7 @@ export default function Layout(props: ParentProps) { aria-label={language.t("common.moreOptions")} /> </Tooltip> - <DropdownMenu.Portal> + <DropdownMenu.Portal mount={!props.mobile ? navRef.current : undefined}> <DropdownMenu.Content onCloseAutoFocus={(event) => { if (!pendingRename()) return @@ -1980,7 +2003,7 @@ export default function Layout(props: ParentProps) { aria-label={language.t("common.moreOptions")} /> </Tooltip> - <DropdownMenu.Portal> + <DropdownMenu.Portal mount={!props.mobile ? navRef.current : undefined}> <DropdownMenu.Content onCloseAutoFocus={(event) => { if (!pendingRename()) return @@ -2291,6 +2314,10 @@ export default function Layout(props: ParentProps) { } const createWorkspace = async (project: LocalProject) => { + if (!layout.sidebar.opened()) { + setHoverSession(undefined) + setHoverProject(undefined) + } const created = await globalSDK.client.worktree .create({ directory: project.worktree }) .then((x) => x.data) @@ -2392,7 +2419,7 @@ export default function Layout(props: ParentProps) { class="shrink-0 size-6 rounded-md opacity-0 group-hover/project:opacity-100 data-[expanded]:opacity-100 data-[expanded]:bg-surface-base-active" aria-label={language.t("common.moreOptions")} /> - <DropdownMenu.Portal> + <DropdownMenu.Portal mount={!panelProps.mobile ? navRef.current : undefined}> <DropdownMenu.Content class="mt-1"> <DropdownMenu.Item onSelect={() => dialog.show(() => <DialogEditProject project={p} />)}> <DropdownMenu.ItemLabel>{language.t("common.edit")}</DropdownMenu.ItemLabel> @@ -2440,6 +2467,10 @@ export default function Layout(props: ParentProps) { icon="plus-small" class="w-full" onClick={() => { + if (!layout.sidebar.opened()) { + setHoverSession(undefined) + setHoverProject(undefined) + } navigate(`/${base64Encode(p.worktree)}/session`) layout.mobileSidebar.hide() }} @@ -2628,7 +2659,13 @@ export default function Layout(props: ParentProps) { "relative shrink-0": true, }} style={{ width: layout.sidebar.opened() ? `${Math.max(layout.sidebar.width(), 244)}px` : "64px" }} - onMouseLeave={() => setHoverProject(undefined)} + ref={(el) => { + navRef.current = el + }} + onMouseLeave={() => { + setHoverSession(undefined) + setHoverProject(undefined) + }} > <div class="@container w-full h-full contain-strict"> <SidebarContent /> |
