DEV Community

Michael Turner
Michael Turner

Posted on

Getting Started with Mantine DataTable in React: Building Your First Data Table

Mantine DataTable is a lightweight, feature-rich data table component built on top of Mantine UI and TanStack Table. It provides essential table functionality like sorting, filtering, pagination, and row selection with a clean, modern API. This guide walks through setting up and creating your first interactive data table using Mantine DataTable with React, from installation to a working implementation. This is part 10 of a series on using Mantine DataTable with React.

Prerequisites

Before you begin, make sure you have:

  • Node.js version 16.0 or higher installed
  • npm, yarn, or pnpm package manager
  • A React project (version 16.8 or higher) or create-react-app setup
  • Basic knowledge of React hooks (useState)
  • Mantine UI installed (required dependency)

Installation

First, install Mantine UI core (required dependency):

npm install @mantine/core @mantine/hooks
Enter fullscreen mode Exit fullscreen mode

Then install Mantine DataTable:

npm install mantine-datatable
Enter fullscreen mode Exit fullscreen mode

Or install everything with yarn:

yarn add @mantine/core @mantine/hooks mantine-datatable
Enter fullscreen mode Exit fullscreen mode

Or with pnpm:

pnpm add @mantine/core @mantine/hooks mantine-datatable
Enter fullscreen mode Exit fullscreen mode

After installation, your package.json should include:

{
  "dependencies": {
    "mantine-datatable": "^7.0.0",
    "@mantine/core": "^7.0.0",
    "@mantine/hooks": "^7.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Project Setup

Mantine requires a theme provider. Set up your app with the Mantine provider. Update your main entry file:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import '@mantine/core/styles.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <MantineProvider>
      <App />
    </MantineProvider>
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

First Example / Basic Usage

Let's create a simple data table component. Create a new file src/DataTable.jsx:

// src/DataTable.jsx
import React from 'react';
import { DataTable } from 'mantine-datatable';

function DataTable() {
  // Sample data - array of objects
  const records = [
    { id: 1, name: 'John Doe', email: 'john@example.com', age: 28, department: 'Engineering' },
    { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 32, department: 'Marketing' },
    { id: 3, name: 'Bob Johnson', email: 'bob@example.com', age: 45, department: 'Sales' },
    { id: 4, name: 'Alice Williams', email: 'alice@example.com', age: 29, department: 'Engineering' }
  ];

  // Column definitions
  const columns = [
    { accessor: 'id', title: 'ID' },
    { accessor: 'name', title: 'Name' },
    { accessor: 'email', title: 'Email' },
    { accessor: 'age', title: 'Age' },
    { accessor: 'department', title: 'Department' }
  ];

  return (
    <div style={{ padding: '20px' }}>
      <h2>Employee Data Table</h2>
      <DataTable
        records={records}
        columns={columns}
        withTableBorder
        withColumnBorders
        striped
        highlightOnHover
      />
    </div>
  );
}

export default DataTable;
Enter fullscreen mode Exit fullscreen mode

Now, update your App.jsx to use the data table:

// src/App.jsx
import React from 'react';
import { Container, Title } from '@mantine/core';
import DataTable from './DataTable';
import './App.css';

function App() {
  return (
    <Container size="xl" py="xl">
      <Title order={1} mb="lg">Mantine DataTable Example</Title>
      <DataTable />
    </Container>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This creates a fully functional data table with:

  • Bordered table and columns
  • Striped rows for better readability
  • Hover highlighting
  • Clean, modern styling from Mantine

Understanding the Basics

Mantine DataTable uses a simple, declarative API where:

  • records: Array of data objects, where each object represents a table row
  • columns: Array of column definition objects
  • accessor: Property key in your data objects
  • title: Optional column header text (defaults to accessor if not provided)

Key concepts:

  • Records: Your data array - each object is a row
  • Columns: Define which fields to display and how
  • Accessor: Maps to a property in your record objects
  • Props: Enable features like borders, stripes, hover effects

Here's a simpler example with minimal configuration:

// src/SimpleTable.jsx
import React from 'react';
import { DataTable } from 'mantine-datatable';

function SimpleTable() {
  const records = [
    { id: 1, name: 'Item 1', value: 100 },
    { id: 2, name: 'Item 2', value: 200 },
    { id: 3, name: 'Item 3', value: 300 }
  ];

  const columns = [
    { accessor: 'id' },
    { accessor: 'name' },
    { accessor: 'value' }
  ];

  return (
    <DataTable records={records} columns={columns} />
  );
}

export default SimpleTable;
Enter fullscreen mode Exit fullscreen mode

Practical Example / Building Something Real

Let's build a product inventory table with more features:

// src/ProductInventory.jsx
import React, { useState } from 'react';
import { DataTable } from 'mantine-datatable';
import { Text, Badge, Box } from '@mantine/core';

function ProductInventory() {
  const [records, setRecords] = useState([
    { 
      id: 1, 
      name: 'Laptop', 
      category: 'Electronics', 
      price: 999.99, 
      stock: 15, 
      status: 'In Stock' 
    },
    { 
      id: 2, 
      name: 'Mouse', 
      category: 'Electronics', 
      price: 29.99, 
      stock: 8, 
      status: 'Low Stock' 
    },
    { 
      id: 3, 
      name: 'Keyboard', 
      category: 'Electronics', 
      price: 79.99, 
      stock: 12, 
      status: 'In Stock' 
    },
    { 
      id: 4, 
      name: 'Monitor', 
      category: 'Electronics', 
      price: 299.99, 
      stock: 5, 
      status: 'Low Stock' 
    },
    { 
      id: 5, 
      name: 'Desk Chair', 
      category: 'Furniture', 
      price: 199.99, 
      stock: 20, 
      status: 'In Stock' 
    }
  ]);

  const columns = [
    { 
      accessor: 'id', 
      title: 'ID',
      textAlign: 'right',
      width: 80
    },
    { 
      accessor: 'name', 
      title: 'Product Name',
      width: 200
    },
    { 
      accessor: 'category', 
      title: 'Category',
      width: 150
    },
    { 
      accessor: 'price', 
      title: 'Price',
      textAlign: 'right',
      width: 120,
      render: ({ price }) => `$${price.toFixed(2)}`
    },
    { 
      accessor: 'stock', 
      title: 'Stock',
      textAlign: 'right',
      width: 100,
      render: ({ stock }) => (
        <Text 
          fw={stock < 10 ? 700 : 400} 
          c={stock < 10 ? 'red' : 'inherit'}
        >
          {stock}
        </Text>
      )
    },
    { 
      accessor: 'status', 
      title: 'Status',
      width: 120,
      render: ({ status }) => (
        <Badge 
          color={status === 'In Stock' ? 'green' : 'orange'}
          variant="light"
        >
          {status}
        </Badge>
      )
    }
  ];

  return (
    <Box p="xl">
      <Text size="xl" fw={700} mb="md">Product Inventory</Text>
      <DataTable
        records={records}
        columns={columns}
        withTableBorder
        borderRadius="sm"
        withColumnBorders
        striped
        highlightOnHover
        minHeight={200}
        onRowClick={({ record }) => {
          console.log('Clicked row:', record);
        }}
      />
    </Box>
  );
}

export default ProductInventory;
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Custom cell rendering with React components (Badge, Text)
  • Conditional styling based on data values
  • Right-aligned numeric columns
  • Custom formatting (currency for price)
  • Row click handling
  • Column width specification
  • Status badges with color coding

Common Issues / Troubleshooting

  1. Table not rendering: Ensure you've wrapped your app with MantineProvider from @mantine/core and imported the Mantine CSS (@mantine/core/styles.css).

  2. Data not displaying: Verify that your records array contains objects and that columns accessors match the property names in your records.

  3. Styling issues: Make sure you've imported Mantine's CSS. The DataTable component relies on Mantine's styling system.

  4. TypeScript errors: If using TypeScript, ensure you have proper type definitions. Mantine DataTable has built-in TypeScript support.

  5. Missing Mantine components: If you use Mantine components (like Badge, Text) in custom renders, make sure @mantine/core is installed.

Next Steps

Now that you have a basic understanding of Mantine DataTable:

  • Learn about advanced features like sorting, filtering, and pagination
  • Explore row selection and bulk operations
  • Implement server-side data loading
  • Add custom cell renderers and formatters
  • Discover column resizing and reordering
  • Check the official documentation: https://icflorescu.github.io/mantine-datatable/
  • Look for part 11 of this series for more advanced topics

Summary

You've successfully set up Mantine DataTable in your React application and created your first interactive data table. The component provides a clean, simple API for building data-rich interfaces with essential table functionality, all styled with Mantine's modern design system.

Top comments (0)