render()

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>
    );
  }