React | Table
by matox
HTML
<div id="root"></div>
CSS
/* Center tables for demo */
.tableSearch {
display: flex;
justify-content: center;
margin: 1rem 0;
}
table {
margin: 0 auto;
}
/* Default Table Style */
table {
color: #333;
background: white;
border: 1px solid grey;
font-size: 12pt;
border-collapse: collapse;
}
table thead th,
table tfoot th {
color: #777;
background: rgba(0,0,0,.1);
}
table caption {
padding:.5em;
}
table th,
table td {
padding: .5em;
border: 1px solid lightgrey;
}
/* Zebra Table Style */
[data-table-theme*=zebra] tbody tr:nth-of-type(odd) {
background: rgba(0,0,0,.05);
}
[data-table-theme*=zebra][data-table-theme*=dark] tbody tr:nth-of-type(odd) {
background: rgba(255,255,255,.05);
}
/* Dark Style */
[data-table-theme*=dark] {
color: #ddd;
background: #333;
font-size: 12pt;
border-collapse: collapse;
}
[data-table-theme*=dark] thead th,
[data-table-theme*=dark] tfoot th {
color: #aaa;
background: rgba(0255,255,255,.15);
}
[data-table-theme*=dark] caption {
padding:.5em;
}
[data-table-theme*=dark] th,
[data-table-theme*=dark] td {
padding: .5em;
border: 1px solid grey;
}
React
function Table(props) {
const [table, setTable] = React.useState([]);
const [searchQuery, setSearchQuery] = React.useState();
const [tableSort, setTableSort] = React.useState({field: 'id', asc: true});
React.useEffect(() => {
async function fetchData() {
/* const response = await fetch('https://table.free.beeceptor.com/data'); */
const response = {
status: 200,
text: () => new Promise((resolve, reject) => {
resolve('[{"id":"627a9d0f7e286a09bf041aa1","isActive":true,"age":28,"name":"Horton Franklin","company":"BARKARAMA"},{"id":"627a9d0fc04ffcab2f575f42","isActive":true,"age":20,"name":"Lee Landry","company":"XANIDE"},{"id":"627a9d0f3f69fd8b7bf14063","isActive":false,"age":36,"name":"Carey Mcdowell","company":"MOBILDATA"},{"id":"627a9d0f4c430e638ecb8779","isActive":true,"age":22,"name":"Karina Patton","company":"SONGLINES"},{"id":"627a9d0f273d7cc7aaac61c5","isActive":true,"age":26,"name":"Dora Leach","company":"BRAINQUIL"},{"id":"627a9d0f39fecf79c80005c2","isActive":true,"age":37,"name":"Norton Christensen","company":"CANDECOR"}]')
})
};
if (response.status === 200) {
const json = JSON.parse(await response.text());
setTable(json);
}
}
fetchData();
}, []);
const sortTable = (a, b) => {
const {field, asc} = tableSort;
const [fa, fb] = [a[field], b[field]].map(String);
return ((fa < fb) ? 1 : -1) * (asc ? 1 : -1);
}
const tableRows = table
.filter(row => {
if (searchQuery == null) {
return row;
}
const obj = JSON.stringify(row).toLowerCase();
const q = searchQuery.toLowerCase();
return obj.includes(q) ? row : null;
})
.sort(sortTable)
.map((row) =>
<TableRow
key={row.id}
row={row}
/>
);
const handleSearch = (query) => setSearchQuery(query);
const handleSort = (field) => {
const state = tableSort;
setTableSort({
...