Skip to content

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.json

Usage

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

PropTypeDefaultDescription
data*Conversation[]—Chats, grouped into Pinned, Today, Yesterday, Previous 7 days and Older.
activeIdstring—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.
undoMsnumber5000How long Undo stays available.
variant"sidebar" | "compact""sidebar"Compact lists titles only, without search or group labels.
nowstring—Reference time for the date groups (ISO); defaults to now.
headerActionReactNode—Extra control in the header next to New chat, e.g. a hide-sidebar toggle.
classNamestring—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
};