ActionBar

ActionBar

항목 선택 시 나타나는 고정 위치 하단 바(bottom bar)로, 선택된 항목에 대한 맥락적 일괄 작업을 제공해요. Affix, Transition, Paper 컴포넌트로 만들어져 있어요.

출처: 문서

본문

Usage

ActionBar는 항목이 선택되었을 때 나타나는 고정 위치 하단 바예요. 선택된 항목에 대한 맥락적 일괄 작업을 제공해요. Affix, Transition, Paper 컴포넌트로 만들어져 있어요.

ActionBar 안의 콘텐츠는 기존 Mantine 컴포넌트(Button, ActionIcon, Group, Text 등)로 자유롭게 구성해요. ActionBar.Divider로 세로 구분선을 추가하고, ActionBar.CloseButton으로 onClose 콜백을 실행하는 닫기 버튼을 추가할 수 있어요.

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}>
      <Table.Td>
        <Checkbox 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 checked={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>{selection.length} selected</Text>
        <ActionBar.CloseButton />
        <ActionBar.Divider />
        <Button>Delete</Button>
        <Button>Move</Button>
        <Button>Archive</Button>
      </ActionBar>
    </>
  );
}

ActionBar 루트는 role="group", 구분선은 role="separator"를 가져서 보조 기술이 컨트롤을 하나의 바(bar)로 안내해요. aria-label을 설정해 작업이 적용되는 대상을 설명하세요.

With ActionIcon buttons

ActionIcon 버튼으로도 동일한 동작을 구현할 수 있어요.

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}>
      <Table.Td>
        <Checkbox 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 checked={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>{selection.length} rows selected</Text>
        <Tooltip label="Archive"><ActionIcon variant="subtle"><ArchiveIcon /></ActionIcon></Tooltip>
        <Tooltip label="Move"><ActionIcon variant="subtle"><FolderIcon /></ActionIcon></Tooltip>
        <Tooltip label="Delete"><ActionIcon variant="subtle" color="red"><TrashIcon /></ActionIcon></Tooltip>
      </ActionBar>
    </>
  );
}

Placement

기본적으로 ActionBar는 화면 하단 중앙에 배치돼요. position prop으로 위치를 바꿀 수 있어요. 중앙이 아닌 위치를 사용할 때는 styles={{ root: { marginInline: 0 } }}로 자동 중앙 정렬을 제거하세요. (Center (default) / Left / Right)

Close on Escape

기본적으로 ActionBar는 Escape 키를 눌러도 닫히지 않아요. closeOnEscape를 설정하면 이 동작을 활성화할 수 있어요.

Transitions

ActionBar는 Transition 컴포넌트로 애니메이션되며 기본값은 { transition: 'pop', duration: 200 }이에요. transitionProps로 트랜지션, 지속 시간, 타이밍 함수를 바꿀 수 있어요.

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

function Demo() {
  return (
    <ActionBar opened transitionProps={{ transition: 'fade', duration: 150 }}>
      <Button>Delete</Button>
    </ActionBar>
  );
}

keepMounted

기본적으로 액션 바는 닫히면 DOM에서 제거돼요. keepMounted를 설정하면 마운트된 상태를 유지하고 display: none으로 숨겨요. 예를 들어 바 안에 열릴 때마다 보존해야 하는 폼 상태가 있을 때 유용해요.

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

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

Rendering in a portal

ActionBar는 기본적으로 Portal 안에 렌더링되어 부모 요소의 overflow와 transform 스타일의 영향을 받지 않아요. withinPortal={false}로 제자리에 렌더링하고, portalProps로 Portal 컴포넌트에 props를 전달할 수 있어요.

더 알아보기 (Learn more)