public render()

in packages/react/src/components/DetailsList/DetailsRow.base.tsx [177:375]


  public render(): JSX.Element {
    const {
      className,
      columns = NO_COLUMNS,
      dragDropEvents,
      item,
      itemIndex,
      id,
      flatIndexOffset = 2,
      onRenderCheck = this._onRenderCheck,
      onRenderDetailsCheckbox,
      onRenderItemColumn,
      getCellValueKey,
      selectionMode,
      rowWidth = 0,
      checkboxVisibility,
      getRowAriaLabel,
      getRowAriaDescription,
      getRowAriaDescribedBy,
      checkButtonAriaLabel,
      checkboxCellClassName,
      /** Alias rowFieldsAs as RowFields and default to DetailsRowFields if rowFieldsAs does not exist */
      rowFieldsAs: RowFields = DetailsRowFields,
      selection,
      indentWidth,
      enableUpdateAnimations,
      compact,
      theme,
      styles,
      cellsByColumn,
      groupNestingDepth,
      useFastIcons = true,
      cellStyleProps,
      group,
      focusZoneProps,
      disabled = false,
    } = this.props;
    const { columnMeasureInfo, isDropping } = this.state;
    const { isSelected = false, isSelectionModal = false } = this.state.selectionState;
    const isDraggable = dragDropEvents ? !!(dragDropEvents.canDrag && dragDropEvents.canDrag(item)) : undefined;
    const droppingClassName = isDropping ? this._droppingClassNames || DEFAULT_DROPPING_CSS_CLASS : '';
    const ariaLabel = getRowAriaLabel ? getRowAriaLabel(item) : undefined;
    const ariaRowDescription = getRowAriaDescription ? getRowAriaDescription(item) : undefined;
    const ariaDescribedBy = getRowAriaDescribedBy ? getRowAriaDescribedBy(item) : undefined;
    const canSelect = !!selection && selection.canSelectItem(item, itemIndex) && !disabled;
    const isContentUnselectable = selectionMode === SelectionMode.multiple;
    const showCheckbox = selectionMode !== SelectionMode.none && checkboxVisibility !== CheckboxVisibility.hidden;
    const ariaSelected = selectionMode === SelectionMode.none ? undefined : isSelected;
    const ariaPositionInSet = group ? itemIndex - group.startIndex + 1 : undefined;
    const ariaSetSize = group ? group.count : undefined;
    const focusZoneDirection = focusZoneProps ? focusZoneProps.direction : FocusZoneDirection.horizontal;

    this._classNames = {
      ...this._classNames,
      ...getClassNames(styles, {
        theme: theme!,
        isSelected,
        canSelect: !isContentUnselectable,
        anySelected: isSelectionModal,
        checkboxCellClassName,
        droppingClassName,
        className,
        compact,
        enableUpdateAnimations,
        cellStyleProps,
        disabled,
      }),
    };

    const rowClassNames: IDetailsRowFieldsProps['rowClassNames'] = {
      isMultiline: this._classNames.isMultiline,
      isRowHeader: this._classNames.isRowHeader,
      cell: this._classNames.cell,
      cellAnimation: this._classNames.cellAnimation,
      cellPadded: this._classNames.cellPadded,
      cellUnpadded: this._classNames.cellUnpadded,
      fields: this._classNames.fields,
    };

    // Only re-assign rowClassNames when classNames have changed.
    // Otherwise, they will cause DetailsRowFields to unnecessarily
    // re-render, see https://github.com/microsoft/fluentui/pull/8799.
    // Refactor DetailsRowFields to generate own styles to remove need for this.
    if (!shallowCompare(this._rowClassNames || {}, rowClassNames)) {
      this._rowClassNames = rowClassNames;
    }

    const rowFields = (
      <RowFields
        rowClassNames={this._rowClassNames}
        rowHeaderId={`${id}-header`}
        cellsByColumn={cellsByColumn}
        columns={columns}
        item={item}
        itemIndex={itemIndex}
        columnStartIndex={(showCheckbox ? 1 : 0) + (groupNestingDepth ? 1 : 0)}
        onRenderItemColumn={onRenderItemColumn}
        getCellValueKey={getCellValueKey}
        enableUpdateAnimations={enableUpdateAnimations}
        cellStyleProps={cellStyleProps}
      />
    );

    const defaultRole = 'row';
    const role = this.props.role ? this.props.role : defaultRole;
    this._ariaRowDescriptionId = getId('DetailsRow-description');

    return (
      <FocusZone
        data-is-focusable={true}
        {...getNativeProps(this.props, divProperties)}
        {...(typeof isDraggable === 'boolean'
          ? {
              'data-is-draggable': isDraggable, // This data attribute is used by some host applications.
              draggable: isDraggable,
            }
          : {})}
        {...focusZoneProps}
        direction={focusZoneDirection}
        elementRef={this._root}
        componentRef={this._focusZone}
        role={role}
        aria-label={ariaLabel}
        aria-disabled={disabled || undefined}
        aria-describedby={ariaRowDescription ? this._ariaRowDescriptionId : ariaDescribedBy}
        className={this._classNames.root}
        data-selection-index={itemIndex}
        data-selection-touch-invoke={true}
        data-selection-disabled={disabled || undefined}
        data-item-index={itemIndex}
        aria-rowindex={ariaPositionInSet === undefined ? itemIndex + flatIndexOffset : undefined}
        aria-level={(groupNestingDepth && groupNestingDepth + 1) || undefined}
        aria-posinset={ariaPositionInSet}
        aria-setsize={ariaSetSize}
        data-automationid="DetailsRow"
        style={{ minWidth: rowWidth }}
        aria-selected={ariaSelected}
        allowFocusRoot={true}
      >
        {ariaRowDescription ? (
          <span key="description" role="presentation" hidden={true} id={this._ariaRowDescriptionId}>
            {ariaRowDescription}
          </span>
        ) : null}
        {showCheckbox && (
          <div role="gridcell" aria-colindex={1} data-selection-toggle={true} className={this._classNames.checkCell}>
            {onRenderCheck({
              id: id ? `${id}-checkbox` : undefined,
              selected: isSelected,
              selectionMode,
              anySelected: isSelectionModal,
              'aria-label': checkButtonAriaLabel,
              'aria-labelledby': id ? `${id}-checkbox ${id}-header` : undefined,
              canSelect,
              compact,
              className: this._classNames.check,
              theme,
              isVisible: checkboxVisibility === CheckboxVisibility.always,
              onRenderDetailsCheckbox: onRenderDetailsCheckbox,
              useFastIcons,
            })}
          </div>
        )}

        <GroupSpacer
          indentWidth={indentWidth}
          role="gridcell"
          count={groupNestingDepth! - (this.props.collapseAllVisibility === CollapseAllVisibility.hidden ? 1 : 0)}
        />

        {item && rowFields}
        {columnMeasureInfo && (
          <span
            role="presentation"
            className={css(this._classNames.cellMeasurer, this._classNames.cell)}
            ref={this._cellMeasurer}
          >
            <RowFields
              rowClassNames={this._rowClassNames}
              rowHeaderId={`${id}-header`}
              columns={[columnMeasureInfo.column]}
              item={item}
              itemIndex={itemIndex}
              columnStartIndex={(showCheckbox ? 1 : 0) + (groupNestingDepth ? 1 : 0) + columns.length}
              onRenderItemColumn={onRenderItemColumn}
              getCellValueKey={getCellValueKey}
            />
          </span>
        )}

        <span
          role="checkbox"
          className={this._classNames.checkCover}
          aria-checked={isSelected}
          data-selection-toggle={true}
        />
      </FocusZone>
    );
  }