Docs
Cloudflare
Railway
CodeRabbit
OpenRouter
AG Grid
Clerk
SerpAPI
Netlify
WorkOS
Electric
Prisma
Unkey
Sentry
Cloudflare
Railway
CodeRabbit
OpenRouter
AG Grid
Clerk
SerpAPI
Netlify
WorkOS
Electric
Prisma
Unkey
Sentry
Table API Reference
Column API Reference
Row API Reference
Cell API Reference
Header API Reference
Features API Reference
Static Functions API Reference
Legacy API Reference

React Example: Mantine React Table

import * as React from 'react'
import ReactDOM from 'react-dom/client'

import '@mantine/core/styles.css'

import {
  Badge,
  Box,
  Button,
  Group,
  MantineProvider,
  Stack,
  Text,
  Title,
} from '@mantine/core'

import {
  MantineReactTable,
  createMRTColumnHelper,
  useMantineReactTable,
} from './mantine-react-table'
import { makeData } from './makeData'
import type { Person } from './makeData'
import './index.css'

const columnHelper = createMRTColumnHelper<Person>()

const columns = columnHelper.columns([
  columnHelper.accessor('firstName', {
    header: 'First Name',
    size: 140,
  }),
  columnHelper.accessor('lastName', {
    header: 'Last Name',
    size: 140,
  }),
  columnHelper.accessor('email', {
    header: 'Email',
    size: 220,
    Cell: ({ cell }) => (
      <a href={`mailto:${cell.getValue<string>()}`}>
        {cell.getValue<string>()}
      </a>
    ),
  }),
  columnHelper.accessor('age', {
    header: 'Age',
    size: 80,
    filterVariant: 'range',
  }),
  columnHelper.accessor('jobTitle', {
    header: 'Job Title',
    size: 200,
  }),
  columnHelper.accessor('city', {
    header: 'City',
    size: 140,
  }),
  columnHelper.accessor('state', {
    header: 'State',
    size: 80,
    filterVariant: 'select',
  }),
  columnHelper.accessor('salary', {
    header: 'Salary',
    size: 130,
    filterVariant: 'range',
    Cell: ({ cell }) =>
      cell.getValue<number>().toLocaleString('en-US', {
        style: 'currency',
        currency: 'USD',
        maximumFractionDigits: 0,
      }),
    aggregationFn: 'mean',
    AggregatedCell: ({ cell }) => (
      <Box component="span" fs="italic">
        Avg:{' '}
        {cell.getValue<number>().toLocaleString('en-US', {
          style: 'currency',
          currency: 'USD',
          maximumFractionDigits: 0,
        })}
      </Box>
    ),
  }),
  columnHelper.accessor('status', {
    header: 'Status',
    size: 110,
    filterVariant: 'select',
    Cell: ({ cell }) => {
      const value = cell.getValue<Person['status']>()
      const color =
        value === 'active' ? 'green' : value === 'inactive' ? 'gray' : 'yellow'
      return (
        <Badge color={color} variant="light" tt="capitalize">
          {value}
        </Badge>
      )
    },
  }),
])

function App() {
  const [data, setData] = React.useState(() => makeData(50))

  const table = useMantineReactTable({
    columns,
    data,
    enableColumnFilters: true,
    enableColumnOrdering: true,
    enableColumnPinning: true,
    enableColumnResizing: true,
    enableExpanding: false,
    enableFacetedValues: true,
    enableGlobalFilter: true,
    enableGrouping: true,
    enablePagination: true,
    enableRowActions: true,
    enableRowSelection: true,
    enableEditing: true,
    editDisplayMode: 'modal',
    createDisplayMode: 'modal',
    initialState: {
      pagination: { pageIndex: 0, pageSize: 10 },
    },
    positionToolbarAlertBanner: 'bottom',
    renderRowActionMenuItems: () => (
      <>
        <Box style={{ padding: '6px 16px', cursor: 'pointer' }}>
          View Profile
        </Box>
        <Box style={{ padding: '6px 16px', cursor: 'pointer' }}>Edit</Box>
      </>
    ),
    renderTopToolbarCustomActions: () => (
      <Group gap="xs">
        <Button variant="default" onClick={() => setData(makeData(50))}>
          Regenerate Data
        </Button>
        <Button variant="default" onClick={() => setData(makeData(1_000))}>
          1k rows
        </Button>
      </Group>
    ),
  })

  return (
    <Box p="xl">
      <Stack gap="xs" mb="lg">
        <Title order={3}>Mantine React Table</Title>
        <Text c="dimmed" size="sm">
          TanStack Table v9 + Mantine v9 — full feature set
        </Text>
      </Stack>
      <MantineReactTable table={table} />
    </Box>
  )
}

const rootElement = document.getElementById('root')
if (!rootElement) throw new Error('Failed to find the root element')

ReactDOM.createRoot(rootElement).render(
  <React.StrictMode>
    <MantineProvider defaultColorScheme="auto">
      <App />
    </MantineProvider>
  </React.StrictMode>,
)
import * as React from 'react'
import ReactDOM from 'react-dom/client'

import '@mantine/core/styles.css'

import {
  Badge,
  Box,
  Button,
  Group,
  MantineProvider,
  Stack,
  Text,
  Title,
} from '@mantine/core'

import {
  MantineReactTable,
  createMRTColumnHelper,
  useMantineReactTable,
} from './mantine-react-table'
import { makeData } from './makeData'
import type { Person } from './makeData'
import './index.css'

const columnHelper = createMRTColumnHelper<Person>()

const columns = columnHelper.columns([
  columnHelper.accessor('firstName', {
    header: 'First Name',
    size: 140,
  }),
  columnHelper.accessor('lastName', {
    header: 'Last Name',
    size: 140,
  }),
  columnHelper.accessor('email', {
    header: 'Email',
    size: 220,
    Cell: ({ cell }) => (
      <a href={`mailto:${cell.getValue<string>()}`}>
        {cell.getValue<string>()}
      </a>
    ),
  }),
  columnHelper.accessor('age', {
    header: 'Age',
    size: 80,
    filterVariant: 'range',
  }),
  columnHelper.accessor('jobTitle', {
    header: 'Job Title',
    size: 200,
  }),
  columnHelper.accessor('city', {
    header: 'City',
    size: 140,
  }),
  columnHelper.accessor('state', {
    header: 'State',
    size: 80,
    filterVariant: 'select',
  }),
  columnHelper.accessor('salary', {
    header: 'Salary',
    size: 130,
    filterVariant: 'range',
    Cell: ({ cell }) =>
      cell.getValue<number>().toLocaleString('en-US', {
        style: 'currency',
        currency: 'USD',
        maximumFractionDigits: 0,
      }),
    aggregationFn: 'mean',
    AggregatedCell: ({ cell }) => (
      <Box component="span" fs="italic">
        Avg:{' '}
        {cell.getValue<number>().toLocaleString('en-US', {
          style: 'currency',
          currency: 'USD',
          maximumFractionDigits: 0,
        })}
      </Box>
    ),
  }),
  columnHelper.accessor('status', {
    header: 'Status',
    size: 110,
    filterVariant: 'select',
    Cell: ({ cell }) => {
      const value = cell.getValue<Person['status']>()
      const color =
        value === 'active' ? 'green' : value === 'inactive' ? 'gray' : 'yellow'
      return (
        <Badge color={color} variant="light" tt="capitalize">
          {value}
        </Badge>
      )
    },
  }),
])

function App() {
  const [data, setData] = React.useState(() => makeData(50))

  const table = useMantineReactTable({
    columns,
    data,
    enableColumnFilters: true,
    enableColumnOrdering: true,
    enableColumnPinning: true,
    enableColumnResizing: true,
    enableExpanding: false,
    enableFacetedValues: true,
    enableGlobalFilter: true,
    enableGrouping: true,
    enablePagination: true,
    enableRowActions: true,
    enableRowSelection: true,
    enableEditing: true,
    editDisplayMode: 'modal',
    createDisplayMode: 'modal',
    initialState: {
      pagination: { pageIndex: 0, pageSize: 10 },
    },
    positionToolbarAlertBanner: 'bottom',
    renderRowActionMenuItems: () => (
      <>
        <Box style={{ padding: '6px 16px', cursor: 'pointer' }}>
          View Profile
        </Box>
        <Box style={{ padding: '6px 16px', cursor: 'pointer' }}>Edit</Box>
      </>
    ),
    renderTopToolbarCustomActions: () => (
      <Group gap="xs">
        <Button variant="default" onClick={() => setData(makeData(50))}>
          Regenerate Data
        </Button>
        <Button variant="default" onClick={() => setData(makeData(1_000))}>
          1k rows
        </Button>
      </Group>
    ),
  })

  return (
    <Box p="xl">
      <Stack gap="xs" mb="lg">
        <Title order={3}>Mantine React Table</Title>
        <Text c="dimmed" size="sm">
          TanStack Table v9 + Mantine v9 — full feature set
        </Text>
      </Stack>
      <MantineReactTable table={table} />
    </Box>
  )
}

const rootElement = document.getElementById('root')
if (!rootElement) throw new Error('Failed to find the root element')

ReactDOM.createRoot(rootElement).render(
  <React.StrictMode>
    <MantineProvider defaultColorScheme="auto">
      <App />
    </MantineProvider>
  </React.StrictMode>,
)