Skip to content

Commit f2bf620

Browse files
committed
fix(app): highlight selected change
Track clicked file in the Changes tree and apply selection styling to the matching review diff.
1 parent 00c7729 commit f2bf620

7 files changed

Lines changed: 52 additions & 3 deletions

File tree

packages/app/src/components/file-tree.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export default function FileTree(props: {
2929
path: string
3030
class?: string
3131
nodeClass?: string
32+
active?: string
3233
level?: number
3334
allowed?: readonly string[]
3435
modified?: readonly string[]
@@ -149,6 +150,7 @@ export default function FileTree(props: {
149150
component={local.as ?? "div"}
150151
classList={{
151152
"w-full min-w-0 h-6 flex items-center justify-start gap-x-1.5 rounded-md px-1.5 py-0 text-left hover:bg-surface-raised-base-hover active:bg-surface-base-active transition-colors cursor-pointer": true,
153+
"bg-surface-base-active": local.node.path === props.active,
152154
...(local.classList ?? {}),
153155
[local.class ?? ""]: !!local.class,
154156
[props.nodeClass ?? ""]: !!props.nodeClass,
@@ -297,7 +299,7 @@ export default function FileTree(props: {
297299
<Show when={ignored()}>
298300
<>
299301
<span class="mx-1 font-bold text-text-invert-strong"></span>
300-
<span class="shrink-0 text-text-invert-weak">Ignored</span>
302+
<span class="shrink-0 text-text-invert-strong">Ignored</span>
301303
</>
302304
</Show>
303305
</div>
@@ -343,6 +345,7 @@ export default function FileTree(props: {
343345
allowed={props.allowed}
344346
modified={props.modified}
345347
kinds={props.kinds}
348+
active={props.active}
346349
draggable={props.draggable}
347350
tooltip={props.tooltip}
348351
onFileClick={props.onFileClick}

packages/app/src/pages/session.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ interface SessionReviewTabProps {
8989
comments?: LineComment[]
9090
focusedComment?: { file: string; id: string } | null
9191
onFocusedCommentChange?: (focus: { file: string; id: string } | null) => void
92+
focusedFile?: string
9293
onScrollRef?: (el: HTMLDivElement) => void
9394
classes?: {
9495
root?: string
@@ -213,6 +214,7 @@ function SessionReviewTab(props: SessionReviewTabProps) {
213214
diffStyle={props.diffStyle}
214215
onDiffStyleChange={props.onDiffStyleChange}
215216
onViewFile={props.onViewFile}
217+
focusedFile={props.focusedFile}
216218
readFile={readFile}
217219
onLineComment={props.onLineComment}
218220
comments={props.comments}
@@ -480,12 +482,29 @@ export default function Page() {
480482
}
481483

482484
const kinds = createMemo(() => {
485+
const merge = (a: "add" | "del" | "mix" | undefined, b: "add" | "del" | "mix") => {
486+
if (!a) return b
487+
if (a === b) return a
488+
return "mix" as const
489+
}
490+
491+
const normalize = (p: string) => p.replaceAll("\\\\", "/").replace(/\/+$/, "")
492+
483493
const out = new Map<string, "add" | "del" | "mix">()
484494
for (const diff of diffs()) {
495+
const file = normalize(diff.file)
485496
const add = diff.additions > 0
486497
const del = diff.deletions > 0
487498
const kind = add && del ? "mix" : add ? "add" : del ? "del" : "mix"
488-
out.set(diff.file, kind)
499+
500+
out.set(file, kind)
501+
502+
const parts = file.split("/")
503+
for (const [idx] of parts.slice(0, -1).entries()) {
504+
const dir = parts.slice(0, idx + 1).join("/")
505+
if (!dir) continue
506+
out.set(dir, merge(out.get(dir), kind))
507+
}
489508
}
490509
return out
491510
})
@@ -1084,12 +1103,15 @@ export default function Page() {
10841103
const [tree, setTree] = createStore({
10851104
reviewScroll: undefined as HTMLDivElement | undefined,
10861105
pendingDiff: undefined as string | undefined,
1106+
activeDiff: undefined as string | undefined,
10871107
})
10881108

10891109
const reviewScroll = () => tree.reviewScroll
10901110
const setReviewScroll = (value: HTMLDivElement | undefined) => setTree("reviewScroll", value)
10911111
const pendingDiff = () => tree.pendingDiff
10921112
const setPendingDiff = (value: string | undefined) => setTree("pendingDiff", value)
1113+
const activeDiff = () => tree.activeDiff
1114+
const setActiveDiff = (value: string | undefined) => setTree("activeDiff", value)
10931115

10941116
const showAllFiles = () => {
10951117
if (fileTreeTab() !== "changes") return
@@ -1151,6 +1173,7 @@ export default function Page() {
11511173
const focusReviewDiff = (path: string) => {
11521174
const current = view().review.open() ?? []
11531175
if (!current.includes(path)) view().review.setOpen([...current, path])
1176+
setActiveDiff(path)
11541177
setPendingDiff(path)
11551178
}
11561179

@@ -1697,6 +1720,7 @@ export default function Page() {
16971720
diffs={diffs}
16981721
view={view}
16991722
diffStyle="unified"
1723+
focusedFile={activeDiff()}
17001724
onLineComment={(comment) => addCommentToContext({ ...comment, origin: "review" })}
17011725
comments={comments.all()}
17021726
focusedComment={comments.focus()}
@@ -2046,6 +2070,7 @@ export default function Page() {
20462070
</StickyAddButton>
20472071
</Tabs.List>
20482072
</div>
2073+
20492074
<Tabs.Content value="empty" class="flex flex-col h-full overflow-hidden contain-strict">
20502075
<Show when={activeTab() === "empty"}>
20512076
<div class="relative pt-2 flex-1 min-h-0 overflow-hidden">
@@ -2597,6 +2622,7 @@ export default function Page() {
25972622
diffStyle={layout.review.diffStyle()}
25982623
onDiffStyleChange={layout.review.setDiffStyle}
25992624
onScrollRef={setReviewScroll}
2625+
focusedFile={activeDiff()}
26002626
onLineComment={(comment) => addCommentToContext({ ...comment, origin: "review" })}
26012627
comments={comments.all()}
26022628
focusedComment={comments.focus()}
@@ -2664,6 +2690,7 @@ export default function Page() {
26642690
allowed={diffFiles()}
26652691
kinds={kinds()}
26662692
draggable={false}
2693+
active={activeDiff()}
26672694
onFileClick={(node) => focusReviewDiff(node.path)}
26682695
/>
26692696
</Show>

packages/ui/src/components/button.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
background-color: transparent;
4444
color: var(--text-strong);
4545

46+
[data-slot="icon-svg"] {
47+
color: var(--icon-base);
48+
}
49+
4650
&:hover:not(:disabled) {
4751
background-color: var(--surface-raised-base-hover);
4852
}
@@ -54,8 +58,11 @@
5458
}
5559
&:disabled {
5660
color: var(--text-weak);
57-
opacity: 0.7;
5861
cursor: not-allowed;
62+
63+
[data-slot="icon-svg"] {
64+
color: var(--icon-disabled);
65+
}
5966
}
6067
&[data-selected="true"]:not(:disabled) {
6168
background-color: var(--surface-raised-base-hover);

packages/ui/src/components/session-review.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@
5454
background-color: var(--background-stronger) !important;
5555
}
5656

57+
[data-slot="session-review-accordion-item"][data-selected] {
58+
[data-slot="session-review-accordion-content"] {
59+
box-shadow: var(--shadow-xs-border-select);
60+
border-radius: var(--radius-lg);
61+
}
62+
}
63+
5764
[data-slot="accordion-item"] {
5865
[data-slot="accordion-content"] {
5966
display: none;

packages/ui/src/components/session-review.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export interface SessionReviewProps {
4444
comments?: SessionReviewComment[]
4545
focusedComment?: SessionReviewFocus | null
4646
onFocusedCommentChange?: (focus: SessionReviewFocus | null) => void
47+
focusedFile?: string
4748
open?: string[]
4849
onOpenChange?: (open: string[]) => void
4950
scrollRef?: (el: HTMLDivElement) => void
@@ -501,6 +502,7 @@ export const SessionReview = (props: SessionReviewProps) => {
501502
id={diffId(diff.file)}
502503
data-file={diff.file}
503504
data-slot="session-review-accordion-item"
505+
data-selected={props.focusedFile === diff.file ? "" : undefined}
504506
>
505507
<StickyAccordionHeader>
506508
<Accordion.Trigger>

packages/ui/src/styles/theme.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@
286286
--icon-diff-add-active: var(--mint-light-12);
287287
--icon-diff-delete-base: var(--ember-light-10);
288288
--icon-diff-delete-hover: var(--ember-light-11);
289+
--icon-diff-modified-base: var(--icon-warning-base);
289290
--syntax-comment: var(--text-weak);
290291
--syntax-regexp: var(--text-base);
291292
--syntax-string: #006656;
@@ -543,6 +544,7 @@
543544
--icon-diff-add-active: var(--mint-dark-11);
544545
--icon-diff-delete-base: var(--ember-dark-9);
545546
--icon-diff-delete-hover: var(--ember-dark-10);
547+
--icon-diff-modified-base: var(--icon-warning-base);
546548
--syntax-comment: var(--text-weak);
547549
--syntax-regexp: var(--text-base);
548550
--syntax-string: #00ceb9;

packages/ui/src/theme/resolve.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export function resolveThemeVariant(variant: ThemeVariant, isDark: boolean): Res
240240
tokens["icon-diff-add-active"] = diffAdd[isDark ? 10 : 11]
241241
tokens["icon-diff-delete-base"] = diffDelete[isDark ? 8 : 9]
242242
tokens["icon-diff-delete-hover"] = diffDelete[isDark ? 9 : 10]
243+
tokens["icon-diff-modified-base"] = tokens["icon-warning-base"]
243244

244245
tokens["syntax-comment"] = "var(--text-weak)"
245246
tokens["syntax-regexp"] = "var(--text-base)"

0 commit comments

Comments
 (0)