Marble UI
← Components

Action Bar (bulk actions)

Preview: Floating

Bulk-action bar for selections (React Aria Toolbar: arrow keys move between actions).

Import

import { ActionBar } from '@marbleui/ui'

Props

<ActionBar>

PropTypeDefaultDescription
children *requiredReactNode—
count *requirednumber—Number of selected items; the bar shows when > 0.
onClear *required() => void—
classNamestring—
label(count: number) => ReactNode(n) => `${n} selected`
variant'floating' | 'inline''floating'"floating": pill above the content. "inline": full-width strip (e.g. above a table).

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitive: React Aria Toolbar. Follow the primitive's docs for the full keyboard map.

Usage notes

Bulk-action bar that appears when items are selected. Use floating for a pill over the content or inline for a strip above a list or table. For per-row actions use Menu or ListViewItem actions.

<ActionBar count={selected.length} onClear={() => setSelected([])}>
  <Button size="sm" variant="ghost">Archive</Button>
  <Button size="sm" variant="ghost">Delete</Button>
</ActionBar>
  • The bar renders only while count > 0 and animates in and out. You own the selection state.
  • label customises the text (default is “N selected”); the text is aria-live="polite".
  • Actions sit in a toolbar labelled “Bulk actions”: one tab stop, arrow keys move between them. The clear button is labelled “Clear selection”.
  • It does not position itself: place it where you want it (for example in a fixed-height wrapper).
Example source · show
import { useState } from 'react'
import { Button } from '../button'
import { Checkbox, CheckboxGroup } from '../checkbox'
import { ActionBar } from './action-bar'

function Demo({ variant }: { variant: 'floating' | 'inline' }) {
  const [selected, setSelected] = useState<string[]>(['a', 'c'])
  return (
    <div className="flex w-96 flex-col gap-4">
      {variant === 'inline' && (
        <div className="h-10">
          <ActionBar variant="inline" count={selected.length} onClear={() => setSelected([])}>
            <Button size="sm" variant="ghost">Archive</Button>
            <Button size="sm" variant="ghost">Delete</Button>
          </ActionBar>
        </div>
      )}
      <CheckboxGroup aria-label="Issues" value={selected} onChange={setSelected}>
        {['a', 'b', 'c', 'd'].map((id, i) => (
          <Checkbox key={id} value={id} variant="card">Issue ACME-{140 + i}</Checkbox>
        ))}
      </CheckboxGroup>
      {variant === 'floating' && (
        <div className="flex h-12 justify-center">
          <ActionBar count={selected.length} onClear={() => setSelected([])}>
            <Button size="sm" variant="ghost">Assign</Button>
            <Button size="sm" variant="ghost">Label</Button>
            <Button size="sm" variant="ghost" className="text-danger-fg">Delete</Button>
          </ActionBar>
        </div>
      )}
    </div>
  )
}

export const styles = { Floating: () => <Demo variant="floating" />, Inline: () => <Demo variant="inline" /> }

Source: packages/ui/src/action-bar/action-bar.tsx

Catalog

Category
overlays
Priority
Core
Primitive
composed
React Aria
Toolbar
Base UI
Toolbar