Fix sticky date divider handoff

Group messages by day so sticky date labels push each other out during scroll instead of overlapping.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Thomas Petersen
2026-05-04 18:48:15 -04:00
parent 57b10f3940
commit 11998b11e0
2 changed files with 22 additions and 12 deletions

View File

@@ -6,7 +6,7 @@ export function DayDivider({ label }: { label: string }) {
data-testid="message-timeline-day-divider"
data-day-label={label}
>
<p className="shrink-0 rounded-full bg-background/80 px-2 py-0.5 text-[10px] font-medium tracking-[0.02em] text-muted-foreground/65 backdrop-blur-sm">
<p className="shrink-0 rounded-full bg-background/90 px-2 py-0.5 text-[10px] font-medium tracking-[0.02em] text-muted-foreground/65 backdrop-blur-sm">
{label}
</p>
</section>

View File

@@ -52,27 +52,32 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
searchMatchingMessageIds,
searchQuery,
}: TimelineMessageListProps) {
const elements: React.ReactNode[] = [];
const entries = React.useMemo(
() => buildMainTimelineEntries(messages),
[messages],
);
const dayGroups: Array<{
key: string;
label: string;
elements: React.ReactNode[];
}> = [];
let currentDayGroup: (typeof dayGroups)[number] | null = null;
for (let i = 0; i < entries.length; i++) {
const { message, summary } = entries[i];
const prev = i > 0 ? entries[i - 1]?.message : null;
if (!prev || !isSameDay(prev.createdAt, message.createdAt)) {
elements.push(
<DayDivider
key={`day-${message.createdAt}`}
label={formatDayHeading(message.createdAt)}
/>,
);
currentDayGroup = {
key: `day-${message.createdAt}`,
label: formatDayHeading(message.createdAt),
elements: [],
};
dayGroups.push(currentDayGroup);
}
if (message.kind === KIND_SYSTEM_MESSAGE) {
elements.push(
currentDayGroup?.elements.push(
<SystemMessageRow
key={message.id}
message={message}
@@ -83,7 +88,7 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
/>,
);
} else if (summary && onReply) {
elements.push(
currentDayGroup?.elements.push(
<div key={message.id} className="flex flex-col gap-0">
<MessageRow
activeReplyTargetId={activeReplyTargetId}
@@ -115,7 +120,7 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
const isSearchMatch = searchMatchingMessageIds?.has(message.id) ?? false;
const isSearchActive = message.id === searchActiveMessageId;
elements.push(
currentDayGroup?.elements.push(
<MessageRow
key={message.id}
activeReplyTargetId={activeReplyTargetId}
@@ -140,5 +145,10 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
}
}
return elements;
return dayGroups.map((group) => (
<section className="flex flex-col gap-2" key={group.key}>
<DayDivider label={group.label} />
{group.elements}
</section>
));
});