import * as React from 'react'; import styled from '@emotion/styled'; import { ColumnDef, flexRender, getCoreRowModel, useReactTable, } from '@tanstack/react-table'; import TableHeader from './table-header/TableHeader'; import { FilterConfigType, SelectedFilterType, } from '../../interfaces/filters/interface'; import { SortType, SelectedSortType } from '../../interfaces/sorts/interface'; declare module 'react' { function forwardRef( render: (props: P, ref: React.Ref) => React.ReactElement | null, ): (props: P & React.RefAttributes) => React.ReactElement | null; } type OwnProps< TData extends { id: string; __typename: 'companies' | 'people' }, SortField, > = { data: Array; columns: Array>; viewName: string; viewIcon?: React.ReactNode; availableSorts?: Array>; availableFilters?: FilterConfigType[]; onSortsUpdate?: (sorts: Array>) => void; onFiltersUpdate?: (filters: Array>) => void; onRowSelectionChange?: (rowSelection: string[]) => void; }; const StyledTable = styled.table` min-width: 1000px; width: calc(100% - ${(props) => props.theme.spacing(4)}); border-radius: 4px; border-spacing: 0; border-collapse: collapse; margin-left: ${(props) => props.theme.spacing(2)}; margin-right: ${(props) => props.theme.spacing(2)}; th { border-collapse: collapse; color: ${(props) => props.theme.text40}; padding: 0; border: 1px solid ${(props) => props.theme.tertiaryBackground}; text-align: left; :last-child { border-right-color: transparent; } :first-of-type { border-left-color: transparent; } } td { border-collapse: collapse; color: ${(props) => props.theme.text80}; padding: 0; border: 1px solid ${(props) => props.theme.tertiaryBackground}; text-align: left; :last-child { border-right-color: transparent; } :first-of-type { border-left-color: transparent; } } `; const StyledTableWithHeader = styled.div` display: flex; flex-direction: column; flex: 1; width: 100%; `; const StyledTableScrollableContainer = styled.div` overflow: auto; height: 100%; flex: 1; `; const Table = < TData extends { id: string; __typename: 'companies' | 'people' }, SortField, >( { data, columns, viewName, viewIcon, availableSorts, availableFilters, onSortsUpdate, onFiltersUpdate, onRowSelectionChange, }: OwnProps, ref: React.ForwardedRef<{ resetRowSelection: () => void } | undefined>, ) => { const [internalRowSelection, setInternalRowSelection] = React.useState({}); const table = useReactTable({ data, columns, state: { rowSelection: internalRowSelection, }, getCoreRowModel: getCoreRowModel(), enableRowSelection: true, onRowSelectionChange: setInternalRowSelection, getRowId: (row) => row.id, }); const selectedRows = table.getSelectedRowModel().rows; React.useEffect(() => { const selectedRowIds = selectedRows.map((row) => row.original.id); onRowSelectionChange && onRowSelectionChange(selectedRowIds); }, [onRowSelectionChange, selectedRows]); React.useImperativeHandle(ref, () => { return { resetRowSelection: () => { table.resetRowSelection(); }, }; }); return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.map((row, index) => ( {row.getVisibleCells().map((cell) => { return ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ); })} ))} ); }; export default React.forwardRef(Table);