json-to-table-mui
Version:
A lightweight React component to render JSON data as a responsive Material UI table with built-in pagination, sorting, and search.
59 lines (58 loc) • 3.91 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useState } from 'react';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination, TableSortLabel, Paper, TextField } from '@mui/material';
const JsonToTable = ({ data, headerBgColor = '#1976d2', headerFontColor = '#ffffff', footerBgColor = '#e0e0e0', footerFontColor = '#000000', bodyFontColor = '#000000', onFirstValueClick }) => {
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(5);
const [orderBy, setOrderBy] = useState('');
const [order, setOrder] = useState('asc');
const [search, setSearch] = useState('');
const columns = useMemo(() => data.length > 0 ? Object.keys(data[0]) : [], [data]);
const handleSort = (property) => {
const isAsc = orderBy === property && order === 'asc';
setOrder(isAsc ? 'desc' : 'asc');
setOrderBy(property);
};
const filteredData = useMemo(() => {
if (!search)
return data;
return data.filter(row => columns.some(col => String(row[col]).toLowerCase().includes(search.toLowerCase())));
}, [search, data, columns]);
const sortedData = useMemo(() => {
if (!orderBy)
return filteredData;
return [...filteredData].sort((a, b) => {
if (a[orderBy] < b[orderBy])
return order === 'asc' ? -1 : 1;
if (a[orderBy] > b[orderBy])
return order === 'asc' ? 1 : -1;
return 0;
});
}, [filteredData, orderBy, order]);
const paginatedData = useMemo(() => {
const start = page * rowsPerPage;
return sortedData.slice(start, start + rowsPerPage);
}, [sortedData, page, rowsPerPage]);
return (_jsxs(Paper, { children: [_jsx(TextField, { label: "Search", variant: "outlined", fullWidth: true, margin: "normal", value: search, onChange: (e) => setSearch(e.target.value) }), _jsx(TableContainer, { children: _jsxs(Table, { children: [_jsx(TableHead, { children: _jsx(TableRow, { children: columns.map((col) => (_jsx(TableCell, { sx: {
backgroundColor: headerBgColor,
color: headerFontColor,
fontWeight: 'bold',
}, children: _jsx(TableSortLabel, { active: orderBy === col, direction: orderBy === col ? order : 'asc', onClick: () => handleSort(col), children: col }) }, col))) }) }), _jsx(TableBody, { children: paginatedData.map((row, index) => (_jsx(TableRow, { sx: {
backgroundColor: footerBgColor,
color: footerFontColor,
fontWeight: 'medium',
textAlign: 'center',
}, children: columns.map((col, index) => (index === 0
? _jsx(TableCell, { sx: {
cursor: 'pointer',
textDecoration: 'underline'
}, onClick: () => onFirstValueClick(row), children: row[col] }, col)
: _jsx(TableCell, { sx: {
cursor: 'none',
textDecoration: 'none'
}, children: row[col] }, col))) }, index))) })] }) }), _jsx(TablePagination, { component: "div", count: sortedData.length, page: page, onPageChange: (e, newPage) => setPage(newPage), rowsPerPage: rowsPerPage, onRowsPerPageChange: (e) => {
setRowsPerPage(parseInt(e.target.value, 10));
setPage(0);
}, rowsPerPageOptions: [5, 10, 25] })] }));
};
export default JsonToTable;