in src/table/table.tsx [186:350]
render() {
const {
data,
selection,
columns,
caption,
getItemKey,
selectable,
focused,
isItemSelectable,
getItemLevel,
getItemClassName,
getMetaColumnClassName,
getItemDataTest,
draggable,
alwaysShowDragHandle,
dragHandleTitle,
loading,
onSort,
sortKey,
sortOrder,
loaderClassName,
stickyHeader,
stickyHeaderOffset,
isItemCollapsible,
isParentCollapsible,
isItemCollapsed,
onItemCollapse,
onItemExpand,
isDisabledSelectionVisible,
getCheckboxTooltip,
onItemDoubleClick,
onItemClick,
renderEmpty,
RowComponent,
renderLoader,
} = this.props;
// NOTE: Do not construct new object per render because it causes all rows rerendering
const columnsArray = typeof columns === 'function' ? columns(null) : columns;
const headerProps: HeaderAttrs = {
caption,
selectable,
draggable,
columns: columnsArray,
onSort,
sortKey,
sortOrder,
sticky: stickyHeader,
topStickOffset: stickyHeaderOffset,
className: this.props.headerClassName,
};
const selectedSize = selection.getSelected().size;
const allSelectedSize = selection.selectAll().getSelected().size;
headerProps.checked = selectedSize > 0 && selectedSize === allSelectedSize;
headerProps.onCheckboxChange = this.onCheckboxChange;
headerProps.checkboxDisabled = this.props.data.length === 0;
const wrapperClasses = classNames(
{
[style.tableWrapper]: true,
[style.loading]: loading,
},
this.props.wrapperClassName,
);
const classes = classNames(this.props.className, {
[style.table]: true,
[style.wideFirstColumn]: this.props.wideFirstColumn,
[style.multiSelection]: selection.getSelected().size > 0,
[style.userSelectNone]: this.state.userSelectNone,
[style.disabledHover]: this.props.disabledHover,
});
const renderList = ({children, props}: Partial<RenderListParams>) => {
const empty = (
<tr>
<td colSpan={columnsArray.length || 1} className={style.tableMessage}>
{renderEmpty ? renderEmpty() : null}
</td>
</tr>
);
const tbody = Array.isArray(children) && children.length > 0 ? children : empty;
return (
<table className={classes} data-test='ring-table'>
<Header {...headerProps} />
<tbody {...props} data-test='ring-table-body'>
{tbody}
</tbody>
</table>
);
};
const renderItem = ({value, props = {}, isDragged}: Partial<RenderItemParams<T>>) => {
if (value === null || value === undefined) {
return null;
}
const {ref, ...restProps} = props;
const row = (
<RowComponent<T>
innerRef={ref}
level={getItemLevel(value)}
item={value}
showFocus={selection.isFocused(value)}
autofocus={selection.isFocused(value)}
focused={focused && selection.isFocused(value)}
selectable={selectable && isItemSelectable(value)}
selected={selectable && selection.isSelected(value)}
onFocus={this.onRowFocus}
onSelect={this.onRowSelect}
onDoubleClick={onItemDoubleClick}
onClick={onItemClick}
collapsible={isItemCollapsible(value)}
parentCollapsible={isParentCollapsible(value)}
collapsed={isItemCollapsed(value)}
onCollapse={onItemCollapse}
onExpand={onItemExpand}
showDisabledSelection={isDisabledSelectionVisible(value)}
checkboxTooltip={getCheckboxTooltip(value)}
className={classNames(getItemClassName(value), {[style.draggingRow]: isDragged})}
metaColumnClassName={getMetaColumnClassName(value)}
draggable={draggable}
alwaysShowDragHandle={alwaysShowDragHandle}
dragHandleTitle={dragHandleTitle}
columns={columns}
data-test={getItemDataTest(value)}
cellClassName={this.props.cellClassName}
{...restProps}
key={restProps.key ?? getItemKey(value)}
/>
);
return isDragged ? (
<table style={{...props.style}} className={style.draggingTable}>
<tbody>{row}</tbody>
</table>
) : (
row
);
};
return (
<div className={wrapperClasses} data-test='ring-table-wrapper' ref={this.props.innerRef}>
{focused && <Shortcuts map={this.props.shortcutsMap} scope={this.state.shortcutsScope} />}
{/* Handler detects that user holds Shift key */}
<div role='presentation' onMouseDown={this.onMouseDown}>
{draggable ? (
<List values={data as T[]} renderList={renderList} renderItem={renderItem} onChange={this.onSortEnd} />
) : (
renderList({children: data.map((value, index) => renderItem({value, index}))})
)}
</div>
{loading && (
<div className={style.loadingOverlay}>
{renderLoader ? renderLoader(loaderClassName) : <Loader className={loaderClassName} />}
</div>
)}
</div>
);
}