Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Components

Free

Action Bar for Ark UI

Show bulk actions while rows are selected, then hide them when the selection clears. For React with Ark UI, when those actions should not sit in a toolbar all the time.

Framework
UI library

Bulk actions for selected rows sit at the bottom of the screen.

Use it for the life of a selection. Actions that are always available belong in a Button Group. In React, set open when the selection isn't empty, and Ark UI shows the bar.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Anatomy

Action Bar anatomy: content, value, body, separator, close

Usage

import {
  ArchiveIcon, DownloadIcon, PencilIcon, Trash2Icon, XIcon,
} from "lucide-react";
import {
  ActionBar, ActionBarBody, ActionBarClose, ActionBarContent,
  ActionBarSeparator, ActionBarTrigger, ActionBarValue,
} from "@/components/ui/action-bar";
import { Button } from "@/components/ui/button";
<ActionBar>
  <ActionBarTrigger asChild>
    <Button variant="outline">Open</Button>
  </ActionBarTrigger>
  <ActionBarContent aria-label="Bulk actions">
    <ActionBarValue count={3} />
    <ActionBarSeparator />
    <ActionBarBody>
      <Button variant="ghost">
        <PencilIcon />
        <span className="max-sm:sr-only">Edit</span>
      </Button>
      <Button variant="ghost">
        <DownloadIcon />
        <span className="max-sm:sr-only">Export</span>
      </Button>
      <Button variant="ghost">
        <ArchiveIcon />
        <span className="max-sm:sr-only">Archive</span>
      </Button>
      <ActionBarSeparator />
      <Button variant="destructive">
        <Trash2Icon />
        <span className="max-sm:sr-only">Delete</span>
      </Button>
    </ActionBarBody>
    <ActionBarSeparator />
    <ActionBarClose asChild>
      <Button size="icon-md" variant="ghost">
        <XIcon />
      </Button>
    </ActionBarClose>
  </ActionBarContent>
</ActionBar>

Accessibility

Enter
Activate the focused control.
Space
Activate the focused control.

Demos

Close Trigger

The X is ActionBarClose, a button that asks the bar to close. Here open is controlled, so that click comes back through onOpenChange as false and you can clear the selection in the same handler. Use a visible close when Escape is easy to miss, especially on a phone. If closing must leave the checkboxes alone, do not put that reset in the close handler.

Preview width

Controlled

No trigger lives inside the bar. A Toggle button outside it flips open, and the bar reports every close through onOpenChange, including the X and Escape. Control open when visibility follows a selection or some other state, which is the real product case. An ActionBarTrigger only fits when people open the bar on purpose, and a selection is not that.

Preview width

Custom Spacing

ActionBarContent pads itself from the --space token. The component starts at spacing step 2, and this class sets that same step so the override has an obvious place. Pass a smaller or larger step when the bar should sit tighter on a dense table, or roomier around large actions. The count, the buttons, and the close control share that padding, so you change it once.

Preview width

Dialog

Delete does not run immediately. The destructive button opens an alert dialog that names the action and asks for a confirm. Put a dialog on any bar action that destroys data or is hard to undo, and leave export or edit as plain buttons. The bar is where the action starts, the dialog is where it is confirmed, and cancel returns to the same selection.

Preview width

Gutter

Two buttons set positioning.gutter to 24px or 32px, with placement staying at the bottom. Gutter is the gap between the bar and the screen edge. The default is 16px, and the bar also adds the bottom safe-area inset so a phone home indicator does not cover the actions. Raise the gutter when a banner or a mini player already occupies that edge.

Preview width

The body of the bar is a single menu, opened upward with placement set to top, holding Archive, Duplicate, and a destructive Delete. Use a menu when the rare actions would make the bar a long row, and keep the everyday ones as buttons beside it. Upward matters because the bar is already at the bottom of the screen. A menu that opens downward runs off the viewport.

Preview width

Positioning

Three buttons set positioning.placement to bottom-start, bottom, or bottom-end. Centered is the usual bulk bar, in the middle of the viewport. Start and end pin it to a corner when the selection lives in a sidebar or a narrow pane and a centered bar would cover the wrong column. The bar stays on the bottom edge, and placement will not move it to the top.

Preview width

Table

Checkboxes on the orders drive the bar: open is true while the selected ids are not empty, and closing the bar clears that selection. The content shows the count, Send, Edit, a more menu, and Delete behind an alert dialog that lists the chosen orders. Copy this when the selection is rows. A bar with an Open button is only for trying the parts.

Preview width

FAQ

When should I use an Action Bar instead of a toolbar or a menu?

Use an Action Bar for actions on a selection: it floats at the bottom of the screen while items are selected, as in the Table demo. For actions that are always on screen, use a Button Group; for a few actions on a single item, a Dropdown Menu.

How do I show the Action Bar when rows are selected in React?

Control it from your selection state and clear the selection when it closes. Pass open, such as selected.length > 0, and handle onOpenChange, which receives false when the bar closes. The Table demo does this with checkboxes.

How do I show how many items are selected in the Action Bar?

Add ActionBarValue with count: it renders the number in a secondary badge. Pass label or children for text such as 3 selected, and variant, size or pill to restyle the badge.

How do I change where the Action Bar appears on the screen?

Pass positioning on ActionBar: placement is bottom, bottom-start or bottom-end, and gutter sets the distance from the edge, 16px by default. The bar also adds the bottom safe-area inset on phones. The Positioning and Gutter demos show both.

Does the Action Bar close when I press Escape?

Yes. Escape closes it and calls onOpenChange with false. Set closeOnEscape to false to keep it open until the selection is cleared, for example when Escape should only clear a search field.

Is the Ark UI Action Bar accessible to screen readers?

Its content renders in a portal as a role="toolbar", so give ActionBarContent an aria-label such as Bulk actions, as in the Usage example. Icon buttons can hide their text on small screens with max-sm:sr-only and still keep it for screen readers.

Can I open a confirmation dialog or a menu from the Action Bar?

Yes. The Dialog demo confirms a destructive action from the bar, and the Menu demo puts more actions behind a menu button, so the bar stays short on small screens.

How do I install the Action Bar in React?

Run the command in the Installation section above: it adds action-bar to your components/ui folder with what it needs. React and Solid use the shadcn CLI, Vue uses shadcn-vue and Svelte uses shadcn-svelte, each after its one-time setup.

API Reference

ActionBar

PropType
open?boolean

The open state of the action bar.

defaultOpen?boolean

The default open state of the action bar.

Default
false
onOpenChange?(open: boolean) → void

The function to call when the open state of the action bar changes.

Parameters

open – boolean

Returns
void
closeOnEscape?boolean

Whether to close the action bar when the Escape key is pressed.

Default
true
lazyMount?boolean

Whether to lazy mount the action bar.

Default
true
positioning?object

Placement and gutter of the action bar.

Type
{ gutter?: string; placement?: "bottom" | "bottom-start" | "bottom-end" }
unmountOnExit?boolean

The function to call when the action bar is mounted.

Default
true

ActionBarTrigger

<button> data-slot="action-bar-trigger"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

AttributeType
data-state?string

"open" when isOpen is true, otherwise "closed".

CSS variableType
--gutterstring

ActionBarContent

<div> data-slot="action-bar-positioner"

PropType
placement?"bottom" | "bottom-end" | "bottom-start"

Where it sits at the bottom of the screen: bottom, bottom-start or bottom-end.

Type
"bottom" | "bottom-end" | "bottom-start"
Default
"bottom"
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

className?string

Merged with the part's classes.

AttributeType
data-placement?string

Mirrors placement.

CSS variableType
--spacestring

ActionBarSeparator

data-slot="action-bar-separator"

PropType
orientation?"horizontal" | "vertical"

The orientation of the separator. Ark default: horizontal.

Type
"horizontal" | "vertical"
Default
vertical
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

className?string

Merged with the part's classes.

ActionBarClose

<button> data-slot="action-bar-close"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

className?string

Merged with the part's classes.

AttributeType
data-state?string

"open" when isOpen is true, otherwise "closed".

ActionBarValue

data-slot="action-bar-value"

PropType
countnumber

The number of items selected.

Default
0
label?string

The label of the selection trigger.

pill?boolean

Fully rounded corners.

Default
false
size?"lg" | "md" | "sm"

The size.

Type
"lg" | "md" | "sm"
Default
"md"
variant?"default" | "destructive" | "ghost" | "info" | "link" | "outline" | "secondary" | "success" | "warning"

Ark default: default.

Type
"default" | "destructive" | "ghost" | "info" | "link" | "outline" | "secondary" | "success" | "warning"
Default
secondary
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

className?string

Merged with the part's classes.

ActionBarBody

<div> data-slot="action-bar-body"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

className?string

Merged with the part's classes.

With other components

  • Table

    Data

    Appears when rows are selected

  • Checkbox

    Selection

    The selection that opens it

  • Button

    Buttons

    The actions in the bar

  • More actions in one slot

  • Tooltip

    Overlays

    Name an icon action

  • Dialog

    Overlays

    Confirm a destructive action