import { memo, useEffect, useRef } from 'react'; import { areEqual, FixedSizeList } from 'react-window'; import { Row } from 'react-table'; import { useTableContext } from './Tablev2.component'; import { HeadRow, TableRow, TableBody, TableHeader, SortCaret, } from './Tablestyle'; import { TableHeightKeyType, TableLocalType, TableVariantType, } from './TableUtils'; import { RenderRowType, TableRows, useTableScrollbar } from './TableCommon'; import useSyncedScroll from './useSyncedScroll'; import { Loader } from '../loader/Loader.component'; import { Box } from '../box/Box'; import { spacing } from '../../spacing'; export type SingleSelectableContentProps< DATA_ROW extends Record = Record, > = { rowHeight: TableHeightKeyType; separationLineVariant: TableVariantType; onRowSelected?: (row: Row) => void; selectedId?: string; locale?: TableLocalType; customItemKey?: (index: number, data: DATA_ROW) => string; hasScrollbar?: boolean; isLoadingMoreItems?: boolean; children?: (rows: JSX.Element) => JSX.Element; autoScrollToSelected?: boolean; }; export function SingleSelectableContent< DATA_ROW extends Record = Record, >({ rowHeight = 'h40', separationLineVariant = 'backgroundLevel3', locale = 'en', selectedId, isLoadingMoreItems, onRowSelected, customItemKey, children, autoScrollToSelected = false, }: SingleSelectableContentProps) { if (selectedId && !onRowSelected) { console.error('Please specify the onRowSelected function.'); } const { headerRef } = useSyncedScroll(); const listRef = useRef[]>>(null); const { headerGroups, prepareRow, rows, setRowHeight } = useTableContext(); useEffect(() => { setRowHeight(rowHeight); }, [rowHeight, setRowHeight]); useEffect(() => { if (!autoScrollToSelected || !selectedId || !listRef.current) return; const selectedIndex = rows.findIndex((row) => row.id === selectedId); if (selectedIndex < 0) return; const timer = setTimeout(() => { if (!listRef.current) return; listRef.current.scrollToItem(selectedIndex, 'center'); }, 100); return () => clearTimeout(timer); }, [autoScrollToSelected, selectedId, rows]); const RenderRow = memo(({ index, style }: RenderRowType) => { const row = rows[index]; prepareRow(row); let rowProps = row.getRowProps({ /** * Note: We need to pass the style property to the row component. * Otherwise when we scroll down, the next rows are flashing * because they are re-rendered in loop. */ style: { ...style }, }); rowProps = { ...rowProps, ...{ onClick: () => { if (onRowSelected) return onRowSelected(row); }, tabIndex: onRowSelected ? 0 : undefined, onKeyDown: (event) => { if ( onRowSelected && (event.key === ' ' || event.key === 'Enter' || event.key === 'Spacebar') ) { event.preventDefault(); onRowSelected(row); } }, }, }; return ( {row.cells.map((cell) => { let cellProps = cell.getCellProps({ style: { ...cell.column.cellStyle, // Vertically center the text in cells. display: 'flex', flexDirection: 'column', justifyContent: 'center', }, role: 'gridcell', }); return (
{cell.render('Cell')}
); })}
); }, areEqual); const { hasScrollbar, scrollBarWidth, handleScrollbarWidth } = useTableScrollbar(); return ( <>
{headerGroups.map((headerGroup) => ( {headerGroup.headers.map((column) => { const headerStyleProps = column.getHeaderProps( Object.assign(column.getSortByToggleProps(), { style: { ...column.cellStyle, position: 'relative' }, }), ); return ( { if ( !column.disableSortBy && (event.key === ' ' || event.key === 'Enter' || event.key === 'Spacebar') ) { event.preventDefault(); // @ts-expect-error - getSortByToggleProps is joined to getHeaderProps headerStyleProps.onClick(event); } }} >
{column.render('Header')}
); })}
))}
{isLoadingMoreItems && ( )} ); }