Skip to content

Commit

Permalink
[DataGrid] Remove GridRowCells (#2811)
Browse files Browse the repository at this point in the history
  • Loading branch information
m4theushw authored Oct 12, 2021
1 parent f685a16 commit 4db8ce3
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 210 deletions.
5 changes: 5 additions & 0 deletions docs/scripts/generateProptypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ async function generateProptypes(program: ttp.ts.Program, sourceFile: string) {
'columns',
'currentColumn',
'colDef',
'renderedColumns',
'scrollBarState',
'renderState',
'cellFocus',
'cellTabIndex',
];
if (propsToNotResolve.includes(name)) {
return false;
Expand Down
147 changes: 135 additions & 12 deletions packages/grid/_modules_/grid/components/GridRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,33 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { GridEvents } from '../constants/eventsConstants';
import { GridRowId } from '../models/gridRows';
import { GridEditModes, GridRowModes } from '../models/gridEditRowModel';
import { gridDensityRowHeightSelector } from '../hooks/features/density';
import { GridRowId, GridRowData } from '../models/gridRows';
import { GridEditModes, GridRowModes, GridEditRowsModel } from '../models/gridEditRowModel';
import { useGridApiContext } from '../hooks/root/useGridApiContext';
import { useGridSelector } from '../hooks/features/core/useGridSelector';
import { composeClasses } from '../utils/material-ui-utils';
import { getDataGridUtilityClass } from '../gridClasses';
import { getDataGridUtilityClass, gridClasses } from '../gridClasses';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { GridComponentProps } from '../GridComponentProps';
import { GridCellIdentifier } from '../hooks/features/focus/gridFocusState';
import { GridScrollBarState } from '../models/gridContainerProps';
import { GridStateColDef } from '../models/colDef/gridColDef';
import { GridEmptyCell } from './cell/GridEmptyCell';
import { GridRenderingState } from '../hooks/features/virtualization/renderingState';

export interface GridRowProps {
id: GridRowId;
selected: boolean;
rowIndex: number;
index: number;
rowHeight: number;
row: GridRowData;
renderState: GridRenderingState;
firstColumnToRender: number;
renderedColumns: GridStateColDef[];
children: React.ReactNode;
cellFocus: GridCellIdentifier | null;
cellTabIndex: GridCellIdentifier | null;
editRowsModel: GridEditRowsModel;
scrollBarState: GridScrollBarState;
onClick?: React.MouseEventHandler<HTMLDivElement>;
onDoubleClick?: React.MouseEventHandler<HTMLDivElement>;
}
Expand All @@ -40,11 +52,27 @@ const useUtilityClasses = (ownerState: OwnerState) => {
};

function GridRow(props: GridRowProps) {
const { selected, id, rowIndex, children, onClick, onDoubleClick, ...other } = props;
const ariaRowIndex = rowIndex + 2; // 1 for the header row and 1 as it's 1 based
const {
selected,
id,
row,
index,
rowHeight,
renderedColumns,
firstColumnToRender,
children,
cellFocus,
cellTabIndex,
editRowsModel,
scrollBarState, // to be removed
renderState, // to be removed
onClick,
onDoubleClick,
...other
} = props;
const ariaRowIndex = index + 2; // 1 for the header row and 1 as it's 1 based
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const rowHeight = useGridSelector(apiRef, gridDensityRowHeightSelector);

const ownerState = {
...props,
Expand Down Expand Up @@ -90,11 +118,95 @@ function GridRow(props: GridRowProps) {
typeof rootProps.getRowClassName === 'function' &&
rootProps.getRowClassName(apiRef.current.getRowParams(id));

const cells: JSX.Element[] = [];

for (let i = 0; i < renderedColumns.length; i += 1) {
const column = renderedColumns[i];
const indexRelativeToAllColumns = firstColumnToRender + i;

const isLastColumn = indexRelativeToAllColumns === renderedColumns.length - 1;
const removeLastBorderRight =
isLastColumn && scrollBarState.hasScrollX && !scrollBarState.hasScrollY;
const showRightBorder = !isLastColumn
? rootProps.showCellRightBorder
: !removeLastBorderRight && rootProps.disableExtendRowFullWidth;

const cellParams = apiRef.current.getCellParams(id, column.field);

const classNames: string[] = [];

if (column.cellClassName) {
classNames.push(
clsx(
typeof column.cellClassName === 'function'
? column.cellClassName(cellParams)
: column.cellClassName,
),
);
}

const editCellState = editRowsModel[id] && editRowsModel[id][column.field];
let content: React.ReactNode = null;

if (editCellState == null && column.renderCell) {
content = column.renderCell({ ...cellParams, api: apiRef.current });
// TODO move to GridCell
classNames.push(
clsx(gridClasses['cell--withRenderer'], rootProps.classes?.['cell--withRenderer']),
);
}

if (editCellState != null && column.renderEditCell) {
const params = { ...cellParams, ...editCellState, api: apiRef.current };
content = column.renderEditCell(params);
// TODO move to GridCell
classNames.push(clsx(gridClasses['cell--editing'], rootProps.classes?.['cell--editing']));
}

if (rootProps.getCellClassName) {
// TODO move to GridCell
classNames.push(rootProps.getCellClassName(cellParams));
}

const hasFocus = cellFocus !== null && cellFocus.id === id && cellFocus.field === column.field;

const tabIndex =
cellTabIndex !== null &&
cellTabIndex.id === id &&
cellTabIndex.field === column.field &&
cellParams.cellMode === 'view'
? 0
: -1;

cells.push(
<rootProps.components.Cell
key={column.field} // This is wrong. The key should be the index so the cells can be recycled.
value={cellParams.value}
field={column.field}
width={column.computedWidth}
rowId={id}
height={rowHeight}
showRightBorder={showRightBorder}
formattedValue={cellParams.formattedValue}
align={column.align || 'left'}
cellMode={cellParams.cellMode}
colIndex={indexRelativeToAllColumns}
isEditable={cellParams.isEditable}
hasFocus={hasFocus}
tabIndex={tabIndex}
className={clsx(classNames)}
{...rootProps.componentsProps?.cell}
>
{content}
</rootProps.components.Cell>,
);
}

return (
<div
key={id}
data-id={id}
data-rowindex={rowIndex}
data-rowindex={index}
role="row"
className={clsx(rowClassName, classes.root)}
aria-rowindex={ariaRowIndex}
Expand All @@ -104,7 +216,9 @@ function GridRow(props: GridRowProps) {
onDoubleClick={publish(GridEvents.rowDoubleClick, onDoubleClick)}
{...other}
>
{children}
<GridEmptyCell width={renderState.renderContext!.leftEmptyWidth} height={rowHeight} />
{cells}
<GridEmptyCell width={renderState.renderContext!.rightEmptyWidth} height={rowHeight} />
</div>
);
}
Expand All @@ -114,11 +228,20 @@ GridRow.propTypes = {
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
cellFocus: PropTypes.object,
cellTabIndex: PropTypes.object,
children: PropTypes.node,
editRowsModel: PropTypes.object.isRequired,
firstColumnToRender: PropTypes.number.isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
index: PropTypes.number.isRequired,
onClick: PropTypes.func,
onDoubleClick: PropTypes.func,
rowIndex: PropTypes.number.isRequired,
renderedColumns: PropTypes.arrayOf(PropTypes.object).isRequired,
renderState: PropTypes.object.isRequired,
row: PropTypes.object.isRequired,
rowHeight: PropTypes.number.isRequired,
scrollBarState: PropTypes.object.isRequired,
selected: PropTypes.bool.isRequired,
} as any;

Expand Down
41 changes: 16 additions & 25 deletions packages/grid/_modules_/grid/components/GridViewport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import { gridSelectionStateSelector } from '../hooks/features/selection/gridSele
import { gridRenderingSelector } from '../hooks/features/virtualization/renderingStateSelector';
import { useGridApiContext } from '../hooks/root/useGridApiContext';
import { GridDataContainer } from './containers/GridDataContainer';
import { GridEmptyCell } from './cell/GridEmptyCell';
import { GridRenderingZone } from './GridRenderingZone';
import { GridRowCells } from './cell/GridRowCells';
import { GridStickyContainer } from './GridStickyContainer';
import {
gridContainerSizesSelector,
Expand Down Expand Up @@ -68,35 +66,28 @@ export const GridViewport: ViewportType = React.forwardRef<HTMLDivElement, {}>(
renderState.renderContext.lastRowIdx!,
);

const renderedColumns = visibleColumns.slice(
renderState.renderContext.firstColIdx!,
renderState.renderContext.lastColIdx! + 1,
);

return renderedRows.map(([id, row], idx) => (
<rootProps.components.Row
key={id}
id={id}
row={row}
selected={selectionLookup[id] !== undefined}
rowIndex={renderState.renderContext!.firstRowIdx! + idx}
index={renderState.renderContext!.firstRowIdx! + idx}
rowHeight={rowHeight}
renderedColumns={renderedColumns}
firstColumnToRender={renderState.renderContext!.firstColIdx!}
cellFocus={cellFocus}
cellTabIndex={cellTabIndex}
editRowsModel={editRowsState}
scrollBarState={scrollBarState}
renderState={renderState}
{...rootProps.componentsProps?.row}
>
<GridEmptyCell width={renderState.renderContext!.leftEmptyWidth} height={rowHeight} />
<GridRowCells
columns={visibleColumns}
row={row}
id={id}
height={rowHeight}
firstColIdx={renderState.renderContext!.firstColIdx!}
lastColIdx={renderState.renderContext!.lastColIdx!}
hasScrollX={scrollBarState.hasScrollX}
hasScrollY={scrollBarState.hasScrollY}
showCellRightBorder={rootProps.showCellRightBorder}
extendRowFullWidth={!rootProps.disableExtendRowFullWidth}
rowIndex={renderState.renderContext!.firstRowIdx! + idx}
cellFocus={cellFocus}
cellTabIndex={cellTabIndex}
isSelected={selectionLookup[id] !== undefined}
editRowState={editRowsState[id]}
getCellClassName={rootProps.getCellClassName}
/>
<GridEmptyCell width={renderState.renderContext!.rightEmptyWidth} height={rowHeight} />
</rootProps.components.Row>
/>
));
};

Expand Down
Loading

0 comments on commit 4db8ce3

Please sign in to comment.