Buttons for message actions like copy, edit, reload, speak, and feedback.
Buttons to interact with the message.
Anatomy
import { ActionBarPrimitive } from "@assistant-ui/react";
const UserMessageBar = () => (
<ActionBarPrimitive.Root>
<ActionBarPrimitive.Edit />
<ActionBarPrimitive.Copy />
</ActionBarPrimitive.Root>
);
const AssistantMessageBar = () => (
<ActionBarPrimitive.Root>
<ActionBarPrimitive.Reload />
<ActionBarPrimitive.Copy />
</ActionBarPrimitive.Root>
);API Reference
Container
Containts all parts of the action bar.
This primitive renders a <div> element unless asChild is set.
ActionBarPrimitiveRootPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
hideWhenRunning: boolean= falseDo not render the ActionBar when the thread is in running state.
autohide: "always" | "not-last" | "never"= "never"Do not render the ActionBar unless the mouse is hovering over the message."always": always autohide."not-last"; only autohide if the message is not the last one in the thread.
autohideFloat: "always" | "single-branch" | "never"= "never"Float the ActionBar during autohide."always": always float during autohide."single-branch": only float if the message is the only one in the thread.
Note: this only sets `data-floating` on the ActionBar. You need to set the appropriate styles on the ActionBar to make it float.
| Data attribute | Values |
|---|---|
[data-floating] | Present when floating |
Edit
Enables edit mode on user message.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveEditPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
Reload
Regenerates the assistant message.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveReloadPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
Copy
Copies the message to the clipboard.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveCopyPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
copiedDuration: number= 3000The duration in milliseconds to change the message status to 'copied'.
| Data attribute | Values |
|---|---|
[data-copied] | Present when the message was recently copied. |
Copied state
Show a different icon for a few seconds after the message is copied.
<ActionBarPrimitive.Copy>
<AuiIf condition={(s) => !s.message.isCopied}>
<CopyIcon />
</AuiIf>
<AuiIf condition={(s) => s.message.isCopied}>
<CopySuccessIcon />
</AuiIf>
</ActionBarPrimitive.Copy>or using the data-copied attribute:
<ActionBarPrimitive.Copy className="group">
<CopyIcon className="group-data-[copied]:hidden" />
<CheckIcon className="hidden group-data-[copied]:block" />
</ActionBarPrimitive.Copy>Speak
Plays the message text as speech.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveSpeakPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
StopSpeaking
Stops the message text from being played as speech.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveStopSpeakingPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
Feedback Positive
Shows a positive feedback submission button.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveFeedbackPositivePropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
| Data attribute | Values |
|---|---|
[data-submitted] | Present when positive feedback was submitted. |
Feedback Negative
Shows a negative feedback submission button.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveFeedbackNegativePropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
| Data attribute | Values |
|---|---|
[data-submitted] | Present when negative feedback was submitted. |
ExportMarkdown
Exports the message content as a Markdown file download by default, or calls a custom export handler when onExport is provided.
This primitive renders a <button> element unless asChild is set.
ActionBarPrimitiveExportMarkdownPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.
filename?: stringThe filename for the downloaded Markdown file. Defaults to 'message-{timestamp}.md'. Ignored when onExport is provided.
onExport?: (content: string) => void | Promise<void>Optional callback function that receives the message content. When provided, overrides the default Markdown download behavior. Use this to implement custom export logic (PDF, JSON, TXT, etc.).
Examples
Default Markdown export:
<ActionBarPrimitive.ExportMarkdown>
<DownloadIcon />
Export as Markdown
</ActionBarPrimitive.ExportMarkdown>With custom filename:
<ActionBarPrimitive.ExportMarkdown filename="chat-response.md">
<DownloadIcon />
Download
</ActionBarPrimitive.ExportMarkdown>Export as PDF (with custom logic):
<ActionBarPrimitive.ExportMarkdown
onExport={async (content) => {
const pdf = await generatePdf(content);
downloadFile(pdf, "message.pdf");
}}
>
<FileIcon />
Export PDF
</ActionBarPrimitive.ExportMarkdown>Export as JSON:
<ActionBarPrimitive.ExportMarkdown
onExport={(content) => {
const json = JSON.stringify({ content, timestamp: Date.now() });
const blob = new Blob([json], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "message.json";
a.click();
URL.revokeObjectURL(url);
}}
>
<CodeIcon />
Export JSON
</ActionBarPrimitive.ExportMarkdown>