Toolbar

Accessible toolbar with toggle groups and roving tabindex keyboard navigation

Usage

Toolbar is a group of toggle buttons with role="toolbar" and arrow keys navigation. Toolbar.Toggle is a polymorphic component, it can be rendered as any element, for example as a link.

Toolbar.Toggle is stateless: pass active and update it in onClick, or use Toolbar.ToggleGroup to manage state of a set of toggles. For a toggle that manages its own state, use the standalone Toggle component.

import { useState } from 'react';
import {
  LinkSimpleIcon,
  TextAlignCenterIcon,
  TextAlignLeftIcon,
  TextAlignRightIcon,
  TextBIcon,
  TextItalicIcon,
  TextUnderlineIcon,
} from '@phosphor-icons/react';
import { Toolbar } from '@mantine/core';

function Demo() {
  const [formatting, setFormatting] = useState<string[]>([]);
  const [alignment, setAlignment] = useState<string | null>('left');

  return (
    <Toolbar>
      <Toolbar.ToggleGroup type="multiple" value={formatting} onChange={setFormatting}>
        <Toolbar.ToggleItem value="bold" aria-label="Bold">
          <TextBIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="italic" aria-label="Italic">
          <TextItalicIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="underline" aria-label="Underline">
          <TextUnderlineIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>

      <Toolbar.Divider />

      <Toolbar.ToggleGroup type="single" value={alignment} onChange={setAlignment}>
        <Toolbar.ToggleItem value="left" aria-label="Align left">
          <TextAlignLeftIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="center" aria-label="Align center">
          <TextAlignCenterIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="right" aria-label="Align right">
          <TextAlignRightIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>

      <Toolbar.Divider />

      <Toolbar.Toggle
        component="a"
        href="https://mantine.dev"
        target="_blank"
        aria-label="Mantine website"
      >
        <LinkSimpleIcon weight="bold" size="100%" />
      </Toolbar.Toggle>
    </Toolbar>
  );
}

Toggle groups

Use Toolbar.ToggleGroup with Toolbar.ToggleItem to create groups of toggle buttons. Set type="single" to allow one active item at a time or type="multiple" to allow several. With type="single", clicking the active item deselects it and the value becomes null.

import { useState } from 'react';
import {
  TextAlignCenterIcon,
  TextAlignLeftIcon,
  TextAlignRightIcon,
  TextBIcon,
  TextItalicIcon,
  TextUnderlineIcon,
} from '@phosphor-icons/react';
import { Toolbar } from '@mantine/core';

function Demo() {
  const [formatting, setFormatting] = useState<string[]>([]);
  const [alignment, setAlignment] = useState<string | null>('left');

  return (
    <Toolbar>
      <Toolbar.ToggleGroup type="multiple" value={formatting} onChange={setFormatting}>
        <Toolbar.ToggleItem value="bold" aria-label="Bold">
          <TextBIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="italic" aria-label="Italic">
          <TextItalicIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="underline" aria-label="Underline">
          <TextUnderlineIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>

      <Toolbar.Divider />

      <Toolbar.ToggleGroup type="single" value={alignment} onChange={setAlignment}>
        <Toolbar.ToggleItem value="left" aria-label="Align left">
          <TextAlignLeftIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="center" aria-label="Align center">
          <TextAlignCenterIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="right" aria-label="Align right">
          <TextAlignRightIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>
    </Toolbar>
  );
}

Size, orientation, variant and color

The size prop controls the size of all toggles, padding and gap. Set orientation="vertical" to render a vertical toolbar. variant and color props control the appearance of active toggles.

Orientation
Variant
Color
Size
Radius
import {
  TextAlignCenterIcon,
  TextAlignLeftIcon,
  TextAlignRightIcon,
  TextBIcon,
  TextItalicIcon,
  TextUnderlineIcon,
} from '@phosphor-icons/react';
import { Toolbar } from '@mantine/core';

function Demo() {
  return (
    <Toolbar color="blue">
      <Toolbar.ToggleGroup type="multiple">
        <Toolbar.ToggleItem value="bold" aria-label="Bold">
          <TextBIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="italic" aria-label="Italic">
          <TextItalicIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="underline" aria-label="Underline">
          <TextUnderlineIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>

      <Toolbar.Divider />

      <Toolbar.ToggleGroup type="single" defaultValue="left">
        <Toolbar.ToggleItem value="left" aria-label="Align left">
          <TextAlignLeftIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="center" aria-label="Align center">
          <TextAlignCenterIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="right" aria-label="Align right">
          <TextAlignRightIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>
    </Toolbar>
  );
}

Auto contrast

Set autoContrast prop to automatically adjust icon color based on the active toggle background color, for example with variant="filled" and light colors.

import {
  TextAlignCenterIcon,
  TextAlignLeftIcon,
  TextAlignRightIcon,
  TextBIcon,
  TextItalicIcon,
  TextUnderlineIcon,
} from '@phosphor-icons/react';
import { Stack, Toolbar } from '@mantine/core';

function Demo() {
  return (
    <Stack>
      <Toolbar variant="filled" color="lime.4">
        <Toolbar.ToggleGroup type="multiple" defaultValue={['bold']}>
          <Toolbar.ToggleItem value="bold" aria-label="Bold">
            <TextBIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="italic" aria-label="Italic">
            <TextItalicIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="underline" aria-label="Underline">
            <TextUnderlineIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
        </Toolbar.ToggleGroup>

        <Toolbar.Divider />

        <Toolbar.ToggleGroup type="single" defaultValue="left">
          <Toolbar.ToggleItem value="left" aria-label="Align left">
            <TextAlignLeftIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="center" aria-label="Align center">
            <TextAlignCenterIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="right" aria-label="Align right">
            <TextAlignRightIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
        </Toolbar.ToggleGroup>
      </Toolbar>

      <Toolbar autoContrast variant="filled" color="lime.4">
        <Toolbar.ToggleGroup type="multiple" defaultValue={['bold']}>
          <Toolbar.ToggleItem value="bold" aria-label="Bold">
            <TextBIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="italic" aria-label="Italic">
            <TextItalicIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="underline" aria-label="Underline">
            <TextUnderlineIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
        </Toolbar.ToggleGroup>

        <Toolbar.Divider />

        <Toolbar.ToggleGroup type="single" defaultValue="left">
          <Toolbar.ToggleItem value="left" aria-label="Align left">
            <TextAlignLeftIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="center" aria-label="Align center">
            <TextAlignCenterIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
          <Toolbar.ToggleItem value="right" aria-label="Align right">
            <TextAlignRightIcon weight="bold" size="100%" />
          </Toolbar.ToggleItem>
        </Toolbar.ToggleGroup>
      </Toolbar>
    </Stack>
  );
}

Auto width

By default, Toolbar.Toggle and Toolbar.ToggleItem render as square buttons. Set autoWidth prop on either of them to allow the toggle width to adjust to its content, for example a text label.

import { TextBIcon, TextItalicIcon } from '@phosphor-icons/react';
import { Toolbar } from '@mantine/core';

function Demo() {
  return (
    <Toolbar>
      <Toolbar.Toggle aria-label="Bold">
        <TextBIcon weight="bold" size="100%" />
      </Toolbar.Toggle>
      <Toolbar.Toggle aria-label="Italic">
        <TextItalicIcon weight="bold" size="100%" />
      </Toolbar.Toggle>

      <Toolbar.Divider />

      <Toolbar.Toggle autoWidth>Save</Toolbar.Toggle>
      <Toolbar.Toggle autoWidth>Cancel</Toolbar.Toggle>
    </Toolbar>
  );
}

Disabled state

Set disabled prop on individual Toolbar.ToggleItem components, or on Toolbar.ToggleGroup to disable all items within the group.

When Toolbar.Toggle is rendered as a non-button element (for example, component="a"), the disabled prop sets aria-disabled, removes the element from the tab order and prevents clicks.

import {
  TextAlignCenterIcon,
  TextAlignLeftIcon,
  TextAlignRightIcon,
  TextBIcon,
  TextItalicIcon,
  TextUnderlineIcon,
} from '@phosphor-icons/react';
import { Toolbar } from '@mantine/core';

function Demo() {
  return (
    <Toolbar>
      <Toolbar.ToggleGroup type="multiple">
        <Toolbar.ToggleItem value="bold" aria-label="Bold">
          <TextBIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="italic" aria-label="Italic" disabled>
          <TextItalicIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="underline" aria-label="Underline">
          <TextUnderlineIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>

      <Toolbar.Divider />

      <Toolbar.ToggleGroup type="single" defaultValue="left" disabled>
        <Toolbar.ToggleItem value="left" aria-label="Align left">
          <TextAlignLeftIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="center" aria-label="Align center">
          <TextAlignCenterIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
        <Toolbar.ToggleItem value="right" aria-label="Align right">
          <TextAlignRightIcon weight="bold" size="100%" />
        </Toolbar.ToggleItem>
      </Toolbar.ToggleGroup>
    </Toolbar>
  );
}

Accessibility

  • Toolbar has role="toolbar" and aria-orientation that matches the orientation prop
  • Toolbar.ToggleItem always has aria-pressed attribute. Toolbar.Toggle has it only when the active prop is passed, without it Toolbar.Toggle is a regular button
  • Set aria-label on icon-only toggles

Keyboard interactions

Toolbar.Toggle and Toolbar.ToggleItem components share a single tab stop, arrow keys move focus between them. Other interactive children (ActionIcon, Button, standalone Toggle) are not part of the arrow key navigation and remain separate tab stops.

KeyDescriptionCondition
TabMoves focus into and out of the toolbar–
ArrowRightMoves focus to the next item (previous item when dir="rtl")orientation="horizontal"
ArrowLeftMoves focus to the previous item (next item when dir="rtl")orientation="horizontal"
ArrowDownMoves focus to the next itemorientation="vertical"
ArrowUpMoves focus to the previous itemorientation="vertical"
HomeMoves focus to the first item–
EndMoves focus to the last item–
Space/EnterActivates the focused toggle item–