da158cfd84
Tests / test (push) Successful in 2m26s
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/5
61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import * as React from 'react';
|
|
import styles from './DataTable.module.scss';
|
|
|
|
export interface IColumn<T> {
|
|
key: string;
|
|
header: string;
|
|
render: (row: T) => React.ReactNode;
|
|
align?: 'left' | 'right' | 'center';
|
|
width?: string;
|
|
// Держит колонку у правого края видимой области при горизонтальной
|
|
// прокрутке — чтобы кнопки действий не уезжали за край на узких экранах.
|
|
sticky?: boolean;
|
|
}
|
|
|
|
export interface IDataTableProps<T> {
|
|
columns: IColumn<T>[];
|
|
rows: T[];
|
|
keyOf: (row: T) => string | number;
|
|
emptyMessage: string;
|
|
}
|
|
|
|
export function DataTable<T>({ columns, rows, keyOf, emptyMessage }: IDataTableProps<T>): React.ReactElement {
|
|
return (
|
|
<div className={styles.wrap}>
|
|
<div className={styles.scroll}>
|
|
<table className={styles.table}>
|
|
<thead>
|
|
<tr>
|
|
{columns.map(col => (
|
|
<th
|
|
key={col.key}
|
|
className={col.sticky ? styles.stickyCell : undefined}
|
|
style={{ width: col.width, textAlign: col.align ?? 'left' }}
|
|
>
|
|
{col.header}
|
|
</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{rows.map(row => (
|
|
<tr key={keyOf(row)}>
|
|
{columns.map(col => (
|
|
<td
|
|
key={col.key}
|
|
className={col.sticky ? styles.stickyCell : undefined}
|
|
style={{ textAlign: col.align ?? 'left' }}
|
|
>
|
|
{col.render(row)}
|
|
</td>
|
|
))}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{rows.length === 0 && <div className={styles.empty}>{emptyMessage}</div>}
|
|
</div>
|
|
);
|
|
}
|