@itwin/itwinui-react
Version:
A react component library for iTwinUI
157 lines (156 loc) • 5.11 kB
JavaScript
import * as React from 'react';
import cx from 'classnames';
import { Box, useIntersection, useMergedRefs } from '../../utils/index.js';
import { TableCell } from './TableCell.js';
export const TableRow = (props) => {
let {
row,
rowProps,
isLast,
onRowInViewport,
onBottomReached,
intersectionMargin,
onClick,
subComponent,
isDisabled,
tableHasSubRows,
tableInstance,
expanderCell,
scrollContainerRef,
tableRowRef,
density,
virtualItem,
virtualizer,
} = props;
let onIntersect = React.useCallback(() => {
onRowInViewport.current?.(row.original);
isLast && onBottomReached.current?.();
}, [isLast, onBottomReached, onRowInViewport, row.original]);
let intersectionRoot = React.useMemo(() => {
let isTableScrollable =
(scrollContainerRef?.scrollHeight ?? 0) >
(scrollContainerRef?.offsetHeight ?? 0);
if (isTableScrollable) return scrollContainerRef;
}, [scrollContainerRef]);
let intersectionRef = useIntersection(onIntersect, {
rootMargin: `${intersectionMargin}px`,
root: intersectionRoot,
});
let userRowProps = rowProps?.(row) ?? {};
let { status, isLoading, ...restUserRowProps } = userRowProps;
let mergedProps = {
...row.getRowProps({
style: {
flex: '0 0 auto',
minWidth: '100%',
...(null != virtualItem
? {
transform: `translateY(${virtualItem.start}px)`,
}
: {}),
},
}),
...restUserRowProps,
...{
className: cx(
'iui-table-row',
{
'iui-table-row-expanded': row.isExpanded && subComponent,
'iui-loading': isLoading,
},
userRowProps?.className,
),
'aria-selected': row.isSelected || void 0,
'aria-disabled': isDisabled || void 0,
'data-iui-status': status,
'data-iui-index': virtualItem?.index,
...(null != virtualItem && {
'data-iui-virtualizer': 'item',
}),
},
};
let refs = useMergedRefs(
intersectionRef,
mergedProps.ref,
tableRowRef,
virtualizer?.measureElement,
);
return React.createElement(
React.Fragment,
null,
React.createElement(
Box,
{
...mergedProps,
key: mergedProps.key,
ref: refs,
onClick: (event) => {
mergedProps?.onClick?.(event);
onClick?.(event, row);
},
},
row.cells.map((cell, index) =>
React.createElement(TableCell, {
key: cell.getCellProps().key,
cell: cell,
cellIndex: index,
isDisabled: isDisabled,
tableHasSubRows: tableHasSubRows,
tableInstance: tableInstance,
expanderCell: expanderCell,
density: density,
}),
),
),
);
};
let hasAnySelectedSubRow = (row, selectedRowIds) => {
if (selectedRowIds?.[row.id]) return true;
return row.subRows.some((subRow) =>
hasAnySelectedSubRow(subRow, selectedRowIds),
);
};
export const TableRowMemoized = React.memo(
TableRow,
(prevProp, nextProp) =>
prevProp.isLast === nextProp.isLast &&
prevProp.state.hiddenColumns?.length ===
nextProp.state.hiddenColumns?.length &&
!!prevProp.state.hiddenColumns?.every(
(column, index) => nextProp.state.hiddenColumns?.[index] === column,
) &&
prevProp.onRowInViewport === nextProp.onRowInViewport &&
prevProp.onBottomReached === nextProp.onBottomReached &&
prevProp.onClick === nextProp.onClick &&
prevProp.row.original === nextProp.row.original &&
prevProp.state.selectedRowIds?.[prevProp.row.id] ===
nextProp.state.selectedRowIds?.[nextProp.row.id] &&
prevProp.row.subRows.some((subRow) =>
hasAnySelectedSubRow(subRow, prevProp.state.selectedRowIds),
) ===
nextProp.row.subRows.some((subRow) =>
hasAnySelectedSubRow(subRow, nextProp.state.selectedRowIds),
) &&
prevProp.state.expanded?.[prevProp.row.id] ===
nextProp.state.expanded?.[nextProp.row.id] &&
prevProp.subComponent === nextProp.subComponent &&
prevProp.row.cells.every(
(cell, index) => nextProp.row.cells[index].column === cell.column,
) &&
prevProp.isDisabled === nextProp.isDisabled &&
prevProp.rowProps === nextProp.rowProps &&
prevProp.expanderCell === nextProp.expanderCell &&
prevProp.tableHasSubRows === nextProp.tableHasSubRows &&
prevProp.scrollContainerRef === nextProp.scrollContainerRef &&
prevProp.state.columnOrder === nextProp.state.columnOrder &&
!nextProp.state.columnResizing.isResizingColumn &&
prevProp.state.isTableResizing === nextProp.state.isTableResizing &&
prevProp.state.sticky.isScrolledToLeft ===
nextProp.state.sticky.isScrolledToLeft &&
prevProp.state.sticky.isScrolledToRight ===
nextProp.state.sticky.isScrolledToRight &&
prevProp.density === nextProp.density &&
prevProp.virtualizer === nextProp.virtualizer &&
prevProp.virtualItem?.index === nextProp.virtualItem?.index &&
prevProp.virtualItem?.start === nextProp.virtualItem?.start,
);