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#
Root#
Contains all parts of the action bar.
This primitive renders a <div> element unless asChild is set.
<ParametersTable
type="ActionBarPrimitiveRootProps"
parameters={[
{
name: "asChild",
},
{
name: "hideWhenRunning",
type: "boolean",
default: "false",
description: (
Do not render the ActionBar when the thread is in running state.
),
},
{
name: "autohide",
type: '"always" | "not-last" | "never"',
default: '"never"',
description: (
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.
),
},
{
name: "autohideFloat",
type: '"always" | "single-branch" | "never"',
default: '"never"',
description: (
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.
<ParametersTable
type="ActionBarPrimitiveEditProps"
parameters={[
{
name: "asChild",
},
]}
/>
Reload#
Regenerates the assistant message.
This primitive renders a <button> element unless asChild is set.
<ParametersTable
type="ActionBarPrimitiveReloadProps"
parameters={[
{
name: "asChild",
},
]}
/>
Copy#
Copies the message to the clipboard.
This primitive renders a <button> element unless asChild is set.
<ParametersTable
type="ActionBarPrimitiveCopyProps"
parameters={[
{
name: "asChild",
},
{
name: "copiedDuration",
type: "number",
description:
"The duration in milliseconds to change the message status to 'copied'.",
default: "3000",
},
]}
/>
| 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.
<ParametersTable
type="ActionBarPrimitiveSpeakProps"
parameters={[
{
name: "asChild",
},
]}
/>
StopSpeaking#
Stops the message text from being played as speech.
This primitive renders a <button> element unless asChild is set.
<ParametersTable
type="ActionBarPrimitiveStopSpeakingProps"
parameters={[
{
name: "asChild",
},
]}
/>
Feedback Positive#
Shows a positive feedback submission button.
This primitive renders a <button> element unless asChild is set.
<ParametersTable
type="ActionBarPrimitiveFeedbackPositiveProps"
parameters={[
{
name: "asChild",
},
]}
/>
| 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.
<ParametersTable
type="ActionBarPrimitiveFeedbackNegativeProps"
parameters={[
{
name: "asChild",
},
]}
/>
| 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.
<ParametersTable
type="ActionBarPrimitiveExportMarkdownProps"
parameters={[
{
name: "asChild",
},
{
name: "filename",
type: "string",
description:
"The filename for the downloaded Markdown file. Defaults to 'message-{timestamp}.md'. Ignored when onExport is provided.",
},
{
name: "onExport",
type: "(content: string) => void | Promise",
description:
"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>