# ActionBar
URL: /docs/primitives/action-bar
Build message action buttons with auto-hide, copy state, and intelligent disabling.
The ActionBar primitive provides message actions: copy, reload, edit, feedback, speech, and export. It handles intelligent visibility with auto-hide on hover, automatic disabling based on message state, and floating behavior. You compose the buttons; the primitive handles action state and availability.
```tsx
import {
ActionBarPrimitive,
MessagePrimitive,
} from "@assistant-ui/react";
import { CheckIcon, CopyIcon, RefreshCwIcon } from "lucide-react";
function AssistantMessage() {
return (
);
}
```
Quick Start \[#quick-start]
A minimal action bar with copy and reload:
```tsx
import { ActionBarPrimitive } from "@assistant-ui/react";
Copy
Reload
```
`Root` renders a `
`, action buttons render `
` elements. Each button auto-disables when its action isn't available (e.g., Copy is disabled when there's no content, Reload is disabled while the model is running).
ActionBar must be placed inside a `MessagePrimitive.Root` because it reads message state from the nearest message context.
Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRuntimeProvider` with a runtime (for example `useLocalRuntime(...)`). See [Pick a Runtime](/docs/runtimes/pick-a-runtime).
Core Concepts \[#core-concepts]
Auto-Hide & Floating \[#auto-hide--floating]
The `autohide` prop controls when the action bar is visible:
* **`"never"`** (default): always visible
* **`"not-last"`**: hidden on all messages except the last, shown on hover
* **`"always"`**: hidden on all messages, shown on hover
When `autohideFloat` is set, hidden action bars get the `data-floating` attribute instead of being removed from the DOM. This lets you animate them with CSS:
```tsx
{/* buttons */}
```
The `"single-branch"` option for `autohideFloat` only floats when the message has a single branch (no alternatives).
Automatic Disabling \[#automatic-disabling]
Action buttons automatically disable based on state, with no manual wiring needed:
* **Copy**: disabled when there's no copyable text content or an assistant message is still running
* **Reload**: disabled when the thread is running or the message role isn't assistant
* **Edit**: disabled when the message is already being edited
* **Speak**: disabled when there's no speakable text or an assistant message is still running
Copy State \[#copy-state]
After clicking Copy, the button gets a `data-copied` attribute for a configurable duration (default 3 seconds). Use this for visual feedback:
```tsx
```
Feedback Buttons \[#feedback-buttons]
Feedback buttons track submission state with `data-submitted`:
```tsx
👍
👎
```
Parts \[#parts]
Root \[#root]
Container with auto-hide and floating behavior. Renders a `` element unless `asChild` is set.
```tsx
Copy
Reload
```
Copy \[#copy]
Copies message text to clipboard. Renders a `
` element unless `asChild` is set.
```tsx
```
Reload \[#reload]
Reloads or regenerates the current assistant message. Renders a `` element unless `asChild` is set.
```tsx
Regenerate
```
Edit \[#edit]
Enters edit mode for the current message. Renders a `` element unless `asChild` is set.
```tsx
Edit
```
Speak \[#speak]
Starts speech playback for the current message. Renders a `` element unless `asChild` is set.
```tsx
Play
```
StopSpeaking \[#stopspeaking]
Stops speech playback for the current message. Renders a `` element unless `asChild` is set.
```tsx
Stop
```
FeedbackPositive \[#feedbackpositive]
Submits positive feedback for the current message. Renders a `` element unless `asChild` is set.
```tsx
Helpful
```
FeedbackNegative \[#feedbacknegative]
Submits negative feedback for the current message. Renders a `` element unless `asChild` is set.
```tsx
Not helpful
```
ExportMarkdown \[#exportmarkdown]
Downloads message as Markdown or calls custom handler. Renders a `` element unless `asChild` is set.
```tsx
{
await navigator.clipboard.writeText(content);
}}
>
Export
```
Patterns \[#patterns]
Assistant Action Bar \[#assistant-action-bar]
```tsx
Copy
Regenerate
Export
```
User Action Bar \[#user-action-bar]
```tsx
Edit
```
Speech Toggle \[#speech-toggle]
```tsx
!s.message.isSpeaking}>
Play
s.message.isSpeaking}>
Stop
```
Speech requires a `SpeechSynthesisAdapter` configured in your runtime. See [Speech & Dictation](/docs/guides/speech) for setup.
Export with Custom Handler \[#export-with-custom-handler]
```tsx
{
await navigator.clipboard.writeText(content);
toast("Copied as Markdown!");
}}
>
Copy Markdown
```
Overflow Menu (ActionBarMorePrimitive) \[#overflow-menu-actionbarmoreprimitive]
`ActionBarMorePrimitive` is a Radix DropdownMenu for overflow actions, using the same pattern as `ThreadListItemMorePrimitive`. Use it to group secondary actions behind a "more" button.
`ActionBarMorePrimitive.Item` maps to Radix `DropdownMenu.Item`, so it preserves menu keyboard/focus semantics. Prefer `asChild` when composing an `ActionBarPrimitive` button into a menu item.
`ActionBarMorePrimitive.Content` defaults to `sideOffset={4}` so the menu has a small gap from the trigger.
| Part | Element | Purpose |
| ----------- | ---------------- | ------------------------------ |
| `Root` | N/A | Radix DropdownMenu provider |
| `Trigger` | `` | Opens the dropdown |
| `Content` | `` (portal) | The dropdown panel |
| `Item` | `
` | A menu item |
| `Separator` | `
` | Visual separator between items |
```tsx
import {
ActionBarPrimitive,
ActionBarMorePrimitive,
} from "@assistant-ui/react";
import { MoreHorizontalIcon } from "lucide-react";
Copy
Regenerate
Export Markdown
Helpful
```
See the [ActionBarMorePrimitive API Reference](/docs/api-reference/primitives/action-bar-more) for full prop details.
Relationship to Components \[#relationship-to-components]
The shadcn [Thread](/docs/ui/thread) component uses `ActionBarPrimitive` inside its `AssistantMessage` (with Copy, Reload, and an export dropdown) and `UserMessage` (with Edit). If those defaults work, use the component. Reach for `ActionBarPrimitive` directly when you need different actions, custom layout, or actions outside the standard thread UI.
ActionBar is commonly paired with [BranchPicker](/docs/primitives/branch-picker) for navigating between alternative responses on assistant messages.
API Reference \[#api-reference]
For full prop details on every part, see the [ActionBarPrimitive API Reference](/docs/api-reference/primitives/action-bar).
Related:
* [ActionBarMorePrimitive API Reference](/docs/api-reference/primitives/action-bar-more)