# Decomposition
URL: /docs/legacy/styled/decomposition

Break down styled components into smaller customizable parts.

Overview \[#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 \[#thread]

Renders an entire conversation thread.

```tsx
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:**

```ts
<MyThread />
```

Thread.Root \[#threadroot]

Contains all parts of the thread. Accepts a `config` prop which is used by many other styled components.

Thread.Viewport \[#threadviewport]

The scrollable area containing all messages. Anchors scroll to the bottom as new messages are added.

Thread.Messages \[#threadmessages]

Renders all messages. This renders a separate component for each message (passed to the `components` prop).

Thread.ViewportFooter \[#threadviewportfooter]

Renders the footer of the thread viewport. This is the sticky footer that does not scroll with the messages.

Thread.ScrollToBottom \[#threadscrolltobottom]

A button to scroll the viewport to the bottom. Hidden when the viewport is already at bottom.

ThreadWelcome \[#threadwelcome]

Renders the welcome message when no messages are present.

```tsx
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`.

```ts
const MyThread: FC<ThreadConfig> = (config) => {
  ...
  <MyThreadWelcome />
  ...
};
```

ThreadWelcome.Root \[#threadwelcomeroot]

Contains all parts of the welcome message.

ThreadWelcome.Center \[#threadwelcomecenter]

The centered content of the welcome message.

ThreadWelcome.Avatar \[#threadwelcomeavatar]

The avatar of the assistant.

ThreadWelcome.Message \[#threadwelcomemessage]

The welcome message.

ThreadWelcome.Suggestions \[#threadwelcomesuggestions]

Conversation starter suggestions.

```tsx
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 \[#threadwelcomesuggestion]

A conversation starter suggestion.

Composer \[#composer]

Renders the composer.

```tsx
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`.

```ts
const MyThread: FC<ThreadConfig> = (config) => {
  ...
  <MyComposer />
  ...
};
```

Composer.Root \[#composerroot]

Contains all parts of the composer.

Composer.Input \[#composerinput]

The text input field for the user to type a new message.

Composer.Action \[#composeraction]

The button to send or cancel the message.

```tsx
import { Composer } from "@assistant-ui/react-ui";
import { AuiIf } from "@assistant-ui/react";

const MyComposerAction: FC = () => {
  return (
    <>
      <AuiIf condition={(s) => !s.thread.isRunning}>
        <Composer.Send />
      </AuiIf>
      <AuiIf condition={(s) => s.thread.isRunning}>
        <Composer.Cancel />
      </AuiIf>
    </>
  );
};
```

Composer.Send \[#composersend]

The button to send the message.

Composer.Cancel \[#composercancel]

Sends a cancel action.

Composer.Attachments \[#composerattachments]

Renders attachments.

Composer.AddAttachment \[#composeraddattachment]

Renders an add attachment button.

AttachmentUI \[#attachmentui]

<Callout type="info" emoji="💡">
  `AttachmentUI` is still experimental.
</Callout>

Renders an attachment.

```tsx
import { AttachmentUI } from "@assistant-ui/react-ui";

const MyAttachmentUI: FC = () => {
  return (
    <AttachmentUI.Root>
      attachment
      <AttachmentUI.Remove />
    </AttachmentUI.Root>
  );
};
```

AttachmentUI.Root \[#attachmentuiroot]

Contains all parts of the composer attachment.

AttachmentUI.Remove \[#attachmentuiremove]

Renders a remove attachment button.

AssistantMessage \[#assistantmessage]

Renders an assistant message.

```tsx
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

```ts
const MyThread: FC<ThreadConfig> = (config) => {
  ...
  <Thread.Messages components={{ AssistantMessage: MyAssistantMessage }} />
  ...
};
```

AssistantMessage.Root \[#assistantmessageroot]

Contains all parts of the assistant message.

AssistantMessage.Avatar \[#assistantmessageavatar]

The avatar of the assistant.

AssistantMessage.Content \[#assistantmessagecontent]

The content of the assistant message.

AssistantActionBar \[#assistantactionbar]

Renders the action bar for the assistant message.

```tsx
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`.

```ts
const MyAssistantMessage: FC = () => {
  ...
  <MyAssistantActionBar />
  ...
};
```

AssistantActionBar.Root \[#assistantactionbarroot]

Contains all parts of the assistant action bar.

AssistantActionBar.Reload \[#assistantactionbarreload]

Shows a reload button.

AssistantActionBar.Copy \[#assistantactionbarcopy]

Shows a copy button.

AssistantActionBar.SpeechControl \[#assistantactionbarspeechcontrol]

Shows a speech control button (either Speak or StopSpeaking).

AssistantActionBar.Speak \[#assistantactionbarspeak]

Shows a speak button.

AssistantActionBar.StopSpeaking \[#assistantactionbarstopspeaking]

Shows a stop speaking button.

AssistantActionBar.FeedbackPositive \[#assistantactionbarfeedbackpositive]

Shows a positive feedback button.

AssistantActionBar.FeedbackNegative \[#assistantactionbarfeedbacknegative]

Shows a negative feedback button.

BranchPicker \[#branchpicker]

Renders the branch picker.

```tsx
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`.

```ts
const MyAssistantMessage: FC = () => {
  ...
  <MyBranchPicker />
  ...
};
```

```ts
const MyUserMessage: FC = () => {
  ...
  <MyBranchPicker />
  ...
};
```

BranchPicker.Root \[#branchpickerroot]

Contains all parts of the branch picker.

BranchPicker.Previous \[#branchpickerprevious]

Shows a previous button.

BranchPicker.Next \[#branchpickernext]

Shows a next button.

BranchPicker.State \[#branchpickerstate]

Shows the current branch number and total number of branches.

```tsx
import { BranchPicker } from "@assistant-ui/react-ui";

const MyBranchPickerState: FC = () => {
  return (
    <span className="aui-branch-picker-state">
      <BranchPicker.Number /> / <BranchPicker.Count />
    </span>
  );
};
```

BranchPicker.Number \[#branchpickernumber]

The current branch number.

BranchPicker.Count \[#branchpickercount]

The total number of branches.

UserMessage \[#usermessage]

Renders a user message.

```tsx
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

```ts
const MyThread: FC<ThreadConfig> = (config) => {
  ...
  <Thread.Messages components={{ UserMessage: MyUserMessage }} />
  ...
};
```

UserMessage.Root \[#usermessageroot]

Contains all parts of the user message.

UserMessage.Content \[#usermessagecontent]

The content of the user message.

UserMessage.Attachments \[#usermessageattachments]

Renders attachments.

UserActionBar \[#useractionbar]

Renders the action bar for the user message.

```tsx
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`.

```ts
const MyUserMessage: FC = () => {
  ...
  <MyUserActionBar />
  ...
};
```

UserActionBar.Root \[#useractionbarroot]

Contains all parts of the user action bar.

UserActionBar.Edit \[#useractionbaredit]

Shows an edit button.

UserAttachment \[#userattachment]

Renders an attachment.

```tsx
import { UserAttachment } from "@assistant-ui/react-ui";

const MyUserAttachment: FC = () => {
  return <UserAttachment.Root>attachment</UserAttachment.Root>;
};
```

UserAttachment.Root \[#userattachmentroot]

Contains all parts of the user attachment.

EditComposer \[#editcomposer]

Renders a user message being edited.

```tsx
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`.

```ts
const MyThread: FC<ThreadConfig> = (config) => {
  ...
  <Thread.Messages components={{ EditComposer: MyEditComposer }} />
  ...
};
```

EditComposer.Root \[#editcomposerroot]

Contains all parts of the edit composer.

EditComposer.Input \[#editcomposerinput]

The text input field for the user to type a new message.

EditComposer.Footer \[#editcomposerfooter]

The footer of the edit composer.

EditComposer.Cancel \[#editcomposercancel]

Sends a cancel action.

EditComposer.Send \[#editcomposersend]

Sends the message.

AssistantModal \[#assistantmodal]

Renders the assistant modal.

```tsx
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:**

```ts
<MyAssistantModal />
```

ThreadList \[#threadlist]

Renders a thread list.

```tsx
import { ThreadList, ThreadListItem } from "@assistant-ui/react-ui";

const MyThreadList = () => {
  return (
    <ThreadList.Root>
      <ThreadList.New />
      <ThreadList.Items />
    </ThreadList.Root>
  );
};
```

ThreadListItem \[#threadlistitem]

Renders a thread list item.

```tsx
import { ThreadListItem, ThreadListItemPrimitive } from "@assistant-ui/react-ui";

const MyThreadListItem = () => {
  return (
    <ThreadListItem.Root>
      <ThreadListItemTrigger>
        <ThreadListItemTitle />
      </ThreadListItemTrigger>
      <ThreadListItem.Archive />
    </ThreadListItem.Root>
  );
};
```
