improved theming, error handling, table sort
This commit is contained in:
parent
35256ba88d
commit
7ce0e543ec
11 changed files with 151 additions and 68 deletions
|
@ -1,13 +1,22 @@
|
|||
.Button {
|
||||
border: solid var(--border-size-thin) var(--color-primary);
|
||||
border: solid var(--border-size-thin);
|
||||
padding: var(--padding-normal);
|
||||
|
||||
color: var(--color-primary);
|
||||
background: var(--color-background);
|
||||
}
|
||||
|
||||
.Button:hover, .Button:active {
|
||||
.Button:enabled {
|
||||
border-color: var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.Button:hover:enabled {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-background);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.Button:disabled {
|
||||
border-color: var(--color-text);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
.DataTable > table {
|
||||
table-layout: auto;
|
||||
|
||||
border-collapse: separate;
|
||||
border-spacing: calc(2*var(--padding-normal));
|
||||
}
|
||||
|
|
|
@ -1,24 +1,13 @@
|
|||
import {ReactNode} from "react";
|
||||
import {ReactNode, useState} from "react";
|
||||
import './DataTable.css';
|
||||
|
||||
export type DataTableColumnDefinition<T> = {
|
||||
field: string,
|
||||
label?: string,
|
||||
visualize?: (value: T) => ReactNode
|
||||
visualize?: (value: T) => ReactNode,
|
||||
sorter?: (a: T, b: T) => number
|
||||
};
|
||||
|
||||
function TableHead({columns}: { columns: DataTableColumnDefinition<any>[] }) {
|
||||
return <thead className='DataTableHead'>
|
||||
<tr>
|
||||
{
|
||||
columns.map(column =>
|
||||
<th key={column.field}>
|
||||
{column.label ?? column.field}
|
||||
</th>)
|
||||
}
|
||||
</tr>
|
||||
</thead>;
|
||||
}
|
||||
|
||||
function DataTableRow({rowData, columns}: {
|
||||
rowData: any,
|
||||
|
@ -44,11 +33,46 @@ export default function DataTable<T>({data, columns, className}: {
|
|||
columns: DataTableColumnDefinition<any>[],
|
||||
className?: string
|
||||
}) {
|
||||
const [sortBy, setSortBy] = useState<DataTableColumnDefinition<any> | null>(null);
|
||||
const [sortReversed, setSortReversed] = useState(false);
|
||||
|
||||
const headerClick = (column: DataTableColumnDefinition<any>) => {
|
||||
console.log('column clicked', column);
|
||||
|
||||
if (column.field === sortBy?.field)
|
||||
setSortReversed(prevState => !prevState);
|
||||
else if (column.sorter)
|
||||
setSortBy(column);
|
||||
else
|
||||
console.log('cannot sort by', column)
|
||||
};
|
||||
|
||||
const dataToDisplay = [...data];
|
||||
const actualSorter = sortReversed && sortBy?.sorter
|
||||
? (a: T, b: T) => -sortBy.sorter!(a, b)
|
||||
: sortBy?.sorter;
|
||||
|
||||
dataToDisplay.sort(actualSorter)
|
||||
|
||||
console.log('sorted', {dataToDisplay});
|
||||
|
||||
return <div className={'DataTable ' + (className ?? '')}>
|
||||
<table>
|
||||
<TableHead columns={columns}/>
|
||||
<thead className='DataTableHead'>
|
||||
<tr>
|
||||
{
|
||||
columns.map(column =>
|
||||
<th key={column.field} onClick={() => headerClick(column)}>
|
||||
{column.label ?? column.field}
|
||||
</th>)
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((element, index) => <DataTableRow key={index} rowData={element} columns={columns}/>)}
|
||||
{
|
||||
dataToDisplay.map((element, index) =>
|
||||
<DataTableRow key={`${sortBy?.field}-${index}`} rowData={element} columns={columns}/>)
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue