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 { .dir-table {
overflow: auto;
width: 100%;
border: 2px solid var(--border-color);
border-radius: 3px;
.dir-table-head { .dir-table-head {
.dir-table-head-row { .dir-table-head-row {
display: flex;
border-bottom: 2px solid var(--border-color);
padding: 4px 0;
.dir-table-head-cell { .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 {
.dir-table-body-row { .dir-table-body-row {
display: flex;
border-radius: 3px;
&:focus { &:focus {
background-color: var(--highlight-bg-color); background-color: var(--accent-color);
} }
.dir-table-body-cell { .dir-table-body-cell {
overflow: hidden;
padding: 0.25rem;
} }
} }
} }

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import React from "react"; 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"; import "./directorytable.less";
@ -36,34 +36,73 @@ function DirectoryTable<T, U>({ data }: DirectoryTableProps) {
getCoreRowModel: getCoreRowModel(), 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 ( return (
<table className="dir-table"> <div className="dir-table" style={{ ...columnSizeVars }}>
<thead className="dir-table-head"> <div className="dir-table-head">
{table.getHeaderGroups().map((headerGroup) => ( {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) => ( {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 {header.isPlaceholder
? null ? null
: flexRender(header.column.columnDef.header, header.getContext())} : flexRender(header.column.columnDef.header, header.getContext())}
</th> <div
className="dir-table-head-resize"
onMouseDown={header.getResizeHandler()}
onTouchStart={header.getResizeHandler()}
/>
</div>
))} ))}
</tr> </div>
))} ))}
</thead> </div>
<tbody className="dir-table-body"> {table.getState().columnSizingInfo.isResizingColumn ? (
{table.getRowModel().rows.map((row) => ( <MemoizedTableBody table={table} />
<tr className="dir-table-body-row" key={row.id} tabIndex={0}> ) : (
{row.getVisibleCells().map((cell) => ( <TableBody table={table} />
<td className="dir-table-body-cell" key={cell.id}> )}
{flexRender(cell.column.columnDef.cell, cell.getContext())} </div>
</td>
))}
</tr>
))}
</tbody>
</table>
); );
} }
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 }; export { DirectoryTable };