UNPKG

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
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;