import MUITable, { TableProps as MUITableProps } from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableHead from '@mui/material/TableHead'; import { TablePaginationProps as MUITablePaginationProps } from '@mui/material/TablePagination'; import { TablePaginationActionsProps } from '@mui/material/TablePagination/TablePaginationActions'; import TableRow from '@mui/material/TableRow'; import clsx from 'clsx'; import React, { Fragment, memo, ReactNode } from 'react'; import { When } from 'react-if'; import { HeaderCell, HeaderCellProps, HeaderProps } from './HeaderCell/HeaderCell'; import { Pagination, PaginationProps } from './Pagination/Pagination'; import { Toolbar, ToolbarProps } from './Toolbar/Toolbar'; import css from './Table.module.scss'; export type TableLabels = Pick & Pick & Pick; export interface TableQAs { /** Data-qa applied to the root table */ table: string; /** Data-qa applied to the pagination components */ pagination: string; /** * Data-qa applied to the toolbar * @deprecated A toolbar in a table is more than a table should do. */ toolbar: string; /** Data-qa applied to the header wrapper */ header: string; /** Data-qa applied to the header row */ headerRow: string; /** Data-qa applied to each header cell */ headerCell: string; /** Data-qa applied to the table body wrapper */ tableBody: string; } export interface TableCustomClasses { /** Custom class(es) for table */ table?: string[]; /** * Custom class(es) for table toolbar * @deprecated A toolbar in a table is more than a table component should do. See Toolbar component. */ tableToolbar?: string[]; /** Custom class(es) for table paginations */ tablePagination?: string[]; /** Custom class(es) for table pagination actions */ tablePaginationActions?: string[]; /** Custom class(es) for table header */ tableHeader?: string[]; /** Custom class(es) for table header row */ tableHeaderRow?: string[]; /** Custom class(es) for table header cell */ tableHeaderCell?: string[]; /** Custom class(es) for table body */ tableBody?: string[]; /** * Custom class(es) for table toolbar searchbar * @deprecated A toolbar in a table is more than a table component should do. See Toolbar component. */ tableSearchbar?: string[]; } export interface TableProps extends Pick< ToolbarProps, 'onsearchclear' | 'onsearchinput' | 'paperElevation' | 'extraIcons' | 'searchdebounce' | 'clearSearch' >, Pick, Pick, Pick< MUITablePaginationProps, 'rowsPerPage' | 'rowsPerPageOptions' | 'page' | 'onPageChange' | 'onRowsPerPageChange' >, MUITableProps { /** Headers for the table */ headers: HeaderProps[]; /** Map that defines how the headers are sorted, either by key or function when targeting nested properties */ headermapping: Map; /** The amount of rows for the table (generally the length of the data) */ rowcount: number; /** Labels used in the table */ labels: TableLabels; /** Data-qa's used in the table */ tableqas: TableQAs; /** Content for the table */ tablebodycontent: ReactNode; /** Customization CSS classes for table components */ tablecss?: TableCustomClasses; /** * Control whether the top bar pagination should be shown * @default false */ showTopPagination?: boolean; /** * Control whether the bottom bar pagination should be shown * @default false */ showBottomPagination?: boolean; /** * The component used for displaying the actions. * Either a string to use a HTML element or a component. * @default TablePaginationActions */ customPagination?: React.ElementType; /** * Disables the table toolbar * @default false * @deprecated A toolbar in a table is more than a table component should do. See Toolbar component. */ disableToolbar?: boolean; /** Additional props to pass to the Material UI Table component */ TableProps?: MUITableProps; /** Additional props to pass to each of the Header cell components */ HeaderCellProps?: HeaderCellProps; /** * Additional props to pass to the toolbar component * @deprecated A toolbar in a table is more than a table component should do. See Toolbar component. */ ToolbarProps?: ToolbarProps; /** Additional props to pass the the pagination component */ PaginationProps?: MUITablePaginationProps; } const renderTablePagination = (props: TableProps, customClasses: string) => { return ( ); }; const renderTableHead = ( props: TableProps, addCustomClasses: (component: keyof TableCustomClasses, baseClass?: string) => string[] ) => ( {props.headers.map((header, index) => ( ))} ); /** * Constructs a table using pre-defined Rijkswaterstaat styling * @param props Props to pass to the table * @example * ```jsx * , * clickEvent: () => console.log('Clicked button!'), * tooltipText: 'Tooltip on button', * } * ]} * tablebodycontent={( * * {props.data * .slice(props.tablePage * props.tableRowsPerPage, props.tablePage * props.tableRowsPerPage + Number(props.tableRowsPerPage)) * .map((item, index) => { * return ( * * * * * ); * }) * } * * )} * /> * ``` */ export const Table = memo( ({ showTopPagination = false, showBottomPagination = false, disableToolbar = false, ...props }: TableProps) => { const addCustomClasses = (component: keyof TableCustomClasses, baseClass?: string): string[] => { const classes: string[] = []; if (baseClass) classes.push(baseClass); if (props.tablecss && props.tablecss[component]) classes.push(...props.tablecss[component]!); // eslint-disable-line @typescript-eslint/no-non-null-assertion return classes; }; // TODO -as- 20210421 a toolbar in a table component is too much for one component. Deprecated the toolbar props. // use the separate Toolbar component. return ( {renderTablePagination(props, clsx(addCustomClasses('tablePagination', css.tableTopPagination)))} {renderTableHead(props, addCustomClasses)} {props.tablebodycontent} {renderTablePagination(props, clsx(addCustomClasses('tablePagination')))} ); } );