DataTable Component
** Last Built**: September 2, 2025 at 4:19 PM The DataTable component provides a comprehensive data display table with built-in sorting, filtering, pagination, and row selection capabilities.
Import
// DataTable component is available in the live scope
Basic Usage
<DataTable
data={users}
columns={[
{ key: 'id', label: 'ID', sortable: true },
{ key: 'name', label: 'Name', sortable: true },
{ key: 'email', label: 'Email', sortable: true },
{ key: 'role', label: 'Role', sortable: true }
]}
onSort={(key, direction) => handleSort(key, direction)}
onRowSelect={(selectedRows) => setSelectedRows(selectedRows)}
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | [] | Array of data to display |
columns | Column[] | [] | Column definitions |
loading | boolean | false | Whether data is loading |
sortable | boolean | true | Whether sorting is enabled |
filterable | boolean | true | Whether filtering is enabled |
selectable | boolean | false | Whether row selection is enabled |
onSort | (key: string, direction: 'asc' | 'desc') => void | - | Sort change handler |
onRowSelect | (selectedRows: T[]) => void | - | Row selection handler |
onRowClick | (row: T) => void | - | Row click handler |
className | string | - | Additional CSS classes |
Column Definition
interface Column {
key: string;
label: string;
sortable?: boolean;
filterable?: boolean;
width?: string | number;
render?: (value: any, row: T) => ReactNode;
}
Examples
Basic Data Table
const users = [
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'User' }
];
const columns = [
{ key: 'id', label: 'ID', sortable: true },
{ key: 'name', label: 'Name', sortable: true },
{ key: 'email', label: 'Email', sortable: true },
{ key: 'role', label: 'Role', sortable: true }
];
<DataTable
data={users}
columns={columns}
onSort={(key, direction) => console.log(`Sorting ${key} by ${direction}`)}
/>
With Custom Column Rendering
const columns = [
{ key: 'id', label: 'ID', sortable: true },
{ key: 'name', label: 'Name', sortable: true },
{ key: 'status', label: 'Status', sortable: true,
render: (value) => (
<Badge variant={value === 'active' ? 'success' : 'danger'}>
{value}
</Badge>
)
},
{
key: 'actions',
label: 'Actions',
sortable: false,
render: (_, row) => (
<div className="flex space-x-2">
<Button size="sm" onClick={() => editUser(row)}>Edit</Button>
<Button size="sm" variant="danger" onClick={() => deleteUser(row.id)}>Delete</Button>
</div>
)
}
];
With Row Selection
const [selectedRows, setSelectedRows] = useState([]);
<DataTable
data={users}
columns={columns}
selectable={true}
onRowSelect={setSelectedRows}
/>
{selectedRows.length > 0 && (
<div className="mt-4">
<Button variant="danger" onClick={() => deleteSelectedUsers(selectedRows)}
>
Delete Selected ({selectedRows.length})
</Button>
</div>
)}
With Loading State
const [loading, setLoading] = useState(false);
const [users, setUsers] = useState([]);
useEffect(() => {
const fetchUsers = async () => {
setLoading(true);
try {
const response = await fetch('/api/users');
const data = await response.json();
setUsers(data);
} catch (error) {
console.error('Failed to fetch users:', error);
} finally {
setLoading(false);
};
fetchUsers();
}, []);
<DataTable
data={users}
columns={columns}
loading={loading}
/>
Integration with Other Components
With SearchBar
const [searchTerm, setSearchTerm] = useState('');
const [filteredData, setFilteredData] = useState(users);
useEffect(() => {
const filtered = users.filter(user => user.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.email.toLowerCase().includes(searchTerm.toLowerCase())
);
setFilteredData(filtered);
}, [searchTerm, users]);
return (
<div className="space-y-4">
<SearchBar
value={searchTerm}
onChange={setSearchTerm}
placeholder="Search users..."
/>
<DataTable
data={filteredData}
columns={columns}
/>
</div>
);
With Pagination
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const totalPages = Math.ceil(users.length / pageSize);
const startIndex = (currentPage - 1) * pageSize;
const endIndex = startIndex + pageSize;
const paginatedData = users.slice(startIndex, endIndex);
return (
<div className="space-y-4">
<DataTable
data={paginatedData}
columns={columns}
/>
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={setCurrentPage}
pageSize={pageSize}
onPageSizeChange={setPageSize}
/>
</div>
);
Accessibility
The DataTable component includes comprehensive accessibility features:
- Proper ARIA labels and descriptions
- Keyboard navigation support
- Screen reader compatibility
- Focus management
- Sort state announcements
<DataTable
data={users}
columns={columns}
aria-label="Users data table"
aria-describedby="table-description"
/>
Best Practices
- Keep columns focused - Don't overload tables with too many columns
- Use meaningful labels - Make column headers clear and descriptive
- Implement proper sorting - Ensure sort logic is efficient and correct
- Handle empty states - Show appropriate messages when no data exists
- Optimize rendering - Use virtualization for large datasets
- Test keyboard navigation - Ensure accessibility compliance
Related Components
- SearchBar - For table filtering
- Pagination - For table pagination
- Button - For action buttons in table rows
- Badge - For status indicators in table cells