summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-11-25 13:49:43 -0600
committerAdam <[email protected]>2025-11-25 13:49:46 -0600
commitcd678044129ef8a183773e3544f2265696645675 (patch)
tree23affcf248612e1e0599682d280a435dc0c9ac36
parent4a95db60138f0c1ab6e384c5b2cba9141420b3a7 (diff)
downloadopencode-cd678044129ef8a183773e3544f2265696645675.tar.gz
opencode-cd678044129ef8a183773e3544f2265696645675.zip
fix: scroll gutter
-rw-r--r--packages/desktop/src/pages/session.tsx19
-rw-r--r--packages/enterprise/src/routes/share/[shareID].tsx24
-rw-r--r--packages/ui/src/components/session-review.css5
-rw-r--r--packages/ui/src/components/session-review.tsx102
4 files changed, 96 insertions, 54 deletions
diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx
index a6188b8e9..0eb0f37ce 100644
--- a/packages/desktop/src/pages/session.tsx
+++ b/packages/desktop/src/pages/session.tsx
@@ -401,10 +401,15 @@ export default function Page() {
<Show when={layout.review.state() === "pane" && session.diffs().length}>
<div
classList={{
- "relative grow px-6 py-3 flex-1 min-h-0 border-l border-border-weak-base": true,
+ "relative grow pt-3 flex-1 min-h-0 border-l border-border-weak-base": true,
}}
>
<SessionReview
+ classes={{
+ root: "pb-20",
+ header: "px-6",
+ container: "px-6",
+ }}
diffs={session.diffs()}
actions={
<Tooltip value="Open in tab">
@@ -427,10 +432,18 @@ export default function Page() {
<Tabs.Content value="review" class="select-text flex flex-col h-full overflow-hidden">
<div
classList={{
- "relative px-6 py-3 flex-1 min-h-0 overflow-hidden": true,
+ "relative pt-3 flex-1 min-h-0 overflow-hidden": true,
}}
>
- <SessionReview diffs={session.diffs()} split class="pb-40" />
+ <SessionReview
+ classes={{
+ root: "pb-40",
+ header: "px-6",
+ container: "px-6",
+ }}
+ diffs={session.diffs()}
+ split
+ />
</div>
</Tabs.Content>
</Show>
diff --git a/packages/enterprise/src/routes/share/[shareID].tsx b/packages/enterprise/src/routes/share/[shareID].tsx
index 50181d71f..292038094 100644
--- a/packages/enterprise/src/routes/share/[shareID].tsx
+++ b/packages/enterprise/src/routes/share/[shareID].tsx
@@ -16,7 +16,7 @@ import { createStore } from "solid-js/store"
import z from "zod"
import NotFound from "../[...404]"
import { Tabs } from "@opencode-ai/ui/tabs"
-import { HunkData, preloadMultiFileDiff, PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
+import { preloadMultiFileDiff, PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
const SessionDataMissingError = NamedError.create(
"SessionDataMissingError",
@@ -304,8 +304,15 @@ export default function () {
</div>
</div>
<Show when={diffs().length > 0}>
- <div class="relative grow px-6 pt-14 flex-1 min-h-0 border-l border-border-weak-base">
- <SessionReview diffs={diffs()} class="pb-20" />
+ <div class="relative grow pt-14 flex-1 min-h-0 border-l border-border-weak-base">
+ <SessionReview
+ diffs={diffs()}
+ classes={{
+ root: "pb-20",
+ header: "px-6",
+ container: "px-6",
+ }}
+ />
</div>
</Show>
</div>
@@ -324,8 +331,15 @@ export default function () {
{turns()}
</Tabs.Content>
<Tabs.Content forceMount value="review" class="!overflow-hidden hidden data-[selected]:block">
- <div class="relative px-4 pt-8 h-full overflow-y-auto no-scrollbar">
- <SessionReview diffs={diffs()} class="pb-20" />
+ <div class="relative h-full pt-8 overflow-y-auto no-scrollbar">
+ <SessionReview
+ diffs={diffs()}
+ classes={{
+ root: "pb-20",
+ header: "px-4",
+ container: "px-4",
+ }}
+ />
</div>
</Tabs.Content>
</Tabs>
diff --git a/packages/ui/src/components/session-review.css b/packages/ui/src/components/session-review.css
index 554de8022..ba195b9f2 100644
--- a/packages/ui/src/components/session-review.css
+++ b/packages/ui/src/components/session-review.css
@@ -5,11 +5,14 @@
height: 100%;
overflow-y: auto;
scrollbar-width: none;
-
&::-webkit-scrollbar {
display: none;
}
+ /* [data-slot="session-review-container"] { */
+ /* height: 100%; */
+ /* } */
+
[data-slot="session-review-header"] {
position: sticky;
top: 0;
diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx
index 36dbf36a9..376317e1b 100644
--- a/packages/ui/src/components/session-review.tsx
+++ b/packages/ui/src/components/session-review.tsx
@@ -6,7 +6,7 @@ import { FileIcon } from "./file-icon"
import { Icon } from "./icon"
import { StickyAccordionHeader } from "./sticky-accordion-header"
import { getDirectory, getFilename } from "@opencode-ai/util/path"
-import { For, Match, Show, Switch, type JSX, splitProps } from "solid-js"
+import { For, Match, Show, Switch, type JSX } from "solid-js"
import { createStore } from "solid-js/store"
import { type FileDiff } from "@opencode-ai/sdk"
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
@@ -15,6 +15,7 @@ export interface SessionReviewProps {
split?: boolean
class?: string
classList?: Record<string, boolean | undefined>
+ classes?: { root?: string; header?: string; container?: string }
actions?: JSX.Element
diffs: (FileDiff & { preloaded?: PreloadMultiFileDiffResult<any> })[]
}
@@ -39,17 +40,21 @@ export const SessionReview = (props: SessionReviewProps) => {
}
}
- const [split] = splitProps(props, ["class", "classList"])
-
return (
<div
data-component="session-review"
classList={{
- ...(split.classList ?? {}),
- [split.class ?? ""]: !!split.class,
+ ...(props.classList ?? {}),
+ [props.classes?.root ?? ""]: !!props.classes?.root,
+ [props.class ?? ""]: !!props.class,
}}
>
- <div data-slot="session-review-header">
+ <div
+ data-slot="session-review-header"
+ classList={{
+ [props.classes?.header ?? ""]: !!props.classes?.header,
+ }}
+ >
<div data-slot="session-review-title">Session changes</div>
<div data-slot="session-review-actions">
<Button size="normal" icon="chevron-grabber-vertical" onClick={handleExpandOrCollapseAll}>
@@ -61,47 +66,54 @@ export const SessionReview = (props: SessionReviewProps) => {
{props.actions}
</div>
</div>
- <Accordion multiple value={store.open} onChange={handleChange}>
- <For each={props.diffs}>
- {(diff) => (
- <Accordion.Item forceMount value={diff.file} data-slot="session-review-accordion-item">
- <StickyAccordionHeader>
- <Accordion.Trigger>
- <div data-slot="session-review-trigger-content">
- <div data-slot="session-review-file-info">
- <FileIcon node={{ path: diff.file, type: "file" }} />
- <div data-slot="session-review-file-name-container">
- <Show when={diff.file.includes("/")}>
- <span data-slot="session-review-directory">{getDirectory(diff.file)}&lrm;</span>
- </Show>
- <span data-slot="session-review-filename">{getFilename(diff.file)}</span>
+ <div
+ data-slot="session-review-container"
+ classList={{
+ [props.classes?.container ?? ""]: !!props.classes?.container,
+ }}
+ >
+ <Accordion multiple value={store.open} onChange={handleChange}>
+ <For each={props.diffs}>
+ {(diff) => (
+ <Accordion.Item forceMount value={diff.file} data-slot="session-review-accordion-item">
+ <StickyAccordionHeader>
+ <Accordion.Trigger>
+ <div data-slot="session-review-trigger-content">
+ <div data-slot="session-review-file-info">
+ <FileIcon node={{ path: diff.file, type: "file" }} />
+ <div data-slot="session-review-file-name-container">
+ <Show when={diff.file.includes("/")}>
+ <span data-slot="session-review-directory">{getDirectory(diff.file)}&lrm;</span>
+ </Show>
+ <span data-slot="session-review-filename">{getFilename(diff.file)}</span>
+ </div>
+ </div>
+ <div data-slot="session-review-trigger-actions">
+ <DiffChanges changes={diff} />
+ <Icon name="chevron-grabber-vertical" size="small" />
</div>
</div>
- <div data-slot="session-review-trigger-actions">
- <DiffChanges changes={diff} />
- <Icon name="chevron-grabber-vertical" size="small" />
- </div>
- </div>
- </Accordion.Trigger>
- </StickyAccordionHeader>
- <Accordion.Content data-slot="session-review-accordion-content">
- <Diff
- preloadedDiff={diff.preloaded}
- diffStyle={props.split ? "split" : "unified"}
- before={{
- name: diff.file!,
- contents: diff.before!,
- }}
- after={{
- name: diff.file!,
- contents: diff.after!,
- }}
- />
- </Accordion.Content>
- </Accordion.Item>
- )}
- </For>
- </Accordion>
+ </Accordion.Trigger>
+ </StickyAccordionHeader>
+ <Accordion.Content data-slot="session-review-accordion-content">
+ <Diff
+ preloadedDiff={diff.preloaded}
+ diffStyle={props.split ? "split" : "unified"}
+ before={{
+ name: diff.file!,
+ contents: diff.before!,
+ }}
+ after={{
+ name: diff.file!,
+ contents: diff.after!,
+ }}
+ />
+ </Accordion.Content>
+ </Accordion.Item>
+ )}
+ </For>
+ </Accordion>
+ </div>
</div>
)
}