mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-14 03:56:55 +03:00
fix(tui): pin sidebar headings without scrollbar flashes (#46449)
Keep the title and workspace label above scrollable sidebar details. Disable the unused horizontal scrollbar and place the automatic vertical scrollbar in the reserved gutter so tab changes do not flash or shift the sidebar.
This commit is contained in:
committed by
GitHub
Unverified
parent
fcce2d7cc9
commit
197d28e033
@@ -29,16 +29,40 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
|
||||
paddingRight={2}
|
||||
position={props.overlay ? "absolute" : "relative"}
|
||||
>
|
||||
<box flexShrink={0} paddingRight={2} paddingBottom={1}>
|
||||
<title_shimmer
|
||||
fg={theme.text.default}
|
||||
rename={{
|
||||
pending: data.session.title.pending(props.sessionID),
|
||||
title: withTimestampedFallback(session()),
|
||||
}}
|
||||
enabled={config.animations ?? true}
|
||||
backdrop={theme.background.default}
|
||||
attributes={
|
||||
data.session.title.pending(props.sessionID) && config.animations === false
|
||||
? TextAttributes.DIM
|
||||
: TextAttributes.BOLD
|
||||
}
|
||||
>
|
||||
{withTimestampedFallback(session())}
|
||||
</title_shimmer>
|
||||
<Show when={session().location.workspaceID}>
|
||||
<text fg={theme.text.subdued}>{session().location.workspaceID}</text>
|
||||
</Show>
|
||||
</box>
|
||||
<scrollbox
|
||||
ref={(scroll) =>
|
||||
queueMicrotask(() => {
|
||||
if (!scroll.isDestroyed) scroll.verticalScrollBar.resetVisibilityControl()
|
||||
})
|
||||
}
|
||||
flexGrow={1}
|
||||
minHeight={0}
|
||||
scrollAcceleration={scrollAcceleration()}
|
||||
// The sidebar only scrolls vertically; a horizontal bar steals a row during initial layout.
|
||||
horizontalScrollbarOptions={{ visible: false }}
|
||||
verticalScrollbarOptions={{
|
||||
visible: false,
|
||||
// Use the content's reserved right padding instead of changing its width when the bar toggles.
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
top: 0,
|
||||
width: 1,
|
||||
height: "100%",
|
||||
trackOptions: {
|
||||
backgroundColor: theme.background.default,
|
||||
foregroundColor: theme.scrollbar.default,
|
||||
@@ -46,27 +70,6 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
|
||||
}}
|
||||
>
|
||||
<box flexShrink={0} gap={1} paddingRight={1}>
|
||||
<box paddingRight={1}>
|
||||
<title_shimmer
|
||||
fg={theme.text.default}
|
||||
rename={{
|
||||
pending: data.session.title.pending(props.sessionID),
|
||||
title: withTimestampedFallback(session()),
|
||||
}}
|
||||
enabled={config.animations ?? true}
|
||||
backdrop={theme.background.default}
|
||||
attributes={
|
||||
data.session.title.pending(props.sessionID) && config.animations === false
|
||||
? TextAttributes.DIM
|
||||
: TextAttributes.BOLD
|
||||
}
|
||||
>
|
||||
{withTimestampedFallback(session())}
|
||||
</title_shimmer>
|
||||
<Show when={session().location.workspaceID}>
|
||||
<text fg={theme.text.subdued}>{session().location.workspaceID}</text>
|
||||
</Show>
|
||||
</box>
|
||||
<Slot path="sidebar.content" input={{ sessionID: props.sessionID }} />
|
||||
</box>
|
||||
</scrollbox>
|
||||
|
||||
Reference in New Issue
Block a user