logoassistant-ui
Primitives

Composer

The user interface to add new messages or edit existing ones.

Dual Use! A Composer placed directly inside a Thread will compose new messages. A Composer placed inside a Message will edit that message.

Anatomy

import { ComposerPrimitive } from "@assistant-ui/react";
 
// creating a new message
const Composer = () => (
  <ComposerPrimitive.Root>
    <ComposerPrimitive.Attachments />
    <ComposerPrimitive.AddAttachment />
    <ComposerPrimitive.Input />
    <ComposerPrimitive.Send />
  </ComposerPrimitive.Root>
);
 
// editing an existing message
const EditComposer = () => (
  <ComposerPrimitive.Root>
    <ComposerPrimitive.Input />
    <ComposerPrimitive.Send />
    <ComposerPrimitive.Cancel />
  </ComposerPrimitive.Root>
);

API Reference

Root

Containts all parts of the composer.

This primitive renders a <form> element unless asChild is set.

ComposerRootProps

asChild:

boolean = false

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

useComposerSend

import { useComposerSend } from "@assistant-ui/react";
 
const Send = () => {
  const send = useComposerSend();
 
  const handleSubmit = (e: FormEvent) => {
    // send action is not available
    if (!send) return;
 
    e.preventDefault();
    send();
  };
 
  return <form onSubmit={handleSubmit}>...</form>;
};

Input

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

This primitive renders a <textarea> element unless asChild is set.

ComposerPrimitiveInputProps

asChild:

boolean = false

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

Keyboard Shortcuts

KeyDescription
Enter
Sends the message.
Escape
Sends a cancel action.

Send

The button to send the message.

This primitive renders a <button> element unless asChild is set.

ComposerPrimitiveSendProps

asChild:

boolean = false

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

Cancel

Sends a cancel action.

In edit composers, this action exits the edit mode.
In thread composers, this action stops the current run.

This primitive renders a <button> element unless asChild is set.

ComposerPrimitiveCancelProps

asChild:

boolean = false

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

useComposerCancel

import { useComposerCancel } from "@assistant-ui/react";
 
const Cancel = () => {
  const cancel = useComposerCancel();
 
  // cancel action is not available
  if (!cancel) return null;
 
  return <button onClick={cancel}>Cancel</button>;
};

Attachments

Renders attachments. This primitive renders a separate component for each attachment.

ComposerPrimitiveAttachmentsProps

components?:

ComposerAttachmentsComponents

The component to render for each attachment.

ComposerPrimitiveAttachmentsProps['components']

Image?:

ComponentType

The component to render for each image attachment.

Document?:

ComponentType

The component to render for each document attachment.

File?:

ComponentType

The component to render for each file attachment.

Fallback?:

ComponentType

The component to render for each attachment type.

AddAttachment

Renders a button to add an attachment.

This primitive renders a <button> element unless asChild is set.

ComposerPrimitiveAddAttachmentProps

asChild:

boolean = false

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

If

Renders children if a condition is met.

UseComposerIfProps

editing?:

boolean | undefined

Render children if the message is being edited.

<Composer.If editing>{/* rendered if message is being edited */}</Composer.If>

useComposerIf

import { useComposerIf } from "@assistant-ui/react";
 
const Composer = () => {
  const isEditing = useComposerIf((c) => c.isEditing);
 
  return isEditing ? <Editing /> : <NotEditing />;
};

On this page

Edit on Github