Conversation divider
Dividers inside a thread: day boundaries (Today, Yesterday, Mon 12 Oct), where unread messages start, context events such as a model change or a compaction, and the point where the user left off. A hairline with a short label, centered or start aligned, with sticky dates.
On this page
Installation
Usage
import {
ConversationDivider,
ConversationDividerAction,
} from "@/components/ui/chatcn/conversation-divider"
<ConversationDivider variant="date" date={message.createdAt} sticky />
<ConversationDivider variant="unread" count={3} />
<ConversationDivider icon={<ContextWindowIcon />} action={<ConversationDividerAction>View summary</ConversationDividerAction>}>
Context compacted, 48k tokens saved
</ConversationDivider>
<ConversationDivider variant="resume" />Dates format relative to now: Today, Yesterday, then the weekday, day and month, with the year only when it differs. Commas from the locale are dropped so the label stays calm. formatDividerDate is exported for use elsewhere, such as a thread list.
Unread uses the blue info tone on the rule, the label and a 6 px dot, and the words carry the meaning on their own. Resume uses a dashed rule. Events stay neutral.
Examples
Divider kinds
Sticky dates
With sticky, a date divider pins to the top of the scrolling thread while its day scrolls by. While pinned, the rules fade out and the label sits on a small card surface so it stays readable over messages.
Long labels and RTL
Props
| Prop | Type | Notes |
|---|---|---|
variant | "date" | "unread" | "event" | "resume" | Defaults to event |
children | ReactNode | The label. Overrides the derived text |
date | Date | number | string | For date |
now | Date | number | Reference for Today and Yesterday. Defaults to the current time |
locale | string | Date locale. Defaults to the browser's |
count | number | For unread: "3 new messages" |
icon | ReactNode | A 14 px icon before the label |
action | ReactNode | Usually a ConversationDividerAction |
meta | ReactNode | Trailing detail such as a time, in tabular figures |
align | "center" | "start" | Defaults to center |
sticky | boolean | Pin to the top of the scroll container |
stickyOffset | number | Px from the top while pinned. Defaults to 8 |
Accessibility
- Date labels are level 3 headings, so screen reader users can jump between days.
- The rules are decorative and hidden. Labels are plain text in reading order, never color alone.
- Actions are real buttons with a 44 px hit area on touch screens.
Motion
- Only the sticky label moves between states: its surface and the rules cross over in 150 ms when it pins or unpins. Under reduced motion that stays a short fade.