logoassistant-ui
Radix UI Primitives

ActionBarPrimitive

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.

ActionBarPrimitiveRootProps

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.

hideWhenRunning:

boolean = false

Do 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 attributeValues
[data-floating]

Present when floating

Edit

Enables edit mode on user message.

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

ActionBarPrimitiveEditProps

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.

Reload

Regenerates the assistant message.

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

ActionBarPrimitiveReloadProps

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.

Copy

Copies the message to the clipboard.

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

ActionBarPrimitiveCopyProps

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.

copiedDuration:

number = 3000

The duration in milliseconds to change the message status to 'copied'.

Data attributeValues
[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>
  <AssistantIf condition={({ message }) => !message.isCopied}>
    <CopyIcon />
  </AssistantIf>
  <AssistantIf condition={({ message }) => message.isCopied}>
    <CopySuccessIcon />
  </AssistantIf>
</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.

ActionBarPrimitiveSpeakProps

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.

StopSpeaking

Stops the message text from being played as speech.

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

ActionBarPrimitiveStopSpeakingProps

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.

Feedback Positive

Shows a positive feedback submission button.

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

ActionBarPrimitiveFeedbackPositiveProps

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.

Data attributeValues
[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.

ActionBarPrimitiveFeedbackNegativeProps

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.

Data attributeValues
[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.

ActionBarPrimitiveExportMarkdownProps

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.

filename?:

string

The 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>