mui-smart-table
v1.0.0
Published
A smart, lightweight, scalable, customizable, and responsive table component built on top of MUI tables with modern React (hooks + TypeScript)
Maintainers
Readme
MUI Smart Table
A smart, lightweight, scalable, customizable, and responsive table component built on top of MUI tables with modern React (hooks + TypeScript).
🎭 Live Demo
Check out the interactive Storybook demo: mui-smart-table.github.io
🚀 Features
- ✅ Fully Responsive - Works seamlessly on desktop, tablet, and mobile
- ✅ Pagination - Both client-side and server-side pagination support with automatic state management
- ✅ Sorting - Clickable column headers with visual sort indicators
- ✅ Search - Built-in search with flexible configuration options
- ✅ Expandable Rows - Show additional details with custom or auto-generated content
- ✅ Action Columns - Flexible action buttons, menus, or custom components
- ✅ Custom Cell Rendering - Render any React component in table cells
- ✅ Smart Defaults - Minimal configuration needed for basic functionality
- ✅ TypeScript First - Full type safety and excellent developer experience
- ✅ Tree Shakeable - Import only what you need
- ✅ Lightweight - Minimal dependencies (React + MUI)
📦 Installation
npm install mui-smart-table
# Peer dependencies (if not already installed)
npm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styled🎯 Quick Start
import { SmartTable } from 'mui-smart-table';
import type { PageHeader } from 'mui-smart-table';
const users = [
{ id: 1, name: 'John Doe', email: '[email protected]', age: 30 },
{ id: 2, name: 'Jane Smith', email: '[email protected]', age: 25 },
];
const headers: PageHeader[] = [
{ field: 'name', label: 'Name', sortable: true },
{ field: 'email', label: 'Email', sortable: true },
{ field: 'age', label: 'Age', sortable: true, align: 'center' },
];
function App() {
return (
<SmartTable
data={users}
pageHeaders={headers}
/>
);
}📚 API Reference
SmartTableProps
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | T[] | - | Required. Array of data objects to display |
| pageHeaders | PageHeader[] | - | Required. Column definitions |
| totalCount | number | - | Total count for server-side pagination |
| page | number | 0 | Current page (0-indexed) |
| rowsPerPage | number | 10 | Number of rows per page |
| rowsPerPageOptions | number[] | [5, 10, 25, 50] | Available rows per page options |
| onPageChange | (page: number) => void | - | Callback for page changes |
| onRowsPerPageChange | (rows: number) => void | - | Callback for rows per page changes |
| onRowClick | (row: T) => void | - | Callback for row clicks |
| onSort | (field: string, direction: 'asc' \| 'desc') => void | - | Callback for sorting (server-side) |
| searchProps | SearchProps | - | Search configuration |
| expandable | ExpandableProps | - | Expandable rows configuration |
| actionColumn | ActionColumnProps | - | Action column configuration |
| classes | SmartTableClasses | {} | CSS class overrides |
| muiTableProps | TableProps | {} | Additional MUI Table props |
| muiTableCellProps | TableCellProps | {} | Additional MUI TableCell props |
| loading | boolean | false | Show loading state |
| emptyMessage | string | 'No data available' | Message when no data |
| scrollable | boolean | false | Enable scrolling with sticky header |
PageHeader
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| field | string | - | Required. Data field key |
| label | string | - | Required. Column header label |
| sortable | boolean | false | Enable sorting for this column |
| align | 'left' \| 'center' \| 'right' | 'left' | Text alignment |
| valign | 'top' \| 'middle' \| 'bottom' | 'middle' | Vertical alignment |
| width | number \| string | - | Column width |
| className | string | - | CSS class for the column |
| render | (value: any, row: any) => ReactNode | - | Custom cell renderer |
SearchProps
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| internal | boolean | true | Use client-side search |
| searchFields | string[] | - | Fields to search in |
| exactMatch | boolean | false | Use exact matching |
| regex | boolean | false | Enable regex search |
| caseInsensitive | boolean | true | Case insensitive search |
| onSearch | (term: string) => void | - | Server-side search callback |
🎨 Examples
Basic Table with Search and Pagination
import { SmartTable } from 'mui-smart-table';
const MyTable = () => {
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
return (
<SmartTable
data={users}
pageHeaders={headers}
page={page}
rowsPerPage={rowsPerPage}
onPageChange={setPage}
onRowsPerPageChange={setRowsPerPage}
searchProps={{
internal: true,
searchFields: ['name', 'email'],
caseInsensitive: true,
}}
/>
);
};Automatic Client-Side Pagination
If you don't provide onPageChange or onRowsPerPageChange callbacks, the table will automatically handle pagination internally:
<SmartTable
data={users}
pageHeaders={headers}
rowsPerPage={5}
rowsPerPageOptions={[5, 10, 20]}
// No pagination callbacks needed - handled automatically!
/>Custom Cell Rendering
const headers: PageHeader[] = [
{ field: 'name', label: 'Name', sortable: true },
{
field: 'status',
label: 'Status',
render: (value) => (
<Chip
label={value}
color={value === 'active' ? 'success' : 'default'}
size="small"
/>
),
},
{
field: 'avatar',
label: 'Avatar',
render: (value, row) => (
<Avatar src={value} alt={row.name}>
{row.name.charAt(0)}
</Avatar>
),
},
];Action Column
<SmartTable
data={users}
pageHeaders={headers}
actionColumn={{
position: 'end',
type: 'button',
renderAction: (row) => (
<div style={{ display: 'flex', gap: '4px' }}>
<IconButton onClick={() => viewUser(row)}>
<Visibility />
</IconButton>
<IconButton onClick={() => editUser(row)}>
<Edit />
</IconButton>
<IconButton onClick={() => deleteUser(row)} color="error">
<Delete />
</IconButton>
</div>
),
}}
/>Multiple Action Buttons with Separate Handlers
Use the new buttons array for multiple action buttons with individual handlers:
<SmartTable
data={users}
pageHeaders={headers}
actionColumn={{
position: 'end',
type: 'button',
buttons: [
{
label: 'View',
onClick: (row) => viewUser(row),
color: 'primary',
variant: 'outlined',
tooltip: 'View details',
},
{
label: 'Edit',
onClick: (row) => editUser(row),
color: 'secondary',
variant: 'contained',
disabled: (row) => !row.canEdit, // Conditionally disable
},
{
label: 'Delete',
onClick: (row) => deleteUser(row),
color: 'error',
variant: 'text',
hidden: (row) => row.role === 'admin', // Conditionally hide
},
],
}}
/>Expandable Rows
<SmartTable
data={users}
pageHeaders={headers}
expandable={{
renderExpanded: (row) => (
<Box sx={{ p: 2, bgcolor: 'grey.50' }}>
<Typography variant="h6">Additional Details</Typography>
<Grid container spacing={2}>
<Grid item xs={6}>
<Typography variant="body2">
Department: {row.department}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="body2">
Location: {row.location}
</Typography>
</Grid>
</Grid>
</Box>
),
}}
/>Server-Side Operations
const ServerSideTable = () => {
const [data, setData] = useState([]);
const [page, setPage] = useState(0);
const [totalCount, setTotalCount] = useState(0);
const [loading, setLoading] = useState(false);
const fetchData = async (pageNum: number, sort?: string, search?: string) => {
setLoading(true);
try {
const response = await api.getUsers({
page: pageNum,
limit: 10,
sort,
search,
});
setData(response.data);
setTotalCount(response.total);
} finally {
setLoading(false);
}
};
return (
<SmartTable
data={data}
totalCount={totalCount}
page={page}
loading={loading}
pageHeaders={headers}
onPageChange={(newPage) => {
setPage(newPage);
fetchData(newPage);
}}
onSort={(field, direction) => {
fetchData(page, `${field}:${direction}`);
}}
searchProps={{
onSearch: (term) => {
fetchData(0, undefined, term);
},
}}
/>
);
};🎭 Styling
Custom Classes
<SmartTable
data={users}
pageHeaders={headers}
classes={{
root: 'my-table-root',
table: 'my-table',
head: 'my-table-head',
body: 'my-table-body',
row: 'my-table-row',
cell: 'my-table-cell',
pagination: 'my-pagination',
search: 'my-search',
}}
/>MUI Theme Integration
import { createTheme, ThemeProvider } from '@mui/material/styles';
const theme = createTheme({
components: {
MuiTable: {
styleOverrides: {
root: {
'& .MuiTableHead-root': {
backgroundColor: '#f5f5f5',
},
},
},
},
},
});
<ThemeProvider theme={theme}>
<SmartTable data={users} pageHeaders={headers} />
</ThemeProvider>🔧 Development
# Clone the repository
git clone https://github.com/deepu9990/mui-smart-table.git
cd mui-smart-table
# Install dependencies
npm install
# Run tests
npm test
# Run Storybook (interactive demo)
npm run dev
# Open http://localhost:6006
# Build package
npm run build
# Build Storybook for production
npm run build-storybook
# Lint and format
npm run lint
npm run format🚀 Demo & Showcase
The package includes a comprehensive Storybook demo showcasing all features:
- Local Development: Run
npm run devand visithttp://localhost:6006 - Online Demo: Visit mui-smart-table.github.io
- GitHub Pages: Automatically deployed from
mainbranch via GitHub Actions
Demo Features
- Interactive examples of all table features
- Live code editing and testing
- Responsive design testing
- Performance demonstrations
- Real-world usage scenarios
🤝 Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
🐛 Issues & Support
- 🐛 Bug Reports: GitHub Issues
- 💡 Feature Requests: GitHub Issues
- 📖 Documentation: Storybook Demo
📊 Roadmap
- [ ] Column resizing & reordering
- [ ] Row selection (single/multi)
- [ ] Export to CSV/Excel
- [ ] Virtual scrolling for large datasets
- [ ] Sticky columns
- [ ] Advanced filtering
- [ ] Column grouping
- [ ] Summary rows
📄 License
MIT © deepu9990
