Decomposition
Overview
The Styled Components can be decomposed into smaller components. At each level, you can swap out a specific component with your own custom component.
Thread
Renders an entire conversation thread.
import {
Thread,
ThreadWelcome,
Composer,
type ThreadConfig,
} from "@assistant-ui/react-ui";
const MyThread: FC<ThreadConfig> = (config) => {
return (
<Thread.Root config={config}>
<Thread.Viewport>
<ThreadWelcome />
<Thread.Messages />
<Thread.FollowupSuggestions />
<Thread.ViewportFooter>
<Thread.ScrollToBottom />
<Composer />
</Thread.ViewportFooter>
</Thread.Viewport>
</Thread.Root>
);
};
Usage:
<MyThread />
Thread.Root
Contains all parts of the thread. Accepts a config
prop which is used by many other styled components.
Thread.Viewport
The scrollable area containing all messages. Anchors scroll to the bottom as new messages are added.
Thread.Messages
Renders all messages. This renders a separate component for each message (passed to the components
prop).
Thread.ViewportFooter
Renders the footer of the thread viewport. This is the sticky footer that does not scroll with the messages.
Thread.ScrollToBottom
A button to scroll the viewport to the bottom. Hidden when the viewport is already at bottom.
ThreadWelcome
Renders the welcome message when no messages are present.
import { ThreadWelcome } from "@assistant-ui/react-ui";
const MyThreadWelcome: FC = () => {
return (
<ThreadWelcome.Root>
<ThreadWelcome.Center>
<ThreadWelcome.Avatar />
<ThreadWelcome.Message />
</ThreadWelcome.Center>
<ThreadWelcome.Suggestions />
</ThreadWelcome.Root>
);
};
Usage:
Decompose Thread
into MyThread
and use MyThreadWelcome
instead of ThreadWelcome
.
const MyThread: FC<ThreadConfig> = (config) => {
...
<MyThreadWelcome />
...
};
ThreadWelcome.Root
Contains all parts of the welcome message.
ThreadWelcome.Center
The centered content of the welcome message.
ThreadWelcome.Avatar
The avatar of the assistant.
ThreadWelcome.Message
The welcome message.
ThreadWelcome.Suggestions
Conversation starter suggestions.
import { ThreadWelcome } from "@assistant-ui/react-ui";
const MyThreadWelcomeSuggestions: FC = () => {
return (
<div className="aui-thread-welcome-suggestions">
<ThreadWelcome.Suggestion prompt="Write me a poem about the weather" />
<ThreadWelcome.Suggestion prompt="What is assistant-ui?" />
</div>
);
};
ThreadWelcome.Suggestion
A conversation starter suggestion.
Composer
Renders the composer.
import { Composer } from "@assistant-ui/react-ui";
const MyComposer: FC = () => {
return (
<Composer.Root>
<Composer.Attachments />
<Composer.AddAttachment />
<Composer.Input autoFocus />
<Composer.Action />
</Composer.Root>
);
};
Usage:
Decompose Thread
into MyThread
and use MyComposer
instead of Composer
.
const MyThread: FC<ThreadConfig> = (config) => {
...
<MyComposer />
...
};
Composer.Root
Contains all parts of the composer.
Composer.Input
The text input field for the user to type a new message.
Composer.Action
The button to send or cancel the message.
import { Composer, ThreadPrimitive } from "@assistant-ui/react-ui";
const MyComposerAction: FC = () => {
return (
<>
<ThreadPrimitive.If running={false}>
<Composer.Send />
</ThreadPrimitive.If>
<ThreadPrimitive.If running>
<Composer.Cancel />
</ThreadPrimitive.If>
</>
);
};
Composer.Send
The button to send the message.
Composer.Cancel
Sends a cancel action.
Composer.Attachments
Renders attachments.
Composer.AddAttachment
Renders an add attachment button.
AttachmentUI
AttachmentUI
is still experimental.
Renders an attachment.
import { AttachmentUI } from "@assistant-ui/react-ui";
const MyAttachmentUI: FC = () => {
return (
<AttachmentUI.Root>
attachment
<AttachmentUI.Remove />
</AttachmentUI.Root>
);
};
AttachmentUI.Root
Contains all parts of the composer attachment.
AttachmentUI.Remove
Renders a remove attachment button.
AssistantMessage
Renders an assistant message.
import { AssistantMessage } from "@assistant-ui/react-ui";
const MyAssistantMessage: FC = () => {
return (
<AssistantMessage.Root>
<AssistantMessage.Avatar />
<AssistantMessage.Content />
<BranchPicker />
<AssistantActionBar />
</AssistantMessage.Root>
);
};
Usage:
Decompose Thread
into MyThread
and pass MyAssistantMessage
to Thread.MEssages
const MyThread: FC<ThreadConfig> = (config) => {
...
<Thread.Messages components={{ AssistantMessage: MyAssistantMessage }} />
...
};
AssistantMessage.Root
Contains all parts of the assistant message.
AssistantMessage.Avatar
The avatar of the assistant.
AssistantMessage.Content
The content of the assistant message.
AssistantActionBar
Renders the action bar for the assistant message.
import { AssistantActionBar } from "@assistant-ui/react-ui";
const MyAssistantActionBar: FC = () => {
return (
<AssistantActionBar.Root
hideWhenRunning
autohide="not-last"
autohideFloat="single-branch"
>
<AssistantActionBar.SpeechControl />
<AssistantActionBar.Copy />
<AssistantActionBar.Reload />
<AssistantActionBar.FeedbackPositive />
<AssistantActionBar.FeedbackNegative />
</AssistantActionBar.Root>
);
};
Usage:
Decompose AssistantMessage
into MyAssistantMessage
and use MyAssistantActionBar
instead of AssistantActionBar
.
const MyAssistantMessage: FC = () => {
...
<MyAssistantActionBar />
...
};
AssistantActionBar.Root
Contains all parts of the assistant action bar.
AssistantActionBar.Reload
Shows a reload button.
AssistantActionBar.Copy
Shows a copy button.
AssistantActionBar.SpeechControl
Shows a speech control button (either Speak or StopSpeaking).
AssistantActionBar.Speak
Shows a speak button.
AssistantActionBar.StopSpeaking
Shows a stop speaking button.
AssistantActionBar.FeedbackPositive
Shows a positive feedback button.
AssistantActionBar.FeedbackNegative
Shows a negative feedback button.
BranchPicker
Renders the branch picker.
import { BranchPicker } from "@assistant-ui/react-ui";
const MyBranchPicker: FC = () => {
return (
<BranchPicker.Root hideWhenSingleBranch>
<BranchPicker.Previous />
<BranchPicker.State />
<BranchPicker.Next />
</BranchPicker.Root>
);
};
Usage:
Decompose AssistantMessage
and UserMessage
and use MyBranchPicker
instead of BranchPicker
.
const MyAssistantMessage: FC = () => {
...
<MyBranchPicker />
...
};
const MyUserMessage: FC = () => {
...
<MyBranchPicker />
...
};
BranchPicker.Root
Contains all parts of the branch picker.
BranchPicker.Previous
Shows a previous button.
BranchPicker.Next
Shows a next button.
BranchPicker.State
Shows the current branch number and total number of branches.
import { BranchPicker } from "@assistant-ui/react-ui";
const MyBranchPickerState: FC = () => {
return (
<span className="aui-branch-picker-state">
<BranchPicker.Number /> / <BranchPicker.Count />
</span>
);
};
BranchPicker.Number
The current branch number.
BranchPicker.Count
The total number of branches.
UserMessage
Renders a user message.
import { UserMessage } from "@assistant-ui/react-ui";
const MyUserMessage: FC = () => {
return (
<UserMessage.Root>
<UserMessage.Attachments />
<UserMessage.Content />
<UserActionBar />
<BranchPicker />
</UserMessage.Root>
);
};
Usage:
Decompose Thread
into MyThread
and pass MyUserMessage
to Thread.Messages
const MyThread: FC<ThreadConfig> = (config) => {
...
<Thread.Messages components={{ UserMessage: MyUserMessage }} />
...
};
UserMessage.Root
Contains all parts of the user message.
UserMessage.Content
The content of the user message.
UserMessage.Attachments
Renders attachments.
UserActionBar
Renders the action bar for the user message.
import { UserActionBar } from "@assistant-ui/react-ui";
const MyUserActionBar: FC = () => {
return (
<UserActionBar.Root hideWhenRunning autohide="not-last">
<UserActionBar.Edit />
</UserActionBar.Root>
);
};
Usage:
Decompose UserMessage
into MyUserMessage
and use MyUserActionBar
instead of UserActionBar
.
const MyUserMessage: FC = () => {
...
<MyUserActionBar />
...
};
UserActionBar.Root
Contains all parts of the user action bar.
UserActionBar.Edit
Shows an edit button.
UserAttachment
Renders an attachment.
import { UserAttachment } from "@assistant-ui/react-ui";
const MyUserAttachment: FC = () => {
return <UserAttachment.Root>attachment</UserAttachment.Root>;
};
UserAttachment.Root
Contains all parts of the user attachment.
EditComposer
Renders a user message being edited.
import { EditComposer } from "@assistant-ui/react-ui";
const MyEditComposer: FC = () => {
return (
<EditComposer.Root>
<EditComposer.Input />
<EditComposer.Footer>
<EditComposer.Cancel />
<EditComposer.Send />
</EditComposer.Footer>
</EditComposer.Root>
);
};
Usage:
Decompose Thread
into MyThread
and pass MyEditComposer
to Thread.Messages
.
const MyThread: FC<ThreadConfig> = (config) => {
...
<Thread.Messages components={{ EditComposer: MyEditComposer }} />
...
};
EditComposer.Root
Contains all parts of the edit composer.
EditComposer.Input
The text input field for the user to type a new message.
EditComposer.Footer
The footer of the edit composer.
EditComposer.Cancel
Sends a cancel action.
EditComposer.Send
Sends the message.
AssistantModal
Renders the assistant modal.
import {
AssistantModal,
Thread,
type ThreadConfig,
} from "@assistant-ui/react-ui";
const MyAssistantModal: FC<ThreadConfig> = (config) => {
return (
<AssistantModal.Root config={config}>
<AssistantModal.Trigger />
<AssistantModal.Content>
<Thread />
</AssistantModal.Content>
</AssistantModal.Root>
);
};
Usage:
<MyAssistantModal />
ThreadList
Renders a thread list.
import { ThreadList, ThreadListItem } from "@assistant-ui/react-ui";
const MyThreadList = () => {
return (
<ThreadList.Root>
<ThreadList.New />
<ThreadList.Items />
</ThreadList.Root>
);
};
ThreadListItem
Renders a thread list item.
import { ThreadListItem, ThreadListItemPrimitive } from "@assistant-ui/react-ui";
const MyThreadListItem = () => {
return (
<ThreadListItem.Root>
<ThreadListItemTrigger>
<ThreadListItemTitle />
</ThreadListItemTrigger>
<ThreadListItem.Archive />
</ThreadListItem.Root>
);
};