primitives
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseassistant-ui Primitives
assistant-ui UI基元
Always consult assistant-ui.com/llms.txt for latest API.
Composable, unstyled components following Radix UI patterns.
请始终参考assistant-ui.com/llms.txt获取最新API。
遵循Radix UI模式的可组合、无样式组件。
References
参考资料
- ./references/thread.md -- ThreadPrimitive deep dive
- ./references/composer.md -- ComposerPrimitive deep dive
- ./references/message.md -- MessagePrimitive deep dive
- ./references/action-bar.md -- ActionBarPrimitive deep dive
- ./references/thread.md -- ThreadPrimitive 深度解析
- ./references/composer.md -- ComposerPrimitive 深度解析
- ./references/message.md -- MessagePrimitive 深度解析
- ./references/action-bar.md -- ActionBarPrimitive 深度解析
Import
导入
tsx
import {
ThreadPrimitive,
ComposerPrimitive,
MessagePrimitive,
ActionBarPrimitive,
BranchPickerPrimitive,
AttachmentPrimitive,
ThreadListPrimitive,
ThreadListItemPrimitive,
} from "@assistant-ui/react";tsx
import {
ThreadPrimitive,
ComposerPrimitive,
MessagePrimitive,
ActionBarPrimitive,
BranchPickerPrimitive,
AttachmentPrimitive,
ThreadListPrimitive,
ThreadListItemPrimitive,
} from "@assistant-ui/react";Primitive Parts
基元组件组成部分
| Primitive | Key Parts |
|---|---|
| |
| |
| |
| |
| |
| 基元组件 | 核心组成 |
|---|---|
| |
| |
| |
| |
| |
Custom Thread Example
自定义对话线程示例
tsx
function CustomThread() {
return (
<ThreadPrimitive.Root className="flex flex-col h-full">
<ThreadPrimitive.Empty>
<div className="flex-1 flex items-center justify-center">
Start a conversation
</div>
</ThreadPrimitive.Empty>
<ThreadPrimitive.Viewport className="flex-1 overflow-y-auto p-4">
<ThreadPrimitive.Messages components={{
UserMessage: CustomUserMessage,
AssistantMessage: CustomAssistantMessage,
}} />
</ThreadPrimitive.Viewport>
<ComposerPrimitive.Root className="border-t p-4 flex gap-2">
<ComposerPrimitive.Input className="flex-1 rounded-lg border px-4 py-2" />
<ComposerPrimitive.Send className="bg-blue-500 text-white px-4 py-2 rounded-lg">
Send
</ComposerPrimitive.Send>
</ComposerPrimitive.Root>
</ThreadPrimitive.Root>
);
}tsx
function CustomThread() {
return (
<ThreadPrimitive.Root className="flex flex-col h-full">
<ThreadPrimitive.Empty>
<div className="flex-1 flex items-center justify-center">
Start a conversation
</div>
</ThreadPrimitive.Empty>
<ThreadPrimitive.Viewport className="flex-1 overflow-y-auto p-4">
<ThreadPrimitive.Messages components={{
UserMessage: CustomUserMessage,
AssistantMessage: CustomAssistantMessage,
}} />
</ThreadPrimitive.Viewport>
<ComposerPrimitive.Root className="border-t p-4 flex gap-2">
<ComposerPrimitive.Input className="flex-1 rounded-lg border px-4 py-2" />
<ComposerPrimitive.Send className="bg-blue-500 text-white px-4 py-2 rounded-lg">
Send
</ComposerPrimitive.Send>
</ComposerPrimitive.Root>
</ThreadPrimitive.Root>
);
}Conditional Rendering
条件渲染
tsx
<MessagePrimitive.If user>User only</MessagePrimitive.If>
<MessagePrimitive.If assistant>Assistant only</MessagePrimitive.If>
<MessagePrimitive.If running>Generating...</MessagePrimitive.If>
<MessagePrimitive.If hasBranches>Has edit history</MessagePrimitive.If>
<ComposerPrimitive.If submitting>
<ComposerPrimitive.Cancel>Stop</ComposerPrimitive.Cancel>
</ComposerPrimitive.If>
<ThreadPrimitive.If empty>No messages</ThreadPrimitive.If>tsx
<MessagePrimitive.If user>User only</MessagePrimitive.If>
<MessagePrimitive.If assistant>Assistant only</MessagePrimitive.If>
<MessagePrimitive.If running>Generating...</MessagePrimitive.If>
<MessagePrimitive.If hasBranches>Has edit history</MessagePrimitive.If>
<ComposerPrimitive.If submitting>
<ComposerPrimitive.Cancel>Stop</ComposerPrimitive.Cancel>
</ComposerPrimitive.If>
<ThreadPrimitive.If empty>No messages</ThreadPrimitive.If>Content Parts
内容组件部分
tsx
<MessagePrimitive.Content components={{
Text: ({ part }) => <p>{part.text}</p>,
Image: ({ part }) => <img src={part.image} alt="" />,
ToolCall: ({ part }) => <div>Tool: {part.toolName}</div>,
Reasoning: ({ part }) => <details><summary>Thinking</summary>{part.text}</details>,
}} />tsx
<MessagePrimitive.Content components={{
Text: ({ part }) => <p>{part.text}</p>,
Image: ({ part }) => <img src={part.image} alt="" />,
ToolCall: ({ part }) => <div>Tool: {part.toolName}</div>,
Reasoning: ({ part }) => <details><summary>Thinking</summary>{part.text}</details>,
}} />Branch Picker
分支选择器
tsx
<MessagePrimitive.If hasBranches>
<BranchPickerPrimitive.Root className="flex items-center gap-1">
<BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
<span><BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count /></span>
<BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
</BranchPickerPrimitive.Root>
</MessagePrimitive.If>tsx
<MessagePrimitive.If hasBranches>
<BranchPickerPrimitive.Root className="flex items-center gap-1">
<BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
<span><BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count /></span>
<BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
</BranchPickerPrimitive.Root>
</MessagePrimitive.If>Common Gotchas
常见问题
Primitives not rendering
- Wrap in
AssistantRuntimeProvider - Ensure parent primitive provides context
Styles not applying
- Primitives are unstyled by default
- Add className or use
@assistant-ui/styles
基元组件未渲染
- 包裹在中
AssistantRuntimeProvider - 确保父级基元组件提供上下文
样式未生效
- 基元组件默认无样式
- 添加className或使用
@assistant-ui/styles