From 2dd83a0130c7944c4fd0995e4aaa1f8c80acb477 Mon Sep 17 00:00:00 2001 From: damien Date: Wed, 28 Apr 2021 18:15:35 +0200 Subject: [PATCH 01/28] perf tweaks --- .../grid/components/cell/GridBooleanCell.tsx | 4 +--- .../grid/components/cell/GridEditBooleanCell.tsx | 4 +--- .../grid/components/cell/GridEditInputCell.tsx | 2 -- .../_modules_/grid/components/cell/GridRowCells.tsx | 11 +++++------ .../columnHeaders/GridColumnHeaderItem.tsx | 8 ++++---- .../features/keyboard/useGridKeyboardNavigation.ts | 12 +++++++----- .../grid/hooks/features/rows/useGridEditRows.ts | 4 +++- .../grid/hooks/features/rows/useGridParamsApi.ts | 11 +++-------- .../_modules_/grid/models/params/gridCellParams.ts | 10 +--------- .../grid/models/params/gridColumnHeaderParams.ts | 6 +----- .../_modules_/grid/models/params/gridRowParams.ts | 6 +----- packages/storybook/src/stories/grid-rows.stories.tsx | 2 +- 12 files changed, 28 insertions(+), 52 deletions(-) diff --git a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx index b49b9627367c4..8544a71c0518c 100644 --- a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx @@ -6,7 +6,7 @@ export function GridBooleanCell(props: GridCellParams & SvgIconProps) { const { id, value, - element, + getElement, formattedValue, api, field, @@ -14,8 +14,6 @@ export function GridBooleanCell(props: GridCellParams & SvgIconProps) { colDef, cellMode, getValue, - rowIndex, - colIndex, isEditable, ...other } = props; diff --git a/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx index fa3fe47045031..ced1f71fd2f95 100644 --- a/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx @@ -11,7 +11,7 @@ export function GridEditBooleanCell( const { id: idProp, value, - element, + getElement, formattedValue, api, field, @@ -19,8 +19,6 @@ export function GridEditBooleanCell( colDef, cellMode, getValue, - rowIndex, - colIndex, isEditable, className, ...other diff --git a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx index 334dbdb173b70..74d6b1672cb65 100644 --- a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx @@ -15,8 +15,6 @@ export function GridEditInputCell(props: GridCellParams & InputBaseProps) { colDef, cellMode, getValue, - rowIndex, - colIndex, isEditable, ...other } = props; diff --git a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx index 566472f34e2a4..4693ec72f5d06 100644 --- a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx @@ -54,7 +54,8 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { const editRowsState = useGridSelector(apiRef, gridEditRowsStateSelector); const cellsProps = columns.slice(firstColIdx, lastColIdx + 1).map((column, colIdx) => { - const isLastColumn = firstColIdx + colIdx === columns.length - 1; + const colIndex = firstColIdx + colIdx; + const isLastColumn = colIndex === columns.length - 1; const removeLastBorderRight = isLastColumn && hasScroll.x && !hasScroll.y; const showRightBorder = !isLastColumn ? showCellRightBorder @@ -102,17 +103,15 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { ...cssClassProp, rowIndex, cellMode: cellParams.cellMode, - colIndex: cellParams.colIndex, + colIndex: colIndex, children: cellComponent, isEditable: cellParams.isEditable, hasFocus: - cellFocus !== null && - cellFocus.rowIndex === rowIndex && - cellFocus.colIndex === cellParams.colIndex, + cellFocus !== null && cellFocus.rowIndex === rowIndex && cellFocus.colIndex === colIndex, tabIndex: cellTabIndex !== null && cellTabIndex.rowIndex === rowIndex && - cellTabIndex.colIndex === cellParams.colIndex + cellTabIndex.colIndex === colIndex ? 0 : -1, }; diff --git a/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx b/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx index 0d69ebfe499c5..22debd2f9cd28 100644 --- a/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx +++ b/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx @@ -68,10 +68,10 @@ export const GridColumnHeaderItem = React.memo( // todo refactor to a prop on col isNumeric or ?? ie: coltype===price wont work const isColumnNumeric = column.type === GRID_NUMBER_COLUMN_TYPE; - let headerComponent: React.ReactElement | null = null; - if (column.renderHeader) { - headerComponent = column.renderHeader(apiRef!.current.getColumnHeaderParams(column.field)!); - } + let headerComponent: React.ReactElement | null = null; + if (column.renderHeader && apiRef!.current) { + headerComponent = column.renderHeader(apiRef!.current.getColumnHeaderParams(column.field)); + } const publish = React.useCallback( (eventName: string) => (event: React.MouseEvent | React.DragEvent) => diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts index 9d53c6f80eca3..cd00074cd0674 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts @@ -86,7 +86,9 @@ export const useGridKeyboardNavigation = ( const navigateCells = React.useCallback( (params: GridCellParams, event: React.KeyboardEvent) => { event.preventDefault(); - const { colIndex, rowIndex } = params; + const colIndex = apiRef.current.getColumnIndex(params.field); + const rowIndex = apiRef.current.getRowIndexFromId(params.id); + const key = mapKey(event); const isCtrlPressed = event.ctrlKey || event.metaKey || event.shiftKey; let rowCount = totalRowCount; @@ -159,10 +161,10 @@ export const useGridKeyboardNavigation = ( ); const navigateColumnHeaders = React.useCallback( - (params: GridCellParams, event: React.KeyboardEvent) => { + (params: GridColumnHeaderParams, event: React.KeyboardEvent) => { event.preventDefault(); let nextColumnHeaderIndexes: GridColumnHeaderIndexCoordinates | null; - const { colIndex } = params; + const colIndex = apiRef.current.getColumnIndex(params.field); const key = mapKey(event); if (isArrowKeys(key)) { @@ -177,7 +179,7 @@ export const useGridKeyboardNavigation = ( // Handle only Page Down key, Page Up should keep the current possition if (key.indexOf('Down') > -1) { apiRef.current.setCellFocus({ - colIndex: params.colIndex, + colIndex, rowIndex: containerSizes!.viewportPageSize - 1, }); } @@ -187,7 +189,7 @@ export const useGridKeyboardNavigation = ( } if (!nextColumnHeaderIndexes) { - apiRef.current.setCellFocus({ colIndex: params.colIndex, rowIndex: 0 }); + apiRef.current.setCellFocus({ colIndex, rowIndex: 0 }); return; } diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts index 179f57ed22bc0..20a19a0a519bd 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts @@ -219,7 +219,9 @@ export function useGridEditRows(apiRef: GridApiRef) { return; } if (isEscapeKey(event.key) || isDeleteKeys(event.key)) { - apiRef.current.setCellFocus(params); + const colIndex = apiRef.current.getColumnIndex(params.field); + const rowIndex = apiRef.current.getRowIndexFromId(params.id); + apiRef.current.setCellFocus({ colIndex, rowIndex }); } }, [apiRef, setCellMode], diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts index 96a891c252151..9f8411c682a94 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts @@ -27,9 +27,8 @@ export function useGridParamsApi(apiRef: GridApiRef) { const getColumnHeaderParams = React.useCallback( (field: string): GridColumnHeaderParams => ({ field, - element: apiRef.current.getColumnHeaderElement(field), + getElement: apiRef.current.getColumnHeaderElement, colDef: apiRef.current.getColumnFromField(field), - colIndex: apiRef.current.getColumnIndex(field, true), api: apiRef!.current, }), [apiRef], @@ -39,11 +38,10 @@ export function useGridParamsApi(apiRef: GridApiRef) { (id: GridRowId) => { const params: GridRowParams = { id, - element: apiRef.current.getRowElement(id), + getElement: apiRef.current.getRowElement, columns: apiRef.current.getAllColumns(), getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), row: apiRef.current.getRowFromId(id), - rowIndex: apiRef.current.getRowIndexFromId(id), api: apiRef.current, }; return params; @@ -53,11 +51,10 @@ export function useGridParamsApi(apiRef: GridApiRef) { const getBaseCellParams = React.useCallback( (id: GridRowId, field: string) => { - const element = apiRef.current.getCellElement(id, field); const row = apiRef.current.getRowFromId(id); const params: GridValueGetterParams = { - element, + getElement: apiRef.current.getCellElement, id, field, row, @@ -65,8 +62,6 @@ export function useGridParamsApi(apiRef: GridApiRef) { getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), colDef: apiRef.current.getColumnFromField(field), cellMode: apiRef.current.getCellMode(id, field), - rowIndex: apiRef.current.getRowIndexFromId(id), - colIndex: apiRef.current.getColumnIndex(field, true), api: apiRef.current, }; diff --git a/packages/grid/_modules_/grid/models/params/gridCellParams.ts b/packages/grid/_modules_/grid/models/params/gridCellParams.ts index 8c966b89f1bcb..c6e01d328ccbe 100644 --- a/packages/grid/_modules_/grid/models/params/gridCellParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridCellParams.ts @@ -12,7 +12,7 @@ export interface GridCellParams { /** * The HTMLElement cell element. */ - element?: HTMLElement | null; + getElement: (id: GridRowId, field: string) => HTMLElement | null; /** * The column field of the cell that triggered the event */ @@ -38,14 +38,6 @@ export interface GridCellParams { * The column of the row that the current cell belongs to. */ colDef: any; - /** - * The row index of the row that the current cell belongs to. - */ - rowIndex: number; - /** - * The column index that the current cell belongs to. - */ - colIndex: number; /** * GridApi that let you manipulate the grid. */ diff --git a/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts b/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts index a002458ada4f4..438ed8428d4cf 100644 --- a/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts @@ -5,7 +5,7 @@ export interface GridColumnHeaderParams { /** * The HTMLElement column header element. */ - element?: HTMLElement | null; + getElement: (field: string) => HTMLElement | null; /** * The column field of the column that triggered the event */ @@ -14,10 +14,6 @@ export interface GridColumnHeaderParams { * The column of the current header component. */ colDef: any; - /** - * The column index of the current header component. - */ - colIndex: number; /** * API ref that let you manipulate the grid. */ diff --git a/packages/grid/_modules_/grid/models/params/gridRowParams.ts b/packages/grid/_modules_/grid/models/params/gridRowParams.ts index d733139176038..ad1ab49bea183 100644 --- a/packages/grid/_modules_/grid/models/params/gridRowParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridRowParams.ts @@ -12,7 +12,7 @@ export interface GridRowParams { /** * The HTMLElement row element. */ - element?: HTMLElement | null; + getElement: (id: GridRowId) => HTMLElement | null; /** * A function that let you get data from other columns. * @param field @@ -26,10 +26,6 @@ export interface GridRowParams { * All grid columns. */ columns: any; - /** - * The row index of the row that the current cell belongs to. - */ - rowIndex: number; /** * GridApiRef that let you manipulate the grid. */ diff --git a/packages/storybook/src/stories/grid-rows.stories.tsx b/packages/storybook/src/stories/grid-rows.stories.tsx index 27ee55b9d085d..409753bfc4848 100644 --- a/packages/storybook/src/stories/grid-rows.stories.tsx +++ b/packages/storybook/src/stories/grid-rows.stories.tsx @@ -853,7 +853,7 @@ export function EditCellWithMessageGrid() { return apiRef.current.subscribeEvent( GRID_CELL_EDIT_ENTER, (params: GridCellParams, event?: React.SyntheticEvent) => { - setMessage(`Editing cell with value: ${params.value} at row: ${params.rowIndex}, column: ${ + setMessage(`Editing cell with value: ${params.value} at row: ${params.id}, column: ${ params.field }, triggered by ${event!.type} From 0aae4c4b8e80d3461f36d45d8e52803354c5267b Mon Sep 17 00:00:00 2001 From: damien Date: Wed, 28 Apr 2021 18:49:55 +0200 Subject: [PATCH 02/28] fix merge --- .../columnSelection/GridCellCheckboxRenderer.tsx | 14 +++++++++----- .../columnSelection/GridHeaderCheckbox.tsx | 10 ++++++---- .../grid/hooks/features/focus/useGridFocus.ts | 11 ++++++----- .../hooks/features/keyboard/useGridKeyboard.ts | 2 +- .../features/keyboard/useGridKeyboardNavigation.ts | 3 ++- .../grid/hooks/features/rows/useGridEditRows.ts | 2 +- .../grid/hooks/features/rows/useGridRows.ts | 2 +- .../grid/_modules_/grid/models/api/gridRowApi.ts | 2 +- 8 files changed, 27 insertions(+), 19 deletions(-) diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx index 5fa50065aa8f6..9782b56d1a551 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -11,22 +11,26 @@ export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { const { getValue, field, id } = props; const apiRef = React.useContext(GridApiContext); const tabIndexState = useGridSelector(apiRef, gridTabIndexCellSelector); + const rowIndex = apiRef!.current.getRowIndex(id); + const colIndex = apiRef!.current.getColumnIndex(field); + const element = props.getElement(id, field); const handleChange = (event: React.ChangeEvent, checked: boolean) => { apiRef!.current.selectRow(id, checked, true); }; + const tabIndex = tabIndexState !== null && - tabIndexState.rowIndex === props.rowIndex && - tabIndexState.colIndex === props.colIndex + tabIndexState.rowIndex === rowIndex && + tabIndexState.colIndex === colIndex ? 0 : -1; React.useLayoutEffect(() => { - if (tabIndex === 0 && props.element) { - props.element!.tabIndex = -1; + if (tabIndex === 0 && element) { + element!.tabIndex = -1; } - }, [props.element, tabIndex]); + }, [element, tabIndex]); const handleKeyDown = React.useCallback( (event) => { diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx index 39d7df58b7fdb..fa61f7170fe72 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx @@ -14,6 +14,8 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { const apiRef = React.useContext(GridApiContext); const visibleRowIds = useGridSelector(apiRef, visibleSortedGridRowIdsSelector); const tabIndexState = useGridSelector(apiRef, gridTabIndexColumnHeaderSelector); + const element = props.getElement(props.field); + const colIndex = apiRef!.current.getColumnIndex(props.field) const totalSelectedRows = useGridSelector(apiRef, selectedGridRowsCountSelector); const totalRows = useGridSelector(apiRef, gridRowCountSelector); @@ -37,12 +39,12 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { apiRef!.current.selectRows(visibleRowIds, checked); }; - const tabIndex = tabIndexState !== null && tabIndexState.colIndex === props.colIndex ? 0 : -1; + const tabIndex = tabIndexState !== null && tabIndexState.colIndex === colIndex ? 0 : -1; React.useLayoutEffect(() => { - if (tabIndex === 0 && props.element) { - props.element!.tabIndex = -1; + if (tabIndex === 0 && element) { + element!.tabIndex = -1; } - }, [props.element, tabIndex]); + }, [element, tabIndex]); const handleKeyDown = React.useCallback( (event) => { diff --git a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts index 46861d389e554..e93cf0fef2fe7 100644 --- a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts +++ b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts @@ -55,12 +55,13 @@ export const useGridFocus = (apiRef: GridApiRef): void => { ); const handleCellFocus = React.useCallback( - (cellParams: GridCellParams, event?: React.SyntheticEvent) => { + (params: GridCellParams, event?: React.SyntheticEvent) => { if (event?.target !== event?.currentTarget) { return; } - - apiRef.current.setCellFocus(cellParams); + const colIndex = apiRef.current.getColumnIndex(params.field); + const rowIndex = apiRef.current.getRowIndex(params.id); + apiRef.current.setCellFocus({colIndex, rowIndex}); }, [apiRef], ); @@ -70,8 +71,8 @@ export const useGridFocus = (apiRef: GridApiRef): void => { if (event?.target !== event?.currentTarget) { return; } - - apiRef.current.setColumnHeaderFocus(params); + const colIndex = apiRef.current.getColumnIndex(params.field); + apiRef.current.setColumnHeaderFocus({colIndex}); }, [apiRef], ); diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts index c74b0dfe6d6f8..38c72195be11c 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts @@ -76,7 +76,7 @@ export const useGridKeyboard = ( // TODO Refactor here to not use api call const selectedRowsIds = [...apiRef.current.getSelectedRows().keys()]; if (selectedRowsIds.length > 0) { - const selectedRowsIndex = selectedRowsIds.map((id) => apiRef.current.getRowIndexFromId(id)); + const selectedRowsIndex = selectedRowsIds.map((id) => apiRef.current.getRowIndex(id)); const diffWithCurrentIndex: number[] = selectedRowsIndex.map((idx) => Math.abs(currentRowIndex - idx), diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts index cd00074cd0674..65e67e6408b84 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts @@ -9,6 +9,7 @@ import { GridColumnHeaderIndexCoordinates, } from '../../../models/gridCell'; import { GridCellParams } from '../../../models/params/gridCellParams'; +import { GridColumnHeaderParams } from '../../../models/params/gridColumnHeaderParams'; import { isArrowKeys, isEnterKey, @@ -87,7 +88,7 @@ export const useGridKeyboardNavigation = ( (params: GridCellParams, event: React.KeyboardEvent) => { event.preventDefault(); const colIndex = apiRef.current.getColumnIndex(params.field); - const rowIndex = apiRef.current.getRowIndexFromId(params.id); + const rowIndex = apiRef.current.getRowIndex(params.id); const key = mapKey(event); const isCtrlPressed = event.ctrlKey || event.metaKey || event.shiftKey; diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts index 20a19a0a519bd..8ea355e4f5fe4 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts @@ -220,7 +220,7 @@ export function useGridEditRows(apiRef: GridApiRef) { } if (isEscapeKey(event.key) || isDeleteKeys(event.key)) { const colIndex = apiRef.current.getColumnIndex(params.field); - const rowIndex = apiRef.current.getRowIndexFromId(params.id); + const rowIndex = apiRef.current.getRowIndex(params.id); apiRef.current.setCellFocus({ colIndex, rowIndex }); } }, diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridRows.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridRows.ts index 27f819d31828b..12d11f5f6a7d1 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridRows.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridRows.ts @@ -214,7 +214,7 @@ export const useGridRows = ( const getAllRowIds = React.useCallback(() => apiRef.current.state.rows.allRows, [apiRef]); const rowApi: GridRowApi = { - getRowIndexFromId, + getRowIndex: getRowIndexFromId, getRowIdFromRowIndex, getRowFromId, getRowModels, diff --git a/packages/grid/_modules_/grid/models/api/gridRowApi.ts b/packages/grid/_modules_/grid/models/api/gridRowApi.ts index 7bb1a5e3a265a..93cce25d8889e 100644 --- a/packages/grid/_modules_/grid/models/api/gridRowApi.ts +++ b/packages/grid/_modules_/grid/models/api/gridRowApi.ts @@ -36,7 +36,7 @@ export interface GridRowApi { * Get the row index of a row with a given id. * @param id */ - getRowIndexFromId: (id: GridRowId) => number; + getRowIndex: (id: GridRowId) => number; /** * Get the [[GridRowModel]] of a given rowId. * @param id From ead1858857730451ee5581de06ea87261d1f699f Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 29 Apr 2021 14:34:56 +0200 Subject: [PATCH 03/28] more perf tweaks --- .../grid/components/cell/GridBooleanCell.tsx | 9 +++--- .../components/cell/GridEditBooleanCell.tsx | 2 -- .../components/cell/GridEditInputCell.tsx | 1 - .../columnHeaders/ColumnHeaderMenuIcon.tsx | 5 ++-- .../GridCellCheckboxRenderer.tsx | 6 ++-- .../columnSelection/GridHeaderCheckbox.tsx | 2 +- .../grid/components/containers/GridRoot.tsx | 4 +-- .../_modules_/grid/components/icons/index.tsx | 3 +- .../hooks/features/rows/useGridParamsApi.ts | 12 ++++---- .../grid/models/gridSlotsComponent.ts | 28 +++++++++---------- .../grid/models/params/gridCellParams.ts | 4 +-- .../models/params/gridColumnHeaderParams.ts | 2 +- .../grid/models/params/gridRowParams.ts | 4 +-- .../src/stories/grid-columns.stories.tsx | 4 +-- .../src/stories/grid-error.stories.tsx | 2 +- .../src/stories/grid-sorting.stories.tsx | 4 +-- .../src/stories/grid-style.stories.tsx | 2 +- .../customize-components.stories.tsx | 2 +- 18 files changed, 46 insertions(+), 50 deletions(-) diff --git a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx index 8544a71c0518c..238a9328d60c8 100644 --- a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx @@ -2,23 +2,22 @@ import * as React from 'react'; import { SvgIconProps } from '@material-ui/core/SvgIcon'; import { GridCellParams } from '../../models/params/gridCellParams'; -export function GridBooleanCell(props: GridCellParams & SvgIconProps) { +export const GridBooleanCell = React.memo(( props: GridCellParams & SvgIconProps) => { const { id, value, - getElement, formattedValue, api, field, row, colDef, cellMode, - getValue, isEditable, ...other } = props; - const Icon = value ? api.components.BooleanCellTrueIcon : api.components.BooleanCellFalseIcon; + const Icon = React.useMemo(()=> value ? api.components.BooleanCellTrueIcon : api.components.BooleanCellFalseIcon, + [api.components.BooleanCellFalseIcon, api.components.BooleanCellTrueIcon, value]); return ( ); -} +}); export const renderBooleanCell = (params) => ; diff --git a/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx index ced1f71fd2f95..2fd07f83a9a9c 100644 --- a/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx @@ -11,14 +11,12 @@ export function GridEditBooleanCell( const { id: idProp, value, - getElement, formattedValue, api, field, row, colDef, cellMode, - getValue, isEditable, className, ...other diff --git a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx index 74d6b1672cb65..c189857231749 100644 --- a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx @@ -14,7 +14,6 @@ export function GridEditInputCell(props: GridCellParams & InputBaseProps) { row, colDef, cellMode, - getValue, isEditable, ...other } = props; diff --git a/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx b/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx index b0e0643de789c..5db3af8b6b535 100644 --- a/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx +++ b/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx @@ -11,8 +11,7 @@ import { GridColDef } from '../../models/colDef/gridColDef'; export interface ColumnHeaderFilterIconProps { column: GridColDef; } - -export function ColumnHeaderMenuIcon(props: ColumnHeaderFilterIconProps) { +export const ColumnHeaderMenuIcon = React.memo(( props: ColumnHeaderFilterIconProps) => { const { column } = props; const apiRef = React.useContext(GridApiContext); const columnMenuState = useGridSelector(apiRef, gridColumnMenuStateSelector); @@ -48,4 +47,4 @@ export function ColumnHeaderMenuIcon(props: ColumnHeaderFilterIconProps) { ); -} +}); diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx index 9782b56d1a551..9a24e6f455b16 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -8,12 +8,12 @@ import { isNavigationKey, isSpaceKey } from '../../utils/keyboardUtils'; import { GridApiContext } from '../GridApiContext'; export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { - const { getValue, field, id } = props; + const { field, id } = props; const apiRef = React.useContext(GridApiContext); const tabIndexState = useGridSelector(apiRef, gridTabIndexCellSelector); const rowIndex = apiRef!.current.getRowIndex(id); const colIndex = apiRef!.current.getColumnIndex(field); - const element = props.getElement(id, field); + const element = props.api.getCellElement(id, field); const handleChange = (event: React.ChangeEvent, checked: boolean) => { apiRef!.current.selectRow(id, checked, true); @@ -47,7 +47,7 @@ export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { return ( { const apiRef = React.useContext(GridApiContext); const visibleRowIds = useGridSelector(apiRef, visibleSortedGridRowIdsSelector); const tabIndexState = useGridSelector(apiRef, gridTabIndexColumnHeaderSelector); - const element = props.getElement(props.field); + const element = apiRef!.current.getColumnHeaderElement(props.field); const colIndex = apiRef!.current.getColumnIndex(props.field) const totalSelectedRows = useGridSelector(apiRef, selectedGridRowsCountSelector); diff --git a/packages/grid/_modules_/grid/components/containers/GridRoot.tsx b/packages/grid/_modules_/grid/components/containers/GridRoot.tsx index 1b8d8361aa929..f6ef3c8002b84 100644 --- a/packages/grid/_modules_/grid/components/containers/GridRoot.tsx +++ b/packages/grid/_modules_/grid/components/containers/GridRoot.tsx @@ -8,7 +8,7 @@ import { GridApiContext } from '../GridApiContext'; export type GridRootProps = React.HTMLAttributes; -export const GridRoot = React.forwardRef(function GridRoot( +export const GridRoot = React.memo(React.forwardRef(function GridRoot( props, ref, ) { @@ -32,4 +32,4 @@ export const GridRoot = React.forwardRef(function {...other} /> ); -}); +})); diff --git a/packages/grid/_modules_/grid/components/icons/index.tsx b/packages/grid/_modules_/grid/components/icons/index.tsx index 4d66ffc24d365..164c7b295b362 100644 --- a/packages/grid/_modules_/grid/components/icons/index.tsx +++ b/packages/grid/_modules_/grid/components/icons/index.tsx @@ -67,7 +67,6 @@ export const GridCloseIcon = createSvgIcon( 'Close', ); -export const GridAddIcon = createSvgIcon(, 'Add'); export const GridLoadIcon = createSvgIcon( , @@ -88,3 +87,5 @@ export const GridCheckIcon = createSvgIcon( , 'Check', ); +export const IconTest = React.memo(()=> A ); +export const GridAddIcon = IconTest //createSvgIcon(, 'Add'); diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts index 9f8411c682a94..130b1a3a35ca9 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts @@ -27,7 +27,7 @@ export function useGridParamsApi(apiRef: GridApiRef) { const getColumnHeaderParams = React.useCallback( (field: string): GridColumnHeaderParams => ({ field, - getElement: apiRef.current.getColumnHeaderElement, + // getElement: ()=> apiRef.current.getColumnHeaderElement(field), colDef: apiRef.current.getColumnFromField(field), api: apiRef!.current, }), @@ -38,9 +38,9 @@ export function useGridParamsApi(apiRef: GridApiRef) { (id: GridRowId) => { const params: GridRowParams = { id, - getElement: apiRef.current.getRowElement, + // getElement: ()=> apiRef.current.getRowElement(id), columns: apiRef.current.getAllColumns(), - getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), + // getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), row: apiRef.current.getRowFromId(id), api: apiRef.current, }; @@ -54,12 +54,12 @@ export function useGridParamsApi(apiRef: GridApiRef) { const row = apiRef.current.getRowFromId(id); const params: GridValueGetterParams = { - getElement: apiRef.current.getCellElement, + // getElement: ()=> apiRef.current.getCellElement(id, field), id, field, row, value: row[field], - getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), + // getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), colDef: apiRef.current.getColumnFromField(field), cellMode: apiRef.current.getCellMode(id, field), api: apiRef.current, @@ -78,7 +78,7 @@ export function useGridParamsApi(apiRef: GridApiRef) { const params: GridCellParams = { ...baseParams, value, - getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), + // getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), formattedValue: value, }; if (colDef.valueFormatter) { diff --git a/packages/grid/_modules_/grid/models/gridSlotsComponent.ts b/packages/grid/_modules_/grid/models/gridSlotsComponent.ts index b3b6dd246e63d..cb7981ce6b9bf 100644 --- a/packages/grid/_modules_/grid/models/gridSlotsComponent.ts +++ b/packages/grid/_modules_/grid/models/gridSlotsComponent.ts @@ -16,7 +16,7 @@ import { GridViewStreamIcon, GridSaveAltIcon, GridCloseIcon, - GridCheckIcon, + GridCheckIcon, IconTest, } from '../components/icons/index'; import { GridLoadingOverlay } from '../components/GridLoadingOverlay'; import { GridColumnMenu } from '../components/menu/columnMenu/GridColumnMenu'; @@ -90,19 +90,19 @@ export interface GridSlotsComponent extends GridIconSlotsComponent { } export const DEFAULT_GRID_SLOTS_ICONS: GridIconSlotsComponent = { - BooleanCellTrueIcon: GridCheckIcon, - BooleanCellFalseIcon: GridCloseIcon, - OpenFilterButtonIcon: GridFilterListIcon, - ColumnFilteredIcon: GridFilterAltIcon, - ColumnSelectorIcon: GridColumnIcon, - ColumnMenuIcon: GridTripleDotsVerticalIcon, - ColumnSortedAscendingIcon: GridArrowUpwardIcon, - ColumnSortedDescendingIcon: GridArrowDownwardIcon, - ColumnResizeIcon: GridSeparatorIcon, - DensityCompactIcon: GridViewHeadlineIcon, - DensityStandardIcon: GridTableRowsIcon, - DensityComfortableIcon: GridViewStreamIcon, - ExportIcon: GridSaveAltIcon, + BooleanCellTrueIcon: IconTest, + BooleanCellFalseIcon: IconTest, + OpenFilterButtonIcon: IconTest, + ColumnFilteredIcon: IconTest, + ColumnSelectorIcon: IconTest, + ColumnMenuIcon: IconTest, + ColumnSortedAscendingIcon: IconTest, + ColumnSortedDescendingIcon: IconTest, + ColumnResizeIcon: IconTest, + DensityCompactIcon: IconTest, + DensityStandardIcon: IconTest, + DensityComfortableIcon: IconTest, + ExportIcon: IconTest, }; export const DEFAULT_GRID_SLOTS_COMPONENTS: GridApiRefComponentsProperty = { diff --git a/packages/grid/_modules_/grid/models/params/gridCellParams.ts b/packages/grid/_modules_/grid/models/params/gridCellParams.ts index c6e01d328ccbe..ecde57058c0e6 100644 --- a/packages/grid/_modules_/grid/models/params/gridCellParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridCellParams.ts @@ -12,7 +12,7 @@ export interface GridCellParams { /** * The HTMLElement cell element. */ - getElement: (id: GridRowId, field: string) => HTMLElement | null; + // getElement: () => HTMLElement | null; /** * The column field of the cell that triggered the event */ @@ -29,7 +29,7 @@ export interface GridCellParams { * A function that let you get data from other columns. * @param field */ - getValue: (field: string) => GridCellValue; + // getValue: (field: string) => GridCellValue; /** * The row model of the row that the current cell belongs to. */ diff --git a/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts b/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts index 438ed8428d4cf..c63c3456b7f79 100644 --- a/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts @@ -5,7 +5,7 @@ export interface GridColumnHeaderParams { /** * The HTMLElement column header element. */ - getElement: (field: string) => HTMLElement | null; + // getElement: () => HTMLElement | null; /** * The column field of the column that triggered the event */ diff --git a/packages/grid/_modules_/grid/models/params/gridRowParams.ts b/packages/grid/_modules_/grid/models/params/gridRowParams.ts index ad1ab49bea183..d7f5a2fc79707 100644 --- a/packages/grid/_modules_/grid/models/params/gridRowParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridRowParams.ts @@ -12,12 +12,12 @@ export interface GridRowParams { /** * The HTMLElement row element. */ - getElement: (id: GridRowId) => HTMLElement | null; + // getElement: () => HTMLElement | null; /** * A function that let you get data from other columns. * @param field */ - getValue: (field: string) => GridCellValue; + // getValue: (field: string) => GridCellValue; /** * The row model of the row that the current cell belongs to. */ diff --git a/packages/storybook/src/stories/grid-columns.stories.tsx b/packages/storybook/src/stories/grid-columns.stories.tsx index 783eee43028b9..b120959124558 100644 --- a/packages/storybook/src/stories/grid-columns.stories.tsx +++ b/packages/storybook/src/stories/grid-columns.stories.tsx @@ -299,12 +299,12 @@ export const ValueGetterAndFormatter = () => { { field: 'firstAge', valueGetter: (params: GridValueGetterParams) => - `${params.getValue('first')}_${params.getValue('age')}`, + `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue(params.id, 'age')}`, }, { field: 'firstAgeFormatted', valueGetter: (params: GridValueGetterParams) => - `${params.getValue('first')}_${params.getValue('age')}`, + `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue(params.id, 'age')}`, valueFormatter: (params) => `${params.value} yrs`, }, ], diff --git a/packages/storybook/src/stories/grid-error.stories.tsx b/packages/storybook/src/stories/grid-error.stories.tsx index a7eb54a1934f6..8697e330d7863 100644 --- a/packages/storybook/src/stories/grid-error.stories.tsx +++ b/packages/storybook/src/stories/grid-error.stories.tsx @@ -26,7 +26,7 @@ const getColumns: () => GridColDef[] = () => [ description: 'this column has a value getter and is not sortable', sortable: false, valueGetter: (params) => - `${params.getValue('firstName') || ''} ${params.getValue('lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, }, { field: 'isRegistered', diff --git a/packages/storybook/src/stories/grid-sorting.stories.tsx b/packages/storybook/src/stories/grid-sorting.stories.tsx index 57d1cf7c4e0a4..6d875814accd1 100644 --- a/packages/storybook/src/stories/grid-sorting.stories.tsx +++ b/packages/storybook/src/stories/grid-sorting.stories.tsx @@ -234,7 +234,7 @@ export const UnsortableLastCol = () => { field: 'username', sortable: false, valueGetter: (params) => - `${params.getValue('name') || 'unknown'}_${params.getValue('age') || 'x'}`, + `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${params.api.getCellValue(params.id, 'age') || 'x'}`, width: 150, }; @@ -250,7 +250,7 @@ export const CustomComparator = () => { columns[columns.length] = { field: 'username', valueGetter: (params) => - `${params.getValue('name') || 'unknown'}_${params.getValue('age') || 'x'}`, + `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${params.api.getCellValue(params.id, 'age') || 'x'}`, sortComparator: (v1, v2, cellParams1, cellParams2) => cellParams1.row.age - cellParams2.row.age, width: 150, }; diff --git a/packages/storybook/src/stories/grid-style.stories.tsx b/packages/storybook/src/stories/grid-style.stories.tsx index 7cec9b0b27c69..bcc8b615a3f5e 100644 --- a/packages/storybook/src/stories/grid-style.stories.tsx +++ b/packages/storybook/src/stories/grid-style.stories.tsx @@ -61,7 +61,7 @@ const getColumns: () => GridColDef[] = () => [ description: 'this column has a value getter and is not sortable', sortable: false, valueGetter: (params) => - `${params.getValue('firstName') || ''} ${params.getValue('lastName') || ''}`.trim(), + `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`.trim(), }, { field: 'isRegistered', diff --git a/packages/storybook/src/stories/playground/customize-components.stories.tsx b/packages/storybook/src/stories/playground/customize-components.stories.tsx index 8831c01f52f02..90af5ee1f104f 100644 --- a/packages/storybook/src/stories/playground/customize-components.stories.tsx +++ b/packages/storybook/src/stories/playground/customize-components.stories.tsx @@ -158,7 +158,7 @@ StyledColumns.args = { headerClassName: 'highlight', sortable: false, valueGetter: (params) => - `${params.getValue('firstName') || ''} ${params.getValue('lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, cellClassRules: { common: (params) => params.row.lastName === 'Smith', unknown: (params) => !params.row.lastName, From fba54015c55f8be98496c8f1c8a5bfef983f9017 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 30 Apr 2021 15:12:10 +0200 Subject: [PATCH 04/28] fix GridRowsCell props --- .../grid/_modules_/grid/components/GridViewport.tsx | 3 ++- .../_modules_/grid/components/cell/GridRowCells.tsx | 10 ++++++---- .../grid/hooks/features/sorting/useGridSorting.ts | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/grid/_modules_/grid/components/GridViewport.tsx b/packages/grid/_modules_/grid/components/GridViewport.tsx index b2308beb731ae..afb96740d9d5b 100644 --- a/packages/grid/_modules_/grid/components/GridViewport.tsx +++ b/packages/grid/_modules_/grid/components/GridViewport.tsx @@ -67,7 +67,8 @@ export const GridViewport: ViewportType = React.forwardRef( id={id} firstColIdx={renderState.renderContext!.firstColIdx!} lastColIdx={renderState.renderContext!.lastColIdx!} - hasScroll={{ y: scrollBarState!.hasScrollY, x: scrollBarState.hasScrollX }} + hasScrollX={scrollBarState.hasScrollX } + hasScrollY={scrollBarState.hasScrollY } showCellRightBorder={!!options.showCellRightBorder} extendRowFullWidth={!options.disableExtendRowFullWidth} rowIndex={renderState.renderContext!.firstRowIdx! + idx} diff --git a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx index 4693ec72f5d06..eb3a92f374758 100644 --- a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx @@ -28,7 +28,8 @@ interface RowCellsProps { extendRowFullWidth: boolean; firstColIdx: number; id: GridRowId; - hasScroll: { y: boolean; x: boolean }; + hasScrollX: boolean; + hasScrollY: boolean; lastColIdx: number; row: GridRowModel; rowIndex: number; @@ -41,7 +42,8 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { const { columns, firstColIdx, - hasScroll, + hasScrollX, + hasScrollY, id, lastColIdx, rowIndex, @@ -56,7 +58,7 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { const cellsProps = columns.slice(firstColIdx, lastColIdx + 1).map((column, colIdx) => { const colIndex = firstColIdx + colIdx; const isLastColumn = colIndex === columns.length - 1; - const removeLastBorderRight = isLastColumn && hasScroll.x && !hasScroll.y; + const removeLastBorderRight = isLastColumn && hasScrollX && !hasScrollY; const showRightBorder = !isLastColumn ? showCellRightBorder : !removeLastBorderRight && !props.extendRowFullWidth; @@ -103,7 +105,7 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { ...cssClassProp, rowIndex, cellMode: cellParams.cellMode, - colIndex: colIndex, + colIndex, children: cellComponent, isEditable: cellParams.isEditable, hasFocus: diff --git a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts index 1c9dae34bc891..2114ef709920f 100644 --- a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts +++ b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts @@ -169,10 +169,10 @@ export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { } const sortModel = apiRef.current.getState().sorting.sortModel; - logger.debug('Sorting rows with ', sortModel); const sorted = [...rowIds]; if (sortModel.length > 0) { comparatorList.current = buildComparatorList(sortModel); + logger.debug('Sorting rows with ', sortModel); sorted.sort(comparatorListAggregate); } From 03b5cd2d4c29ae4bb75087540c3784640981f01d Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 30 Apr 2021 15:26:45 +0200 Subject: [PATCH 05/28] restore icons --- .../_modules_/grid/components/icons/index.tsx | 4 +-- .../grid/models/gridSlotsComponent.ts | 28 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/grid/_modules_/grid/components/icons/index.tsx b/packages/grid/_modules_/grid/components/icons/index.tsx index 164c7b295b362..c550bc624efb2 100644 --- a/packages/grid/_modules_/grid/components/icons/index.tsx +++ b/packages/grid/_modules_/grid/components/icons/index.tsx @@ -87,5 +87,5 @@ export const GridCheckIcon = createSvgIcon( , 'Check', ); -export const IconTest = React.memo(()=> A ); -export const GridAddIcon = IconTest //createSvgIcon(, 'Add'); + +export const GridAddIcon = createSvgIcon(, 'Add'); diff --git a/packages/grid/_modules_/grid/models/gridSlotsComponent.ts b/packages/grid/_modules_/grid/models/gridSlotsComponent.ts index cb7981ce6b9bf..b3b6dd246e63d 100644 --- a/packages/grid/_modules_/grid/models/gridSlotsComponent.ts +++ b/packages/grid/_modules_/grid/models/gridSlotsComponent.ts @@ -16,7 +16,7 @@ import { GridViewStreamIcon, GridSaveAltIcon, GridCloseIcon, - GridCheckIcon, IconTest, + GridCheckIcon, } from '../components/icons/index'; import { GridLoadingOverlay } from '../components/GridLoadingOverlay'; import { GridColumnMenu } from '../components/menu/columnMenu/GridColumnMenu'; @@ -90,19 +90,19 @@ export interface GridSlotsComponent extends GridIconSlotsComponent { } export const DEFAULT_GRID_SLOTS_ICONS: GridIconSlotsComponent = { - BooleanCellTrueIcon: IconTest, - BooleanCellFalseIcon: IconTest, - OpenFilterButtonIcon: IconTest, - ColumnFilteredIcon: IconTest, - ColumnSelectorIcon: IconTest, - ColumnMenuIcon: IconTest, - ColumnSortedAscendingIcon: IconTest, - ColumnSortedDescendingIcon: IconTest, - ColumnResizeIcon: IconTest, - DensityCompactIcon: IconTest, - DensityStandardIcon: IconTest, - DensityComfortableIcon: IconTest, - ExportIcon: IconTest, + BooleanCellTrueIcon: GridCheckIcon, + BooleanCellFalseIcon: GridCloseIcon, + OpenFilterButtonIcon: GridFilterListIcon, + ColumnFilteredIcon: GridFilterAltIcon, + ColumnSelectorIcon: GridColumnIcon, + ColumnMenuIcon: GridTripleDotsVerticalIcon, + ColumnSortedAscendingIcon: GridArrowUpwardIcon, + ColumnSortedDescendingIcon: GridArrowDownwardIcon, + ColumnResizeIcon: GridSeparatorIcon, + DensityCompactIcon: GridViewHeadlineIcon, + DensityStandardIcon: GridTableRowsIcon, + DensityComfortableIcon: GridViewStreamIcon, + ExportIcon: GridSaveAltIcon, }; export const DEFAULT_GRID_SLOTS_COMPONENTS: GridApiRefComponentsProperty = { From 7012a72137e85172f55814bfe6d1d31d931b71c8 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 30 Apr 2021 19:23:25 +0200 Subject: [PATCH 06/28] fix checkbox focus --- .../GridCellCheckboxRenderer.tsx | 32 +++++++++++++++---- .../grid/components/containers/GridRoot.tsx | 4 +-- .../grid/hooks/features/focus/useGridFocus.ts | 3 +- .../hooks/features/rows/useGridParamsApi.ts | 5 +++ .../playground/real-data-demo.stories.tsx | 4 +-- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx index 9a24e6f455b16..4c6e9874b4af0 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -8,16 +8,18 @@ import { isNavigationKey, isSpaceKey } from '../../utils/keyboardUtils'; import { GridApiContext } from '../GridApiContext'; export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { - const { field, id } = props; + const {field, id} = props; const apiRef = React.useContext(GridApiContext); const tabIndexState = useGridSelector(apiRef, gridTabIndexCellSelector); const rowIndex = apiRef!.current.getRowIndex(id); const colIndex = apiRef!.current.getColumnIndex(field); const element = props.api.getCellElement(id, field); - - const handleChange = (event: React.ChangeEvent, checked: boolean) => { - apiRef!.current.selectRow(id, checked, true); - }; + const [, forceUpdate] = React.useState(false) + // const [tabIndex, setTabIndex] = React.useState(tabIndexState !== null && + // tabIndexState.rowIndex === rowIndex && + // tabIndexState.colIndex === colIndex + // ? 0 + // : -1); const tabIndex = tabIndexState !== null && @@ -26,6 +28,10 @@ export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { ? 0 : -1; + const handleChange = (event: React.ChangeEvent, checked: boolean) => { + apiRef!.current.selectRow(id, checked, true); + }; + React.useLayoutEffect(() => { if (tabIndex === 0 && element) { element!.tabIndex = -1; @@ -44,14 +50,26 @@ export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { [apiRef, props], ); + const handleCellNavigation = React.useCallback( + (params: GridCellParams) => { + forceUpdate(p=> !p) + }, + [], + ); + + React.useEffect(()=> { + return apiRef!.current.subscribeEvent('cellFocusChange', handleCellNavigation); + }, [apiRef, handleCellNavigation]) + console.log('Rendering ', tabIndex) + return ( ); diff --git a/packages/grid/_modules_/grid/components/containers/GridRoot.tsx b/packages/grid/_modules_/grid/components/containers/GridRoot.tsx index f6ef3c8002b84..1b8d8361aa929 100644 --- a/packages/grid/_modules_/grid/components/containers/GridRoot.tsx +++ b/packages/grid/_modules_/grid/components/containers/GridRoot.tsx @@ -8,7 +8,7 @@ import { GridApiContext } from '../GridApiContext'; export type GridRootProps = React.HTMLAttributes; -export const GridRoot = React.memo(React.forwardRef(function GridRoot( +export const GridRoot = React.forwardRef(function GridRoot( props, ref, ) { @@ -32,4 +32,4 @@ export const GridRoot = React.memo(React.forwardRef ); -})); +}); diff --git a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts index e93cf0fef2fe7..38cb3dfd84ef3 100644 --- a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts +++ b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts @@ -32,9 +32,10 @@ export const useGridFocus = (apiRef: GridApiRef): void => { focus: { cell: { rowIndex, colIndex }, columnHeader: null }, }; }); + apiRef.current.publishEvent('cellFocusChange'); forceUpdate(); }, - [forceUpdate, logger, setGridState], + [apiRef, forceUpdate, logger, setGridState], ); const setColumnHeaderFocus = React.useCallback( diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts index 130b1a3a35ca9..f6720c6652ddd 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts @@ -11,6 +11,8 @@ import { getGridRowElement, } from '../../../utils/domUtils'; import { useGridApiMethod } from '../../root/useGridApiMethod'; +import { useGridSelector } from '../core/useGridSelector'; +import { gridFocusCellSelector, gridTabIndexCellSelector } from '../focus/gridFocusStateSelector'; let warnedOnce = false; function warnMissingColumn(field) { @@ -24,6 +26,9 @@ function warnMissingColumn(field) { } export function useGridParamsApi(apiRef: GridApiRef) { + const cellFocus = useGridSelector(apiRef, gridFocusCellSelector); + const cellTabIndex = useGridSelector(apiRef, gridTabIndexCellSelector); + const getColumnHeaderParams = React.useCallback( (field: string): GridColumnHeaderParams => ({ field, diff --git a/packages/storybook/src/stories/playground/real-data-demo.stories.tsx b/packages/storybook/src/stories/playground/real-data-demo.stories.tsx index f8a91659190ba..0e1c47044e453 100644 --- a/packages/storybook/src/stories/playground/real-data-demo.stories.tsx +++ b/packages/storybook/src/stories/playground/real-data-demo.stories.tsx @@ -40,10 +40,10 @@ export default { }, }, rowLength: { - defaultValue: 2000, + defaultValue: 500, control: { type: 'select', - options: [10, 50, 100, 500, 1000, 2000, 5000, 8000, 10000, 50000, 100000, 500000], + options: [1, 9, 10, 50, 100, 500, 1000, 2000, 5000, 8000, 10000, 50000, 100000, 500000], }, }, multipleGrid: { From 36db1b0778a38f8c952fb2772bbf81025dbd30f5 Mon Sep 17 00:00:00 2001 From: damien Date: Mon, 3 May 2021 16:50:42 +0200 Subject: [PATCH 07/28] sort optimisation --- .../hooks/features/sorting/useGridSorting.ts | 2 -- .../_modules_/grid/models/gridSortModel.ts | 2 -- .../grid/_modules_/grid/utils/sortingUtils.ts | 27 +++++-------------- .../src/stories/grid-sorting.stories.tsx | 3 ++- 4 files changed, 8 insertions(+), 26 deletions(-) diff --git a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts index 2114ef709920f..abfa1fa7d0447 100644 --- a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts +++ b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts @@ -100,9 +100,7 @@ export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { const params: GridSortCellParams = { id, field, - row: apiRef.current.getRowFromId(id), value: apiRef.current.getCellValue(id, field), - getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), api: apiRef.current, }; diff --git a/packages/grid/_modules_/grid/models/gridSortModel.ts b/packages/grid/_modules_/grid/models/gridSortModel.ts index 801ef2900bfcb..c284aa6c1d9c6 100644 --- a/packages/grid/_modules_/grid/models/gridSortModel.ts +++ b/packages/grid/_modules_/grid/models/gridSortModel.ts @@ -8,9 +8,7 @@ export type GridFieldComparatorList = { field: string; comparator: GridComparato export interface GridSortCellParams { id: GridRowId; field: string; - row: GridRowData; value: GridCellValue; - getValue: (columnField: string) => GridCellValue; api: any; } diff --git a/packages/grid/_modules_/grid/utils/sortingUtils.ts b/packages/grid/_modules_/grid/utils/sortingUtils.ts index abef6e3b884ac..25a62d2cc0918 100644 --- a/packages/grid/_modules_/grid/utils/sortingUtils.ts +++ b/packages/grid/_modules_/grid/utils/sortingUtils.ts @@ -24,14 +24,9 @@ export const gridNillComparer = (v1: GridCellValue, v2: GridCellValue): number | }; export const gridStringNumberComparer: GridComparatorFn = ( - v1: GridCellValue, - v2: GridCellValue, - cellParams1, - cellParams2, + value1: GridCellValue, + value2: GridCellValue, ) => { - const value1 = cellParams1.getValue(cellParams1.field); - const value2 = cellParams2.getValue(cellParams2.field); - const nillResult = gridNillComparer(value1, value2); if (nillResult !== null) { return nillResult; @@ -44,14 +39,9 @@ export const gridStringNumberComparer: GridComparatorFn = ( }; export const gridNumberComparer: GridComparatorFn = ( - v1: GridCellValue, - v2: GridCellValue, - cellParams1, - cellParams2, + value1: GridCellValue, + value2: GridCellValue, ) => { - const value1 = cellParams1.getValue(cellParams1.field); - const value2 = cellParams2.getValue(cellParams2.field); - const nillResult = gridNillComparer(value1, value2); if (nillResult !== null) { return nillResult; @@ -61,14 +51,9 @@ export const gridNumberComparer: GridComparatorFn = ( }; export const gridDateComparer = ( - v1: GridCellValue, - v2: GridCellValue, - cellParams1, - cellParams2, + value1: GridCellValue, + value2: GridCellValue, ): number => { - const value1 = cellParams1.getValue(cellParams1.field); - const value2 = cellParams2.getValue(cellParams2.field); - const nillResult = gridNillComparer(value1, value2); if (nillResult !== null) { return nillResult; diff --git a/packages/storybook/src/stories/grid-sorting.stories.tsx b/packages/storybook/src/stories/grid-sorting.stories.tsx index 6d875814accd1..a5755798133b0 100644 --- a/packages/storybook/src/stories/grid-sorting.stories.tsx +++ b/packages/storybook/src/stories/grid-sorting.stories.tsx @@ -251,7 +251,8 @@ export const CustomComparator = () => { field: 'username', valueGetter: (params) => `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${params.api.getCellValue(params.id, 'age') || 'x'}`, - sortComparator: (v1, v2, cellParams1, cellParams2) => cellParams1.row.age - cellParams2.row.age, + sortComparator: (v1, v2, cellParams1, cellParams2) => + cellParams1.api.getCellValue(cellParams1.id, 'age') - cellParams2.api.getCellValue(cellParams2.id, 'age') , width: 150, }; From 4c8afd2a7ae0efea27f63570eb4cee48e3778b96 Mon Sep 17 00:00:00 2001 From: damien Date: Mon, 3 May 2021 19:04:47 +0200 Subject: [PATCH 08/28] refactor focus --- .../grid/components/GridViewport.tsx | 2 + .../grid/components/cell/GridBooleanCell.tsx | 2 + .../grid/components/cell/GridRowCells.tsx | 14 +++-- .../GridColumnHeadersItemCollection.tsx | 4 +- .../GridCellCheckboxRenderer.tsx | 51 ++++++------------- .../columnSelection/GridHeaderCheckbox.tsx | 5 +- .../grid/constants/eventsConstants.ts | 3 +- .../hooks/features/focus/gridFocusState.ts | 12 +++-- .../features/focus/gridFocusStateSelector.ts | 10 ++-- .../grid/hooks/features/focus/useGridFocus.ts | 30 +++++------ .../features/keyboard/useGridKeyboard.ts | 9 ++-- .../keyboard/useGridKeyboardNavigation.ts | 21 +++++--- .../hooks/features/rows/useGridEditRows.ts | 4 +- .../hooks/features/rows/useGridParamsApi.ts | 10 ++-- .../_modules_/grid/models/api/gridFocusApi.ts | 10 ++-- .../grid/models/params/gridCellParams.ts | 2 + 16 files changed, 93 insertions(+), 96 deletions(-) diff --git a/packages/grid/_modules_/grid/components/GridViewport.tsx b/packages/grid/_modules_/grid/components/GridViewport.tsx index afb96740d9d5b..ebf041fc3fdcd 100644 --- a/packages/grid/_modules_/grid/components/GridViewport.tsx +++ b/packages/grid/_modules_/grid/components/GridViewport.tsx @@ -74,11 +74,13 @@ export const GridViewport: ViewportType = React.forwardRef( rowIndex={renderState.renderContext!.firstRowIdx! + idx} cellFocus={cellFocus} cellTabIndex={cellTabIndex} + selected={selectionState[id] !== undefined} /> )); }; + console.log('viepo on ', props); return ( diff --git a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx index 238a9328d60c8..15429c0f8b468 100644 --- a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx @@ -13,6 +13,8 @@ export const GridBooleanCell = React.memo(( props: GridCellParams & SvgIconProps colDef, cellMode, isEditable, + hasFocus, + tabIndex, ...other } = props; diff --git a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx index eb3a92f374758..2e30a9347a71e 100644 --- a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { GridCellIdentifier } from '../../hooks/features/focus/gridFocusState'; import { gridEditRowsStateSelector } from '../../hooks/features/rows/gridEditRowsSelector'; import { GridCellClassParams, @@ -34,8 +35,9 @@ interface RowCellsProps { row: GridRowModel; rowIndex: number; showCellRightBorder: boolean; - cellFocus: GridCellIndexCoordinates | null; - cellTabIndex: GridCellIndexCoordinates | null; + cellFocus: GridCellIdentifier | null; + cellTabIndex: GridCellIdentifier | null; + selected: boolean; } export const GridRowCells = React.memo((props: RowCellsProps) => { @@ -50,6 +52,7 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { cellFocus, cellTabIndex, showCellRightBorder, + selected, } = props; const apiRef = React.useContext(GridApiContext); const rowHeight = useGridSelector(apiRef, gridDensityRowHeightSelector); @@ -109,17 +112,18 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { children: cellComponent, isEditable: cellParams.isEditable, hasFocus: - cellFocus !== null && cellFocus.rowIndex === rowIndex && cellFocus.colIndex === colIndex, + cellFocus !== null && cellFocus.id === id && cellFocus.field === column.field, tabIndex: cellTabIndex !== null && - cellTabIndex.rowIndex === rowIndex && - cellTabIndex.colIndex === colIndex + cellTabIndex.id === id && + cellTabIndex.field === column.field ? 0 : -1, }; return cellProps; }); + console.log('rowcells on ', props); return ( diff --git a/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeadersItemCollection.tsx b/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeadersItemCollection.tsx index 957079bf9d23b..417fbf657e4d1 100644 --- a/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeadersItemCollection.tsx +++ b/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeadersItemCollection.tsx @@ -45,11 +45,11 @@ export function GridColumnHeadersItemCollection(props: GridColumnHeadersItemColl const isFirstColumn = colIndex === 0; const hasTabbableElement = !(tabIndexState === null && cellTabIndexState === null); const tabIndex = - (tabIndexState !== null && tabIndexState.colIndex === colIndex) || + (tabIndexState !== null && tabIndexState.field === col.field) || (isFirstColumn && !hasTabbableElement) ? 0 : -1; - const hasFocus = columnHeaderFocus !== null && columnHeaderFocus.colIndex === colIndex; + const hasFocus = columnHeaderFocus !== null && columnHeaderFocus.field === col.field; return ( { - const {field, id} = props; +export const GridCellCheckboxRenderer = (props: GridCellParams) => { + const {field, id, value, tabIndex, hasFocus} = props; const apiRef = React.useContext(GridApiContext); - const tabIndexState = useGridSelector(apiRef, gridTabIndexCellSelector); - const rowIndex = apiRef!.current.getRowIndex(id); - const colIndex = apiRef!.current.getColumnIndex(field); + const checkboxElement = React.useRef(null); const element = props.api.getCellElement(id, field); - const [, forceUpdate] = React.useState(false) - // const [tabIndex, setTabIndex] = React.useState(tabIndexState !== null && - // tabIndexState.rowIndex === rowIndex && - // tabIndexState.colIndex === colIndex - // ? 0 - // : -1); - - const tabIndex = - tabIndexState !== null && - tabIndexState.rowIndex === rowIndex && - tabIndexState.colIndex === colIndex - ? 0 - : -1; const handleChange = (event: React.ChangeEvent, checked: boolean) => { apiRef!.current.selectRow(id, checked, true); @@ -35,8 +20,12 @@ export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { React.useLayoutEffect(() => { if (tabIndex === 0 && element) { element!.tabIndex = -1; + if(hasFocus) { + console.log('focusing on ', checkboxElement); + checkboxElement.current!.focus(); + } } - }, [element, tabIndex]); + }, [element, hasFocus, tabIndex]); const handleKeyDown = React.useCallback( (event) => { @@ -50,27 +39,19 @@ export const GridCellCheckboxRenderer = React.memo((props: GridCellParams) => { [apiRef, props], ); - const handleCellNavigation = React.useCallback( - (params: GridCellParams) => { - forceUpdate(p=> !p) - }, - [], - ); - - React.useEffect(()=> { - return apiRef!.current.subscribeEvent('cellFocusChange', handleCellNavigation); - }, [apiRef, handleCellNavigation]) - console.log('Rendering ', tabIndex) + console.log('Rendering on ', props); return ( ); -}); +}; diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx index 1984837d067b7..b07917487606a 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx @@ -15,7 +15,6 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { const visibleRowIds = useGridSelector(apiRef, visibleSortedGridRowIdsSelector); const tabIndexState = useGridSelector(apiRef, gridTabIndexColumnHeaderSelector); const element = apiRef!.current.getColumnHeaderElement(props.field); - const colIndex = apiRef!.current.getColumnIndex(props.field) const totalSelectedRows = useGridSelector(apiRef, selectedGridRowsCountSelector); const totalRows = useGridSelector(apiRef, gridRowCountSelector); @@ -39,7 +38,7 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { apiRef!.current.selectRows(visibleRowIds, checked); }; - const tabIndex = tabIndexState !== null && tabIndexState.colIndex === colIndex ? 0 : -1; + const tabIndex = tabIndexState !== null && tabIndexState.field === props.field ? 0 : -1; React.useLayoutEffect(() => { if (tabIndex === 0 && element) { element!.tabIndex = -1; @@ -57,7 +56,7 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { }, [apiRef, props], ); - +console.log('header cb rendered') return ( state.focus; export const gridFocusCellSelector = createSelector< GridState, GridFocusState, - GridCellIndexCoordinates | null + GridCellIdentifier | null >(gridFocusStateSelector, (focusState: GridFocusState) => focusState.cell); export const gridFocusColumnHeaderSelector = createSelector< GridState, GridFocusState, - GridColumnHeaderIndexCoordinates | null + GridColIdentifier | null >(gridFocusStateSelector, (focusState: GridFocusState) => focusState.columnHeader); export const gridTabIndexStateSelector = (state: GridState) => state.tabIndex; @@ -25,11 +25,11 @@ export const gridTabIndexStateSelector = (state: GridState) => state.tabIndex; export const gridTabIndexCellSelector = createSelector< GridState, GridTabIndexState, - GridCellIndexCoordinates | null + GridCellIdentifier | null >(gridTabIndexStateSelector, (state: GridTabIndexState) => state.cell); export const gridTabIndexColumnHeaderSelector = createSelector< GridState, GridTabIndexState, - GridColumnHeaderIndexCoordinates | null + GridColIdentifier | null >(gridTabIndexStateSelector, (state: GridTabIndexState) => state.columnHeader); diff --git a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts index 38cb3dfd84ef3..e133db94eb9a3 100644 --- a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts +++ b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts @@ -16,20 +16,20 @@ import { useGridApiMethod } from '../../root/useGridApiMethod'; import { useGridState } from '../core/useGridState'; import { useLogger } from '../../utils/useLogger'; import { useGridApiEventHandler } from '../../root/useGridApiEventHandler'; +import { GridCellIdentifier, GridColIdentifier } from './gridFocusState'; export const useGridFocus = (apiRef: GridApiRef): void => { const logger = useLogger('useGridFocus'); const [, setGridState, forceUpdate] = useGridState(apiRef); const setCellFocus = React.useCallback( - (nextCellIndexes: GridCellIndexCoordinates) => { + ({id, field}: GridCellIdentifier) => { setGridState((state) => { - const { rowIndex, colIndex } = nextCellIndexes; - logger.debug(`Focusing on cell with rowIndex=${rowIndex} and colIndex=${colIndex}`); + logger.debug(`Focusing on cell with id=${id} and field=${field}`); return { ...state, - tabIndex: { cell: { rowIndex, colIndex }, columnHeader: null }, - focus: { cell: { rowIndex, colIndex }, columnHeader: null }, + tabIndex: { cell: {id, field}, columnHeader: null }, + focus: { cell: {id, field}, columnHeader: null }, }; }); apiRef.current.publishEvent('cellFocusChange'); @@ -39,20 +39,21 @@ export const useGridFocus = (apiRef: GridApiRef): void => { ); const setColumnHeaderFocus = React.useCallback( - (nextColumnHeaderIndexes: GridColumnHeaderIndexCoordinates) => { + ({field}: GridColIdentifier) => { setGridState((state) => { - const { colIndex } = nextColumnHeaderIndexes; - logger.debug(`Focusing on column header with colIndex=${colIndex}`); + logger.debug(`Focusing on column header with colIndex=${field}`); return { ...state, - tabIndex: { columnHeader: { colIndex }, cell: null }, - focus: { columnHeader: { colIndex }, cell: null }, + tabIndex: { columnHeader: { field }, cell: null }, + focus: { columnHeader: { field }, cell: null }, }; }); + apiRef.current.publishEvent('cellFocusChange'); + forceUpdate(); }, - [forceUpdate, logger, setGridState], + [apiRef, forceUpdate, logger, setGridState], ); const handleCellFocus = React.useCallback( @@ -60,9 +61,7 @@ export const useGridFocus = (apiRef: GridApiRef): void => { if (event?.target !== event?.currentTarget) { return; } - const colIndex = apiRef.current.getColumnIndex(params.field); - const rowIndex = apiRef.current.getRowIndex(params.id); - apiRef.current.setCellFocus({colIndex, rowIndex}); + apiRef.current.setCellFocus(params); }, [apiRef], ); @@ -72,8 +71,7 @@ export const useGridFocus = (apiRef: GridApiRef): void => { if (event?.target !== event?.currentTarget) { return; } - const colIndex = apiRef.current.getColumnIndex(params.field); - apiRef.current.setColumnHeaderFocus({colIndex}); + apiRef.current.setColumnHeaderFocus(params); }, [apiRef], ); diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts index 38c72195be11c..8b24b5413194c 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts @@ -87,12 +87,13 @@ export const useGridKeyboard = ( apiRef.current.publishEvent(GRID_CELL_NAVIGATION_KEYDOWN, params, event); - const nextCellIndexes = apiRef.current.getState().focus.cell!; + const focusCell = apiRef.current.getState().focus.cell!; + const rowIndex = apiRef.current.getRowIndex(focusCell.id) // We select the rows in between - const rowIds = Array(Math.abs(nextCellIndexes.rowIndex - selectionFromRowIndex) + 1).fill( - nextCellIndexes.rowIndex > selectionFromRowIndex + const rowIds = Array(Math.abs(rowIndex - selectionFromRowIndex) + 1).fill( + rowIndex > selectionFromRowIndex ? selectionFromRowIndex - : nextCellIndexes.rowIndex, + : rowIndex, ); logger.debug('Selecting rows '); diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts index 65e67e6408b84..14b4ac4b3b3fd 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts @@ -132,7 +132,8 @@ export const useGridKeyboardNavigation = ( } if (nextCellIndexes.rowIndex < 0) { - apiRef.current.setColumnHeaderFocus({ colIndex: nextCellIndexes.colIndex }); + const field = apiRef.current.getVisibleColumns()[nextCellIndexes.colIndex].field; + apiRef.current.setColumnHeaderFocus({ field }); return; } @@ -147,7 +148,9 @@ export const useGridKeyboardNavigation = ( `Navigating to next cell row ${nextCellIndexes.rowIndex}, col ${nextCellIndexes.colIndex}`, ); apiRef.current.scrollToIndexes(nextCellIndexes); - apiRef.current.setCellFocus(nextCellIndexes); + const field = apiRef.current.getVisibleColumns()[nextCellIndexes.colIndex].field; + const id = apiRef.current.getRowIdFromRowIndex(nextCellIndexes.rowIndex) + apiRef.current.setCellFocus({field, id}); }, [ totalRowCount, @@ -179,9 +182,12 @@ export const useGridKeyboardNavigation = ( } else if (isPageKeys(key)) { // Handle only Page Down key, Page Up should keep the current possition if (key.indexOf('Down') > -1) { + const field = apiRef.current.getVisibleColumns()[colIndex].field; + const id = apiRef.current.getRowIdFromRowIndex(containerSizes!.viewportPageSize - 1) + apiRef.current.setCellFocus({ - colIndex, - rowIndex: containerSizes!.viewportPageSize - 1, + field, + id, }); } return; @@ -190,7 +196,9 @@ export const useGridKeyboardNavigation = ( } if (!nextColumnHeaderIndexes) { - apiRef.current.setCellFocus({ colIndex, rowIndex: 0 }); + const field = apiRef.current.getVisibleColumns()[colIndex].field; + const id = apiRef.current.getRowIdFromRowIndex(0) + apiRef.current.setCellFocus({ id,field }); return; } @@ -202,7 +210,8 @@ export const useGridKeyboardNavigation = ( logger.debug(`Navigating to next column row ${nextColumnHeaderIndexes.colIndex}`); apiRef.current.scrollToIndexes(nextColumnHeaderIndexes); - apiRef.current.setColumnHeaderFocus(nextColumnHeaderIndexes); + const field = apiRef.current.getVisibleColumns()[nextColumnHeaderIndexes.colIndex].field; + apiRef.current.setColumnHeaderFocus({field}); }, [apiRef, colCount, containerSizes, logger], ); diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts index 8ea355e4f5fe4..179f57ed22bc0 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts @@ -219,9 +219,7 @@ export function useGridEditRows(apiRef: GridApiRef) { return; } if (isEscapeKey(event.key) || isDeleteKeys(event.key)) { - const colIndex = apiRef.current.getColumnIndex(params.field); - const rowIndex = apiRef.current.getRowIndex(params.id); - apiRef.current.setCellFocus({ colIndex, rowIndex }); + apiRef.current.setCellFocus(params); } }, [apiRef, setCellMode], diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts index f6720c6652ddd..b0636372725de 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts @@ -32,7 +32,6 @@ export function useGridParamsApi(apiRef: GridApiRef) { const getColumnHeaderParams = React.useCallback( (field: string): GridColumnHeaderParams => ({ field, - // getElement: ()=> apiRef.current.getColumnHeaderElement(field), colDef: apiRef.current.getColumnFromField(field), api: apiRef!.current, }), @@ -43,9 +42,7 @@ export function useGridParamsApi(apiRef: GridApiRef) { (id: GridRowId) => { const params: GridRowParams = { id, - // getElement: ()=> apiRef.current.getRowElement(id), columns: apiRef.current.getAllColumns(), - // getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), row: apiRef.current.getRowFromId(id), api: apiRef.current, }; @@ -59,20 +56,20 @@ export function useGridParamsApi(apiRef: GridApiRef) { const row = apiRef.current.getRowFromId(id); const params: GridValueGetterParams = { - // getElement: ()=> apiRef.current.getCellElement(id, field), id, field, row, value: row[field], - // getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), colDef: apiRef.current.getColumnFromField(field), cellMode: apiRef.current.getCellMode(id, field), api: apiRef.current, + hasFocus: cellFocus !== null && cellFocus.field === field && cellFocus.id === id, + tabIndex: cellTabIndex && cellTabIndex.field === field && cellTabIndex.id === id ? 0 : -1, }; return params; }, - [apiRef], + [apiRef, cellFocus, cellTabIndex], ); const getCellParams = React.useCallback( @@ -83,7 +80,6 @@ export function useGridParamsApi(apiRef: GridApiRef) { const params: GridCellParams = { ...baseParams, value, - // getValue: (columnField: string) => apiRef.current.getCellValue(id, columnField), formattedValue: value, }; if (colDef.valueFormatter) { diff --git a/packages/grid/_modules_/grid/models/api/gridFocusApi.ts b/packages/grid/_modules_/grid/models/api/gridFocusApi.ts index d27fa2dac6f23..5c1322f1e17a2 100644 --- a/packages/grid/_modules_/grid/models/api/gridFocusApi.ts +++ b/packages/grid/_modules_/grid/models/api/gridFocusApi.ts @@ -1,14 +1,14 @@ -import { GridCellIndexCoordinates, GridColumnHeaderIndexCoordinates } from '../gridCell'; +import { GridCellIdentifier, GridColIdentifier } from '../../hooks/features/focus/gridFocusState'; export interface GridFocusApi { /** * Set the active element to the cell with the indexes. - * @param indexes + * @param params */ - setCellFocus: (indexes: GridCellIndexCoordinates) => void; + setCellFocus: (params: GridCellIdentifier) => void; /** * Set the active element to the column header with the indexes. - * @param indexes + * @param params */ - setColumnHeaderFocus: (indexes: GridColumnHeaderIndexCoordinates) => void; + setColumnHeaderFocus: (params: GridColIdentifier) => void; } diff --git a/packages/grid/_modules_/grid/models/params/gridCellParams.ts b/packages/grid/_modules_/grid/models/params/gridCellParams.ts index ecde57058c0e6..5d57770dd29c9 100644 --- a/packages/grid/_modules_/grid/models/params/gridCellParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridCellParams.ts @@ -50,6 +50,8 @@ export interface GridCellParams { * The mode of the cell. */ cellMode: GridCellMode; + hasFocus: boolean; + tabIndex: 0 | -1; } /** From 44d6e3423384520f8f49e7e1ba55c22e0cf69135 Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 4 May 2021 13:13:12 +0200 Subject: [PATCH 09/28] fix cell renderer focus and selection --- .../_modules_/grid/components/GridViewport.tsx | 1 - .../_modules_/grid/components/cell/GridCell.tsx | 2 +- .../grid/components/cell/GridRowCells.tsx | 1 - .../columnSelection/GridCellCheckboxRenderer.tsx | 16 ++++++++-------- .../columnSelection/GridHeaderCheckbox.tsx | 13 +++++++++++-- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/grid/_modules_/grid/components/GridViewport.tsx b/packages/grid/_modules_/grid/components/GridViewport.tsx index ebf041fc3fdcd..096b3a48f2c1c 100644 --- a/packages/grid/_modules_/grid/components/GridViewport.tsx +++ b/packages/grid/_modules_/grid/components/GridViewport.tsx @@ -80,7 +80,6 @@ export const GridViewport: ViewportType = React.forwardRef( )); }; - console.log('viepo on ', props); return ( diff --git a/packages/grid/_modules_/grid/components/cell/GridCell.tsx b/packages/grid/_modules_/grid/components/cell/GridCell.tsx index 0bc95dc367a56..18b9c0d0c0ac1 100644 --- a/packages/grid/_modules_/grid/components/cell/GridCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridCell.tsx @@ -149,7 +149,7 @@ export const GridCell = React.memo((props: GridCellProps) => { cellRef.current && (!document.activeElement || !cellRef.current!.contains(document.activeElement)) ) { - const focusableElement = cellRef.current.querySelector('[tabindex="0"]') as HTMLElement; + const focusableElement = cellRef.current!.querySelector('[tabindex="0"]') as HTMLElement; if (focusableElement) { focusableElement!.focus(); } else { diff --git a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx index 2e30a9347a71e..421a088c3abfa 100644 --- a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx @@ -123,7 +123,6 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { return cellProps; }); - console.log('rowcells on ', props); return ( diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx index 95f1930ef120a..3accd39bae41a 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -20,12 +20,15 @@ export const GridCellCheckboxRenderer = (props: GridCellParams) => { React.useLayoutEffect(() => { if (tabIndex === 0 && element) { element!.tabIndex = -1; - if(hasFocus) { - console.log('focusing on ', checkboxElement); - checkboxElement.current!.focus(); - } } - }, [element, hasFocus, tabIndex]); + }, [element, tabIndex]); + + React.useLayoutEffect(() => { + if(hasFocus) { + const input = checkboxElement.current!.querySelector('input')!; + input!.focus(); + } + }, [hasFocus]); const handleKeyDown = React.useCallback( (event) => { @@ -39,8 +42,6 @@ export const GridCellCheckboxRenderer = (props: GridCellParams) => { [apiRef, props], ); - console.log('Rendering on ', props); - return ( { color="primary" inputProps={{'aria-label': 'Select Row checkbox'}} onKeyDown={handleKeyDown} - // autoFocus={hasFocus} /> ); }; diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx index b07917487606a..859cb575dea7d 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx @@ -1,6 +1,6 @@ import Checkbox from '@material-ui/core/Checkbox'; import * as React from 'react'; -import { GRID_COLUMN_HEADER_NAVIGATION_KEYDOWN } from '../../constants/eventsConstants'; +import { GRID_COLUMN_HEADER_NAVIGATION_KEYDOWN, GRID_SELECTION_CHANGED } from '../../constants/eventsConstants'; import { useGridSelector } from '../../hooks/features/core/useGridSelector'; import { visibleSortedGridRowIdsSelector } from '../../hooks/features/filter/gridFilterSelector'; import { gridTabIndexColumnHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector'; @@ -11,6 +11,7 @@ import { isNavigationKey, isSpaceKey } from '../../utils/keyboardUtils'; import { GridApiContext } from '../GridApiContext'; export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { + const [, forceUpdate] = React.useState(false); const apiRef = React.useContext(GridApiContext); const visibleRowIds = useGridSelector(apiRef, visibleSortedGridRowIdsSelector); const tabIndexState = useGridSelector(apiRef, gridTabIndexColumnHeaderSelector); @@ -56,7 +57,15 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { }, [apiRef, props], ); -console.log('header cb rendered') + + const handleSelectionChange = React.useCallback(()=> { + forceUpdate(p=> !p); + }, []); + + React.useEffect(()=> { + return apiRef?.current.subscribeEvent(GRID_SELECTION_CHANGED, handleSelectionChange); + }, [apiRef, handleSelectionChange]); + return ( Date: Tue, 4 May 2021 13:15:24 +0200 Subject: [PATCH 10/28] cleanup --- packages/grid/_modules_/grid/constants/eventsConstants.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/grid/_modules_/grid/constants/eventsConstants.ts b/packages/grid/_modules_/grid/constants/eventsConstants.ts index 5e27a5bbcc132..9f314d8ce73f7 100644 --- a/packages/grid/_modules_/grid/constants/eventsConstants.ts +++ b/packages/grid/_modules_/grid/constants/eventsConstants.ts @@ -29,7 +29,6 @@ export const GRID_CELL_EDIT_ENTER = 'cellEditEnter'; export const GRID_CELL_EDIT_EXIT = 'cellEditExit'; export const GRID_CELL_NAVIGATION_KEYDOWN = 'cellNavigationKeyDown'; export const GRID_CELL_FOCUS = 'cellFocus'; -// export const GRID_CELL_FOCUS = 'cellFocusChange'; export const GRID_CELL_DRAG_START = 'cellDragStart'; export const GRID_CELL_DRAG_ENTER = 'cellDragEnter'; export const GRID_CELL_DRAG_OVER = 'cellDragOver'; From 3529abd894bc1aa3d1d08e37781c732361ad8a1e Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 4 May 2021 15:27:15 +0200 Subject: [PATCH 11/28] cleanup --- .../grid/components/GridViewport.tsx | 6 ++--- .../grid/components/cell/GridBooleanCell.tsx | 8 ++++--- .../grid/components/cell/GridCell.tsx | 3 +++ .../grid/components/cell/GridRowCells.tsx | 17 ++++++-------- .../columnHeaders/ColumnHeaderMenuIcon.tsx | 2 +- .../columnHeaders/GridColumnHeaderItem.tsx | 8 +++---- .../GridCellCheckboxRenderer.tsx | 10 ++++----- .../columnSelection/GridHeaderCheckbox.tsx | 13 ++++++----- .../_modules_/grid/components/icons/index.tsx | 1 - .../hooks/features/focus/gridFocusState.ts | 12 ++++------ .../features/focus/gridFocusStateSelector.ts | 15 +++++++------ .../grid/hooks/features/focus/useGridFocus.ts | 22 ++++++++----------- .../features/keyboard/useGridKeyboard.ts | 6 ++--- .../keyboard/useGridKeyboardNavigation.ts | 19 +++++++--------- .../hooks/features/rows/useGridEditRows.ts | 2 +- .../_modules_/grid/models/api/gridFocusApi.ts | 6 ++--- .../_modules_/grid/models/gridSortModel.ts | 2 +- .../grid/models/params/gridRowParams.ts | 1 - .../grid/_modules_/grid/utils/sortingUtils.ts | 5 +---- .../src/stories/grid-columns.stories.tsx | 10 +++++++-- .../src/stories/grid-error.stories.tsx | 4 +++- .../src/stories/grid-sorting.stories.tsx | 11 +++++++--- .../src/stories/grid-style.stories.tsx | 4 +++- .../customize-components.stories.tsx | 4 +++- 24 files changed, 97 insertions(+), 94 deletions(-) diff --git a/packages/grid/_modules_/grid/components/GridViewport.tsx b/packages/grid/_modules_/grid/components/GridViewport.tsx index 096b3a48f2c1c..46a5f22dbfcbb 100644 --- a/packages/grid/_modules_/grid/components/GridViewport.tsx +++ b/packages/grid/_modules_/grid/components/GridViewport.tsx @@ -67,14 +67,14 @@ export const GridViewport: ViewportType = React.forwardRef( id={id} firstColIdx={renderState.renderContext!.firstColIdx!} lastColIdx={renderState.renderContext!.lastColIdx!} - hasScrollX={scrollBarState.hasScrollX } - hasScrollY={scrollBarState.hasScrollY } + hasScrollX={scrollBarState.hasScrollX} + hasScrollY={scrollBarState.hasScrollY} showCellRightBorder={!!options.showCellRightBorder} extendRowFullWidth={!options.disableExtendRowFullWidth} rowIndex={renderState.renderContext!.firstRowIdx! + idx} cellFocus={cellFocus} cellTabIndex={cellTabIndex} - selected={selectionState[id] !== undefined} + isSelected={selectionState[id] !== undefined} /> diff --git a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx index 15429c0f8b468..432cdc95faecc 100644 --- a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { SvgIconProps } from '@material-ui/core/SvgIcon'; import { GridCellParams } from '../../models/params/gridCellParams'; -export const GridBooleanCell = React.memo(( props: GridCellParams & SvgIconProps) => { +export const GridBooleanCell = React.memo((props: GridCellParams & SvgIconProps) => { const { id, value, @@ -18,8 +18,10 @@ export const GridBooleanCell = React.memo(( props: GridCellParams & SvgIconProps ...other } = props; - const Icon = React.useMemo(()=> value ? api.components.BooleanCellTrueIcon : api.components.BooleanCellFalseIcon, - [api.components.BooleanCellFalseIcon, api.components.BooleanCellTrueIcon, value]); + const Icon = React.useMemo( + () => (value ? api.components.BooleanCellTrueIcon : api.components.BooleanCellFalseIcon), + [api.components.BooleanCellFalseIcon, api.components.BooleanCellTrueIcon, value], + ); return ( { hasFocus, height, isEditable, + isSelected, rowIndex, rowId, showRightBorder, @@ -166,6 +168,7 @@ export const GridCell = React.memo((props: GridCellProps) => { data-value={value} data-field={field} data-rowindex={rowIndex} + data-rowselected={isSelected} data-editable={isEditable} data-mode={cellMode} aria-colindex={colIndex} diff --git a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx index 421a088c3abfa..ba154cae30bda 100644 --- a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx @@ -7,7 +7,6 @@ import { GridRowModel, GridCellClassRules, GridCellParams, - GridCellIndexCoordinates, GridRowId, } from '../../models/index'; import { GridCell, GridCellProps } from './GridCell'; @@ -29,15 +28,15 @@ interface RowCellsProps { extendRowFullWidth: boolean; firstColIdx: number; id: GridRowId; - hasScrollX: boolean; - hasScrollY: boolean; + hasScrollX: boolean; + hasScrollY: boolean; lastColIdx: number; row: GridRowModel; rowIndex: number; showCellRightBorder: boolean; cellFocus: GridCellIdentifier | null; cellTabIndex: GridCellIdentifier | null; - selected: boolean; + isSelected: boolean; } export const GridRowCells = React.memo((props: RowCellsProps) => { @@ -52,7 +51,7 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { cellFocus, cellTabIndex, showCellRightBorder, - selected, + isSelected, } = props; const apiRef = React.useContext(GridApiContext); const rowHeight = useGridSelector(apiRef, gridDensityRowHeightSelector); @@ -111,12 +110,10 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { colIndex, children: cellComponent, isEditable: cellParams.isEditable, - hasFocus: - cellFocus !== null && cellFocus.id === id && cellFocus.field === column.field, + isSelected, + hasFocus: cellFocus !== null && cellFocus.id === id && cellFocus.field === column.field, tabIndex: - cellTabIndex !== null && - cellTabIndex.id === id && - cellTabIndex.field === column.field + cellTabIndex !== null && cellTabIndex.id === id && cellTabIndex.field === column.field ? 0 : -1, }; diff --git a/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx b/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx index 5db3af8b6b535..a6b8007fef35c 100644 --- a/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx +++ b/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderMenuIcon.tsx @@ -11,7 +11,7 @@ import { GridColDef } from '../../models/colDef/gridColDef'; export interface ColumnHeaderFilterIconProps { column: GridColDef; } -export const ColumnHeaderMenuIcon = React.memo(( props: ColumnHeaderFilterIconProps) => { +export const ColumnHeaderMenuIcon = React.memo((props: ColumnHeaderFilterIconProps) => { const { column } = props; const apiRef = React.useContext(GridApiContext); const columnMenuState = useGridSelector(apiRef, gridColumnMenuStateSelector); diff --git a/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx b/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx index 22debd2f9cd28..85291b9f33b37 100644 --- a/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx +++ b/packages/grid/_modules_/grid/components/columnHeaders/GridColumnHeaderItem.tsx @@ -68,10 +68,10 @@ export const GridColumnHeaderItem = React.memo( // todo refactor to a prop on col isNumeric or ?? ie: coltype===price wont work const isColumnNumeric = column.type === GRID_NUMBER_COLUMN_TYPE; - let headerComponent: React.ReactElement | null = null; - if (column.renderHeader && apiRef!.current) { - headerComponent = column.renderHeader(apiRef!.current.getColumnHeaderParams(column.field)); - } + let headerComponent: React.ReactElement | null = null; + if (column.renderHeader && apiRef!.current) { + headerComponent = column.renderHeader(apiRef!.current.getColumnHeaderParams(column.field)); + } const publish = React.useCallback( (eventName: string) => (event: React.MouseEvent | React.DragEvent) => diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx index 3accd39bae41a..c52a8787c8c4d 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -1,14 +1,12 @@ import Checkbox from '@material-ui/core/Checkbox'; import * as React from 'react'; -import { - GRID_CELL_NAVIGATION_KEYDOWN, -} from '../../constants/eventsConstants'; +import { GRID_CELL_NAVIGATION_KEYDOWN } from '../../constants/eventsConstants'; import { GridCellParams } from '../../models/params/gridCellParams'; import { isNavigationKey, isSpaceKey } from '../../utils/keyboardUtils'; import { GridApiContext } from '../GridApiContext'; export const GridCellCheckboxRenderer = (props: GridCellParams) => { - const {field, id, value, tabIndex, hasFocus} = props; + const { field, id, value, tabIndex, hasFocus } = props; const apiRef = React.useContext(GridApiContext); const checkboxElement = React.useRef(null); const element = props.api.getCellElement(id, field); @@ -24,7 +22,7 @@ export const GridCellCheckboxRenderer = (props: GridCellParams) => { }, [element, tabIndex]); React.useLayoutEffect(() => { - if(hasFocus) { + if (hasFocus) { const input = checkboxElement.current!.querySelector('input')!; input!.focus(); } @@ -50,7 +48,7 @@ export const GridCellCheckboxRenderer = (props: GridCellParams) => { onChange={handleChange} className="MuiDataGrid-checkboxInput" color="primary" - inputProps={{'aria-label': 'Select Row checkbox'}} + inputProps={{ 'aria-label': 'Select Row checkbox' }} onKeyDown={handleKeyDown} /> ); diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx index 859cb575dea7d..6622db1715d61 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx @@ -1,6 +1,9 @@ import Checkbox from '@material-ui/core/Checkbox'; import * as React from 'react'; -import { GRID_COLUMN_HEADER_NAVIGATION_KEYDOWN, GRID_SELECTION_CHANGED } from '../../constants/eventsConstants'; +import { + GRID_COLUMN_HEADER_NAVIGATION_KEYDOWN, + GRID_SELECTION_CHANGED, +} from '../../constants/eventsConstants'; import { useGridSelector } from '../../hooks/features/core/useGridSelector'; import { visibleSortedGridRowIdsSelector } from '../../hooks/features/filter/gridFilterSelector'; import { gridTabIndexColumnHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector'; @@ -39,7 +42,7 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { apiRef!.current.selectRows(visibleRowIds, checked); }; - const tabIndex = tabIndexState !== null && tabIndexState.field === props.field ? 0 : -1; + const tabIndex = tabIndexState !== null && tabIndexState.field === props.field ? 0 : -1; React.useLayoutEffect(() => { if (tabIndex === 0 && element) { element!.tabIndex = -1; @@ -58,11 +61,11 @@ export const GridHeaderCheckbox = (props: GridColumnHeaderParams) => { [apiRef, props], ); - const handleSelectionChange = React.useCallback(()=> { - forceUpdate(p=> !p); + const handleSelectionChange = React.useCallback(() => { + forceUpdate((p) => !p); }, []); - React.useEffect(()=> { + React.useEffect(() => { return apiRef?.current.subscribeEvent(GRID_SELECTION_CHANGED, handleSelectionChange); }, [apiRef, handleSelectionChange]); diff --git a/packages/grid/_modules_/grid/components/icons/index.tsx b/packages/grid/_modules_/grid/components/icons/index.tsx index c550bc624efb2..32b3a4c1e0276 100644 --- a/packages/grid/_modules_/grid/components/icons/index.tsx +++ b/packages/grid/_modules_/grid/components/icons/index.tsx @@ -67,7 +67,6 @@ export const GridCloseIcon = createSvgIcon( 'Close', ); - export const GridLoadIcon = createSvgIcon( , 'Load', diff --git a/packages/grid/_modules_/grid/hooks/features/focus/gridFocusState.ts b/packages/grid/_modules_/grid/hooks/features/focus/gridFocusState.ts index 68450228848c7..3f48a81200300 100644 --- a/packages/grid/_modules_/grid/hooks/features/focus/gridFocusState.ts +++ b/packages/grid/_modules_/grid/hooks/features/focus/gridFocusState.ts @@ -1,18 +1,14 @@ -import { - GridCellIndexCoordinates, - GridColumnHeaderIndexCoordinates, -} from '../../../models/gridCell'; import { GridRowId } from '../../../models/gridRows'; -export type GridCellIdentifier = {id: GridRowId, field: string}; -export type GridColIdentifier = { field: string}; +export type GridCellIdentifier = { id: GridRowId; field: string }; +export type GridColumnIdentifier = { field: string }; export interface GridFocusState { cell: GridCellIdentifier | null; - columnHeader: GridColIdentifier | null; + columnHeader: GridColumnIdentifier | null; } export interface GridTabIndexState { cell: GridCellIdentifier | null; - columnHeader: GridColIdentifier | null; + columnHeader: GridColumnIdentifier | null; } diff --git a/packages/grid/_modules_/grid/hooks/features/focus/gridFocusStateSelector.ts b/packages/grid/_modules_/grid/hooks/features/focus/gridFocusStateSelector.ts index fa866f90797fd..a5a6380391fb9 100644 --- a/packages/grid/_modules_/grid/hooks/features/focus/gridFocusStateSelector.ts +++ b/packages/grid/_modules_/grid/hooks/features/focus/gridFocusStateSelector.ts @@ -1,10 +1,11 @@ import { createSelector } from 'reselect'; -import { - GridCellIndexCoordinates, - GridColumnHeaderIndexCoordinates, -} from '../../../models/gridCell'; import { GridState } from '../core/gridState'; -import { GridCellIdentifier, GridColIdentifier, GridFocusState, GridTabIndexState } from './gridFocusState'; +import { + GridCellIdentifier, + GridColumnIdentifier, + GridFocusState, + GridTabIndexState, +} from './gridFocusState'; export const gridFocusStateSelector = (state: GridState) => state.focus; @@ -17,7 +18,7 @@ export const gridFocusCellSelector = createSelector< export const gridFocusColumnHeaderSelector = createSelector< GridState, GridFocusState, - GridColIdentifier | null + GridColumnIdentifier | null >(gridFocusStateSelector, (focusState: GridFocusState) => focusState.columnHeader); export const gridTabIndexStateSelector = (state: GridState) => state.tabIndex; @@ -31,5 +32,5 @@ export const gridTabIndexCellSelector = createSelector< export const gridTabIndexColumnHeaderSelector = createSelector< GridState, GridTabIndexState, - GridColIdentifier | null + GridColumnIdentifier | null >(gridTabIndexStateSelector, (state: GridTabIndexState) => state.columnHeader); diff --git a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts index e133db94eb9a3..ebe64ec1a762e 100644 --- a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts +++ b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts @@ -7,29 +7,25 @@ import { } from '../../../constants/eventsConstants'; import { GridApiRef } from '../../../models/api/gridApiRef'; import { GridFocusApi } from '../../../models/api/gridFocusApi'; -import { - GridCellIndexCoordinates, - GridColumnHeaderIndexCoordinates, -} from '../../../models/gridCell'; +import { GridRowId } from '../../../models/gridRows'; import { GridCellParams } from '../../../models/params/gridCellParams'; import { useGridApiMethod } from '../../root/useGridApiMethod'; import { useGridState } from '../core/useGridState'; import { useLogger } from '../../utils/useLogger'; import { useGridApiEventHandler } from '../../root/useGridApiEventHandler'; -import { GridCellIdentifier, GridColIdentifier } from './gridFocusState'; export const useGridFocus = (apiRef: GridApiRef): void => { const logger = useLogger('useGridFocus'); const [, setGridState, forceUpdate] = useGridState(apiRef); const setCellFocus = React.useCallback( - ({id, field}: GridCellIdentifier) => { + (id: GridRowId, field: string) => { setGridState((state) => { logger.debug(`Focusing on cell with id=${id} and field=${field}`); return { ...state, - tabIndex: { cell: {id, field}, columnHeader: null }, - focus: { cell: {id, field}, columnHeader: null }, + tabIndex: { cell: { id, field }, columnHeader: null }, + focus: { cell: { id, field }, columnHeader: null }, }; }); apiRef.current.publishEvent('cellFocusChange'); @@ -39,7 +35,7 @@ export const useGridFocus = (apiRef: GridApiRef): void => { ); const setColumnHeaderFocus = React.useCallback( - ({field}: GridColIdentifier) => { + (field: string) => { setGridState((state) => { logger.debug(`Focusing on column header with colIndex=${field}`); @@ -57,21 +53,21 @@ export const useGridFocus = (apiRef: GridApiRef): void => { ); const handleCellFocus = React.useCallback( - (params: GridCellParams, event?: React.SyntheticEvent) => { + ({ id, field }: GridCellParams, event?: React.SyntheticEvent) => { if (event?.target !== event?.currentTarget) { return; } - apiRef.current.setCellFocus(params); + apiRef.current.setCellFocus(id, field); }, [apiRef], ); const handleColumnHeaderFocus = React.useCallback( - (params: GridCellParams, event?: React.SyntheticEvent) => { + ({ field }: GridCellParams, event?: React.SyntheticEvent) => { if (event?.target !== event?.currentTarget) { return; } - apiRef.current.setColumnHeaderFocus(params); + apiRef.current.setColumnHeaderFocus(field); }, [apiRef], ); diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts index 8b24b5413194c..100c00a84311a 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts @@ -88,12 +88,10 @@ export const useGridKeyboard = ( apiRef.current.publishEvent(GRID_CELL_NAVIGATION_KEYDOWN, params, event); const focusCell = apiRef.current.getState().focus.cell!; - const rowIndex = apiRef.current.getRowIndex(focusCell.id) + const rowIndex = apiRef.current.getRowIndex(focusCell.id); // We select the rows in between const rowIds = Array(Math.abs(rowIndex - selectionFromRowIndex) + 1).fill( - rowIndex > selectionFromRowIndex - ? selectionFromRowIndex - : rowIndex, + rowIndex > selectionFromRowIndex ? selectionFromRowIndex : rowIndex, ); logger.debug('Selecting rows '); diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts index 14b4ac4b3b3fd..d8206d9e18db9 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboardNavigation.ts @@ -133,7 +133,7 @@ export const useGridKeyboardNavigation = ( if (nextCellIndexes.rowIndex < 0) { const field = apiRef.current.getVisibleColumns()[nextCellIndexes.colIndex].field; - apiRef.current.setColumnHeaderFocus({ field }); + apiRef.current.setColumnHeaderFocus(field); return; } @@ -149,8 +149,8 @@ export const useGridKeyboardNavigation = ( ); apiRef.current.scrollToIndexes(nextCellIndexes); const field = apiRef.current.getVisibleColumns()[nextCellIndexes.colIndex].field; - const id = apiRef.current.getRowIdFromRowIndex(nextCellIndexes.rowIndex) - apiRef.current.setCellFocus({field, id}); + const id = apiRef.current.getRowIdFromRowIndex(nextCellIndexes.rowIndex); + apiRef.current.setCellFocus(id, field); }, [ totalRowCount, @@ -183,12 +183,9 @@ export const useGridKeyboardNavigation = ( // Handle only Page Down key, Page Up should keep the current possition if (key.indexOf('Down') > -1) { const field = apiRef.current.getVisibleColumns()[colIndex].field; - const id = apiRef.current.getRowIdFromRowIndex(containerSizes!.viewportPageSize - 1) + const id = apiRef.current.getRowIdFromRowIndex(containerSizes!.viewportPageSize - 1); - apiRef.current.setCellFocus({ - field, - id, - }); + apiRef.current.setCellFocus(id, field); } return; } else { @@ -197,8 +194,8 @@ export const useGridKeyboardNavigation = ( if (!nextColumnHeaderIndexes) { const field = apiRef.current.getVisibleColumns()[colIndex].field; - const id = apiRef.current.getRowIdFromRowIndex(0) - apiRef.current.setCellFocus({ id,field }); + const id = apiRef.current.getRowIdFromRowIndex(0); + apiRef.current.setCellFocus(id, field); return; } @@ -211,7 +208,7 @@ export const useGridKeyboardNavigation = ( logger.debug(`Navigating to next column row ${nextColumnHeaderIndexes.colIndex}`); apiRef.current.scrollToIndexes(nextColumnHeaderIndexes); const field = apiRef.current.getVisibleColumns()[nextColumnHeaderIndexes.colIndex].field; - apiRef.current.setColumnHeaderFocus({field}); + apiRef.current.setColumnHeaderFocus(field); }, [apiRef, colCount, containerSizes, logger], ); diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts index 179f57ed22bc0..87b598e05f11a 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts @@ -219,7 +219,7 @@ export function useGridEditRows(apiRef: GridApiRef) { return; } if (isEscapeKey(event.key) || isDeleteKeys(event.key)) { - apiRef.current.setCellFocus(params); + apiRef.current.setCellFocus(params.id, params.field); } }, [apiRef, setCellMode], diff --git a/packages/grid/_modules_/grid/models/api/gridFocusApi.ts b/packages/grid/_modules_/grid/models/api/gridFocusApi.ts index 5c1322f1e17a2..79e0661b5faf8 100644 --- a/packages/grid/_modules_/grid/models/api/gridFocusApi.ts +++ b/packages/grid/_modules_/grid/models/api/gridFocusApi.ts @@ -1,14 +1,14 @@ -import { GridCellIdentifier, GridColIdentifier } from '../../hooks/features/focus/gridFocusState'; +import { GridRowId } from '../gridRows'; export interface GridFocusApi { /** * Set the active element to the cell with the indexes. * @param params */ - setCellFocus: (params: GridCellIdentifier) => void; + setCellFocus: (id: GridRowId, field: string) => void; /** * Set the active element to the column header with the indexes. * @param params */ - setColumnHeaderFocus: (params: GridColIdentifier) => void; + setColumnHeaderFocus: (field: string) => void; } diff --git a/packages/grid/_modules_/grid/models/gridSortModel.ts b/packages/grid/_modules_/grid/models/gridSortModel.ts index c284aa6c1d9c6..31ba340989f9e 100644 --- a/packages/grid/_modules_/grid/models/gridSortModel.ts +++ b/packages/grid/_modules_/grid/models/gridSortModel.ts @@ -1,5 +1,5 @@ import { GridCellValue } from './gridCell'; -import { GridRowData, GridRowId } from './gridRows'; +import { GridRowId } from './gridRows'; export type GridSortDirection = 'asc' | 'desc' | null | undefined; diff --git a/packages/grid/_modules_/grid/models/params/gridRowParams.ts b/packages/grid/_modules_/grid/models/params/gridRowParams.ts index d7f5a2fc79707..e9692098878ed 100644 --- a/packages/grid/_modules_/grid/models/params/gridRowParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridRowParams.ts @@ -1,4 +1,3 @@ -import { GridCellValue } from '../gridCell'; import { GridRowId, GridRowModel } from '../gridRows'; /** diff --git a/packages/grid/_modules_/grid/utils/sortingUtils.ts b/packages/grid/_modules_/grid/utils/sortingUtils.ts index 25a62d2cc0918..516fad6f46f13 100644 --- a/packages/grid/_modules_/grid/utils/sortingUtils.ts +++ b/packages/grid/_modules_/grid/utils/sortingUtils.ts @@ -50,10 +50,7 @@ export const gridNumberComparer: GridComparatorFn = ( return Number(value1) - Number(value2); }; -export const gridDateComparer = ( - value1: GridCellValue, - value2: GridCellValue, -): number => { +export const gridDateComparer = (value1: GridCellValue, value2: GridCellValue): number => { const nillResult = gridNillComparer(value1, value2); if (nillResult !== null) { return nillResult; diff --git a/packages/storybook/src/stories/grid-columns.stories.tsx b/packages/storybook/src/stories/grid-columns.stories.tsx index b120959124558..f10ac66f28e59 100644 --- a/packages/storybook/src/stories/grid-columns.stories.tsx +++ b/packages/storybook/src/stories/grid-columns.stories.tsx @@ -299,12 +299,18 @@ export const ValueGetterAndFormatter = () => { { field: 'firstAge', valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue(params.id, 'age')}`, + `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue( + params.id, + 'age', + )}`, }, { field: 'firstAgeFormatted', valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue(params.id, 'age')}`, + `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue( + params.id, + 'age', + )}`, valueFormatter: (params) => `${params.value} yrs`, }, ], diff --git a/packages/storybook/src/stories/grid-error.stories.tsx b/packages/storybook/src/stories/grid-error.stories.tsx index 8697e330d7863..695884061abe1 100644 --- a/packages/storybook/src/stories/grid-error.stories.tsx +++ b/packages/storybook/src/stories/grid-error.stories.tsx @@ -26,7 +26,9 @@ const getColumns: () => GridColDef[] = () => [ description: 'this column has a value getter and is not sortable', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' + }`, }, { field: 'isRegistered', diff --git a/packages/storybook/src/stories/grid-sorting.stories.tsx b/packages/storybook/src/stories/grid-sorting.stories.tsx index a5755798133b0..e727ffa32a12d 100644 --- a/packages/storybook/src/stories/grid-sorting.stories.tsx +++ b/packages/storybook/src/stories/grid-sorting.stories.tsx @@ -234,7 +234,9 @@ export const UnsortableLastCol = () => { field: 'username', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${params.api.getCellValue(params.id, 'age') || 'x'}`, + `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${ + params.api.getCellValue(params.id, 'age') || 'x' + }`, width: 150, }; @@ -250,9 +252,12 @@ export const CustomComparator = () => { columns[columns.length] = { field: 'username', valueGetter: (params) => - `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${params.api.getCellValue(params.id, 'age') || 'x'}`, + `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${ + params.api.getCellValue(params.id, 'age') || 'x' + }`, sortComparator: (v1, v2, cellParams1, cellParams2) => - cellParams1.api.getCellValue(cellParams1.id, 'age') - cellParams2.api.getCellValue(cellParams2.id, 'age') , + cellParams1.api.getCellValue(cellParams1.id, 'age') - + cellParams2.api.getCellValue(cellParams2.id, 'age'), width: 150, }; diff --git a/packages/storybook/src/stories/grid-style.stories.tsx b/packages/storybook/src/stories/grid-style.stories.tsx index bcc8b615a3f5e..69cf2c2e4b54f 100644 --- a/packages/storybook/src/stories/grid-style.stories.tsx +++ b/packages/storybook/src/stories/grid-style.stories.tsx @@ -61,7 +61,9 @@ const getColumns: () => GridColDef[] = () => [ description: 'this column has a value getter and is not sortable', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`.trim(), + `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' + }`.trim(), }, { field: 'isRegistered', diff --git a/packages/storybook/src/stories/playground/customize-components.stories.tsx b/packages/storybook/src/stories/playground/customize-components.stories.tsx index 90af5ee1f104f..f1578eab28349 100644 --- a/packages/storybook/src/stories/playground/customize-components.stories.tsx +++ b/packages/storybook/src/stories/playground/customize-components.stories.tsx @@ -158,7 +158,9 @@ StyledColumns.args = { headerClassName: 'highlight', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' + }`, cellClassRules: { common: (params) => params.row.lastName === 'Smith', unknown: (params) => !params.row.lastName, From 98e2754facb92147d1de496233a3dcbd01282099 Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 4 May 2021 15:46:21 +0200 Subject: [PATCH 12/28] cleanup --- .../_modules_/grid/models/api/gridFocusApi.ts | 5 +++-- .../grid/models/params/gridCellParams.ts | 15 ++++++--------- .../grid/models/params/gridColumnHeaderParams.ts | 4 ---- .../_modules_/grid/models/params/gridRowParams.ts | 9 --------- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/packages/grid/_modules_/grid/models/api/gridFocusApi.ts b/packages/grid/_modules_/grid/models/api/gridFocusApi.ts index 79e0661b5faf8..81434915d4ed7 100644 --- a/packages/grid/_modules_/grid/models/api/gridFocusApi.ts +++ b/packages/grid/_modules_/grid/models/api/gridFocusApi.ts @@ -3,12 +3,13 @@ import { GridRowId } from '../gridRows'; export interface GridFocusApi { /** * Set the active element to the cell with the indexes. - * @param params + * @param id + * @param field */ setCellFocus: (id: GridRowId, field: string) => void; /** * Set the active element to the column header with the indexes. - * @param params + * @param field */ setColumnHeaderFocus: (field: string) => void; } diff --git a/packages/grid/_modules_/grid/models/params/gridCellParams.ts b/packages/grid/_modules_/grid/models/params/gridCellParams.ts index 5d57770dd29c9..8a8d35afae43a 100644 --- a/packages/grid/_modules_/grid/models/params/gridCellParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridCellParams.ts @@ -9,10 +9,6 @@ export interface GridCellParams { * The grid row id. */ id: GridRowId; - /** - * The HTMLElement cell element. - */ - // getElement: () => HTMLElement | null; /** * The column field of the cell that triggered the event */ @@ -25,11 +21,6 @@ export interface GridCellParams { * The cell value formatted with the column valueFormatter. */ formattedValue: GridCellValue; - /** - * A function that let you get data from other columns. - * @param field - */ - // getValue: (field: string) => GridCellValue; /** * The row model of the row that the current cell belongs to. */ @@ -50,7 +41,13 @@ export interface GridCellParams { * The mode of the cell. */ cellMode: GridCellMode; + /** + * If true, the cell is the active element. + */ hasFocus: boolean; + /** + * the tabIndex value. + */ tabIndex: 0 | -1; } diff --git a/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts b/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts index c63c3456b7f79..9f0362e138fa0 100644 --- a/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridColumnHeaderParams.ts @@ -2,10 +2,6 @@ * Object passed as parameter in the column [[GridColDef]] header renderer. */ export interface GridColumnHeaderParams { - /** - * The HTMLElement column header element. - */ - // getElement: () => HTMLElement | null; /** * The column field of the column that triggered the event */ diff --git a/packages/grid/_modules_/grid/models/params/gridRowParams.ts b/packages/grid/_modules_/grid/models/params/gridRowParams.ts index e9692098878ed..934baa33e63f5 100644 --- a/packages/grid/_modules_/grid/models/params/gridRowParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridRowParams.ts @@ -8,15 +8,6 @@ export interface GridRowParams { * The grid row id. */ id: GridRowId; - /** - * The HTMLElement row element. - */ - // getElement: () => HTMLElement | null; - /** - * A function that let you get data from other columns. - * @param field - */ - // getValue: (field: string) => GridCellValue; /** * The row model of the row that the current cell belongs to. */ From 34e2d6ac9c6037e0269515b97c6d7cbc0258c93e Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 4 May 2021 16:27:16 +0200 Subject: [PATCH 13/28] fix ts issues --- .../pages/components/data-grid/columns/ValueGetterGrid.js | 4 ++-- .../components/data-grid/columns/ValueGetterGrid.tsx | 4 ++-- .../data-grid/editing/CatchEditingEventsGrid.js | 2 +- .../data-grid/editing/CatchEditingEventsGrid.tsx | 4 ++-- .../components/data-grid/editing/ValueGetterGrid.tsx | 4 ++-- .../pages/components/data-grid/overview/DataGridDemo.js | 4 +++- .../pages/components/data-grid/overview/DataGridDemo.tsx | 2 +- .../components/data-grid/sorting/ComparatorSortingGrid.js | 8 ++++++-- .../data-grid/sorting/ComparatorSortingGrid.tsx | 5 +++-- .../grid/hooks/features/rows/useGridParamsApi.ts | 3 ++- .../grid/data-grid/src/tests/layout.DataGrid.test.tsx | 4 ++-- packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx | 2 +- 12 files changed, 27 insertions(+), 19 deletions(-) diff --git a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js index f93d8d163f799..90255696054bf 100644 --- a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js +++ b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js @@ -2,8 +2,8 @@ import * as React from 'react'; import { DataGrid } from '@material-ui/data-grid'; function getFullName(params) { - return `${params.getValue('firstName') || ''} ${ - params.getValue('lastName') || '' + return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx index 2eb1b973de312..e6a496fae164a 100644 --- a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx +++ b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx @@ -2,8 +2,8 @@ import * as React from 'react'; import { DataGrid, GridColDef, GridSortCellParams } from '@material-ui/data-grid'; function getFullName(params: GridSortCellParams) { - return `${params.getValue('firstName') || ''} ${ - params.getValue('lastName') || '' + return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.js b/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.js index 447045d274820..4f7089c12ce29 100644 --- a/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.js +++ b/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.js @@ -20,7 +20,7 @@ export default function CatchEditingEventsGrid() { React.useEffect(() => { return apiRef.current.subscribeEvent(GRID_CELL_EDIT_ENTER, (params, event) => { setMessage( - `Editing cell with value: ${params.value} at row: ${params.rowIndex}, column: ${params.field}, triggered by ${event.type}.`, + `Editing cell with value: ${params.value} and row id: ${params.id}, column: ${params.field}, triggered by ${event.type}.`, ); }); }, [apiRef]); diff --git a/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx b/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx index e78846854065e..c4a6419f51dce 100644 --- a/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx +++ b/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx @@ -25,8 +25,8 @@ export default function CatchEditingEventsGrid() { GRID_CELL_EDIT_ENTER, (params: GridCellParams, event?: React.SyntheticEvent) => { setMessage( - `Editing cell with value: ${params.value} at row: ${ - params.rowIndex + `Editing cell with value: ${params.value} and row id: ${ + params.id }, column: ${params.field}, triggered by ${event!.type}.`, ); }, diff --git a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx index d2fbc8d917b47..765bc28577743 100644 --- a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx +++ b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx @@ -8,8 +8,8 @@ import { } from '@material-ui/data-grid'; function getFullName(params: GridSortCellParams) { - return `${params.getValue('firstName') || ''} ${ - params.getValue('lastName') || '' + return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/overview/DataGridDemo.js b/docs/src/pages/components/data-grid/overview/DataGridDemo.js index bd7016c6d1deb..e19d69b23d344 100644 --- a/docs/src/pages/components/data-grid/overview/DataGridDemo.js +++ b/docs/src/pages/components/data-grid/overview/DataGridDemo.js @@ -18,7 +18,9 @@ const columns = [ sortable: false, width: 160, valueGetter: (params) => - `${params.getValue('firstName') || ''} ${params.getValue('lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' + }`, }, ]; diff --git a/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx b/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx index f4fa10db58e5b..7e5f52019afc4 100644 --- a/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx +++ b/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx @@ -18,7 +18,7 @@ const columns: GridColDef[] = [ sortable: false, width: 160, valueGetter: (params: GridValueGetterParams) => - `${params.getValue('firstName') || ''} ${params.getValue('lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, }, ]; diff --git a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js index da1f16b3b11b5..d41d23cf9284c 100644 --- a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js +++ b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js @@ -11,8 +11,12 @@ const columns = [ { field: 'username', valueGetter: (params) => - `${params.getValue('name') || 'unknown'} - ${params.getValue('age') || 'x'}`, - sortComparator: (v1, v2, param1, param2) => param1.row.age - param2.row.age, + `${params.api.getCellValue(params.id, 'name') || 'unknown'} - ${ + params.api.getCellValue(params.id, 'age') || 'x' + }`, + sortComparator: (v1, v2, param1, param2) => + param1.api.getCellValue(param1.id, 'age') - + param2.api.getCellValue(param2.id, 'age'), width: 150, }, { field: 'dateCreated', type: 'date', width: 180 }, diff --git a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx index 77de800d57aae..78aea57951b2e 100644 --- a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx +++ b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx @@ -17,8 +17,9 @@ const columns: GridColumns = [ { field: 'username', valueGetter: (params: GridValueGetterParams) => - `${params.getValue('name') || 'unknown'} - ${params.getValue('age') || 'x'}`, - sortComparator: (v1, v2, param1, param2) => param1.row.age - param2.row.age, + `${params.api.getCellValue(params.id, 'name') || 'unknown'} - ${params.api.getCellValue(params.id, 'age') || 'x'}`, + sortComparator: (v1, v2, param1, param2) => + param1.api.getCellValue(param1.id, 'age') - param2.api.getCellValue(param2.id, 'age'), width: 150, }, { field: 'dateCreated', type: 'date', width: 180 }, diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts index b0636372725de..a2a3990b6b606 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts @@ -62,6 +62,7 @@ export function useGridParamsApi(apiRef: GridApiRef) { value: row[field], colDef: apiRef.current.getColumnFromField(field), cellMode: apiRef.current.getCellMode(id, field), + // getValue: apiRef.current.getCellValue, api: apiRef.current, hasFocus: cellFocus !== null && cellFocus.field === field && cellFocus.id === id, tabIndex: cellTabIndex && cellTabIndex.field === field && cellTabIndex.id === id ? 0 : -1, @@ -152,6 +153,6 @@ export function useGridParamsApi(apiRef: GridApiRef) { getColumnHeaderParams, getColumnHeaderElement, }, - 'CellApi', + 'GridParamsApi', ); } diff --git a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx index 984ec63bea151..bd161caa6a6f6 100644 --- a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx +++ b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx @@ -117,7 +117,7 @@ describe(' - Layout & Warnings', () => { { field: 'fullName', valueGetter: (params) => - `${params.getValue('firstName') || ''} ${params.getValue('lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, }, ]; @@ -186,7 +186,7 @@ describe(' - Layout & Warnings', () => { { field: 'id', hide: true }, { field: 'fullName', - valueGetter: (params: GridValueGetterParams) => params.getValue('age'), + valueGetter: (params: GridValueGetterParams) => params.api.getCellValue(params.id, 'age'), }, ]; expect(() => { diff --git a/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx b/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx index acd5d686b193c..46746bd2f6c89 100644 --- a/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx @@ -59,7 +59,7 @@ describe(' - Edit Rows', () => { ); }; - it('isCellEditable should add the class MuiDataGrid-cellEditable to editable cells but not prevent a cell from switching mode', () => { + it.only('isCellEditable should add the class MuiDataGrid-cellEditable to editable cells but not prevent a cell from switching mode', () => { render( params.value === 'Adidas'} />); const cellNike = getCell(0, 0); expect(cellNike).not.to.have.class('MuiDataGrid-cellEditable'); From add56c5f0206483b42e2c96d4950bd666015f530 Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 4 May 2021 16:29:24 +0200 Subject: [PATCH 14/28] fix test --- packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx b/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx index 46746bd2f6c89..acd5d686b193c 100644 --- a/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx @@ -59,7 +59,7 @@ describe(' - Edit Rows', () => { ); }; - it.only('isCellEditable should add the class MuiDataGrid-cellEditable to editable cells but not prevent a cell from switching mode', () => { + it('isCellEditable should add the class MuiDataGrid-cellEditable to editable cells but not prevent a cell from switching mode', () => { render( params.value === 'Adidas'} />); const cellNike = getCell(0, 0); expect(cellNike).not.to.have.class('MuiDataGrid-cellEditable'); From 2c592eb17d6d37cdfde07e0892dec93367c1aebf Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 4 May 2021 16:37:28 +0200 Subject: [PATCH 15/28] cleanup --- .../pages/components/data-grid/editing/ValueGetterGrid.js | 4 ++-- .../pages/components/data-grid/overview/DataGridDemo.tsx | 4 +++- .../src/pages/components/data-grid/rows/StylingRowsGrid.js | 4 +++- .../pages/components/data-grid/rows/StylingRowsGrid.tsx | 4 +++- .../components/data-grid/sorting/ComparatorSortingGrid.tsx | 7 +++++-- packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx | 7 +++++-- packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx | 3 ++- 7 files changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js index a06d2c26d0c56..b88ab73d31e30 100644 --- a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js +++ b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js @@ -3,8 +3,8 @@ import * as React from 'react'; import { DataGrid } from '@material-ui/data-grid'; function getFullName(params) { - return `${params.getValue('firstName') || ''} ${ - params.getValue('lastName') || '' + return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx b/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx index 7e5f52019afc4..c370440799adc 100644 --- a/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx +++ b/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx @@ -18,7 +18,9 @@ const columns: GridColDef[] = [ sortable: false, width: 160, valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' + }`, }, ]; diff --git a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js index 1578f397b6eb4..4c076ace6dea6 100644 --- a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js +++ b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js @@ -56,7 +56,9 @@ export default function StylingRowsGrid() {
`super-app-theme--${params.getValue('status')}`} + getRowClassName={(params) => + `super-app-theme--${params.api.getCellValue(params.id, 'status')}` + } />
); diff --git a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx index 1578f397b6eb4..4c076ace6dea6 100644 --- a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx +++ b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx @@ -56,7 +56,9 @@ export default function StylingRowsGrid() {
`super-app-theme--${params.getValue('status')}`} + getRowClassName={(params) => + `super-app-theme--${params.api.getCellValue(params.id, 'status')}` + } />
); diff --git a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx index 78aea57951b2e..d810187b946a9 100644 --- a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx +++ b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx @@ -17,9 +17,12 @@ const columns: GridColumns = [ { field: 'username', valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'name') || 'unknown'} - ${params.api.getCellValue(params.id, 'age') || 'x'}`, + `${params.api.getCellValue(params.id, 'name') || 'unknown'} - ${ + params.api.getCellValue(params.id, 'age') || 'x' + }`, sortComparator: (v1, v2, param1, param2) => - param1.api.getCellValue(param1.id, 'age') - param2.api.getCellValue(param2.id, 'age'), + param1.api.getCellValue(param1.id, 'age') - + param2.api.getCellValue(param2.id, 'age'), width: 150, }, { field: 'dateCreated', type: 'date', width: 180 }, diff --git a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx index bd161caa6a6f6..a3623225fe7cd 100644 --- a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx +++ b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx @@ -117,7 +117,9 @@ describe(' - Layout & Warnings', () => { { field: 'fullName', valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${params.api.getCellValue(params.id, 'lastName') || ''}`, + `${params.api.getCellValue(params.id, 'firstName') || ''} ${ + params.api.getCellValue(params.id, 'lastName') || '' + }`, }, ]; @@ -186,7 +188,8 @@ describe(' - Layout & Warnings', () => { { field: 'id', hide: true }, { field: 'fullName', - valueGetter: (params: GridValueGetterParams) => params.api.getCellValue(params.id, 'age'), + valueGetter: (params: GridValueGetterParams) => + params.api.getCellValue(params.id, 'age'), }, ]; expect(() => { diff --git a/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx b/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx index 8facc016c3e11..fd1ca9e07ca42 100644 --- a/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx @@ -85,7 +85,8 @@ describe(' - Rows', () => { it('should apply the CSS class returned by getRowClassName', () => { const getRowId = (row) => `${row.clientId}`; - const getRowClassName = (params) => (params.getValue('age') < 20 ? 'under-age' : ''); + const getRowClassName = (params) => + params.api.getCellValue(params.id, 'age') < 20 ? 'under-age' : ''; render(
From 89eaee1f867024077ca9e9d03b83b3642463fb69 Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 4 May 2021 17:09:19 +0200 Subject: [PATCH 16/28] restore icons --- packages/grid/_modules_/grid/components/icons/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grid/_modules_/grid/components/icons/index.tsx b/packages/grid/_modules_/grid/components/icons/index.tsx index 32b3a4c1e0276..4d66ffc24d365 100644 --- a/packages/grid/_modules_/grid/components/icons/index.tsx +++ b/packages/grid/_modules_/grid/components/icons/index.tsx @@ -67,6 +67,8 @@ export const GridCloseIcon = createSvgIcon( 'Close', ); +export const GridAddIcon = createSvgIcon(, 'Add'); + export const GridLoadIcon = createSvgIcon( , 'Load', @@ -86,5 +88,3 @@ export const GridCheckIcon = createSvgIcon( , 'Check', ); - -export const GridAddIcon = createSvgIcon(, 'Add'); From c532ddf6a8858bfddc0e6ffc6a1a08d288f097c4 Mon Sep 17 00:00:00 2001 From: damien Date: Wed, 5 May 2021 16:39:56 +0200 Subject: [PATCH 17/28] add getValue pointer to getCellValue api method --- .../components/data-grid/columns/ValueGetterGrid.tsx | 4 ++-- .../components/data-grid/editing/ValueGetterGrid.tsx | 4 ++-- .../pages/components/data-grid/overview/DataGridDemo.tsx | 4 ++-- .../pages/components/data-grid/rows/StylingRowsGrid.tsx | 2 +- .../data-grid/sorting/ComparatorSortingGrid.tsx | 4 ++-- .../_modules_/grid/components/cell/GridBooleanCell.tsx | 1 + .../grid/components/cell/GridEditBooleanCell.tsx | 1 + .../_modules_/grid/components/cell/GridEditInputCell.tsx | 1 + .../grid/hooks/features/rows/useGridParamsApi.ts | 2 +- .../grid/_modules_/grid/models/params/gridCellParams.ts | 6 ++++++ .../grid/data-grid/src/tests/layout.DataGrid.test.tsx | 6 +++--- packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx | 2 +- packages/storybook/src/stories/grid-columns.stories.tsx | 4 ++-- packages/storybook/src/stories/grid-error.stories.tsx | 4 ++-- packages/storybook/src/stories/grid-sorting.stories.tsx | 8 ++++---- packages/storybook/src/stories/grid-style.stories.tsx | 4 ++-- .../stories/playground/customize-components.stories.tsx | 4 ++-- 17 files changed, 35 insertions(+), 26 deletions(-) diff --git a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx index e6a496fae164a..f7f201b16036a 100644 --- a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx +++ b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx @@ -2,8 +2,8 @@ import * as React from 'react'; import { DataGrid, GridColDef, GridSortCellParams } from '@material-ui/data-grid'; function getFullName(params: GridSortCellParams) { - return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + return `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx index 765bc28577743..0a0883ab04b0d 100644 --- a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx +++ b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx @@ -8,8 +8,8 @@ import { } from '@material-ui/data-grid'; function getFullName(params: GridSortCellParams) { - return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + return `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx b/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx index c370440799adc..b775918b5f790 100644 --- a/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx +++ b/docs/src/pages/components/data-grid/overview/DataGridDemo.tsx @@ -18,8 +18,8 @@ const columns: GridColDef[] = [ sortable: false, width: 160, valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`, }, ]; diff --git a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx index 4c076ace6dea6..775cf218b8c9e 100644 --- a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx +++ b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.tsx @@ -57,7 +57,7 @@ export default function StylingRowsGrid() { - `super-app-theme--${params.api.getCellValue(params.id, 'status')}` + `super-app-theme--${params.getValue(params.id, 'status')}` } />
diff --git a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx index d810187b946a9..ae0ad2891ad25 100644 --- a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx +++ b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.tsx @@ -17,8 +17,8 @@ const columns: GridColumns = [ { field: 'username', valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'name') || 'unknown'} - ${ - params.api.getCellValue(params.id, 'age') || 'x' + `${params.getValue(params.id, 'name') || 'unknown'} - ${ + params.getValue(params.id, 'age') || 'x' }`, sortComparator: (v1, v2, param1, param2) => param1.api.getCellValue(param1.id, 'age') - diff --git a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx index 432cdc95faecc..f6caca5c0931c 100644 --- a/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridBooleanCell.tsx @@ -15,6 +15,7 @@ export const GridBooleanCell = React.memo((props: GridCellParams & SvgIconProps) isEditable, hasFocus, tabIndex, + getValue, ...other } = props; diff --git a/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx b/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx index 2fd07f83a9a9c..774e26e104fed 100644 --- a/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridEditBooleanCell.tsx @@ -19,6 +19,7 @@ export function GridEditBooleanCell( cellMode, isEditable, className, + getValue, ...other } = props; diff --git a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx index c189857231749..487b7dc1d8bf1 100644 --- a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx @@ -15,6 +15,7 @@ export function GridEditInputCell(props: GridCellParams & InputBaseProps) { colDef, cellMode, isEditable, + getValue, ...other } = props; diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts index a2a3990b6b606..fcac3c4c0db5d 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts @@ -62,7 +62,7 @@ export function useGridParamsApi(apiRef: GridApiRef) { value: row[field], colDef: apiRef.current.getColumnFromField(field), cellMode: apiRef.current.getCellMode(id, field), - // getValue: apiRef.current.getCellValue, + getValue: apiRef.current.getCellValue, api: apiRef.current, hasFocus: cellFocus !== null && cellFocus.field === field && cellFocus.id === id, tabIndex: cellTabIndex && cellTabIndex.field === field && cellTabIndex.id === id ? 0 : -1, diff --git a/packages/grid/_modules_/grid/models/params/gridCellParams.ts b/packages/grid/_modules_/grid/models/params/gridCellParams.ts index 8a8d35afae43a..fb7c59a44b7f7 100644 --- a/packages/grid/_modules_/grid/models/params/gridCellParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridCellParams.ts @@ -49,6 +49,12 @@ export interface GridCellParams { * the tabIndex value. */ tabIndex: 0 | -1; + /** + * Get the cell value of a row and field. + * @param id + * @param field + */ + getValue: (id: GridRowId, field: string) => GridCellValue; } /** diff --git a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx index a3623225fe7cd..70a13a0067f82 100644 --- a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx +++ b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx @@ -117,8 +117,8 @@ describe(' - Layout & Warnings', () => { { field: 'fullName', valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`, }, ]; @@ -189,7 +189,7 @@ describe(' - Layout & Warnings', () => { { field: 'fullName', valueGetter: (params: GridValueGetterParams) => - params.api.getCellValue(params.id, 'age'), + params.getValue(params.id, 'age'), }, ]; expect(() => { diff --git a/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx b/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx index fd1ca9e07ca42..7061390e9abed 100644 --- a/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx @@ -86,7 +86,7 @@ describe(' - Rows', () => { it('should apply the CSS class returned by getRowClassName', () => { const getRowId = (row) => `${row.clientId}`; const getRowClassName = (params) => - params.api.getCellValue(params.id, 'age') < 20 ? 'under-age' : ''; + params.getValue(params.id, 'age') < 20 ? 'under-age' : ''; render(
diff --git a/packages/storybook/src/stories/grid-columns.stories.tsx b/packages/storybook/src/stories/grid-columns.stories.tsx index f10ac66f28e59..5a0f0d8500af9 100644 --- a/packages/storybook/src/stories/grid-columns.stories.tsx +++ b/packages/storybook/src/stories/grid-columns.stories.tsx @@ -299,7 +299,7 @@ export const ValueGetterAndFormatter = () => { { field: 'firstAge', valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue( + `${params.getValue(params.id, 'first')}_${params.getValue( params.id, 'age', )}`, @@ -307,7 +307,7 @@ export const ValueGetterAndFormatter = () => { { field: 'firstAgeFormatted', valueGetter: (params: GridValueGetterParams) => - `${params.api.getCellValue(params.id, 'first')}_${params.api.getCellValue( + `${params.getValue(params.id, 'first')}_${params.getValue( params.id, 'age', )}`, diff --git a/packages/storybook/src/stories/grid-error.stories.tsx b/packages/storybook/src/stories/grid-error.stories.tsx index 695884061abe1..1c50ed7f9542a 100644 --- a/packages/storybook/src/stories/grid-error.stories.tsx +++ b/packages/storybook/src/stories/grid-error.stories.tsx @@ -26,8 +26,8 @@ const getColumns: () => GridColDef[] = () => [ description: 'this column has a value getter and is not sortable', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`, }, { diff --git a/packages/storybook/src/stories/grid-sorting.stories.tsx b/packages/storybook/src/stories/grid-sorting.stories.tsx index e727ffa32a12d..007c4cf57406f 100644 --- a/packages/storybook/src/stories/grid-sorting.stories.tsx +++ b/packages/storybook/src/stories/grid-sorting.stories.tsx @@ -234,8 +234,8 @@ export const UnsortableLastCol = () => { field: 'username', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${ - params.api.getCellValue(params.id, 'age') || 'x' + `${params.getValue(params.id, 'name') || 'unknown'}_${ + params.getValue(params.id, 'age') || 'x' }`, width: 150, }; @@ -252,8 +252,8 @@ export const CustomComparator = () => { columns[columns.length] = { field: 'username', valueGetter: (params) => - `${params.api.getCellValue(params.id, 'name') || 'unknown'}_${ - params.api.getCellValue(params.id, 'age') || 'x' + `${params.getValue(params.id, 'name') || 'unknown'}_${ + params.getValue(params.id, 'age') || 'x' }`, sortComparator: (v1, v2, cellParams1, cellParams2) => cellParams1.api.getCellValue(cellParams1.id, 'age') - diff --git a/packages/storybook/src/stories/grid-style.stories.tsx b/packages/storybook/src/stories/grid-style.stories.tsx index 69cf2c2e4b54f..4374ade8521ae 100644 --- a/packages/storybook/src/stories/grid-style.stories.tsx +++ b/packages/storybook/src/stories/grid-style.stories.tsx @@ -61,8 +61,8 @@ const getColumns: () => GridColDef[] = () => [ description: 'this column has a value getter and is not sortable', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`.trim(), }, { diff --git a/packages/storybook/src/stories/playground/customize-components.stories.tsx b/packages/storybook/src/stories/playground/customize-components.stories.tsx index f1578eab28349..4a9d52cd94cc2 100644 --- a/packages/storybook/src/stories/playground/customize-components.stories.tsx +++ b/packages/storybook/src/stories/playground/customize-components.stories.tsx @@ -158,8 +158,8 @@ StyledColumns.args = { headerClassName: 'highlight', sortable: false, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`, cellClassRules: { common: (params) => params.row.lastName === 'Smith', From 140ae6b314e00af84e278e8c68a61e8faea0d3c3 Mon Sep 17 00:00:00 2001 From: damien Date: Wed, 5 May 2021 18:22:29 +0200 Subject: [PATCH 18/28] fix edit cell --- .../grid/_modules_/grid/components/GridViewport.tsx | 3 +++ .../_modules_/grid/components/cell/GridRowCells.tsx | 7 ++++--- .../grid/data-grid/src/tests/layout.DataGrid.test.tsx | 3 +-- .../grid/data-grid/src/tests/rows.DataGrid.test.tsx | 3 +-- .../storybook/src/stories/grid-columns.stories.tsx | 10 ++-------- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/packages/grid/_modules_/grid/components/GridViewport.tsx b/packages/grid/_modules_/grid/components/GridViewport.tsx index 46a5f22dbfcbb..cc9864154deff 100644 --- a/packages/grid/_modules_/grid/components/GridViewport.tsx +++ b/packages/grid/_modules_/grid/components/GridViewport.tsx @@ -7,6 +7,7 @@ import { gridFocusCellSelector, gridTabIndexCellSelector, } from '../hooks/features/focus/gridFocusStateSelector'; +import { gridEditRowsStateSelector } from '../hooks/features/rows/gridEditRowsSelector'; import { gridSelectionStateSelector } from '../hooks/features/selection/gridSelectionSelector'; import { renderStateSelector } from '../hooks/features/virtualization/renderingStateSelector'; import { optionsSelector } from '../hooks/utils/optionsSelector'; @@ -40,6 +41,7 @@ export const GridViewport: ViewportType = React.forwardRef( const selectionState = useGridSelector(apiRef, gridSelectionStateSelector); const rows = useGridSelector(apiRef, visibleSortedGridRowsAsArraySelector); const rowHeight = useGridSelector(apiRef, gridDensityRowHeightSelector); + const editRowsState = useGridSelector(apiRef, gridEditRowsStateSelector); const getRowsElements = () => { if (renderState.renderContext == null) { @@ -75,6 +77,7 @@ export const GridViewport: ViewportType = React.forwardRef( cellFocus={cellFocus} cellTabIndex={cellTabIndex} isSelected={selectionState[id] !== undefined} + editRowState={editRowsState[id]} /> diff --git a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx index ba154cae30bda..9e4acc40e562f 100644 --- a/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridRowCells.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { GridCellIdentifier } from '../../hooks/features/focus/gridFocusState'; -import { gridEditRowsStateSelector } from '../../hooks/features/rows/gridEditRowsSelector'; import { GridCellClassParams, GridColumns, @@ -8,6 +7,7 @@ import { GridCellClassRules, GridCellParams, GridRowId, + GridEditRowProps, } from '../../models/index'; import { GridCell, GridCellProps } from './GridCell'; import { GridApiContext } from '../GridApiContext'; @@ -37,6 +37,7 @@ interface RowCellsProps { cellFocus: GridCellIdentifier | null; cellTabIndex: GridCellIdentifier | null; isSelected: boolean; + editRowState?: GridEditRowProps; } export const GridRowCells = React.memo((props: RowCellsProps) => { @@ -52,10 +53,10 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { cellTabIndex, showCellRightBorder, isSelected, + editRowState, } = props; const apiRef = React.useContext(GridApiContext); const rowHeight = useGridSelector(apiRef, gridDensityRowHeightSelector); - const editRowsState = useGridSelector(apiRef, gridEditRowsStateSelector); const cellsProps = columns.slice(firstColIdx, lastColIdx + 1).map((column, colIdx) => { const colIndex = firstColIdx + colIdx; @@ -81,7 +82,7 @@ export const GridRowCells = React.memo((props: RowCellsProps) => { cssClassProp = { cssClass: `${cssClassProp.cssClass} ${cssClass}` }; } - const editCellState = editRowsState[id] && editRowsState[id][column.field]; + const editCellState = editRowState && editRowState[column.field]; let cellComponent: React.ReactElement | null = null; if (editCellState == null && column.renderCell) { diff --git a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx index 70a13a0067f82..9e85814eda0fd 100644 --- a/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx +++ b/packages/grid/data-grid/src/tests/layout.DataGrid.test.tsx @@ -188,8 +188,7 @@ describe(' - Layout & Warnings', () => { { field: 'id', hide: true }, { field: 'fullName', - valueGetter: (params: GridValueGetterParams) => - params.getValue(params.id, 'age'), + valueGetter: (params: GridValueGetterParams) => params.getValue(params.id, 'age'), }, ]; expect(() => { diff --git a/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx b/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx index 7061390e9abed..3653b7f010e24 100644 --- a/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx @@ -85,8 +85,7 @@ describe(' - Rows', () => { it('should apply the CSS class returned by getRowClassName', () => { const getRowId = (row) => `${row.clientId}`; - const getRowClassName = (params) => - params.getValue(params.id, 'age') < 20 ? 'under-age' : ''; + const getRowClassName = (params) => (params.getValue(params.id, 'age') < 20 ? 'under-age' : ''); render(
diff --git a/packages/storybook/src/stories/grid-columns.stories.tsx b/packages/storybook/src/stories/grid-columns.stories.tsx index 5a0f0d8500af9..feed9714c8ddf 100644 --- a/packages/storybook/src/stories/grid-columns.stories.tsx +++ b/packages/storybook/src/stories/grid-columns.stories.tsx @@ -299,18 +299,12 @@ export const ValueGetterAndFormatter = () => { { field: 'firstAge', valueGetter: (params: GridValueGetterParams) => - `${params.getValue(params.id, 'first')}_${params.getValue( - params.id, - 'age', - )}`, + `${params.getValue(params.id, 'first')}_${params.getValue(params.id, 'age')}`, }, { field: 'firstAgeFormatted', valueGetter: (params: GridValueGetterParams) => - `${params.getValue(params.id, 'first')}_${params.getValue( - params.id, - 'age', - )}`, + `${params.getValue(params.id, 'first')}_${params.getValue(params.id, 'age')}`, valueFormatter: (params) => `${params.value} yrs`, }, ], From 982aae79cfcb73ba3704823eed7f9546c4db5c77 Mon Sep 17 00:00:00 2001 From: damien Date: Wed, 5 May 2021 18:35:56 +0200 Subject: [PATCH 19/28] fix tests --- .../grid/components/cell/GridEditInputCell.tsx | 1 + .../hooks/features/rows/useGridParamsApi.ts | 1 + .../grid/models/params/gridRowParams.ts | 7 +++++++ .../grid/x-grid/src/tests/events.XGrid.test.tsx | 17 +++++++---------- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx index 487b7dc1d8bf1..5cc2a555eed7f 100644 --- a/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx +++ b/packages/grid/_modules_/grid/components/cell/GridEditInputCell.tsx @@ -15,6 +15,7 @@ export function GridEditInputCell(props: GridCellParams & InputBaseProps) { colDef, cellMode, isEditable, + hasFocus, getValue, ...other } = props; diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts index fcac3c4c0db5d..468d725ec1939 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridParamsApi.ts @@ -45,6 +45,7 @@ export function useGridParamsApi(apiRef: GridApiRef) { columns: apiRef.current.getAllColumns(), row: apiRef.current.getRowFromId(id), api: apiRef.current, + getValue: apiRef.current.getCellValue, }; return params; }, diff --git a/packages/grid/_modules_/grid/models/params/gridRowParams.ts b/packages/grid/_modules_/grid/models/params/gridRowParams.ts index 934baa33e63f5..f6c6555c1a302 100644 --- a/packages/grid/_modules_/grid/models/params/gridRowParams.ts +++ b/packages/grid/_modules_/grid/models/params/gridRowParams.ts @@ -1,3 +1,4 @@ +import { GridCellValue } from '../gridCell'; import { GridRowId, GridRowModel } from '../gridRows'; /** @@ -20,4 +21,10 @@ export interface GridRowParams { * GridApiRef that let you manipulate the grid. */ api: any; + /** + * Get the cell value of a row and field. + * @param id + * @param field + */ + getValue: (id: GridRowId, field: string) => GridCellValue; } diff --git a/packages/grid/x-grid/src/tests/events.XGrid.test.tsx b/packages/grid/x-grid/src/tests/events.XGrid.test.tsx index 41c0389a99c43..eb14124c24f55 100644 --- a/packages/grid/x-grid/src/tests/events.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/events.XGrid.test.tsx @@ -85,8 +85,6 @@ describe(' - Events Params', () => { expect(eventArgs!.params).to.deep.include({ colDef: apiRef!.current.getColumnFromField('age'), - element: ageColumnElement, - colIndex: 2, field: 'age', api: apiRef.current, }); @@ -107,11 +105,10 @@ describe(' - Events Params', () => { expect(eventArgs!.params).to.deep.include({ id: 2, - element: row1, row: baselineProps.rows[1], - rowIndex: 1, columns: apiRef!.current.getAllColumns(), api: apiRef.current, + getValue: apiRef.current.getCellValue, }); }); }); @@ -133,12 +130,12 @@ describe(' - Events Params', () => { value: 'Jack', formattedValue: 'Jack', isEditable: true, - element: cell11, row: baselineProps.rows[1], - rowIndex: 1, colDef: apiRef!.current.getColumnFromField('first'), - colIndex: 1, api: apiRef.current, + hasFocus: false, + tabIndex: -1, + getValue: apiRef.current.getCellValue, }); }); @@ -160,12 +157,12 @@ describe(' - Events Params', () => { value: 'Jack', formattedValue: 'Jack', isEditable: true, - element: cell01, row: baselineProps.rows[1], - rowIndex: 0, colDef: apiRef!.current.getColumnFromField('first'), - colIndex: 1, api: apiRef.current, + hasFocus: false, + tabIndex: -1, + getValue: apiRef.current.getCellValue, }); }); From d47c332e8bac7e24687acc53244ebea54ef465a1 Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 6 May 2021 11:34:14 +0200 Subject: [PATCH 20/28] format demoes --- .../src/pages/components/data-grid/columns/ValueGetterGrid.js | 4 ++-- .../src/pages/components/data-grid/editing/ValueGetterGrid.js | 4 ++-- docs/src/pages/components/data-grid/overview/DataGridDemo.js | 4 ++-- docs/src/pages/components/data-grid/rows/StylingRowsGrid.js | 2 +- .../components/data-grid/sorting/ComparatorSortingGrid.js | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js index 90255696054bf..ee9365c085e5c 100644 --- a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js +++ b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js @@ -2,8 +2,8 @@ import * as React from 'react'; import { DataGrid } from '@material-ui/data-grid'; function getFullName(params) { - return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + return `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js index b88ab73d31e30..2f7d8b6e72864 100644 --- a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js +++ b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js @@ -3,8 +3,8 @@ import * as React from 'react'; import { DataGrid } from '@material-ui/data-grid'; function getFullName(params) { - return `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + return `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`; } diff --git a/docs/src/pages/components/data-grid/overview/DataGridDemo.js b/docs/src/pages/components/data-grid/overview/DataGridDemo.js index e19d69b23d344..b120e4792794b 100644 --- a/docs/src/pages/components/data-grid/overview/DataGridDemo.js +++ b/docs/src/pages/components/data-grid/overview/DataGridDemo.js @@ -18,8 +18,8 @@ const columns = [ sortable: false, width: 160, valueGetter: (params) => - `${params.api.getCellValue(params.id, 'firstName') || ''} ${ - params.api.getCellValue(params.id, 'lastName') || '' + `${params.getValue(params.id, 'firstName') || ''} ${ + params.getValue(params.id, 'lastName') || '' }`, }, ]; diff --git a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js index 4c076ace6dea6..775cf218b8c9e 100644 --- a/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js +++ b/docs/src/pages/components/data-grid/rows/StylingRowsGrid.js @@ -57,7 +57,7 @@ export default function StylingRowsGrid() { - `super-app-theme--${params.api.getCellValue(params.id, 'status')}` + `super-app-theme--${params.getValue(params.id, 'status')}` } />
diff --git a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js index d41d23cf9284c..eb36240339cc0 100644 --- a/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js +++ b/docs/src/pages/components/data-grid/sorting/ComparatorSortingGrid.js @@ -11,8 +11,8 @@ const columns = [ { field: 'username', valueGetter: (params) => - `${params.api.getCellValue(params.id, 'name') || 'unknown'} - ${ - params.api.getCellValue(params.id, 'age') || 'x' + `${params.getValue(params.id, 'name') || 'unknown'} - ${ + params.getValue(params.id, 'age') || 'x' }`, sortComparator: (v1, v2, param1, param2) => param1.api.getCellValue(param1.id, 'age') - From 170d9405df72ab99f7fa43f65fd80c1690246f6d Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 6 May 2021 11:43:46 +0200 Subject: [PATCH 21/28] fix valueGetter demos --- .../pages/components/data-grid/columns/ValueGetterGrid.js | 3 +-- .../pages/components/data-grid/columns/ValueGetterGrid.tsx | 7 +++---- .../pages/components/data-grid/editing/ValueGetterGrid.js | 3 +-- .../pages/components/data-grid/editing/ValueGetterGrid.tsx | 7 +++---- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js index ee9365c085e5c..49c1462b0866f 100644 --- a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js +++ b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.js @@ -15,8 +15,7 @@ const columns = [ headerName: 'Full name', width: 160, valueGetter: getFullName, - sortComparator: (v1, v2, cellParams1, cellParams2) => - getFullName(cellParams1).localeCompare(getFullName(cellParams2)), + sortComparator: (v1, v2) => v1.toString().localeCompare(v2.toString()), }, ]; diff --git a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx index f7f201b16036a..83953ccdd2855 100644 --- a/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx +++ b/docs/src/pages/components/data-grid/columns/ValueGetterGrid.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; -import { DataGrid, GridColDef, GridSortCellParams } from '@material-ui/data-grid'; +import { DataGrid, GridColDef, GridValueGetterParams } from '@material-ui/data-grid'; -function getFullName(params: GridSortCellParams) { +function getFullName(params: GridValueGetterParams) { return `${params.getValue(params.id, 'firstName') || ''} ${ params.getValue(params.id, 'lastName') || '' }`; @@ -15,8 +15,7 @@ const columns: GridColDef[] = [ headerName: 'Full name', width: 160, valueGetter: getFullName, - sortComparator: (v1, v2, cellParams1, cellParams2) => - getFullName(cellParams1).localeCompare(getFullName(cellParams2)), + sortComparator: (v1, v2) => v1!.toString().localeCompare(v2!.toString()), }, ]; diff --git a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js index 2f7d8b6e72864..6fc4c08b6d865 100644 --- a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js +++ b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.js @@ -48,8 +48,7 @@ const columns = [ width: 160, editable: true, valueGetter: getFullName, - sortComparator: (v1, v2, cellParams1, cellParams2) => - getFullName(cellParams1).localeCompare(getFullName(cellParams2)), + sortComparator: (v1, v2) => v1.toString().localeCompare(v2.toString()), }, ]; diff --git a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx index 0a0883ab04b0d..61fe98bf2f434 100644 --- a/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx +++ b/docs/src/pages/components/data-grid/editing/ValueGetterGrid.tsx @@ -4,10 +4,10 @@ import { DataGrid, GridColDef, GridEditCellPropsParams, - GridSortCellParams, + GridValueGetterParams, } from '@material-ui/data-grid'; -function getFullName(params: GridSortCellParams) { +function getFullName(params: GridValueGetterParams) { return `${params.getValue(params.id, 'firstName') || ''} ${ params.getValue(params.id, 'lastName') || '' }`; @@ -52,8 +52,7 @@ const columns: GridColDef[] = [ width: 160, editable: true, valueGetter: getFullName, - sortComparator: (v1, v2, cellParams1, cellParams2) => - getFullName(cellParams1).localeCompare(getFullName(cellParams2)), + sortComparator: (v1, v2) => v1!.toString().localeCompare(v2!.toString()), }, ]; From fac4d10cafe3e2aa89499455ba80ed7876244aa4 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 7 May 2021 16:19:43 +0200 Subject: [PATCH 22/28] fix conflicts --- .../GridCellCheckboxRenderer.tsx | 31 ++++++++++--------- .../columnSelection/GridHeaderCheckbox.tsx | 28 ++++++++--------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx index 2748b3288d095..e57230f094a40 100644 --- a/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/_modules_/grid/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { useForkRef } from '@material-ui/core/utils'; import { GRID_CELL_NAVIGATION_KEYDOWN } from '../../constants/eventsConstants'; import { GridCellParams } from '../../models/params/gridCellParams'; import { isNavigationKey, isSpaceKey } from '../../utils/keyboardUtils'; @@ -6,14 +7,16 @@ import { GridApiContext } from '../GridApiContext'; export const GridCellCheckboxForwardRef = React.forwardRef( function GridCellCheckboxRenderer(props, ref) { - const { field, id, value, tabIndex, hasFocus } = props; - const apiRef = React.useContext(GridApiContext); - const checkboxElement = React.useRef(null); - const element = props.api.getCellElement(id, field); + const { field, id, value, tabIndex, hasFocus } = props; + const apiRef = React.useContext(GridApiContext); + const checkboxElement = React.useRef(null); - const handleChange = (event: React.ChangeEvent, checked: boolean) => { - apiRef!.current.selectRow(id, checked, true); - }; + const handleRef = useForkRef(checkboxElement, ref); + const element = props.api.getCellElement(id, field); + + const handleChange = (event: React.ChangeEvent, checked: boolean) => { + apiRef!.current.selectRow(id, checked, true); + }; React.useLayoutEffect(() => { if (tabIndex === 0 && element) { @@ -21,12 +24,12 @@ export const GridCellCheckboxForwardRef = React.forwardRef { - if (hasFocus) { - const input = checkboxElement.current!.querySelector('input')!; - input!.focus(); - } - }, [hasFocus]); + React.useLayoutEffect(() => { + if (hasFocus && checkboxElement.current) { + const input = checkboxElement.current.querySelector('input')!; + input!.focus(); + } + }, [hasFocus]); const handleKeyDown = React.useCallback( (event) => { @@ -44,7 +47,7 @@ export const GridCellCheckboxForwardRef = React.forwardRef( function GridHeaderCheckbox(props, ref) { const [, forceUpdate] = React.useState(false); - const apiRef = React.useContext(GridApiContext); + const apiRef = React.useContext(GridApiContext); const visibleRowIds = useGridSelector(apiRef, visibleSortedGridRowIdsSelector); const tabIndexState = useGridSelector(apiRef, gridTabIndexColumnHeaderSelector); - const element = apiRef!.current.getColumnHeaderElement(props.field); + const element = apiRef!.current.getColumnHeaderElement(props.field); const totalSelectedRows = useGridSelector(apiRef, selectedGridRowsCountSelector); const totalRows = useGridSelector(apiRef, gridRowCountSelector); @@ -42,12 +42,12 @@ export const GridHeaderCheckbox = React.forwardRef { - if (tabIndex === 0 && element) { - element!.tabIndex = -1; - } - }, [element, tabIndex]); + const tabIndex = tabIndexState !== null && tabIndexState.field === props.field ? 0 : -1; + React.useLayoutEffect(() => { + if (tabIndex === 0 && element) { + element!.tabIndex = -1; + } + }, [element, tabIndex]); const handleKeyDown = React.useCallback( (event) => { @@ -61,13 +61,13 @@ export const GridHeaderCheckbox = React.forwardRef { - forceUpdate((p) => !p); - }, []); + const handleSelectionChange = React.useCallback(() => { + forceUpdate((p) => !p); + }, []); - React.useEffect(() => { - return apiRef?.current.subscribeEvent(GRID_SELECTION_CHANGED, handleSelectionChange); - }, [apiRef, handleSelectionChange]); + React.useEffect(() => { + return apiRef?.current.subscribeEvent(GRID_SELECTION_CHANGED, handleSelectionChange); + }, [apiRef, handleSelectionChange]); const CheckboxComponent = apiRef?.current.components.Checkbox!; From 9fe9bab731a70952ae2c72fa050eefb1fffcf814 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 8 May 2021 01:55:23 +0200 Subject: [PATCH 23/28] early exit if already sorted --- .../hooks/features/sorting/useGridSorting.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts index abfa1fa7d0447..d5ab0f256ea25 100644 --- a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts +++ b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts @@ -111,21 +111,22 @@ export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { const comparatorListAggregate = React.useCallback( (id1: GridRowId, id2: GridRowId) => { - const result = comparatorList.current.reduce((res, colComparator) => { + return comparatorList.current.reduce((res, colComparator) => { + if (res !== 0) { + return res; + } + const { field, comparator } = colComparator; const sortCellParams1 = getSortCellParams(id1, field); const sortCellParams2 = getSortCellParams(id2, field); - res = - res || - comparator( - sortCellParams1.value, - sortCellParams2.value, - sortCellParams1, - sortCellParams2, - ); + res = comparator( + sortCellParams1.value, + sortCellParams2.value, + sortCellParams1, + sortCellParams2, + ); return res; }, 0); - return result; }, [getSortCellParams], ); From afb06670b6f1df8e18a485a7a8ea7730631604eb Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 8 May 2021 02:14:21 +0200 Subject: [PATCH 24/28] x10 perf of sorting --- .../hooks/features/sorting/useGridSorting.ts | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts index d5ab0f256ea25..a993bda486a09 100644 --- a/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts +++ b/packages/grid/_modules_/grid/hooks/features/sorting/useGridSorting.ts @@ -38,7 +38,6 @@ import { sortedGridRowIdsSelector, sortedGridRowsSelector } from './gridSortingS export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { const logger = useLogger('useGridSorting'); - const comparatorList = React.useRef([]); const [gridState, setGridState, forceUpdate] = useGridState(apiRef); const options = useGridSelector(apiRef, optionsSelector); @@ -110,15 +109,18 @@ export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { ); const comparatorListAggregate = React.useCallback( - (id1: GridRowId, id2: GridRowId) => { - return comparatorList.current.reduce((res, colComparator) => { + (comparatorList: GridFieldComparatorList) => ( + row1: GridSortCellParams[], + row2: GridSortCellParams[], + ) => { + return comparatorList.reduce((res, colComparator, index) => { if (res !== 0) { return res; } - const { field, comparator } = colComparator; - const sortCellParams1 = getSortCellParams(id1, field); - const sortCellParams2 = getSortCellParams(id2, field); + const { comparator } = colComparator; + const sortCellParams1 = row1[index]; + const sortCellParams2 = row2[index]; res = comparator( sortCellParams1.value, sortCellParams2.value, @@ -128,7 +130,7 @@ export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { return res; }, 0); }, - [getSortCellParams], + [], ); const buildComparatorList = React.useCallback( @@ -168,11 +170,18 @@ export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { } const sortModel = apiRef.current.getState().sorting.sortModel; - const sorted = [...rowIds]; + let sorted = rowIds; if (sortModel.length > 0) { - comparatorList.current = buildComparatorList(sortModel); + const comparatorList = buildComparatorList(sortModel); logger.debug('Sorting rows with ', sortModel); - sorted.sort(comparatorListAggregate); + sorted = rowIds + .map((id) => { + return comparatorList.map((colComparator) => { + return getSortCellParams(id, colComparator.field); + }); + }) + .sort(comparatorListAggregate(comparatorList)) + .map((field) => field[0].id); } setGridState((oldState) => { @@ -185,6 +194,7 @@ export const useGridSorting = (apiRef: GridApiRef, rowsProp: GridRowsProp) => { }, [ apiRef, logger, + getSortCellParams, setGridState, forceUpdate, buildComparatorList, From 5aa99df72a19341731e799607f23346bb0e84567 Mon Sep 17 00:00:00 2001 From: damien Date: Mon, 10 May 2021 15:20:39 +0200 Subject: [PATCH 25/28] add tests --- .../columnHeaders/ColumnHeaderFilterIcon.tsx | 2 +- .../x-grid/src/tests/filtering.XGrid.test.tsx | 44 +++++++++++++++++++ .../x-grid/src/tests/sorting.XGrid.test.tsx | 40 ++++++++++++++++- 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderFilterIcon.tsx b/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderFilterIcon.tsx index 40a53cb3d00f0..8ad9a78981148 100644 --- a/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderFilterIcon.tsx +++ b/packages/grid/_modules_/grid/components/columnHeaders/ColumnHeaderFilterIcon.tsx @@ -47,7 +47,7 @@ export function ColumnHeaderFilterIcon(props: ColumnHeaderFilterIconProps) { size="small" tabIndex={-1} > - + ); diff --git a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx index c00b775be5f25..8c7f2ea155b2f 100644 --- a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx @@ -20,8 +20,10 @@ import { createClientRenderStrictMode, // @ts-expect-error need to migrate helpers to TypeScript fireEvent, + waitFor, } from 'test/utils'; import { getColumnHeaderCell, getColumnValues } from 'test/utils/helperFn'; +import { useData } from '../../../../storybook/src/hooks/useData'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -257,6 +259,48 @@ describe(' - Filter', () => { expect(apiRef.current.getVisibleRowModels().get(1)).to.deep.equal({ id: 1, brand: 'Adidas' }); }); + describe('performance', () => { + beforeEach(() => { + clock.restore(); + }); + + it('should filter 5,000 rows in less than 100 ms', async function test() { + // It's simpler to only run the performance test in a single controlled environment. + if (!/HeadlessChrome/.test(window.navigator.userAgent)) { + this.skip(); + return; + } + + const TestCasePerf = () => { + const data = useData(5000, 10); + apiRef = useGridApiRef(); + return ( +
+ +
+ ); + }; + + render(); + const newModel = { + items: [ + { + columnField: 'currencyPair', + value: 'usd', + operatorValue: 'startsWith', + }, + ], + }; + const t0 = performance.now(); + apiRef.current.setFilterModel(newModel); + + await waitFor(() => expect(document.querySelector('.MuiDataGrid-filterIcon')).to.not.be.null); + const t1 = performance.now(); + const time = Math.round(t1 - t0); + expect(time).to.be.lessThan(100); + }); + }); + describe('Server', () => { it('should refresh the filter panel when adding filters', () => { function loadServerRows(commodityFilterValue) { diff --git a/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx b/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx index 374e6f695c3c4..dcc05cb9e6ee7 100644 --- a/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { GridApiRef, GridSortModel, useGridApiRef } from '@material-ui/data-grid'; +import { GridApiRef, GridColDef, GridSortModel, useGridApiRef } from '@material-ui/data-grid'; import { XGrid } from '@material-ui/x-grid'; import { expect } from 'chai'; import { useFakeTimers } from 'sinon'; @@ -221,5 +221,43 @@ describe(' - Sorting', () => { const time = Math.round(t1 - t0); expect(time).to.be.lessThan(300); }); + + it('should render maximum twice', async function test() { + // It's simpler to only run the performance test in a single controlled environment. + if (!/HeadlessChrome/.test(window.navigator.userAgent)) { + this.skip(); + return; + } + + let renderHeaderCount = 0; + const TestCasePerf = () => { + const [cols, setCols] = React.useState([]); + const data = useData(5000, 10); + + React.useEffect(() => { + if (data.columns.length) { + const newColumns = [...data.columns]; + newColumns[1].renderHeader = (params) => { + renderHeaderCount += 1; + return {params.field}; + }; + setCols(newColumns); + } + }, [data.columns]); + + return ( +
+ +
+ ); + }; + + render(); + const header = document.querySelector('.currency-pair-component'); + renderHeaderCount = 0; + fireEvent.click(header); + await waitFor(() => expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.be.null); + expect(renderHeaderCount).to.equal(2); + }); }); }); From 0a80b8b104820fcd4b01255aa3319a4df9b8e41e Mon Sep 17 00:00:00 2001 From: damien Date: Mon, 10 May 2021 17:00:14 +0200 Subject: [PATCH 26/28] fix waitFor import --- packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx index 8c7f2ea155b2f..0f0559ebf6f5a 100644 --- a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx @@ -20,6 +20,7 @@ import { createClientRenderStrictMode, // @ts-expect-error need to migrate helpers to TypeScript fireEvent, + // @ts-expect-error need to migrate helpers to TypeScript waitFor, } from 'test/utils'; import { getColumnHeaderCell, getColumnValues } from 'test/utils/helperFn'; From b7d0bd8079b88278af743d6285694a71621322a1 Mon Sep 17 00:00:00 2001 From: damien Date: Mon, 10 May 2021 18:47:28 +0200 Subject: [PATCH 27/28] fix reviewa --- .../grid/x-grid/src/tests/filtering.XGrid.test.tsx | 4 ++-- packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx index 0f0559ebf6f5a..f635fd067bb88 100644 --- a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx @@ -24,7 +24,7 @@ import { waitFor, } from 'test/utils'; import { getColumnHeaderCell, getColumnValues } from 'test/utils/helperFn'; -import { useData } from '../../../../storybook/src/hooks/useData'; +import { useData } from 'packages/storybook/src/hooks/useData'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -295,7 +295,7 @@ describe(' - Filter', () => { const t0 = performance.now(); apiRef.current.setFilterModel(newModel); - await waitFor(() => expect(document.querySelector('.MuiDataGrid-filterIcon')).to.not.be.null); + await waitFor(() => expect(document.querySelector('.MuiDataGrid-filterIcon')).to.not.equal(null)); const t1 = performance.now(); const time = Math.round(t1 - t0); expect(time).to.be.lessThan(100); diff --git a/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx b/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx index dcc05cb9e6ee7..9e8736a0d612c 100644 --- a/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx @@ -216,19 +216,13 @@ describe(' - Sorting', () => { const t0 = performance.now(); fireEvent.click(header); - await waitFor(() => expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.be.null); + await waitFor(() => expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.equal(null)); const t1 = performance.now(); const time = Math.round(t1 - t0); expect(time).to.be.lessThan(300); }); it('should render maximum twice', async function test() { - // It's simpler to only run the performance test in a single controlled environment. - if (!/HeadlessChrome/.test(window.navigator.userAgent)) { - this.skip(); - return; - } - let renderHeaderCount = 0; const TestCasePerf = () => { const [cols, setCols] = React.useState([]); @@ -256,7 +250,7 @@ describe(' - Sorting', () => { const header = document.querySelector('.currency-pair-component'); renderHeaderCount = 0; fireEvent.click(header); - await waitFor(() => expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.be.null); + await waitFor(() => expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.equal(null)); expect(renderHeaderCount).to.equal(2); }); }); From 3897bf3223898faa5895441b7126403c6e4122bb Mon Sep 17 00:00:00 2001 From: damien Date: Tue, 11 May 2021 12:30:13 +0200 Subject: [PATCH 28/28] update tests --- .../x-grid/src/tests/filtering.XGrid.test.tsx | 4 +++- .../x-grid/src/tests/sorting.XGrid.test.tsx | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx index f635fd067bb88..ef7df70a1ebc7 100644 --- a/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx @@ -295,7 +295,9 @@ describe(' - Filter', () => { const t0 = performance.now(); apiRef.current.setFilterModel(newModel); - await waitFor(() => expect(document.querySelector('.MuiDataGrid-filterIcon')).to.not.equal(null)); + await waitFor(() => + expect(document.querySelector('.MuiDataGrid-filterIcon')).to.not.equal(null), + ); const t1 = performance.now(); const time = Math.round(t1 - t0); expect(time).to.be.lessThan(100); diff --git a/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx b/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx index 9e8736a0d612c..b40ee441e5c99 100644 --- a/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/sorting.XGrid.test.tsx @@ -216,24 +216,34 @@ describe(' - Sorting', () => { const t0 = performance.now(); fireEvent.click(header); - await waitFor(() => expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.equal(null)); + await waitFor(() => + expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.equal(null), + ); const t1 = performance.now(); const time = Math.round(t1 - t0); expect(time).to.be.lessThan(300); }); it('should render maximum twice', async function test() { + let renderCellCount = 0; let renderHeaderCount = 0; const TestCasePerf = () => { const [cols, setCols] = React.useState([]); - const data = useData(5000, 10); + const data = useData(10, 10); React.useEffect(() => { if (data.columns.length) { const newColumns = [...data.columns]; newColumns[1].renderHeader = (params) => { renderHeaderCount += 1; - return {params.field}; + + return {params.field}; + }; + newColumns[1].renderCell = (params) => { + if (params.id === 0) { + renderCellCount += 1; + } + return {params.value}; }; setCols(newColumns); } @@ -247,11 +257,15 @@ describe(' - Sorting', () => { }; render(); - const header = document.querySelector('.currency-pair-component'); + const header = getColumnHeaderCell(2); renderHeaderCount = 0; + renderCellCount = 0; fireEvent.click(header); - await waitFor(() => expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.equal(null)); + await waitFor(() => + expect(document.querySelector('.MuiDataGrid-sortIcon')).to.not.equal(null), + ); expect(renderHeaderCount).to.equal(2); + expect(renderCellCount).to.equal(0); }); }); });