Mantine React Table Accessibility

Permalink to "Mantine React Table Accessibility"

Mantine React Table (MRT) combines TanStack Table’s data logic with Mantine’s components into a feature-rich table: sorting, filtering, pagination, row selection, editing, column hiding and more, with a toolbar of icon buttons. It renders a semantic HTML table by default, which is a strong starting point for screen reader users. The accessibility work is mostly in the surrounding chrome — icon-only toolbar buttons, column action menus, filter inputs — and in the announcements that tell users what their actions did.

This guide belongs to React data grid libraries.

Spec reference

Permalink to "Spec reference"
  • Semantic table — table, thead, th, tbody, td; headers announced by screen readers in browse mode.
  • aria-sort on sortable header cells (verify in your version).
  • Toolbar buttons — icon buttons need accessible names (SC 4.1.2); MRT uses Mantine ActionIcon with tooltips — check that names are present, not only tooltips.
  • SC 4.1.3 (AA) — result counts after filtering, sorting and pagination.
  • SC 2.4.7, 1.4.11 (AA) — focus visibility in the Mantine theme.
Table semantics versus grid semantics in MRT Comparison: the default semantic table suits reading data with screen reader table commands; enabling cell keyboard navigation moves toward grid-like interaction and needs consistent roles. Table semantics versus grid semantics in MRT✗ Default semantic tableBrowse mode table commandsHeaders read automaticallyToolbar and menus do the workSimplest for screen readers✓ Interactive grid behaviourArrow-key cell focusHeaders read on column changeCells hold editors and actionsNeeds role and focus consistency

When to use — and when not to

Permalink to "When to use — and when not to"

Use MRT when you are already on Mantine and need a full-featured table quickly. Keep the semantic table rendering for data that users mainly read and filter. If you enable cell-level keyboard navigation and editing, verify that roles and focus behave consistently as a grid.

Do not leave toolbar icon buttons with tooltip-only names. The misapplication: enabling every toolbar feature (density toggle, full-screen, column hiding, global filter) without checking names and keyboard paths — a dozen unlabelled icons before the table even starts.

MRT features and what to check Matrix of features — global filter, column filters, sorting, row selection, column actions menu, density toggle, full-screen toggle — against accessible name, keyboard operation and announcement. MRT features and what to checkAccessible nameKeyboardAnnouncementGlobal filterPlaceholder only?InputAdd result countColumn filtersCheck labelsInputsAdd result countSortingHeader textEnter on headeraria-sort; add statusRow selectionCheckbox labelsSpaceAdd countColumn actions menuCheck nameMenu keysN/ADensity toggleTooltip only?ButtonN/AFull-screen toggleTooltip only?ButtonFocus handling
Most checks are about names and announcements around the table.

Annotated code example

Permalink to "Annotated code example"
import { MantineReactTable, useMantineReactTable } from 'mantine-react-table';

function Invoices({ data }) {
  const [status, setStatus] = useState('');
  const table = useMantineReactTable({
    columns, data,
    enableRowSelection: true,
    mantineTableProps: { 'aria-labelledby': 'inv-h' },                     // name the table (SC 4.1.2)
    mantineSearchTextInputProps: { 'aria-label': 'Search invoices', placeholder: 'Search invoices' },
    mantineFilterTextInputProps: ({ column }) => ({ 'aria-label': `Filter ${column.columnDef.header}` }),
    mantineSelectCheckboxProps: ({ row }) => ({ 'aria-label': `Select invoice ${row.original.id}` }),
    mantineSelectAllCheckboxProps: { 'aria-label': 'Select all invoices' },
    onSortingChange: (updater) => { setSorting(updater); /* derive message after state update */ },
  });

  useEffect(() => {
    const rows = table.getFilteredRowModel().rows.length;
    const s = table.getState().sorting[0];
    setStatus(`${rows} invoices${s ? `, sorted by ${s.id} ${s.desc ? 'descending' : 'ascending'}` : ''}`);
  }, [table.getState().sorting, table.getState().columnFilters, table.getState().globalFilter]);

  return (<>
    <h2 id="inv-h">Invoices</h2>
    <MantineReactTable table={table} />
    <p role="status" className="visually-hidden">{status}</p>               {/* SC 4.1.3 */}
  </>);
}

Prop names follow MRT’s mantine*Props convention; check them against your installed version.

Keyboard & AT behaviour

Permalink to "Keyboard & AT behaviour"
Interaction Expected behaviour Expected announcement
Tab through toolbar Each control named “Search invoices, edit”, “Show/Hide columns, button”
Enter on sortable header Sort Header with sort state; status message
Space on row checkbox Toggle selection “Select invoice INV-1042, checkbox, checked”
Column actions menu Opens menu; arrows navigate Menu items
Table navigation commands Read cells with headers Native table behaviour
Hardening an MRT table Flow: name the table; label toolbar inputs and icon buttons; label selection checkboxes; add a status message for results; verify focus visibility in the theme. Hardening an MRT tableName the tablearia-labelledby on the tablefrom the page headingLabel inputssearch and column filtersaria-label per columnLabel icon buttonstoolbar actionsnames, not tooltipsLabel checkboxesper row and select-allinclude the recordAnnounce resultsfilter, sort, pagestatus region

Integration context

Permalink to "Integration context"

MRT’s data logic is TanStack Table, so the guidance in accessible sorting with TanStack Table and row selection in TanStack Table React applies. Toolbar naming follows naming icon-only row action buttons. Column hiding follows column visibility menus and column choosers.

Gotchas

Permalink to "Gotchas"

Full-screen mode. Toggling full-screen re-renders the table; check that focus stays on the toggle or moves predictably.

Tooltips as names. Mantine tooltips may not provide accessible names on their own; verify with the accessibility tree.

Editing modes. MRT offers several editing modes (modal, row, cell, table); each has different focus behaviour — test the one you use.

Common mistakes

Permalink to "Common mistakes"
  • Unlabelled column filter inputs.
  • Toolbar icon buttons with tooltip-only names.
  • Generic “Toggle select row” checkbox labels.
  • No result announcements.

Version and upgrade notes

Permalink to "Version and upgrade notes"

MRT follows Mantine major versions; upgrades can change component internals and prop names. After upgrading, re-check accessible names on toolbar controls and filter inputs with the accessibility tree, since those come from component props and defaults that may move.

Worked example

Permalink to "Worked example"

An internal admin tool used MRT with every toolbar feature enabled. An audit found 14 unnamed or generically named controls before the table, unlabelled column filters and silent filtering. Passing aria-labels through MRT’s props, renaming selection checkboxes per record and adding a status region took half a day. The team also disabled the density and full-screen toggles, which nobody used, reducing the toolbar to four clearly named controls.

A minimal accessible MRT configuration

Permalink to "A minimal accessible MRT configuration"

For most internal tools, an accessible MRT configuration needs only a handful of decisions: keep semantic table rendering; enable the features users actually need (often search, column filters, sorting, selection and pagination) and disable the rest; supply names for every enabled control through the mantine*Props options; label selection checkboxes with the record identifier; add one status region driven by table state; and verify focus styles in your Mantine theme. Document this preset once and reuse it, because MRT’s flexibility otherwise produces a slightly different — and differently broken — table in every screen.

Testing checklist

Permalink to "Testing checklist"

Design system notes

Permalink to "Design system notes"

Create a project-level MRT preset that supplies names for every control, an announcer and your theme’s focus styles, and disables rarely used toolbar features by default.

FAQ

Permalink to "FAQ"
Does Mantine React Table render a real table?

Yes, by default it renders semantic table markup, which works well with screen reader table commands.

How do I name the toolbar buttons?

Through MRT’s component props for each control, or by overriding the toolbar rendering; verify names in the accessibility tree.

Does MRT announce sorting?

Headers can expose sort state; add a status message for the result.

Is cell keyboard navigation available?

Recent versions offer keyboard navigation options; test them and keep roles consistent if you enable them.

How do I handle large data?

Use MRT’s virtualization features and test screen reader position announcements.

Should I use MRT or plain TanStack Table?

MRT is faster to start; plain TanStack gives full control of markup. Both can be made accessible.

How do I check that names come through?

Inspect each control in the browser’s accessibility pane after rendering; tooltips and title attributes do not count as reliable names.

Does MRT support right-to-left layouts?

Mantine supports RTL; verify that arrow-key behaviour and column order match the reading direction in your configuration.

Permalink to "Related"

← Back to React Data Grid Libraries