# ActionBar
Package: @mantine/core
Import: import { ActionBar } from '@mantine/core';
Description: A fixed-position bottom bar for bulk selection actions

## Usage

`ActionBar` is a fixed-position bottom bar that appears when items are selected,
providing contextual bulk actions. It is built using [Affix](https://mantine.dev/llms/core-affix.md), [Transition](https://mantine.dev/llms/core-transition.md)
and [Paper](https://mantine.dev/llms/core-paper.md) components.

Content inside `ActionBar` is composed freely using existing Mantine components
(`Button`, `ActionIcon`, `Group`, `Text`, etc.). Use `ActionBar.Divider` to
add a vertical divider and `ActionBar.CloseButton` to add a close button that
triggers the `onClose` callback.

```tsx
import { useState } from 'react';
import { ActionBar, Button, Checkbox, Table, Text } from '@mantine/core';

const elements = [
  { position: 6, mass: 12.011, symbol: 'C', name: 'Carbon' },
  { position: 7, mass: 14.007, symbol: 'N', name: 'Nitrogen' },
  { position: 39, mass: 88.906, symbol: 'Y', name: 'Yttrium' },
  { position: 56, mass: 137.33, symbol: 'Ba', name: 'Barium' },
  { position: 58, mass: 140.12, symbol: 'Ce', name: 'Cerium' },
];

function Demo() {
  const [selection, setSelection] = useState<number[]>([]);

  const toggleRow = (position: number) =>
    setSelection((current) =>
      current.includes(position)
        ? current.filter((item) => item !== position)
        : [...current, position]
    );

  const toggleAll = () =>
    setSelection((current) =>
      current.length === elements.length ? [] : elements.map((element) => element.position)
    );

  const rows = elements.map((element) => (
    <Table.Tr
      key={element.position}
      bg={selection.includes(element.position) ? 'var(--mantine-color-blue-light)' : undefined}
    >
      <Table.Td>
        <Checkbox
          aria-label="Select row"
          checked={selection.includes(element.position)}
          onChange={() => toggleRow(element.position)}
        />
      </Table.Td>
      <Table.Td>{element.position}</Table.Td>
      <Table.Td>{element.name}</Table.Td>
      <Table.Td>{element.symbol}</Table.Td>
      <Table.Td>{element.mass}</Table.Td>
    </Table.Tr>
  ));

  return (
    <>
      <Table>
        <Table.Thead>
          <Table.Tr>
            <Table.Th>
              <Checkbox
                aria-label="Select all"
                checked={selection.length === elements.length}
                indeterminate={selection.length > 0 && selection.length !== elements.length}
                onChange={toggleAll}
              />
            </Table.Th>
            <Table.Th>Element position</Table.Th>
            <Table.Th>Element name</Table.Th>
            <Table.Th>Symbol</Table.Th>
            <Table.Th>Atomic mass</Table.Th>
          </Table.Tr>
        </Table.Thead>
        <Table.Tbody>{rows}</Table.Tbody>
      </Table>

      <ActionBar opened={selection.length > 0} onClose={() => setSelection([])} shadow="md">
        <Text size="sm">{selection.length} selected</Text>
        <ActionBar.Divider />
        <Button variant="default" size="compact-sm">
          Delete
        </Button>
        <Button variant="default" size="compact-sm">
          Move
        </Button>
        <Button variant="default" size="compact-sm">
          Archive
        </Button>
        <ActionBar.CloseButton />
      </ActionBar>
    </>
  );
}
```


`ActionBar` root has `role="group"` and the divider has `role="separator"` so that assistive
technologies announce the controls as one bar. Set `aria-label` to describe what the actions apply to.

## With ActionIcon buttons

```tsx
import { useState } from 'react';
import { ArchiveIcon, FolderIcon, TrashIcon } from '@phosphor-icons/react';
import { ActionBar, ActionIcon, Checkbox, Group, Table, Text, Tooltip } from '@mantine/core';

const elements = [
  { position: 6, mass: 12.011, symbol: 'C', name: 'Carbon' },
  { position: 7, mass: 14.007, symbol: 'N', name: 'Nitrogen' },
  { position: 39, mass: 88.906, symbol: 'Y', name: 'Yttrium' },
  { position: 56, mass: 137.33, symbol: 'Ba', name: 'Barium' },
  { position: 58, mass: 140.12, symbol: 'Ce', name: 'Cerium' },
];

function Demo() {
  const [selection, setSelection] = useState<number[]>([]);

  const toggleRow = (position: number) =>
    setSelection((current) =>
      current.includes(position)
        ? current.filter((item) => item !== position)
        : [...current, position]
    );

  const toggleAll = () =>
    setSelection((current) =>
      current.length === elements.length ? [] : elements.map((element) => element.position)
    );

  const rows = elements.map((element) => (
    <Table.Tr
      key={element.position}
      bg={selection.includes(element.position) ? 'var(--mantine-color-blue-light)' : undefined}
    >
      <Table.Td>
        <Checkbox
          aria-label="Select row"
          checked={selection.includes(element.position)}
          onChange={() => toggleRow(element.position)}
        />
      </Table.Td>
      <Table.Td>{element.position}</Table.Td>
      <Table.Td>{element.name}</Table.Td>
      <Table.Td>{element.symbol}</Table.Td>
      <Table.Td>{element.mass}</Table.Td>
    </Table.Tr>
  ));

  return (
    <>
      <Table>
        <Table.Thead>
          <Table.Tr>
            <Table.Th>
              <Checkbox
                aria-label="Select all"
                checked={selection.length === elements.length}
                indeterminate={selection.length > 0 && selection.length !== elements.length}
                onChange={toggleAll}
              />
            </Table.Th>
            <Table.Th>Element position</Table.Th>
            <Table.Th>Element name</Table.Th>
            <Table.Th>Symbol</Table.Th>
            <Table.Th>Atomic mass</Table.Th>
          </Table.Tr>
        </Table.Thead>
        <Table.Tbody>{rows}</Table.Tbody>
      </Table>

      <ActionBar opened={selection.length > 0} onClose={() => setSelection([])}>
        <Text size="sm" fw={500}>{selection.length} rows selected</Text>
        <ActionBar.Divider />
        <Tooltip.Group openDelay={300} closeDelay={100}>
          <Group gap="xs">
            <Tooltip label="Delete">
              <ActionIcon variant="default" color="red" size="lg">
                <TrashIcon size={16} />
              </ActionIcon>
            </Tooltip>
            <Tooltip label="Move to folder">
              <ActionIcon variant="default" size="lg">
                <FolderIcon size={16} />
              </ActionIcon>
            </Tooltip>
            <Tooltip label="Archive">
              <ActionIcon variant="default" size="lg">
                <ArchiveIcon size={16} />
              </ActionIcon>
            </Tooltip>
          </Group>
        </Tooltip.Group>
        <ActionBar.Divider />
        <ActionBar.CloseButton />
      </ActionBar>
    </>
  );
}
```


## Placement

By default, `ActionBar` is centered at the bottom of the screen. You can change
the position with the `position` prop. When using non-centered positions, set
`styles={{ root: { marginInline: 0 } }}` to remove the auto centering.

```tsx
import { useDisclosure } from '@mantine/hooks';
import { ActionBar, Button, Group, Text } from '@mantine/core';

function Demo() {
  const [center, centerHandlers] = useDisclosure(false);
  const [left, leftHandlers] = useDisclosure(false);
  const [right, rightHandlers] = useDisclosure(false);

  return (
    <>
      <Group justify="center">
        <Button onClick={centerHandlers.toggle}>Center (default)</Button>
        <Button onClick={leftHandlers.toggle}>Left</Button>
        <Button onClick={rightHandlers.toggle}>Right</Button>
      </Group>

      <ActionBar opened={center} onClose={centerHandlers.close}>
        <Text size="sm">Center position (default)</Text>
        <ActionBar.CloseButton />
      </ActionBar>

      <ActionBar
        opened={left}
        onClose={leftHandlers.close}
        position={{ bottom: 30, left: 30 }}
        styles={{ root: { marginInline: 0 } }}
      >
        <Text size="sm">Left position</Text>
        <ActionBar.CloseButton />
      </ActionBar>

      <ActionBar
        opened={right}
        onClose={rightHandlers.close}
        position={{ bottom: 30, right: 30 }}
        styles={{ root: { marginInline: 0 } }}
      >
        <Text size="sm">Right position</Text>
        <ActionBar.CloseButton />
      </ActionBar>
    </>
  );
}
```


## Close on Escape

By default, `ActionBar` does not close when `Escape` key is pressed. Set `closeOnEscape`
to enable this behavior:

```tsx
import { useDisclosure } from '@mantine/hooks';
import { ActionBar, Button, Group, Text } from '@mantine/core';

function Demo() {
  const [opened, { toggle, close }] = useDisclosure(false);

  return (
    <>
      <Group justify="center">
        <Button onClick={toggle}>Toggle action bar</Button>
      </Group>

      <ActionBar opened={opened} onClose={close} closeOnEscape>
        <Text size="sm">Press Escape to close this bar</Text>
        <ActionBar.Divider />
        <Button variant="default" size="compact-sm" onClick={close}>
          Close
        </Button>
      </ActionBar>
    </>
  );
}
```


## Transitions

`ActionBar` is animated with the [Transition](https://mantine.dev/llms/core-transition.md) component,
`{ transition: 'pop', duration: 200 }` by default. Use `transitionProps` to change
the transition, its duration and timing function:

```tsx
import { ActionBar, Button } from '@mantine/core';

function Demo() {
  return (
    <ActionBar opened transitionProps={{ transition: 'slide-up', duration: 300 }}>
      <Button>Delete</Button>
    </ActionBar>
  );
}
```

## keepMounted

By default, the action bar is removed from the DOM when it is closed. Set `keepMounted`
to keep it mounted and hide it with `display: none` instead – for example, if the bar
contains form state that must be preserved between openings:

```tsx
import { ActionBar, Button } from '@mantine/core';

function Demo() {
  return (
    <ActionBar opened={false} keepMounted>
      <Button>Delete</Button>
    </ActionBar>
  );
}
```

## Rendering in a portal

`ActionBar` is rendered inside [Portal](https://mantine.dev/llms/core-portal.md) by default – this way it is not
affected by `overflow` and `transform` styles of its parent elements. Set
`withinPortal={false}` to render it in place, and use `portalProps` to pass props
down to the `Portal` component.


#### Props

**ActionBar props**

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| aria-label | string | - | `aria-label` of the actions group, `'Actions'` by default |
| closeOnEscape | boolean | - | Determines whether the action bar should be closed when `Escape` key is pressed, `false` by default |
| keepMounted | boolean | - | If set, the component uses `display: none` to hide the root element instead of removing the DOM node, `false` by default |
| onClose | () => void | - | Called when close button is clicked or Escape is pressed |
| opened | boolean | required | Controls visibility |
| portalProps | BasePortalProps | - | Props passed down to the `Portal` component. Ignored when `withinPortal` is `false`. |
| position | AffixPosition | - | Affix position on screen |
| radius | MantineRadius \| number | - | Key of `theme.radius` or any valid CSS value to set `border-radius` |
| shadow | MantineShadow | - | Key of `theme.shadows` or any valid CSS `box-shadow` value |
| transitionProps | TransitionProps | - | Props passed down to the `Transition` component, `{ transition: 'pop', duration: 200 }` by default |
| withBorder | boolean | - | Adds border to the root element |
| withinPortal | boolean | - | Determines whether the component is rendered within `Portal` |
| zIndex | React.CSSProperties["zIndex"] | - | Root element `z-index` property |


#### Styles API

ActionBar component supports Styles API. With Styles API, you can customize styles of any inner element. Follow the documentation to learn how to use CSS modules, CSS variables and inline styles to get full control over component styles.

**ActionBar selectors**

| Selector | Static selector | Description |
|----------|----------------|-------------|
| root | .mantine-ActionBar-root | Root element (Paper) |
| divider | .mantine-ActionBar-divider | ActionBar.Divider element |
| closeButton | .mantine-ActionBar-closeButton | ActionBar.CloseButton element |
