diff --git a/apps/web/src/components/chat/MessagesTimeline.test.tsx b/apps/web/src/components/chat/MessagesTimeline.test.tsx index 076873bca4f..cd03feb8262 100644 --- a/apps/web/src/components/chat/MessagesTimeline.test.tsx +++ b/apps/web/src/components/chat/MessagesTimeline.test.tsx @@ -9,6 +9,7 @@ vi.mock("@legendapp/list/react", async () => { const LegendList = (props: { data: Array<{ id: string }>; + extraData?: unknown; keyExtractor: (item: { id: string }) => string; renderItem: (args: { item: { id: string } }) => ReactNode; ListHeaderComponent?: ReactNode; @@ -48,6 +49,7 @@ vi.mock("@legendapp/list/react", async () => { return (
{ expect(markup).toContain('data-anchor-on-ready="true"'); expect(markup).not.toContain("data-anchor-max-size="); expect(markup).toContain('data-content-inset-end="144"'); + expect(markup).toContain('data-extra-data-matches-rows="true"'); expect(markup).toContain("[overflow-anchor:none]"); expect(markup).not.toContain('data-maintain-scroll-at-end="enabled"'); expect(markup).toContain('data-maintain-visible-content-position="object"'); diff --git a/apps/web/src/components/chat/MessagesTimeline.tsx b/apps/web/src/components/chat/MessagesTimeline.tsx index 52ccf07ed13..861218a41ac 100644 --- a/apps/web/src/components/chat/MessagesTimeline.tsx +++ b/apps/web/src/components/chat/MessagesTimeline.tsx @@ -532,7 +532,11 @@ export const MessagesTimeline = memo(function MessagesTimeline({ // from TimelineRowCtx, which propagates through LegendList's memo. const renderItem = useCallback( ({ item }: { item: MessagesTimelineRow }) => ( -
+
), @@ -567,6 +571,12 @@ export const MessagesTimeline = memo(function MessagesTimeline({ ref={listRef} data={rows} + // LegendList can retain a mounted container's previous child while + // anchored end-space is recomputed around a newly inserted turn. + // Re-running mounted renderers on each logical row-set change keeps + // the container content aligned with its current item key; memoized + // TimelineRowContent still skips unchanged rows. + extraData={rows} keyExtractor={keyExtractor} getItemType={getItemType} renderItem={renderItem}