From 9d57f21f9fedddc753908d2727f0422408eaa878 Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Fri, 3 Apr 2026 19:02:53 +0530 Subject: [PATCH] feat(ui): redesign modified files section in session turn (#20348) Co-authored-by: David Hill --- packages/ui/src/components/session-turn.css | 64 +++--- packages/ui/src/components/session-turn.tsx | 203 ++++++++++---------- packages/ui/src/i18n/en.ts | 4 + 3 files changed, 131 insertions(+), 140 deletions(-) diff --git a/packages/ui/src/components/session-turn.css b/packages/ui/src/components/session-turn.css index c4a8726ac5..53e2b58f45 100644 --- a/packages/ui/src/components/session-turn.css +++ b/packages/ui/src/components/session-turn.css @@ -92,33 +92,15 @@ min-width: 0; } - [data-slot="session-turn-diffs"] - > [data-component="collapsible"] - > [data-slot="collapsible-trigger"][aria-expanded="true"] { - position: sticky; - top: var(--sticky-accordion-top, 0px); - z-index: 20; - height: 40px; - padding-bottom: 8px; - background-color: var(--background-stronger); - } - - [data-component="session-turn-diffs-trigger"] { - width: 100%; + [data-slot="session-turn-diffs-header"] { display: flex; - align-items: center; - justify-content: flex-start; - gap: 8px; - padding: 0; - } - - [data-slot="session-turn-diffs-title"] { - display: inline-flex; align-items: baseline; gap: 8px; + padding-bottom: 12px; } [data-slot="session-turn-diffs-label"] { + font-variant-numeric: tabular-nums; color: var(--text-strong); font-family: var(--font-family-sans); font-size: var(--font-size-base); @@ -126,28 +108,38 @@ line-height: var(--line-height-large); } - [data-slot="session-turn-diffs-count"] { - color: var(--text-base); + [data-slot="session-turn-diffs-toggle"] { + color: var(--text-interactive-base); font-family: var(--font-family-sans); - font-variant-numeric: tabular-nums; font-size: var(--font-size-base); font-weight: var(--font-weight-regular); - line-height: var(--line-height-x-large); + line-height: var(--line-height-large); + cursor: pointer; + opacity: 0; + transition: opacity 0.15s ease; + margin-left: 4px; } - [data-slot="session-turn-diffs-meta"] { - display: inline-flex; - align-items: center; - gap: 8px; - flex-shrink: 0; + [data-component="session-turn-diffs-group"]:hover [data-slot="session-turn-diffs-toggle"] { + opacity: 1; + } - [data-slot="collapsible-arrow"] { - margin-left: -6px; - transform: translateY(2px); - } + [data-component="session-turn-diffs-group"][data-show-all] [data-slot="session-turn-diffs-toggle"] { + opacity: 1; + } - [data-component="diff-changes"][data-variant="bars"] { - transform: translateY(1px); + [data-slot="session-turn-diffs-more"] { + color: var(--text-weak); + font-family: var(--font-family-sans); + font-size: var(--font-size-small); + line-height: var(--line-height-large); + margin-top: 12px; + padding: 0 0 6px; + cursor: pointer; + transition: color 0.15s ease; + + &:hover { + color: var(--text-link-base); } } diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index fe029485a1..c20e5fb1ce 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -12,7 +12,6 @@ import { AssistantParts, Message, MessageDivider, PART_MAPPING, type UserActions import { Card } from "./card" import { Accordion } from "./accordion" import { StickyAccordionHeader } from "./sticky-accordion-header" -import { Collapsible } from "./collapsible" import { DiffChanges } from "./diff-changes" import { Icon } from "./icon" import { TextShimmer } from "./text-shimmer" @@ -241,23 +240,20 @@ export function SessionTurn( }, []) .reverse() }) + const MAX_FILES = 10 const edited = createMemo(() => diffs().length) const [state, setState] = createStore({ - open: false, + showAll: false, expanded: [] as string[], }) - const open = () => state.open + const showAll = () => state.showAll const expanded = () => state.expanded - - createEffect( - on( - open, - (value, prev) => { - if (!value && prev) setState("expanded", []) - }, - { defer: true }, - ), - ) + const overflow = createMemo(() => Math.max(0, edited() - MAX_FILES)) + const visible = createMemo(() => (showAll() ? diffs() : diffs().slice(0, MAX_FILES))) + const toggleAll = () => { + autoScroll.pause() + setState("showAll", !showAll()) + } const assistantMessages = createMemo( () => { @@ -425,101 +421,100 @@ export function SessionTurn( 0 && !working()}> -
- setState("open", value)} variant="ghost"> - -
-
- {i18n.t("ui.sessionReview.change.modified")} - - {edited()} {i18n.t(edited() === 1 ? "ui.common.file.one" : "ui.common.file.other")} - -
- - -
-
-
-
- - -
- - setState("expanded", Array.isArray(value) ? value : value ? [value] : []) - } - > - - {(diff) => { - const active = createMemo(() => expanded().includes(diff.file)) - const [visible, setVisible] = createSignal(false) +
+
+ + {edited()} {i18n.t("ui.sessionTurn.diffs.changed")}{" "} + {i18n.t(edited() === 1 ? "ui.common.file.one" : "ui.common.file.other")} + + + 0}> + + {showAll() ? i18n.t("ui.sessionTurn.diffs.showLess") : i18n.t("ui.sessionTurn.diffs.showAll")} + + +
+
+ setState("expanded", Array.isArray(value) ? value : value ? [value] : [])} + > + + {(diff) => { + const active = createMemo(() => expanded().includes(diff.file)) + const [shown, setShown] = createSignal(false) - createEffect( - on( - active, - (value) => { - if (!value) { - setVisible(false) - return - } + createEffect( + on( + active, + (value) => { + if (!value) { + setShown(false) + return + } - requestAnimationFrame(() => { - if (!active()) return - setVisible(true) - }) - }, - { defer: true }, - ), - ) + requestAnimationFrame(() => { + if (!active()) return + setShown(true) + }) + }, + { defer: true }, + ), + ) - return ( - - - -
- - - - {`\u202A${getDirectory(diff.file)}\u202C`} - - - {getFilename(diff.file)} - -
- - - - - - -
-
-
-
- - -
- -
+ return ( + + + +
+ + + + {`\u202A${getDirectory(diff.file)}\u202C`} + - - - ) - }} - - -
-
- - + {getFilename(diff.file)} + +
+ + + + + + +
+
+ + + + +
+ +
+
+
+ + ) + }} + + + 0}> +
+ {i18n.t("ui.sessionTurn.diffs.more", { count: String(overflow()) })} +
+
+
diff --git a/packages/ui/src/i18n/en.ts b/packages/ui/src/i18n/en.ts index 18823aeaa1..e66b55092b 100644 --- a/packages/ui/src/i18n/en.ts +++ b/packages/ui/src/i18n/en.ts @@ -38,6 +38,10 @@ export const dict: Record = { "ui.sessionTurn.steps.hide": "Hide steps", "ui.sessionTurn.summary.response": "Response", "ui.sessionTurn.diff.showMore": "Show more changes ({{count}})", + "ui.sessionTurn.diffs.changed": "Changed", + "ui.sessionTurn.diffs.showAll": "Show all", + "ui.sessionTurn.diffs.showLess": "Show less", + "ui.sessionTurn.diffs.more": "+{{count}} more files", "ui.sessionTurn.retry.retrying": "retrying", "ui.sessionTurn.retry.inSeconds": "in {{seconds}}s",