summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-03-24 13:35:15 -0500
committerAdam <[email protected]>2026-03-24 13:35:20 -0500
commit9838f56a6f8598ae5d9b587067e4de20adfb303d (patch)
tree07d2856e06952280f24c001084a924433bea3d44
parent98b3340ceeb6928d0d57898d02665d763ef1ea9c (diff)
downloadopencode-9838f56a6f8598ae5d9b587067e4de20adfb303d.tar.gz
opencode-9838f56a6f8598ae5d9b587067e4de20adfb303d.zip
fix(app): sidebar ux
-rw-r--r--packages/app/src/pages/layout.tsx54
1 files changed, 32 insertions, 22 deletions
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index d01c7d3ce..731f0fe5b 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -1818,6 +1818,9 @@ export default function Layout(props: ParentProps) {
document.documentElement.style.setProperty("--dialog-left-margin", `${sidebarWidth}px`)
})
+ const side = createMemo(() => Math.max(layout.sidebar.width(), 244))
+ const panel = createMemo(() => Math.max(side() - 64, 0))
+
const loadedSessionDirs = new Set<string>()
createEffect(
@@ -2094,7 +2097,7 @@ export default function Layout(props: ParentProps) {
"max-w-full overflow-hidden": panelProps.mobile,
}}
style={{
- width: panelProps.mobile ? undefined : `${Math.max(Math.max(layout.sidebar.width(), 244) - 64, 0)}px`,
+ width: panelProps.mobile ? undefined : `${panel()}px`,
}}
>
<Show
@@ -2157,9 +2160,11 @@ export default function Layout(props: ParentProps) {
variant="ghost"
data-action="project-menu"
data-project={slug()}
- class="shrink-0 size-6 rounded-md data-[expanded]:bg-surface-base-active"
+ class="shrink-0 size-6 rounded-md transition-opacity data-[expanded]:bg-surface-base-active"
classList={{
- "opacity-0 group-hover/project:opacity-100 data-[expanded]:opacity-100": !panelProps.mobile,
+ "opacity-100": panelProps.mobile || merged(),
+ "opacity-0 group-hover/project:opacity-100 group-focus-within/project:opacity-100 data-[expanded]:opacity-100":
+ !panelProps.mobile && !merged(),
}}
aria-label={language.t("common.moreOptions")}
/>
@@ -2384,7 +2389,7 @@ export default function Layout(props: ParentProps) {
"absolute inset-y-0 left-0": true,
"z-10": true,
}}
- style={{ width: `${Math.max(layout.sidebar.width(), 244)}px` }}
+ style={{ width: `${side()}px` }}
ref={(el) => {
setState("nav", el)
}}
@@ -2399,24 +2404,29 @@ export default function Layout(props: ParentProps) {
}}
>
<div class="@container w-full h-full contain-strict">{sidebarContent()}</div>
- <Show when={layout.sidebar.opened()}>
- <div onPointerDown={() => setState("sizing", true)}>
- <ResizeHandle
- direction="horizontal"
- size={layout.sidebar.width()}
- min={244}
- max={typeof window === "undefined" ? 1000 : window.innerWidth * 0.3 + 64}
- onResize={(w) => {
- setState("sizing", true)
- if (sizet !== undefined) clearTimeout(sizet)
- sizet = window.setTimeout(() => setState("sizing", false), 120)
- layout.sidebar.resize(w)
- }}
- />
- </div>
- </Show>
</nav>
+ <Show when={layout.sidebar.opened()}>
+ <div
+ class="hidden xl:block absolute inset-y-0 z-30 w-0 overflow-visible"
+ style={{ left: `${side()}px` }}
+ onPointerDown={() => setState("sizing", true)}
+ >
+ <ResizeHandle
+ direction="horizontal"
+ size={layout.sidebar.width()}
+ min={244}
+ max={typeof window === "undefined" ? 1000 : window.innerWidth * 0.3 + 64}
+ onResize={(w) => {
+ setState("sizing", true)
+ if (sizet !== undefined) clearTimeout(sizet)
+ sizet = window.setTimeout(() => setState("sizing", false), 120)
+ layout.sidebar.resize(w)
+ }}
+ />
+ </div>
+ </Show>
+
<div
class="hidden xl:block pointer-events-none absolute top-0 right-0 z-0 border-t border-border-weaker-base"
style={{ left: "calc(4rem + 12px)" }}
@@ -2456,7 +2466,7 @@ export default function Layout(props: ParentProps) {
!state.sizing,
}}
style={{
- "--main-left": layout.sidebar.opened() ? `${Math.max(layout.sidebar.width(), 244)}px` : "4rem",
+ "--main-left": layout.sidebar.opened() ? `${side()}px` : "4rem",
}}
>
<main
@@ -2503,7 +2513,7 @@ export default function Layout(props: ParentProps) {
"duration-180 ease-out": state.peeked && !layout.sidebar.opened(),
"duration-120 ease-in": !state.peeked || layout.sidebar.opened(),
}}
- style={{ left: `calc(4rem + ${Math.max(Math.max(layout.sidebar.width(), 244) - 64, 0)}px)` }}
+ style={{ left: `calc(4rem + ${panel()}px)` }}
>
<div class="h-full w-px" style={{ "box-shadow": "var(--shadow-sidebar-overlay)" }} />
</div>