import classNames from 'classnames' import React, { ReactNode } from 'react' import { SortDirection } from '../hooks/use-order-by' import { SortButton } from './sort-button' import { Tooltip } from '../util/tooltip' export type ColumnConfiguraton> = { /** Unique column ID, used for sorting purposes and to get the value of the cell using rowItem[key] */ key: keyof T /** Column title */ label: string /** If defined, the column is considered sortable. @see SortButton */ onSort?: () => void sortDirection?: SortDirection /** CSS class string. @example "w-24 md:w-32" */ width: string /** Aligns column content. */ align?: 'left' | 'right' /** A warning to be rendered as a tooltip for the column header */ metricWarning?: string /** * Function used to transform the value found at item[key] for the cell. Superseded by renderItem if present. @example 1120 => "1.1k" */ renderValue?: (item: T) => ReactNode /** Function used to create richer cells */ renderItem?: (item: T) => ReactNode } export const TableHeaderCell = ({ children, className, align }: { children: ReactNode className: string align?: 'left' | 'right' }) => { return ( {children} ) } export const TableCell = ({ children, className, align }: { children: ReactNode className: string align?: 'left' | 'right' }) => { return ( {children} ) } export const ItemRow = >({ rowIndex, pageIndex, item, columns }: { rowIndex: number pageIndex?: number item: T columns: ColumnConfiguraton[] }) => { return ( {columns.map(({ key, width, align, renderValue, renderItem }) => ( {renderItem ? renderItem(item) : renderValue ? renderValue(item) : (item[key] ?? '')} ))} ) } export const Table = >({ data, columns }: { columns: ColumnConfiguraton[] data: T[] | { pages: T[][] } }) => { const renderColumnLabel = (column: ColumnConfiguraton) => { if (column.metricWarning) { return ( {column.label + ' *'} ) } else { return column.label } } const warningSpan = (warning: string) => { return ( {'*' + warning} ) } return ( {columns.map((column) => ( {column.onSort ? ( {renderColumnLabel(column)} ) : ( renderColumnLabel(column) )} ))} {Array.isArray(data) ? data.map((item, rowIndex) => ( )) : data.pages.map((page, pageIndex) => page.map((item, rowIndex) => ( )) )}
) }