Skip to main content

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

PropTypeDefaultDescription
dataT[][]Array of data to display
columnsColumn[][]Column definitions
loadingbooleanfalseWhether data is loading
sortablebooleantrueWhether sorting is enabled
filterablebooleantrueWhether filtering is enabled
selectablebooleanfalseWhether 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
classNamestring-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

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

  1. Keep columns focused - Don't overload tables with too many columns
  2. Use meaningful labels - Make column headers clear and descriptive
  3. Implement proper sorting - Ensure sort logic is efficient and correct
  4. Handle empty states - Show appropriate messages when no data exists
  5. Optimize rendering - Use virtualization for large datasets
  6. Test keyboard navigation - Ensure accessibility compliance
  • SearchBar - For table filtering
  • Pagination - For table pagination
  • Button - For action buttons in table rows
  • Badge - For status indicators in table cells