ThreadList プリミティブは、スレッドの一覧表示、新規スレッドの作成、スレッド間の切り替え、古いスレッドのアーカイブ化と削除を行うことで、複数の会話を管理します。
assistant-ui 入門 : プリミティブ – ThreadList
作成 : Masashi Okumura (@classcat.com)
作成日時 : 04/03/2026
バージョン : assistant-ui@0.0.87
* 本記事は assistant-ui.com/docs の以下のページを参考にしています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
assistant-ui 入門 : プリミティブ – ThreadList
会話の一覧表示、作成、切り替え、アーカイブ化、削除を行うためのマルチスレッド管理機能。
ThreadList プリミティブは、スレッドの一覧表示、新規スレッドの作成、スレッド間の切り替え、古いスレッドのアーカイブ化と削除を行うことで、複数の会話を管理します。それは 3 つのプリミティブな名前空間から構成されています: ThreadListPrimitive, ThreadListItemPrimitive, ThreadListItemMorePrimitive.
Preview

Code
import {
ThreadListPrimitive,
ThreadListItemPrimitive,
ThreadListItemMorePrimitive,
} from "@assistant-ui/react";
import { ArchiveIcon, MoreHorizontalIcon, PlusIcon, TrashIcon } from "lucide-react";
function MyThreadList() {
return (
<ThreadListPrimitive.Root className="flex flex-col gap-1">
<ThreadListPrimitive.New className="flex h-9 items-center gap-2 rounded-lg border px-3 text-sm hover:bg-muted">
<PlusIcon className="size-4" />
New Thread
</ThreadListPrimitive.New>
<ThreadListPrimitive.Items>
{() => <ThreadListItem />}
</ThreadListPrimitive.Items>
</ThreadListPrimitive.Root>
);
}
function ThreadListItem() {
return (
<ThreadListItemPrimitive.Root className="group flex h-9 items-center rounded-lg hover:bg-muted data-active:bg-muted">
<ThreadListItemPrimitive.Trigger className="flex-1 truncate px-3 text-sm">
<ThreadListItemPrimitive.Title fallback="New Chat" />
</ThreadListItemPrimitive.Trigger>
<ThreadListItemMorePrimitive.Root>
<ThreadListItemMorePrimitive.Trigger className="mr-2 size-7 rounded-md opacity-0 group-hover:opacity-100">
<MoreHorizontalIcon className="size-4" />
</ThreadListItemMorePrimitive.Trigger>
<ThreadListItemMorePrimitive.Content className="rounded-md border bg-popover p-1 shadow-md">
<ThreadListItemPrimitive.Archive asChild>
<ThreadListItemMorePrimitive.Item className="flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent">
<ArchiveIcon className="size-4" /> Archive
</ThreadListItemMorePrimitive.Item>
</ThreadListItemPrimitive.Archive>
<ThreadListItemPrimitive.Delete asChild>
<ThreadListItemMorePrimitive.Item className="flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-destructive/10">
<TrashIcon className="size-4" /> Delete
</ThreadListItemMorePrimitive.Item>
</ThreadListItemPrimitive.Delete>
</ThreadListItemMorePrimitive.Content>
</ThreadListItemMorePrimitive.Root>
</ThreadListItemPrimitive.Root>
);
}
クイックスタート
最小限の例:
import {
ThreadListPrimitive,
ThreadListItemPrimitive,
} from "@assistant-ui/react";
<ThreadListPrimitive.Root>
<ThreadListPrimitive.New>New Thread</ThreadListPrimitive.New>
<ThreadListPrimitive.Items>
{() => (
<ThreadListItemPrimitive.Root>
<ThreadListItemPrimitive.Trigger>
<ThreadListItemPrimitive.Title fallback="New Chat" />
</ThreadListItemPrimitive.Trigger>
</ThreadListItemPrimitive.Root>
)}
</ThreadListPrimitive.Items>
</ThreadListPrimitive.Root>
Root は <div> をレンダリングし、New は新しいスレッドを作成する <button> をレンダリングし、Items はスレッドリストに対して反復処理します。各アイテムは ThreadListItemPrimitive パーツで構成されています。
ℹ️ ランタイム・セットアップ: プリミティブはランタイム・コンテキストを必要とします。UI をランタイム (例えば useLocalRuntime(…)) を持つ AssistantRuntimeProvider でラップします。See Pick a Runtime.
基本概念
3 つの名前空間
ThreadList は、各々の構成可能な抽象化レベルを維持するために、3 つの名前空間に分割されています :
- ThreadListPrimitive: 外側のコンテナ。Root はリストをラップし、New はスレッドを作成し、Items はそれらを反復処理します。
- ThreadListItemPrimitive: 個々のスレッド行。Root はコンテキストを提供し、Trigger はスレッドを切り替え、Title はスレッド名を表示し、アクションボタン (Archive, Unarchive, Delete) はスレッドのライフサイクルを管理します。
- ThreadListItemMorePrimitive: スレッドアクション用の (Radix DropdownMenu 上に構築された) オーバーフロー・ドロップダウンメニュー。asChild を使用して、アクションボタンをメニューアイテムと組み合わせます。
アクティブ状態
ThreadListPrimitive.New と ThreadListItemPrimitive.Root の両方は、現在のスレッドを表す際に data-active 属性を取得します。これをスタイリングに利用します :
<ThreadListItemPrimitive.Root className="hover:bg-muted data-active:bg-muted">
{/* ... */}
</ThreadListItemPrimitive.Root>
New ボタンは、ユーザが新しい保存されていないスレッドを開いている場合、data-active 属性を取得します。
アイテム・イテレータ
ThreadListPrimitive.Items は、ThreadPrimitive.Messages と同様に、children レンダリング関数を優先するようになりました :
<ThreadListPrimitive.Items>
{({ threadListItem }) => (
<MyThreadItem threadId={threadListItem.id} />
)}
</ThreadListPrimitive.Items>
ℹ️ components is deprecated. Use the children render function instead.
アーカイブされたスレッド
archived を Items に渡して、アーカイブされたスレッドを個別にレンダリングします :
<ThreadListPrimitive.Root>
<ThreadListPrimitive.New>New Thread</ThreadListPrimitive.New>
<ThreadListPrimitive.Items>
{() => <ThreadListItem />}
</ThreadListPrimitive.Items>
<h3>Archived</h3>
<ThreadListPrimitive.Items archived>
{() => <ArchivedThreadItem />}
</ThreadListPrimitive.Items>
</ThreadListPrimitive.Root>
スレッドアクション
Archive, Unarchive, と Delete ボタンは、ランタイム機能が利用できない場合、自動的に無効にされます。
パーツ (部品)
ThreadListPrimitive
Root
完全なスレッドリストのためのコンテナ。asChild が設定されていない限り、<div> 要素をレンダリングします。
<ThreadListPrimitive.Root className="flex flex-col gap-1">
<ThreadListPrimitive.Items>
{() => <MyThreadItem />}
</ThreadListPrimitive.Items>
</ThreadListPrimitive.Root>
New
新しいスレッドを作成するボタン。asChild が設定されていない限り、<button> 要素をレンダリングします。
<ThreadListPrimitive.New className="rounded-lg border px-3 py-2 text-sm">
New Thread
</ThreadListPrimitive.New>
Items
スレッド毎にコンポーネントをレンダリングします。
<ThreadListPrimitive.Items>
{() => <MyThreadItem />}
</ThreadListPrimitive.Items>
ThreadListItemPrimitive
Root
スレッドリストの一つのアイテムのためのコンテナ。asChild が設定されていない限り、<div> 要素をレンダリングします。
<ThreadListItemPrimitive.Root className="flex items-center gap-2 rounded-lg px-2 py-1.5">
<ThreadListItemPrimitive.Trigger className="flex-1 text-left">
<ThreadListItemPrimitive.Title fallback="New Chat" />
</ThreadListItemPrimitive.Trigger>
</ThreadListItemPrimitive.Root>
Trigger
スレッドを選択するインタラクティブなボタン。asChild が設定されていない限り、<button> 要素をレンダリングします。
<ThreadListItemPrimitive.Trigger className="flex-1 text-left">
<ThreadListItemPrimitive.Title fallback="New Chat" />
</ThreadListItemPrimitive.Trigger>
Title
fallback prop を持つスレッドタイトルを表示します。React フラグメントをレンダリングします (ラッパー要素はありません)。スタイルを適用する必要がある場合は、ラッパーを使用してください。
<ThreadListItemPrimitive.Title fallback="New Chat" />
Archive
現在のスレッドアイテムをアーカイブするボタン。asChild が設定されていない限り、<button> 要素をレンダリングします。
<ThreadListItemPrimitive.Archive>Archive</ThreadListItemPrimitive.Archive>
Unarchive
現在のスレッドアイテムをアーカイブから復元するボタン。asChild が設定されていない限り、<button> 要素をレンダリングします。
<ThreadListItemPrimitive.Unarchive>Unarchive</ThreadListItemPrimitive.Unarchive>
Delete
現在のスレッドアイテムを削除するボタン。asChild が設定されていない限り、<button> 要素をレンダリングします。
<ThreadListItemPrimitive.Delete>Delete</ThreadListItemPrimitive.Delete>
ThreadListItemMorePrimitive
Root
オーバーフローメニューのプリミティブのための Root コンテナ。
<ThreadListItemMorePrimitive.Root>
<ThreadListItemMorePrimitive.Trigger>More</ThreadListItemMorePrimitive.Trigger>
</ThreadListItemMorePrimitive.Root>
Trigger
オーバーフローメニューを開くボタン。asChild が設定されていない限り、<button> 要素をレンダリングします。
<ThreadListItemMorePrimitive.Trigger className="rounded-md p-1 hover:bg-muted">
More
</ThreadListItemMorePrimitive.Trigger>
Content
ドロップダウンパネル。ポータルを介して <div> をレンダリングします (トリガーへの相対位置で配置)。
<ThreadListItemMorePrimitive.Content className="rounded-md border bg-popover p-1 shadow-md">
<ThreadListItemPrimitive.Archive asChild>
<ThreadListItemMorePrimitive.Item>Archive</ThreadListItemMorePrimitive.Item>
</ThreadListItemPrimitive.Archive>
</ThreadListItemMorePrimitive.Content>
パターン
New ボタンを備えた基本的なスレッドリスト
<ThreadListPrimitive.Root className="flex flex-col gap-1">
<ThreadListPrimitive.New className="flex items-center gap-2 rounded-lg border px-3 py-2 text-sm">
<PlusIcon className="size-4" /> New Thread
</ThreadListPrimitive.New>
<ThreadListPrimitive.Items>
{() => <ThreadListItem />}
</ThreadListPrimitive.Items>
</ThreadListPrimitive.Root>
以上