update table component
This commit is contained in:
parent
176279ecb5
commit
41d682e9df
4 changed files with 167 additions and 28 deletions
|
|
@ -1,11 +1,12 @@
|
|||
import React from 'react';
|
||||
import usePagination, { Offset } from 'src/hooks/usePagination';
|
||||
|
||||
type DataItem = Record<string, any>;
|
||||
export type DataItem = Record<string, any>;
|
||||
|
||||
export interface Header {
|
||||
key: string;
|
||||
header: string;
|
||||
formatter?: (data: DataItem) => JSX.ElementType;
|
||||
formatter?: (data: DataItem) => string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
|
|
@ -14,33 +15,74 @@ interface Props {
|
|||
}
|
||||
|
||||
export default function Table({ data, headers }: Props): JSX.Element {
|
||||
function getProperty(data: DataItem, header: Header): any {
|
||||
if (header.key === 'index') {
|
||||
return 'index';
|
||||
const { items, changeOffset } = usePagination<DataItem>({ items: data });
|
||||
|
||||
function formatCell(data: DataItem, header: Header): JSX.Element {
|
||||
// This formatting is only used because the source is trusted (private markdown files manage only by me)
|
||||
// and because Astro don't allow me to pass JSX from an Astro file to a TSX file,
|
||||
// so I have to pass the formatted row as a string.
|
||||
// DON'T use this method on a public API
|
||||
if (header.formatter != null) {
|
||||
return (
|
||||
<div dangerouslySetInnerHTML={{ __html: header.formatter(data) }} />
|
||||
);
|
||||
}
|
||||
|
||||
return data[header.key];
|
||||
}
|
||||
|
||||
return (
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
{headers.map((item, idx) => (
|
||||
<th key={idx}>{item.header}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{data.map((item, idx) => (
|
||||
<tr key={idx}>
|
||||
{headers.map((header, hidx) => (
|
||||
<td key={hidx}>{getProperty(item.data, header)}</td>
|
||||
<>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
{headers.map((item, idx) => (
|
||||
<th key={idx}>{item.header}</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{items.map((item, idx) => (
|
||||
<tr key={idx}>
|
||||
{headers.map((header, hidx) => (
|
||||
<td key={hidx}>{formatCell(item, header)}</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<section>
|
||||
<button
|
||||
onClick={() => {
|
||||
changeOffset(Offset.First);
|
||||
}}
|
||||
>
|
||||
First
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
changeOffset(Offset.Prev);
|
||||
}}
|
||||
>
|
||||
Prev
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
changeOffset(Offset.Next);
|
||||
}}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
changeOffset(Offset.Last);
|
||||
}}
|
||||
>
|
||||
Last
|
||||
</button>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue