hyperdx/packages/app/src/components/Table.tsx
Warren e42b78fe53
fix + ci: fix table type + setup unit test ci (#130)
1. Added tsc type check to app lint cmd so it would capture type errors going forward (ex: regression from this PR 03f78dde12)
2. Run app unit tests
2023-11-28 22:32:04 +00:00

114 lines
3 KiB
TypeScript

import * as React from 'react';
import cx from 'classnames';
import {
useReactTable,
getCoreRowModel,
flexRender,
ColumnDef,
} from '@tanstack/react-table';
import { UNDEFINED_WIDTH } from '../tableUtils';
import styles from './Table.module.scss';
type TableProps<T extends Record<string, unknown> | string[]> = {
data?: T[];
columns: ColumnDef<T>[];
emptyMessage?: string;
hideHeader?: boolean;
borderless?: boolean;
density?: 'compact' | 'normal' | 'comfortable';
interactive?: boolean;
};
export const Table = <T extends Record<string, unknown> | string[]>({
data = [],
columns,
emptyMessage,
hideHeader,
borderless,
density = 'normal',
interactive,
}: TableProps<T>) => {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
});
if (!data.length) {
return <div className={styles.emptyMessage}>{emptyMessage}</div>;
}
return (
<div
className={cx(styles.tableWrapper, {
[styles.tableBorderless]: borderless,
[styles.tableDensityCompact]: density === 'compact',
[styles.tableDensityComfortable]: density === 'comfortable',
[styles.tableInteractive]: interactive,
})}
>
<table>
{!hideHeader && (
<thead>
{table.getHeaderGroups().map(headerGroup => (
<tr key={headerGroup.id}>
{headerGroup.headers.map(header => (
<th
key={header.id}
style={{
width:
header.column.getSize() === UNDEFINED_WIDTH
? '100%'
: header.column.getSize(),
}}
>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</th>
))}
</tr>
))}
</thead>
)}
<tbody>
{table.getRowModel().rows.map(row => (
<tr key={row.id}>
{row.getVisibleCells().map(cell => (
<td
key={cell.id}
style={{
width:
cell.column.getSize() === UNDEFINED_WIDTH
? '100%'
: cell.column.getSize(),
}}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
};
export const TableCellButton: React.VFC<{
title?: string;
label: React.ReactNode;
biIcon?: string;
onClick: VoidFunction;
}> = ({ onClick, title, label, biIcon }) => {
return (
<button className={styles.tableCellButton} title={title} onClick={onClick}>
{label && <span>{label}</span>}
{biIcon ? <i className={`bi bi-${biIcon}`} /> : null}
</button>
);
};