summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
authoradamelmore <[email protected]>2026-01-26 07:14:37 -0600
committeradamelmore <[email protected]>2026-01-26 09:33:42 -0600
commitff35db0360fa7e10644b475f05266d4f4b97d05e (patch)
tree89981fe8d514081a9bc5ab23f9b7ebff7ee8d5dc /packages/app/src
parentaf3d8c383e5fe2feba79ace5bb2e1082195a459d (diff)
downloadopencode-ff35db0360fa7e10644b475f05266d4f4b97d05e.tar.gz
opencode-ff35db0360fa7e10644b475f05266d4f4b97d05e.zip
wip(app): full-height sidebar
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/pages/layout.tsx45
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 />