Conversation
Conversation List
Chat history for a sidebar — search, pinned and dated groups, rename inline, archive and delete with undo.
2 variantsMIT
Preview
Chats
Pinned
Recent
Installation
Copies the component into components/ui and installs its dependencies and theme tokens.
pnpm dlx shadcn@latest add https://tuffui.com/r/conversation-list.jsonUsage
Pass your own data and wire the callbacks to your agent runtime.
import { ConversationList } from "@/components/ui/conversation-list";
export function ChatSidebar({ chats, activeId }: Props) {
return (
<ConversationList
data={chats.map((c) => ({
id: c.id,
title: c.title,
updatedAt: c.lastMessageAt,
pinned: c.pinned,
running: c.status === "running",
}))}
activeId={activeId}
onSelect={(c) => router.push(`/chat/${c.id}`)}
onNew={() => router.push("/chat/new")}
onRename={(c, title) => api.rename(c.id, title)}
onPin={(c, pinned) => api.pin(c.id, pinned)}
onArchive={(c) => api.archive(c.id)} // after the undo window
onDelete={(c) => api.delete(c.id)}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| data* | Conversation[] | — | Chats, grouped into Pinned, Today, Yesterday, Previous 7 days and Older. |
| activeId | string | — | The open chat, marked with aria-current. |
| onSelect | (conversation) => void | — | Click or Enter on a row. Arrow keys move between rows. |
| onNew | () => void | — | Shows a New chat button in the header. |
| onRename | (conversation, title) => void | — | Inline rename from the row menu: Enter or blur saves, Esc cancels. |
| onPin | (conversation, pinned) => void | — | Pin or unpin from the row menu. |
| onArchive / onDelete | (conversation) => void | — | The row hides at once with an Undo pill; the callback runs when the undo window closes. |
| undoMs | number | 5000 | How long Undo stays available. |
| variant | "sidebar" | "compact" | "sidebar" | Compact lists titles only, without search or group labels. |
| now | string | — | Reference time for the date groups (ISO); defaults to now. |
| headerAction | ReactNode | — | Extra control in the header next to New chat, e.g. a hide-sidebar toggle. |
| className | string | — | Extra classes for the shell. |
type Conversation = {
id: string;
title: string;
updatedAt: string; // ISO
pinned?: boolean;
running?: boolean; // shows a pulsing dot while the agent works
};