A powerful, customizable data table component for React applications with TypeScript support. Features sorting, pagination, scrolling, and extensive styling options with zero dependencies.
npm install @aniruddha1806/data-table
- 📊 Flexible data display with customizable columns
- 🔄 Multi-column sorting with visual indicators
- 📄 Built-in pagination with page navigation
- 📱 Responsive design with horizontal scrolling
- 🎨 Extensive styling customization (styles + classNames)
- 📏 Fixed headers with vertical scrolling
- 🔍 Custom cell rendering with render functions
- 📝 Empty state handling
- 🎯 TypeScript support with full type definitions
- ♿ Accessibility features
- 🪶 Zero external dependencies
import { DataTable } from '@aniruddha1806/data-table';
function App() {
const data = [
{ id: 1, name: 'John Doe', email: 'john@example.com', age: 30 },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 25 },
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', age: 35 }
];
const columns = [
{ key: 'id', header: 'ID', sorting: true },
{ key: 'name', header: 'Name', sorting: true },
{ key: 'email', header: 'Email', sorting: true },
{ key: 'age', header: 'Age', sorting: true }
];
return (
<DataTable
data={data}
columns={columns}
/>
);
}
Prop | Type | Default | Description |
---|---|---|---|
data |
T[] |
[] |
Array of data objects to display |
columns |
Column<T>[] |
[] |
Column configuration array |
className |
string |
"" |
CSS class for the wrapper container |
tableClassName |
string |
"" |
CSS class for the table element |
headerClassName |
string |
"" |
CSS class for header rows |
rowClassName |
string |
"" |
CSS class for data rows |
cellClassName |
string |
"" |
CSS class for table cells |
emptyMessage |
ReactNode |
"No data available" |
Message shown when no data |
pagination |
PaginationProps |
undefined |
Pagination configuration |
scrollable |
boolean |
false |
Enable horizontal scrolling |
maxHeight |
string |
undefined |
Maximum height with vertical scroll |
Prop | Type | Default | Description |
---|---|---|---|
key |
string |
required |
Data property key |
header |
ReactNode |
required |
Column header content |
render |
(row: T) => ReactNode |
undefined |
Custom cell render function |
sorting |
boolean |
false |
Enable sorting for this column |
width |
string |
undefined |
Fixed column width |
Prop | Type | Default | Description |
---|---|---|---|
currentPage |
number |
required |
Current active page |
pageSize |
number |
required |
Number of items per page |
totalItems |
number |
required |
Total number of items |
onPageChange |
(page: number) => void |
required |
Page change callback |
showPageNumbers |
boolean |
true |
Show page number buttons |
maxPageButtons |
number |
5 |
Maximum page buttons to show |
Simple data table with sorting:
import { DataTable } from '@aniruddha1806/data-table';
function BasicTable() {
const users = [
{ id: 1, name: 'Alice Johnson', role: 'Admin', status: 'Active' },
{ id: 2, name: 'Bob Smith', role: 'User', status: 'Inactive' },
{ id: 3, name: 'Carol Davis', role: 'Editor', status: 'Active' }
];
const columns = [
{ key: 'id', header: 'ID', sorting: true, width: '80px' },
{ key: 'name', header: 'Name', sorting: true },
{ key: 'role', header: 'Role', sorting: true },
{ key: 'status', header: 'Status', sorting: true }
];
return (
<DataTable
data={users}
columns={columns}
/>
);
}
Add pagination for large datasets:
import { useState } from 'react';
import { DataTable } from '@aniruddha1806/data-table';
function PaginatedTable() {
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 10;
// Large dataset
const allData = Array.from({ length: 100 }, (_, i) => ({
id: i + 1,
name: `User ${i + 1}`,
email: `user${i + 1}@example.com`,
department: ['Engineering', 'Marketing', 'Sales', 'HR'][i % 4]
}));
const columns = [
{ key: 'id', header: 'ID', sorting: true },
{ key: 'name', header: 'Name', sorting: true },
{ key: 'email', header: 'Email', sorting: true },
{ key: 'department', header: 'Department', sorting: true }
];
const paginationConfig = {
currentPage,
pageSize,
totalItems: allData.length,
onPageChange: setCurrentPage,
showPageNumbers: true,
maxPageButtons: 5
};
return (
<DataTable
data={allData}
columns={columns}
pagination={paginationConfig}
/>
);
}
Use custom render functions for complex cell content:
import { DataTable } from '@aniruddha1806/data-table';
function CustomRenderTable() {
const products = [
{
id: 1,
name: 'Laptop',
price: 999.99,
stock: 15,
category: 'Electronics',
image: '/laptop.jpg'
},
{
id: 2,
name: 'Phone',
price: 699.99,
stock: 0,
category: 'Electronics',
image: '/phone.jpg'
}
];
const columns = [
{
key: 'image',
header: 'Image',
render: (row) => (
<img
src={row.image || "/placeholder.svg"}
alt={row.name}
style={{ width: '40px', height: '40px', borderRadius: '4px' }}
/>
)
},
{ key: 'name', header: 'Product', sorting: true },
{
key: 'price',
header: 'Price',
sorting: true,
render: (row) => (
<span style={{ fontWeight: 'bold', color: '#059669' }}>
${row.price.toFixed(2)}
</span>
)
},
{
key: 'stock',
header: 'Stock',
sorting: true,
render: (row) => (
<span style={{
padding: '4px 8px',
borderRadius: '12px',
fontSize: '12px',
fontWeight: 'bold',
backgroundColor: row.stock > 0 ? '#dcfce7' : '#fee2e2',
color: row.stock > 0 ? '#166534' : '#991b1b'
}}>
{row.stock > 0 ? `${row.stock} in stock` : 'Out of stock'}
</span>
)
},
{
key: 'actions',
header: 'Actions',
render: (row) => (
<div style={{ display: 'flex', gap: '8px' }}>
<button style={{
padding: '4px 8px',
fontSize: '12px',
backgroundColor: '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}>
Edit
</button>
<button style={{
padding: '4px 8px',
fontSize: '12px',
backgroundColor: '#ef4444',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}>
Delete
</button>
</div>
)
}
];
return (
<DataTable
data={products}
columns={columns}
/>
);
}
Enable scrolling for large tables:
import { DataTable } from '@aniruddha1806/data-table';
function ScrollableTable() {
const wideData = Array.from({ length: 50 }, (_, i) => ({
id: i + 1,
col1: `Data ${i + 1}-1`,
col2: `Data ${i + 1}-2`,
col3: `Data ${i + 1}-3`,
col4: `Data ${i + 1}-4`,
col5: `Data ${i + 1}-5`,
col6: `Data ${i + 1}-6`,
col7: `Data ${i + 1}-7`,
col8: `Data ${i + 1}-8`
}));
const columns = [
{ key: 'id', header: 'ID', sorting: true, width: '80px' },
{ key: 'col1', header: 'Column 1', sorting: true, width: '150px' },
{ key: 'col2', header: 'Column 2', sorting: true, width: '150px' },
{ key: 'col3', header: 'Column 3', sorting: true, width: '150px' },
{ key: 'col4', header: 'Column 4', sorting: true, width: '150px' },
{ key: 'col5', header: 'Column 5', sorting: true, width: '150px' },
{ key: 'col6', header: 'Column 6', sorting: true, width: '150px' },
{ key: 'col7', header: 'Column 7', sorting: true, width: '150px' },
{ key: 'col8', header: 'Column 8', sorting: true, width: '150px' }
];
return (
<DataTable
data={wideData}
columns={columns}
scrollable={true}
maxHeight="400px"
/>
);
}
The component provides full TypeScript support:
import { DataTable, Column, DataTableProps } from '@aniruddha1806/data-table';
interface User {
id: number;
name: string;
email: string;
role: 'admin' | 'user' | 'editor';
createdAt: Date;
}
const UserTable: React.FC = () => {
const users: User[] = [
{
id: 1,
name: 'John Doe',
email: 'john@example.com',
role: 'admin',
createdAt: new Date('2023-01-15')
}
];
const columns: Column<User>[] = [
{ key: 'id', header: 'ID', sorting: true },
{ key: 'name', header: 'Name', sorting: true },
{ key: 'email', header: 'Email', sorting: true },
{
key: 'role',
header: 'Role',
sorting: true,
render: (user: User) => (
<span style={{ textTransform: 'capitalize' }}>
{user.role}
</span>
)
},
{
key: 'createdAt',
header: 'Created',
sorting: true,
render: (user: User) => user.createdAt.toLocaleDateString()
}
];
const tableProps: DataTableProps<User> = {
data: users,
columns,
className: 'user-table'
};
return <DataTable {...tableProps} />;
};