feat: configure resizable tables and basic styles

This commit is contained in:
Sylvia Crowe 2024-05-21 12:14:04 -07:00
parent 304a54a994
commit c8a8f108ba
2 changed files with 91 additions and 21 deletions

View File

@ -1,17 +1,48 @@
.dir-table {
overflow: auto;
width: 100%;
border: 2px solid var(--border-color);
border-radius: 3px;
.dir-table-head {
.dir-table-head-row {
display: flex;
border-bottom: 2px solid var(--border-color);
padding: 4px 0;
.dir-table-head-cell {
position: relative;
padding: 2px 4px;
.dir-table-head-resize {
position: absolute;
top: 0;
right: 0;
height: 100%;
cursor: col-resize;
user-select: none;
touch-action: none;
width: 2px;
background: linear-gradient(var(--border-color), var(--border-color)) no-repeat center/2px 100%;
}
&:last-child {
.dir-table-head-resize {
width: 0;
}
}
}
}
}
.dir-table-body {
.dir-table-body-row {
display: flex;
border-radius: 3px;
&:focus {
background-color: var(--highlight-bg-color);
background-color: var(--accent-color);
}
.dir-table-body-cell {
overflow: hidden;
padding: 0.25rem;
}
}
}

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import React from "react";
import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { createColumnHelper, flexRender, getCoreRowModel, useReactTable, Table } from "@tanstack/react-table";
import "./directorytable.less";
@ -36,34 +36,73 @@ function DirectoryTable<T, U>({ data }: DirectoryTableProps) {
getCoreRowModel: getCoreRowModel(),
});
const columnSizeVars = React.useMemo(() => {
const headers = table.getFlatHeaders();
const colSizes: { [key: string]: number } = {};
for (let i = 0; i < headers.length; i++) {
const header = headers[i]!;
colSizes[`--header-${header.id}-size`] = header.getSize();
colSizes[`--col-${header.column.id}-size`] = header.column.getSize();
}
return colSizes;
}, [table.getState().columnSizingInfo]);
return (
<table className="dir-table">
<thead className="dir-table-head">
<div className="dir-table" style={{ ...columnSizeVars }}>
<div className="dir-table-head">
{table.getHeaderGroups().map((headerGroup) => (
<tr className="dir-table-head-row" key={headerGroup.id}>
<div className="dir-table-head-row" key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th className="dir-table-head-cell" key={header.id}>
<div
className="dir-table-head-cell"
key={header.id}
style={{ width: `calc(var(--header-${header.id}-size) * 1px)` }}
>
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</th>
<div
className="dir-table-head-resize"
onMouseDown={header.getResizeHandler()}
onTouchStart={header.getResizeHandler()}
/>
</div>
))}
</tr>
</div>
))}
</thead>
<tbody className="dir-table-body">
{table.getRowModel().rows.map((row) => (
<tr className="dir-table-body-row" key={row.id} tabIndex={0}>
{row.getVisibleCells().map((cell) => (
<td className="dir-table-body-cell" key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
{table.getState().columnSizingInfo.isResizingColumn ? (
<MemoizedTableBody table={table} />
) : (
<TableBody table={table} />
)}
</div>
);
}
function TableBody({ table }: { table: Table<FileInfo> }) {
return (
<div className="dir-table-body">
{table.getRowModel().rows.map((row) => (
<div className="dir-table-body-row" key={row.id} tabIndex={0}>
{row.getVisibleCells().map((cell) => (
<div
className="dir-table-body-cell"
key={cell.id}
style={{ width: `calc(var(--col-${cell.column.id}-size) * 1px)` }}
>
{cell.renderValue<any>()}
</div>
))}
</div>
))}
</div>
);
}
const MemoizedTableBody = React.memo(
TableBody,
(prev, next) => prev.table.options.data == next.table.options.data
) as typeof TableBody;
export { DirectoryTable };