ThreadList
thread-listLists conversation threads with active state, metadata, deletion, a header action, and an empty state.
Usage
Basic usage
Passing in items (id/title/meta), active marks the current session.
History
<ThreadList
items={[
{ id: "a", title: "Yunqi Technology·President's Personal Secretary", meta: "3 minutes ago", active: true },
{ id: "b", title: "Morning Star Group·Administrative Director", meta: "Yesterday" },
{ id: "c", title: "New resume conversation", meta: "Last week" },
]}
onSelect={(id) => console.log(id)}
/>Can be deleted
Provides a delete button to be rendered on the right side of each item after onDelete (clicking does not trigger onSelect).
History
<ThreadList
items={[
{ id: "a", title: "Yunqi Technology·President's Personal Secretary", meta: "3 minutes ago", active: true },
{ id: "b", title: "Morning Star Group·Administrative Director", meta: "Yesterday" },
]}
onSelect={(id) => open(id)}
onDelete={(id) => remove(id)}
/>Head Action Slot
title Custom + action slot for the "New Conversation" button.
Recent conversations
<ThreadList
title="Recent Conversations"
items={items}
action={
<Button size="sm" variant="ghost">
<Plus className="size-3.5" aria-hidden />
New conversation
</Button>
}
/>Empty
When items is empty, the placeholder is displayed, and empty can be used to customize the copy.
History
There are no historical sessions yet
<ThreadList items={[]} empty="No historical sessions yet" />Inline (no border)
bare Remove the container border background and embed existing containers such as sidebars.
History
<ThreadList bare items={items} />When to Use
Used for the session history list (title + relative time double line, active highlighting, deletion) in the agent sidebar. This component manages "switching/deleting historical conversations", not the message flow itself; the operation bar of a single message uses MessageActions. Pass bare when you need to remove the border and embed your own sidebar layout.
Import
import { ThreadList } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| items* | ThreadListItem[] | — | array of session entries |
| bare | boolean | false | Remove the container border background and use it inline |
| className | string | — | Container additional class |
Events
| Event | Type | Description |
|---|---|---|
| onSelect | (id: string) => void | Click entry callback |
| onDelete | (id: string) => void | Provide a delete button for each rendering (click stopPropagation, onSelect will not be triggered) |
Slots
| Slot | Type | Description |
|---|---|---|
| title | ReactNode | Header title (default "\u5386\u53f2" ("History")) |
| action | ReactNode | Action slot on the right side of the head (such as the "New Conversation" button) |
| empty | ReactNode | Placeholder when items is empty (default "\u6682\u65e0\u5386\u53f2" ("No history")) |
ThreadListItem: { id: string; title: ReactNode; meta?: ReactNode; active?: boolean } (meta is sub-line information, active indicates the currently open session)
Usage Guidelines
activehighlighting is driven by theactivefield on the item and is not maintained internally by the component - the parent needs to calculate and write based on activeId during map.- The delete button is only rendered when
onDeleteis passed; its click has built-in stopPropagation and will not trigger onSelect. - The delete button uses the built-in Chinese accessible label
\u5220\u9664\u4f1a\u8bdd("Delete conversation").
Related
ThinkingBlock · ToolCall · AgentPlan · Dossier · Artifact · ConfirmCard