<!-- Protocore Design System — ActionBar -->
# ActionBar

- **Category:** Overlay (`overlay`)
- **Slug:** `overlay/action-bar`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { ActionBar } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/overlay/action-bar

> A contextual bulk-action bar that slides up when rows are selected — an "N selected" count, action buttons, and a clear control.

## When to use it

An ActionBar is the **bulk-operation surface** for a selectable list or table: the user checks a few rows and a bar rises with the operations that apply to the whole selection — export, archive, delete, assign. Keeping those actions in a floating bar avoids repeating them per row and makes the selected count unmistakable.

By default the bar shows when `count > 0`; pass `visible` to control it explicitly (for example, to keep it mounted through an exit transition). Wire `onClear` back to your selection state so the clear control empties it. For a persistent, non-contextual set of controls above content, use a **[Toolbar](/navigation/toolbar)** instead.

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `children` | `ReactNode` | no | — | Action buttons — typically Buttons or IconButtons. |
| `className` | `string` | no | — | — |
| `clearLabel` | `string` | no | `Clear` | Label for the clear control. |
| `count` | `number` | yes | — | Number of selected items — drives the count label and default visibility. |
| `onClear` | `(() => void)` | no | — | Called when the user clears the selection. Renders a clear control when set. |
| `position` | `enum` | no | `bottom` | Which edge the bar docks to. |
| `renderCount` | `((count: number) => ReactNode)` | no | — | Renders the count label. Defaults to `"{count} selected"`. Return a full string, e.g. `(n) => \`${n} rows\``. |
| `style` | `CSSProperties` | no | — | — |
| `visible` | `boolean` | no | — | Force visibility. When omitted, the bar shows whenever `count > 0`. Set explicitly to keep it mounted during an exit transition or hide it early. |

## Examples

### Bulk selection

Feed `count` the number of selected items; the bar appears whenever it's above zero and slides up from the bottom. Pass action buttons as children and an `onClear` to render the clear control. It's built to pair with [DataTable](/data-display/data-table) row selection.

```tsx
import { useState } from "react";
import { ActionBar, Button, Checkbox, VStack } from "@protocore/pds";

const rows = ["ledger-append", "ledger-read", "keys-rotate", "keys-revoke"];

export default function ActionBarBasics() {
  const [selected, setSelected] = useState<Record<string, boolean>>({});
  const count = Object.values(selected).filter(Boolean).length;

  return (
    <div style={{ position: "relative", minHeight: 200 }}>
      <VStack gap={2} style={{ alignItems: "flex-start" }}>
        {rows.map((row) => (
          <Checkbox
            key={row}
            label={row}
            checked={Boolean(selected[row])}
            onCheckedChange={(v) => setSelected((s) => ({ ...s, [row]: Boolean(v) }))}
          />
        ))}
      </VStack>
      <ActionBar count={count} onClear={() => setSelected({})}>
        <Button size="sm" variant="secondary">
          Export
        </Button>
        <Button size="sm" variant="danger">
          Delete
        </Button>
      </ActionBar>
    </div>
  );
}
```

## Do & don't

**Do**

- Drive count from your selection state and let the bar show itself.
- Wire onClear back to reset the selection.
- Put only actions that apply to the whole selection in the bar.
- Pair it with DataTable's selection for a complete bulk-edit flow.

**Don't**

- Leave it visible with an empty selection — it's contextual, not a toolbar.
- Overflow it with every possible action; keep it to the common few.
- Use it for single-row actions — those belong in the row.
- Forget onClear — users need an obvious way out of a selection.

## Accessibility

**Keyboard**

| Keys | Action |
| --- | --- |
| `Tab` | Moves through the action buttons and the clear control. |
| `Enter / Space` | Activates the focused action. |

**Notes**

- The bar is a role=region labelled "Bulk actions" so assistive tech can find it.
- The count label is an aria-live=polite region, announcing selection changes.
- The clear control is a labelled button with an inline SVG × (no emoji glyph).
- Actions are real buttons — fully keyboard-operable.

## Related

`data-table`, `toolbar`, `checkbox`, `filter-bar`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
