In this section, we will explore how to integrate DataTables with React applications using Tailwind CSS. We will cover two approaches: utilizing a dedicated library and implementing DataTables without a library. Before we begin, ensure that you have installed and configured Tailwind CSS within your React project.
To start, we will create a simple user interface for the DataTable using React and Tailwind CSS.
import React from 'react';
const data = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' },
{ id: 3, name: 'Bob Johnson', email: '[email protected]' },
];
const DataTable = () => {
return (
<div className="flex flex-col container mx-auto">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
ID
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Name
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Email
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{data.map((item) => (
<tr key={item.id}>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{item.id}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{item.name}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{item.email}</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
);
};
export default DataTable;
Let’s build a sortable data table using React and Tailwind CSS.
import React, { useState } from 'react';
const data = [
{ id: 1, name: 'John Doe', email: '[email protected]', age: 32 },
{ id: 2, name: 'Jane Smith', email: '[email protected]', age: 27 },
{ id: 3, name: 'Bob Johnson', email: '[email protected]', age: 45 },
];
const SortableDataTable = () => {
const [sortColumn, setSortColumn] = useState(null);
const [sortDirection, setSortDirection] = useState(null);
const handleSort = (column) => {
if (sortColumn === column) {
setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
} else {
setSortColumn(column);
setSortDirection('asc');
}
};
const sortedData = sortColumn
? [...data].sort((a, b) => {
const valueA = a[sortColumn];
const valueB = b[sortColumn];
if (valueA < valueB) return sortDirection === 'asc' ? -1 : 1;
if (valueA > valueB) return sortDirection === 'asc' ? 1 : -1;
return 0;
})
: data;
return (
<div className="flex flex-col">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
onClick={() => handleSort('id')}
>
ID
{sortColumn === 'id' && (
<span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
)}
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
onClick={() => handleSort('name')}
>
Name
{sortColumn === 'name' && (
<span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
)}
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
onClick={() => handleSort('email')}
>
Email
{sortColumn === 'email' && (
<span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
)}
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
onClick={() => handleSort('age')}
>
Age
{sortColumn === 'age' && (
<span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
)}
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{sortedData.map((item) => (
<tr key={item.id}>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{item.id}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{item.name}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{item.email}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{item.age}</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
);
};
export default SortableDataTable;
To create a visually appealing and feature-rich data table in our React application, we will utilize the powerful react-data-table-component library and leverage the utility-first classes provided by Tailwind CSS for styling.
First, you’ll need to install the react-data-table-component library:
npm install react-data-table-component
Then, you can create a new component and import the necessary modules from the library.
import React, { useState } from 'react';
import DataTable from 'react-data-table-component';
const data = [
{ id: 1, name: 'John Doe', email: '[email protected]', age: 32 },
{ id: 2, name: 'Jane Smith', email: '[email protected]', age: 27 },
{ id: 3, name: 'Bob Johnson', email: '[email protected]', age: 45 },
{ id: 4, name: 'Alice Williams', email: '[email protected]', age: 19 },
{ id: 5, name: 'Tom Davis', email: '[email protected]', age: 35 },
{ id: 6, name: 'Sara Lee', email: '[email protected]', age: 28 },
];
const columns = [
{
name: 'ID',
selector: (row) => row.id,
sortable: true,
},
{
name: 'Name',
selector: (row) => row.name,
sortable: true,
},
{
name: 'Email',
selector: (row) => row.email,
sortable: true,
},
{
name: 'Age',
selector: (row) => row.age,
sortable: true,
},
];
const DataTableExample = () => {
const [filterText, setFilterText] = useState('');
const filteredData = data.filter(
(item) =>
item.name.toLowerCase().includes(filterText.toLowerCase()) ||
item.email.toLowerCase().includes(filterText.toLowerCase())
);
return (
<div className="container mx-auto px-4">
<div className="mb-4">
<label htmlFor="filter" className="block font-medium text-gray-700">
Filter:
</label>
<input
type="text"
id="filter"
value={filterText}
onChange={(e) => setFilterText(e.target.value)}
className="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>
<DataTable
columns={columns}
data={filteredData}
pagination
highlightOnHover
pointerOnHover
className="rounded-lg shadow-md"
customStyles={{
headRow: {
style: {
backgroundColor: '#f3f4f6',
},
},
headCells: {
style: {
color: '#4b5563',
fontSize: '0.875rem',
fontWeight: 600,
textTransform: 'uppercase',
},
},
rows: {
style: {
'&:nth-of-type(even)': {
backgroundColor: '#f9fafb',
},
},
},
cells: {
style: {
color: '#374151',
fontSize: '0.875rem',
},
},
}}
/>
</div>
);
};
export default DataTableExample;
Sources
- react useState (react.dev)
- Table Layout (tailwindcss.com/docs)
- react-data-table-component
See Also
How to Add Drag-and-Drop Image Upload with Dropzone in React Using Tailwind CSS