diff --git a/docs/pages/api-docs/data-grid/data-grid.md b/docs/pages/api-docs/data-grid/data-grid.md index 1f5bb82a1977..8fd4aecb98c4 100644 --- a/docs/pages/api-docs/data-grid/data-grid.md +++ b/docs/pages/api-docs/data-grid/data-grid.md @@ -53,40 +53,40 @@ import { DataGrid } from '@material-ui/data-grid'; | logger | Logger | null | Pass a custom logger in the components that implements the 'Logger' interface. | | logLevel | string \| false | false | Allows to pass the logging level or false to turn off logging. | | nonce | string | | Nonce of the inline styles for [Content Security Policy](https://www.w3.org/TR/2016/REC-CSP2-20161215/#script-src-the-nonce-attribute). | -| onCellBlur | (params: GridCellParams, event: React.FocusEvent) => void | | Callback fired when the active element leaves a cell. | -| onCellClick | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a click event comes from a cell element. | -| onCellDoubleClick | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a double click event comes from a cell element. | +| onCellBlur | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when the active element leaves a cell. | +| onCellClick | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when a click event comes from a cell element. | +| onCellDoubleClick | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when a double click event comes from a cell element. | | onCellFocusOut | (params: GridCellParams, event?: MuiEvent) => void | | Callback fired when a cell loses focus. | -| onCellKeyDown | (params: GridCellParams, event: React.KeyboardEvent) => void | | Callback fired when a keydown event comes from a cell element. | -| onCellOver | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse over event comes from a cell element. | -| onCellOut | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse out comes from a cell element. | -| onCellEnter | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse enter event comes from a cell element. | -| onCellLeave | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse leave event comes from a cell element. | -| onCellModeChange | (params: GridCellModeChangeParams) => void | | Callback fired when the cell mode changed. | -| onColumnHeaderClick | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a click event comes from a column header element. | -| onColumnHeaderDoubleClick | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a double click event comes from a column header element. | -| onColumnHeaderOver | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouseover event comes from a column header element. | -| onColumnHeaderOut | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouseout event comes from a column header element. | -| onColumnHeaderEnter | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouse enter event comes from a column header element. | -| onColumnHeaderLeave | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouse leave event comes from a column header element. | -| onColumnOrderChange | (param: GridColumnOrderChangeParams, event: React.MouseEvent) => void | | Callback fired when a column is reordered. | -| onColumnResize | (param: GridColumnResizeParams) => void | | Callback fired while a column is being resized. | -| onColumnWidthChange | (param: GridColumnResizeParams) => void | | Callback fired when the width of a column is changed. | -| onColumnVisibilityChange | (param: GridColumnVisibilityChangeParams) => void | | Callback fired when a column visibility changes. | +| onCellKeyDown | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when a keydown event comes from a cell element. | +| onCellOver | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when a mouse over event comes from a cell element. | +| onCellOut | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when a mouse out comes from a cell element. | +| onCellEnter | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when a mouse enter event comes from a cell element. | +| onCellLeave | (params: GridCellParams, event: MouseEvent) => void | | Callback fired when a mouse leave event comes from a cell element. | +| onCellModeChange | (params: GridCellModeChangeParams, event: MuiEvent<{}>) => void | | Callback fired when the cell mode changed. | +| onColumnHeaderClick | (param: GridColumnHeaderParams, event: MouseEvent) => void | | Callback fired when a click event comes from a column header element. | +| onColumnHeaderDoubleClick | (param: GridColumnHeaderParams, event: MouseEvent) => void | | Callback fired when a double click event comes from a column header element. | +| onColumnHeaderOver | (param: GridColumnHeaderParams, event: MouseEvent) => void | | Callback fired when a mouseover event comes from a column header element. | +| onColumnHeaderOut | (param: GridColumnHeaderParams, event: MouseEvent) => void | | Callback fired when a mouseout event comes from a column header element. | +| onColumnHeaderEnter | (param: GridColumnHeaderParams, event: MouseEvent) => void | | Callback fired when a mouse enter event comes from a column header element. | +| onColumnHeaderLeave | (param: GridColumnHeaderParams, event: MouseEvent) => void | | Callback fired when a mouse leave event comes from a column header element. | +| onColumnOrderChange | (param: GridColumnOrderChangeParams, event: MouseEvent) => void | | Callback fired when a column is reordered. | +| onColumnResize | (param: GridColumnResizeParams, event: MuiEvent<{}>) => void | | Callback fired while a column is being resized. | +| onColumnWidthChange | (param: GridColumnResizeParams, event: MuiEvent<{}>) => void | | Callback fired when the width of a column is changed. | +| onColumnVisibilityChange | (param: GridColumnVisibilityChangeParams, event: MuiEvent<{}>) => void | | Callback fired when a column visibility changes. | | onError | (args: any) => void | | Callback fired when an exception is thrown in the grid, or when the `showError` API method is called. | -| onEditCellPropsChange | (params: GridEditCellPropsParams, event: React.SyntheticEvent) => void | | Callback fired when the edit cell value changes. | -| onCellEditCommit | (params: GridEditCellPropsParams, event: React.SyntheticEvent) => void | | Callback fired when the cell changes are going to be committed. | +| onEditCellPropsChange | (params: GridEditCellPropsParams, event: MouseEvent) => void | | Callback fired when the edit cell value changes. | +| onCellEditCommit | (params: GridEditCellPropsParams, event: MouseEvent) => void | | Callback fired when the cell changes are going to be committed. | | onEditRowModelChange | (params: GridEditRowModelParams) => void | | Callback fired when the EditRowModel changed. | | onFilterModelChange | (model: GridFilterModel) => void | | Callback fired when the Filter model changes before the filters are applied. | | onPageChange | (page: number) => void | | Callback fired when the current page has changed. | | onPageSizeChange | (pageSize: number) => void | | Callback fired when the page size has changed. | -| onResize | (param: GridResizeParams) => void | | Callback fired when the grid is being resized. | -| onRowClick | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a click event comes from a row container element. | -| onRowDoubleClick | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a double click event comes from a row container element. | -| onRowOver | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse over comes from a row container element. | -| onRowOut | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse out comes from a row container element. | -| onRowEnter | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse enter comes from a row container element. | -| onRowLeave | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse leave event comes from a row container element. | +| onResize | (param: GridResizeParams, event: MuiEvent<{}>) => void | | Callback fired when the grid is being resized. | +| onRowClick | (param: GridRowParams, event: MouseEvent) => void | | Callback fired when a click event comes from a row container element. | +| onRowDoubleClick | (param: GridRowParams, event: MouseEvent) => void | | Callback fired when a double click event comes from a row container element. | +| onRowOver | (param: GridRowParams, event: MouseEvent) => void | | Callback fired when a mouse over comes from a row container element. | +| onRowOut | (param: GridRowParams, event: MouseEvent) => void | | Callback fired when a mouse out comes from a row container element. | +| onRowEnter | (param: GridRowParams, event: MouseEvent) => void | | Callback fired when a mouse enter comes from a row container element. | +| onRowLeave | (param: GridRowParams, event: MouseEvent) => void | | Callback fired when a mouse leave event comes from a row container element. | | onSelectionModelChange | (model: GridSelectionModel) => void | | Callback fired when the selection state of one or multiple rows changes. | | onSortModelChange | (model: GridSortModel) => void | | Callback fired when the sort model changes before a column is sorted. | | page | number | 1 | Set the current page. | diff --git a/docs/pages/api-docs/data-grid/grid-api.md b/docs/pages/api-docs/data-grid/grid-api.md index 35404721f065..ffe014609fb2 100644 --- a/docs/pages/api-docs/data-grid/grid-api.md +++ b/docs/pages/api-docs/data-grid/grid-api.md @@ -10,85 +10,85 @@ import { GridApi } from '@material-ui/x-grid'; ## Properties -| Name | Type | Description | -| :------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| applyFilter | (item: GridFilterItem, linkOperator?: GridLinkOperator) => void | Applies a GridFilterItem on alls rows. If no `linkOperator` is given, the "and" operator is used. | -| applyFilterLinkOperator | (operator: GridLinkOperator) => void | Changes the GridLinkOperator used to connect the filters. | -| applyFilters | () => void | Applies all filters on all rows. | -| applySorting | () => void | Applies the current sort model to the rows. | -| commitCellChange | (params: GridCommitCellChangeParams, event?: SyntheticEvent<Element, Event>) => boolean | Updates the field at the given id with the value stored in the edit row model. | -| components | GridApiRefComponentsProperty | The set of overridable components used in the grid. | -| componentsProps? | GridSlotsComponentsProps | Overrideable components props dynamically passed to the component at rendering. | -| deleteFilter | (item: GridFilterItem) => void | Deletes a GridFilterItem. | -| exportDataAsCsv | (options?: GridExportCsvOptions) => void | Downloads and exports a CSV of the grid's data. | -| forceUpdate | Dispatch<any> | Forces the grid to rerender. It's often used after a state update. | -| getAllColumns | () => GridColumns | Returns an array of [GridColDef](/api/data-grid/grid-col-def/) containing all the column definitions. | -| getAllRowIds | () => GridRowId[] | Gets the list of row ids. | -| getCellElement | (id: GridRowId, field: string) => null \| HTMLDivElement | Gets the underlying DOM element for a cell at the given `id` and `field`. | -| getCellMode | (id: GridRowId, field: string) => GridCellMode | Gets the mode of a cell. | -| getCellParams | (id: GridRowId, field: string) => GridCellParams | Gets the [GridCellParams](/api/data-grid/grid-cell-params/) object that is passed as argument in events. | -| getCellValue | (id: GridRowId, field: string) => GridCellValue | Gets the value of a cell at the given `id` and `field`. | -| getColumn | (field: string) => GridColDef | Returns the [GridColDef](/api/data-grid/grid-col-def/) for the given `field`. | -| getColumnHeaderElement | (field: string) => null \| HTMLDivElement | Gets the underlying DOM element for the column header with the given `field`. | -| getColumnHeaderParams | (field: string) => GridColumnHeaderParams | Gets the GridColumnHeaderParams object that is passed as argument in events. | -| getColumnIndex | (field: string, useVisibleColumns?: boolean) => number | Returns the index position of a column. By default, only the visible columns are considered.
Pass `false` to `useVisibleColumns` to consider all columns. | -| getColumnPosition | (field: string) => number | Returns the left-position of a column relative to the inner border of the grid. | -| getColumnsMeta | () => GridColumnsMeta | Returns the GridColumnsMeta for each column. | -| getDataAsCsv | (options?: GridExportCsvOptions) => string | Returns the grid data as a CSV string.
This method is used internally by `exportDataAsCsv`. | -| getEditRowsModel | () => GridEditRowsModel | Gets the edit rows model of the grid. | -| getLocaleText | <T extends keyof GridLocaleText>(key: T) => GridLocaleText[T] | Returns the translation for the `key`. | -| getRow | (id: GridRowId) => null \| GridRowData | Gets the row data with a given id. | -| getRowElement | (id: GridRowId) => null \| HTMLDivElement | Gets the underlying DOM element for a row at the given `id`. | -| getRowIdFromRowIndex | (index: number) => GridRowId | Gets the `GridRowId` of a row at a specific index. | -| getRowIndex | (id: GridRowId) => number | Gets the row index of a row with a given id. | -| getRowModels | () => Map<GridRowId, GridRowData> | Gets the full set of rows as Map<GridRowId, GridRowModel>. | -| getRowParams | (id: GridRowId) => GridRowParams | Gets the [GridRowParams](/api/data-grid/grid-row-params/) object that is passed as argument in events. | -| getRowsCount | () => number | Gets the total number of rows in the grid. | -| getScrollPosition | () => GridScrollParams | Returns the current scroll position. | -| getSelectedRows | () => Map<GridRowId, GridRowData> | Returns an array of the selected rows. | -| getSortModel | () => GridSortModel | Returns the sort model currently applied to the grid. | -| getSortedRowIds | () => GridRowId[] | Returns all row ids sorted according to the active sort model. | -| getSortedRows | () => GridRowData[] | Returns all rows sorted according to the active sort model. | -| getState | () => GridState | Returns the state of the grid. | -| getVisibleColumns | () => GridColumns | Returns the currently visible columns. | -| getVisibleRowModels | () => Map<GridRowId, GridRowData> | Returns a sorted `Map` containing only the visible rows. | -| hideColumnMenu | () => void | Hides the column menu that is open. | -| hideFilterPanel | () => void | Hides the filter panel. | -| hidePreferences | () => void | Hides the preferences panel. | -| isCellEditable | (params: GridCellParams) => boolean | Controls if a cell is editable. | -| publishEvent | (name: string, ...args: any[]) => void | Emits an event. | -| resize | () => void | Triggers a resize of the component and recalculation of width and height. | -| scroll | (params: Partial<GridScrollParams>) => void | Triggers the viewport to scroll to the given positions (in pixels). | -| scrollToIndexes | (params: Optional<GridCellIndexCoordinates, rowIndex>) => boolean | Triggers the viewport to scroll to the cell at indexes given by `params`.
Returns `true` if the grid had to scroll to reach the target. | -| selectRow | (id: GridRowId, isSelected?: boolean, allowMultiple?: boolean) => void | Change the selection state of a row. | -| selectRows | (ids: GridRowId[], isSelected?: boolean, deselectOtherRows?: boolean) => void | Change the selection state of multiple rows. | -| setCellFocus | (id: GridRowId, field: string) => void | Sets the focus to the cell at the given `id` and `field`. | -| setCellMode | (id: GridRowId, field: string, mode: GridCellMode) => void | Sets the mode of a cell. | -| setColumnHeaderFocus | (field: string, event?: SyntheticEvent<Element, Event>) => void | Sets the focus to the column header at the given `field`. | -| setColumnIndex | (field: string, targetIndexPosition: number) => void | Moves a column from its original position to the position given by `targetIndexPosition`. | -| setColumnVisibility | (field: string, isVisible: boolean) => void | Changes the visibility of the column referred by `field`. | -| setColumnWidth | (field: string, width: number) => void | Updates the width of a column. | -| setDensity | (size: GridDensity, headerHeight?: number, rowHeight?: number) => void | Sets the density of the grid. | -| setEditCellProps | (params: GridEditCellPropsParams) => void | Sets the input props of the edit cell. | -| setEditCellValue | (params: GridEditCellValueParams, event?: SyntheticEvent<Element, Event>) => void | Sets the value of the edit cell.
Commonly used inside the edit cell component. | -| setEditRowsModel | (model: GridEditRowsModel) => void | Set sthe edit rows model of the grid. | -| setFilterModel | (model: GridFilterModelState) => void | Sets the filter model to the one given by `model`. | -| setPage | (page: number) => void | Sets the displayed page to the value given by `page`. | -| setPageSize | (pageSize: number) => void | Sets the number of displayed rows to the value given by `pageSize`. | -| setRows | (rows: GridRowData[]) => void | Sets a new set of rows. | -| setSelectionModel | (rowIds: GridRowId[]) => void | Updates the selected rows to be those passed to the `rowIds` argument.
Any row already selected will be unselected. | -| setSortModel | (model: GridSortModel) => void | Updates the sort model and triggers the sorting of rows. | -| setState | (state: GridState \| ((previousState: GridState) => GridState)) => void | Sets the whole state of the grid. | -| showColumnMenu | (field: string) => void | Display the column menu under the `field` column. | -| showError | (props: any) => void | Displays the error overlay component. | -| showFilterPanel | (targetColumnField?: string) => void | Shows the filter panel. If `targetColumnField` is given, a filter for this field is also added. | -| showPreferences | (newValue: GridPreferencePanelsValue) => void | Displays the preferences panel. The `newValue` argument controls the content of the panel. | -| sortColumn | (column: GridColDef, direction?: GridSortDirection, allowMultipleSorting?: boolean) => void | Sorts a column. | -| state | GridState | Property that contains the whole state of the grid. | -| subscribeEvent | (event: string, handler: (params: any, event?: SyntheticEvent<Element, Event>) => void, options?: GridSubscribeEventOptions) => () => void | Registers a handler for an event. | -| toggleColumnMenu | (field: string) => void | Toggles the column menu under the `field` column. | -| updateColumn | (col: GridColDef) => void | Updates the definition of a column. | -| updateColumns | (cols: GridColDef[]) => void | Updates the definition of multiple columns at the same time. | -| updateRows | (updates: GridRowModelUpdate<>[]) => void | Allows to updates, insert and delete rows in a single call. | -| updateViewport | (forceRender?: boolean) => void | Refreshes the viewport cells according to the scroll positions | -| upsertFilter | (item: GridFilterItem) => void | Updates or inserts a GridFilterItem. | +| Name | Type | Description | +| :------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| applyFilter | (item: GridFilterItem, linkOperator?: GridLinkOperator) => void | Applies a GridFilterItem on alls rows. If no `linkOperator` is given, the "and" operator is used. | +| applyFilterLinkOperator | (operator: GridLinkOperator) => void | Changes the GridLinkOperator used to connect the filters. | +| applyFilters | () => void | Applies all filters on all rows. | +| applySorting | () => void | Applies the current sort model to the rows. | +| commitCellChange | (params: GridCommitCellChangeParams, event?: MouseEvent \| SyntheticEvent<Element, Event>) => boolean | Updates the field at the given id with the value stored in the edit row model. | +| components | GridApiRefComponentsProperty | The set of overridable components used in the grid. | +| componentsProps? | GridSlotsComponentsProps | Overrideable components props dynamically passed to the component at rendering. | +| deleteFilter | (item: GridFilterItem) => void | Deletes a GridFilterItem. | +| exportDataAsCsv | (options?: GridExportCsvOptions) => void | Downloads and exports a CSV of the grid's data. | +| forceUpdate | Dispatch<any> | Forces the grid to rerender. It's often used after a state update. | +| getAllColumns | () => GridColumns | Returns an array of [GridColDef](/api/data-grid/grid-col-def/) containing all the column definitions. | +| getAllRowIds | () => GridRowId[] | Gets the list of row ids. | +| getCellElement | (id: GridRowId, field: string) => null \| HTMLDivElement | Gets the underlying DOM element for a cell at the given `id` and `field`. | +| getCellMode | (id: GridRowId, field: string) => GridCellMode | Gets the mode of a cell. | +| getCellParams | (id: GridRowId, field: string) => GridCellParams | Gets the [GridCellParams](/api/data-grid/grid-cell-params/) object that is passed as argument in events. | +| getCellValue | (id: GridRowId, field: string) => GridCellValue | Gets the value of a cell at the given `id` and `field`. | +| getColumn | (field: string) => GridColDef | Returns the [GridColDef](/api/data-grid/grid-col-def/) for the given `field`. | +| getColumnHeaderElement | (field: string) => null \| HTMLDivElement | Gets the underlying DOM element for the column header with the given `field`. | +| getColumnHeaderParams | (field: string) => GridColumnHeaderParams | Gets the GridColumnHeaderParams object that is passed as argument in events. | +| getColumnIndex | (field: string, useVisibleColumns?: boolean) => number | Returns the index position of a column. By default, only the visible columns are considered.
Pass `false` to `useVisibleColumns` to consider all columns. | +| getColumnPosition | (field: string) => number | Returns the left-position of a column relative to the inner border of the grid. | +| getColumnsMeta | () => GridColumnsMeta | Returns the GridColumnsMeta for each column. | +| getDataAsCsv | (options?: GridExportCsvOptions) => string | Returns the grid data as a CSV string.
This method is used internally by `exportDataAsCsv`. | +| getEditRowsModel | () => GridEditRowsModel | Gets the edit rows model of the grid. | +| getLocaleText | <T extends keyof GridLocaleText>(key: T) => GridLocaleText[T] | Returns the translation for the `key`. | +| getRow | (id: GridRowId) => null \| GridRowData | Gets the row data with a given id. | +| getRowElement | (id: GridRowId) => null \| HTMLDivElement | Gets the underlying DOM element for a row at the given `id`. | +| getRowIdFromRowIndex | (index: number) => GridRowId | Gets the `GridRowId` of a row at a specific index. | +| getRowIndex | (id: GridRowId) => number | Gets the row index of a row with a given id. | +| getRowModels | () => Map<GridRowId, GridRowData> | Gets the full set of rows as Map<GridRowId, GridRowModel>. | +| getRowParams | (id: GridRowId) => GridRowParams | Gets the [GridRowParams](/api/data-grid/grid-row-params/) object that is passed as argument in events. | +| getRowsCount | () => number | Gets the total number of rows in the grid. | +| getScrollPosition | () => GridScrollParams | Returns the current scroll position. | +| getSelectedRows | () => Map<GridRowId, GridRowData> | Returns an array of the selected rows. | +| getSortModel | () => GridSortModel | Returns the sort model currently applied to the grid. | +| getSortedRowIds | () => GridRowId[] | Returns all row ids sorted according to the active sort model. | +| getSortedRows | () => GridRowData[] | Returns all rows sorted according to the active sort model. | +| getState | () => GridState | Returns the state of the grid. | +| getVisibleColumns | () => GridColumns | Returns the currently visible columns. | +| getVisibleRowModels | () => Map<GridRowId, GridRowData> | Returns a sorted `Map` containing only the visible rows. | +| hideColumnMenu | () => void | Hides the column menu that is open. | +| hideFilterPanel | () => void | Hides the filter panel. | +| hidePreferences | () => void | Hides the preferences panel. | +| isCellEditable | (params: GridCellParams) => boolean | Controls if a cell is editable. | +| publishEvent | (name: string, params?: any, event?: MuiEvent<MouseEvent \| UIEvent \| Event \| SyntheticEvent<Element, Event> \| KeyboardEvent \| ClipboardEvent \| ProgressEvent<EventTarget> \| ErrorEvent \| AnimationEvent \| InputEvent \| FocusEvent \| CompositionEvent \| DragEvent \| PointerEvent \| SecurityPolicyViolationEvent \| TouchEvent \| TransitionEvent \| WheelEvent>) => void | Emits an event. | +| resize | () => void | Triggers a resize of the component and recalculation of width and height. | +| scroll | (params: Partial<GridScrollParams>) => void | Triggers the viewport to scroll to the given positions (in pixels). | +| scrollToIndexes | (params: Optional<GridCellIndexCoordinates, rowIndex>) => boolean | Triggers the viewport to scroll to the cell at indexes given by `params`.
Returns `true` if the grid had to scroll to reach the target. | +| selectRow | (id: GridRowId, isSelected?: boolean, allowMultiple?: boolean) => void | Change the selection state of a row. | +| selectRows | (ids: GridRowId[], isSelected?: boolean, deselectOtherRows?: boolean) => void | Change the selection state of multiple rows. | +| setCellFocus | (id: GridRowId, field: string) => void | Sets the focus to the cell at the given `id` and `field`. | +| setCellMode | (id: GridRowId, field: string, mode: GridCellMode) => void | Sets the mode of a cell. | +| setColumnHeaderFocus | (field: string, event?: SyntheticEvent<Element, Event>) => void | Sets the focus to the column header at the given `field`. | +| setColumnIndex | (field: string, targetIndexPosition: number) => void | Moves a column from its original position to the position given by `targetIndexPosition`. | +| setColumnVisibility | (field: string, isVisible: boolean) => void | Changes the visibility of the column referred by `field`. | +| setColumnWidth | (field: string, width: number) => void | Updates the width of a column. | +| setDensity | (size: GridDensity, headerHeight?: number, rowHeight?: number) => void | Sets the density of the grid. | +| setEditCellProps | (params: GridEditCellPropsParams) => void | Sets the input props of the edit cell. | +| setEditCellValue | (params: GridEditCellValueParams, event?: SyntheticEvent<Element, Event>) => void | Sets the value of the edit cell.
Commonly used inside the edit cell component. | +| setEditRowsModel | (model: GridEditRowsModel) => void | Set sthe edit rows model of the grid. | +| setFilterModel | (model: GridFilterModelState) => void | Sets the filter model to the one given by `model`. | +| setPage | (page: number) => void | Sets the displayed page to the value given by `page`. | +| setPageSize | (pageSize: number) => void | Sets the number of displayed rows to the value given by `pageSize`. | +| setRows | (rows: GridRowData[]) => void | Sets a new set of rows. | +| setSelectionModel | (rowIds: GridRowId[]) => void | Updates the selected rows to be those passed to the `rowIds` argument.
Any row already selected will be unselected. | +| setSortModel | (model: GridSortModel) => void | Updates the sort model and triggers the sorting of rows. | +| setState | (state: GridState \| ((previousState: GridState) => GridState)) => void | Sets the whole state of the grid. | +| showColumnMenu | (field: string) => void | Display the column menu under the `field` column. | +| showError | (props: any) => void | Displays the error overlay component. | +| showFilterPanel | (targetColumnField?: string) => void | Shows the filter panel. If `targetColumnField` is given, a filter for this field is also added. | +| showPreferences | (newValue: GridPreferencePanelsValue) => void | Displays the preferences panel. The `newValue` argument controls the content of the panel. | +| sortColumn | (column: GridColDef, direction?: GridSortDirection, allowMultipleSorting?: boolean) => void | Sorts a column. | +| state | GridState | Property that contains the whole state of the grid. | +| subscribeEvent | (event: string, handler: (params: any, event: MuiEvent< \| MouseEvent \| UIEvent \| Event \| SyntheticEvent<Element, Event> \| KeyboardEvent \| ClipboardEvent \| ProgressEvent<EventTarget> \| ErrorEvent \| AnimationEvent \| InputEvent \| FocusEvent \| CompositionEvent \| DragEvent \| PointerEvent \| SecurityPolicyViolationEvent \| TouchEvent \| TransitionEvent \| WheelEvent>) => void, options?: GridSubscribeEventOptions) => () => void | Registers a handler for an event. | +| toggleColumnMenu | (field: string) => void | Toggles the column menu under the `field` column. | +| updateColumn | (col: GridColDef) => void | Updates the definition of a column. | +| updateColumns | (cols: GridColDef[]) => void | Updates the definition of multiple columns at the same time. | +| updateRows | (updates: GridRowModelUpdate<>[]) => void | Allows to updates, insert and delete rows in a single call. | +| updateViewport | (forceRender?: boolean) => void | Refreshes the viewport cells according to the scroll positions | +| upsertFilter | (item: GridFilterItem) => void | Updates or inserts a GridFilterItem. | diff --git a/docs/pages/api-docs/data-grid/x-grid.md b/docs/pages/api-docs/data-grid/x-grid.md index 66db9169547f..d74726712812 100644 --- a/docs/pages/api-docs/data-grid/x-grid.md +++ b/docs/pages/api-docs/data-grid/x-grid.md @@ -60,41 +60,41 @@ import { XGrid } from '@material-ui/x-grid'; | logger | Logger | null | Pass a custom logger in the components that implements the 'Logger' interface. | | logLevel | string \| false | false | Allows to pass the logging level or false to turn off logging. | | nonce | string | | Nonce of the inline styles for [Content Security Policy](https://www.w3.org/TR/2016/REC-CSP2-20161215/#script-src-the-nonce-attribute). | -| onCellBlur | (params: GridCellParams, event: React.FocusEvent) => void | | Callback fired when the active element leaves a cell. | -| onCellClick | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a click event comes from a cell element. | -| onCellDoubleClick | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a double click event comes from a cell element. | +| onCellBlur | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when the active element leaves a cell. | +| onCellClick | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when a click event comes from a cell element. | +| onCellDoubleClick | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when a double click event comes from a cell element. | | onCellFocusOut | (params: GridCellParams, event?: MuiEvent) => void | | Callback fired when a cell loses focus. | -| onCellKeyDown | (params: GridCellParams, event: React.KeyboardEvent) => void | | Callback fired when a keydown event comes from a cell element. | -| onCellOver | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse over event comes from a cell element. | -| onCellOut | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse out comes from a cell element. | -| onCellEnter | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse enter event comes from a cell element. | -| onCellLeave | (params: GridCellParams, event: React.MouseEvent) => void | | Callback fired when a mouse leave event comes from a cell element. | -| onCellModeChange | (params: GridCellModeChangeParams) => void | | Callback fired when the cell mode changed. | -| onColumnHeaderClick | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a click event comes from a column header element. | -| onColumnHeaderDoubleClick | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a double click event comes from a column header element. | -| onColumnHeaderOver | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouseover event comes from a column header element. | -| onColumnHeaderOut | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouseout event comes from a column header element. | -| onColumnHeaderEnter | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouse enter event comes from a column header element. | -| onColumnHeaderLeave | (param: GridColumnHeaderParams, event: React.MouseEvent) => void | | Callback fired when a mouse leave event comes from a column header element. | -| onColumnOrderChange | (param: GridColumnOrderChangeParams, event: React.MouseEvent) => void | | Callback fired when a column is reordered. | -| onColumnResize | (param: GridColumnResizeParams) => void | | Callback fired while a column is being resized. | -| onColumnWidthChange | (param: GridColumnResizeParams) => void | | Callback fired when the width of a column is changed. | -| onColumnVisibilityChange | (param: GridColumnVisibilityChangeParams) => void | | Callback fired when a column visibility changes. | +| onCellKeyDown | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when a keydown event comes from a cell element. | +| onCellOver | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when a mouse over event comes from a cell element. | +| onCellOut | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when a mouse out comes from a cell element. | +| onCellEnter | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when a mouse enter event comes from a cell element. | +| onCellLeave | (params: GridCellParams, event: MuiEvent) => void | | Callback fired when a mouse leave event comes from a cell element. | +| onCellModeChange | (params: GridCellModeChangeParams, event: MuiEvent<{}>) => void | | Callback fired when the cell mode changed. | +| onColumnHeaderClick | (param: GridColumnHeaderParams, event: MuiEvent) => void | | Callback fired when a click event comes from a column header element. | +| onColumnHeaderDoubleClick | (param: GridColumnHeaderParams, event: MuiEvent) => void | | Callback fired when a double click event comes from a column header element. | +| onColumnHeaderOver | (param: GridColumnHeaderParams, event: MuiEvent) => void | | Callback fired when a mouseover event comes from a column header element. | +| onColumnHeaderOut | (param: GridColumnHeaderParams, event: MuiEvent) => void | | Callback fired when a mouseout event comes from a column header element. | +| onColumnHeaderEnter | (param: GridColumnHeaderParams, event: MuiEvent) => void | | Callback fired when a mouse enter event comes from a column header element. | +| onColumnHeaderLeave | (param: GridColumnHeaderParams, event: MuiEvent) => void | | Callback fired when a mouse leave event comes from a column header element. | +| onColumnOrderChange | (param: GridColumnOrderChangeParams, event: MuiEvent) => void | | Callback fired when a column is reordered. | +| onColumnResize | (param: GridColumnResizeParams, event: MuiEvent<{}>) => void | | Callback fired while a column is being resized. | +| onColumnWidthChange | (param: GridColumnResizeParams, event: MuiEvent<{}>) => void | | Callback fired when the width of a column is changed. | +| onColumnVisibilityChange | (param: GridColumnVisibilityChangeParams, event: MuiEvent<{}>) => void | | Callback fired when a column visibility changes. | | onError | (args: any) => void | | Callback fired when an exception is thrown in the grid, or when the `showError` API method is called. | -| onEditCellPropsChange | (params: GridEditCellPropsParams, event: React.SyntheticEvent) => void | | Callback fired when the edit cell value changes. | -| onCellEditCommit | (params: GridEditCellPropsParams, event: React.SyntheticEvent) => void | | Callback fired when the cell changes are going to be committed. | +| onEditCellPropsChange | (params: GridEditCellPropsParams, event: MuiEvent) => void | | Callback fired when the edit cell value changes. | +| onCellEditCommit | (params: GridEditCellPropsParams, event: MuiEvent) => void | | Callback fired when the cell changes are going to be committed. | | onEditRowModelChange | (params: GridEditRowModelParams) => void | | Callback fired when the EditRowModel changed. | | onFilterModelChange | (model: GridFilterModel) => void | | Callback fired when the Filter model changes before the filters are applied. | | onPageChange | (page: number) => void | | Callback fired when the current page has changed. | | onPageSizeChange | (pageSize: number) => void | | Callback fired when the page size has changed. | -| onResize | (param: GridResizeParams) => void | | Callback fired when the grid is being resized. | -| onRowClick | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a click event comes from a row container element. | -| onRowDoubleClick | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a double click event comes from a row container element. | -| onRowOver | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse over comes from a row container element. | -| onRowOut | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse out comes from a row container element. | -| onRowEnter | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse enter comes from a row container element. | -| onRowLeave | (param: GridRowParams, event: React.MouseEvent) => void | | Callback fired when a mouse leave event comes from a row container element. | -| onRowsScrollEnd | (param: GridRowScrollEndParams) => void | | Callback fired when scrolling to the bottom of the grid viewport. | +| onResize | (param: GridResizeParams, event: MuiEvent<{}>) => void | | Callback fired when the grid is being resized. | +| onRowClick | (param: GridRowParams, event: MuiEvent) => void | | Callback fired when a click event comes from a row container element. | +| onRowDoubleClick | (param: GridRowParams, event: MuiEvent) => void | | Callback fired when a double click event comes from a row container element. | +| onRowOver | (param: GridRowParams, event: MuiEvent) => void | | Callback fired when a mouse over comes from a row container element. | +| onRowOut | (param: GridRowParams, event: MuiEvent) => void | | Callback fired when a mouse out comes from a row container element. | +| onRowEnter | (param: GridRowParams, event: MuiEvent) => void | | Callback fired when a mouse enter comes from a row container element. | +| onRowLeave | (param: GridRowParams, event: MuiEvent) => void | | Callback fired when a mouse leave event comes from a row container element. | +| onRowsScrollEnd | (param: GridRowScrollEndParams, event: MuiEvent<{}>) => void | | Callback fired when scrolling to the bottom of the grid viewport. | | onSelectionModelChange | (model: GridSelectionModel) => void | | Callback fired when the selection state of one or multiple rows changes. | | onSortModelChange | (model: GridSortModel) => void | | Callback fired when the sort model changes before a column is sorted. | | page | number | 1 | Set the current page. | diff --git a/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx b/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx index c4a6419f51dc..79507680ffb5 100644 --- a/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx +++ b/docs/src/pages/components/data-grid/editing/CatchEditingEventsGrid.tsx @@ -23,11 +23,13 @@ export default function CatchEditingEventsGrid() { React.useEffect(() => { return apiRef.current.subscribeEvent( GRID_CELL_EDIT_ENTER, - (params: GridCellParams, event?: React.SyntheticEvent) => { + (params: GridCellParams, event) => { setMessage( `Editing cell with value: ${params.value} and row id: ${ params.id - }, column: ${params.field}, triggered by ${event!.type}.`, + }, column: ${params.field}, triggered by ${ + (event as React.SyntheticEvent)!.type + }.`, ); }, ); diff --git a/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.js b/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.js index 8324afff7cf6..d323eb27fa40 100644 --- a/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.js +++ b/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.js @@ -78,13 +78,13 @@ export default function StartEditButtonGrid() { }, []); const handleDoubleCellClick = React.useCallback((params, event) => { - event.stopPropagation(); + event.defaultMuiPrevented = true; }, []); // Prevent from rolling back on escape const handleCellKeyDown = React.useCallback((params, event) => { if (['Escape', 'Delete', 'Backspace', 'Enter'].includes(event.key)) { - event.stopPropagation(); + event.defaultMuiPrevented = true; } }, []); diff --git a/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.tsx b/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.tsx index 3be2b8f0b0e5..848174f5dd18 100644 --- a/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.tsx +++ b/docs/src/pages/components/data-grid/editing/StartEditButtonGrid.tsx @@ -8,7 +8,6 @@ import { useGridApiRef, XGrid, GridApiRef, - MuiEvent, } from '@material-ui/x-grid'; import { randomCreatedDate, @@ -83,32 +82,27 @@ export default function StartEditButtonGrid() { setSelectedCellParams(params); }, []); - const handleDoubleCellClick = React.useCallback( - (params: GridCellParams, event: React.SyntheticEvent) => { - event.stopPropagation(); - }, - [], - ); + const handleDoubleCellClick = React.useCallback((params, event) => { + event.defaultMuiPrevented = true; + }, []); // Prevent from rolling back on escape - const handleCellKeyDown = React.useCallback( - (params, event: React.KeyboardEvent) => { - if (['Escape', 'Delete', 'Backspace', 'Enter'].includes(event.key)) { - event.stopPropagation(); - } - }, - [], - ); + const handleCellKeyDown = React.useCallback((params, event) => { + if ( + ['Escape', 'Delete', 'Backspace', 'Enter'].includes( + (event as React.KeyboardEvent).key, + ) + ) { + event.defaultMuiPrevented = true; + } + }, []); // Prevent from committing on focus out - const handleCellFocusOut = React.useCallback( - (params, event?: MuiEvent) => { - if (params.cellMode === 'edit' && event) { - event.defaultMuiPrevented = true; - } - }, - [], - ); + const handleCellFocusOut = React.useCallback((params, event) => { + if (params.cellMode === 'edit' && event) { + event.defaultMuiPrevented = true; + } + }, []); return (
diff --git a/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.js b/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.js index a0c9594fa202..5447ca4650a1 100644 --- a/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.js +++ b/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.js @@ -64,7 +64,7 @@ export default function ValidateServerNameGrid() { }); }, 100); - event.stopPropagation(); + event.defaultMuiPrevented = true; } }, [apiRef], diff --git a/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.tsx b/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.tsx index 541e1a7370a8..bf0985e5803f 100644 --- a/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.tsx +++ b/docs/src/pages/components/data-grid/editing/ValidateServerNameGrid.tsx @@ -70,7 +70,7 @@ export default function ValidateServerNameGrid() { }); }, 100); - event.stopPropagation(); + event.defaultMuiPrevented = true; } }, [apiRef], diff --git a/docs/src/pages/components/data-grid/editing/editing.md b/docs/src/pages/components/data-grid/editing/editing.md index aacf70ed9b31..95cc54710e2a 100644 --- a/docs/src/pages/components/data-grid/editing/editing.md +++ b/docs/src/pages/components/data-grid/editing/editing.md @@ -87,7 +87,7 @@ Server-side validation works like client-side [validation](#validation). - Validate the value in the server. - Once the server responds, set the `error` attribute to false if it is valid. This allows to commit it. -**Note:** To prevent the default client-side behavior, use `event.stopPropagation()`. +**Note:** To prevent the default client-side behavior, set `event.defaultMuiPrevented` to `true`. This demo shows how you can validate a username asynchronously and prevent the user from committing the value while validating. It's using `XGrid` but the same approach can be used with `DataGrid`. @@ -104,7 +104,7 @@ The demo lets you edit the ratings by double-clicking the cell. ### Edit using external button [](https://material-ui.com/store/items/material-ui-pro/) -You can override the default [start editing](#start-editing) triggers using the `event.stopPropagation()` API on the synthetic React events. +You can override the default [start editing](#start-editing) triggers using the [`event.defaultMuiPrevented`](/components/data-grid/events#disabling-the-default-behavior) on the synthetic React events. {{"demo": "pages/components/data-grid/editing/StartEditButtonGrid.js", "bg": "inline", "disableAd": true}} diff --git a/docs/src/pages/components/data-grid/events/DoubleClickWithCtrlToEdit.js b/docs/src/pages/components/data-grid/events/DoubleClickWithCtrlToEdit.js new file mode 100644 index 000000000000..fa02f6faddc8 --- /dev/null +++ b/docs/src/pages/components/data-grid/events/DoubleClickWithCtrlToEdit.js @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { DataGrid } from '@material-ui/data-grid'; +import { useDemoData } from '@material-ui/x-grid-data-generator'; + +export default function DoubleClickWithCtrlToEdit() { + const { data } = useDemoData({ + dataSet: 'Commodity', + rowLength: 100, + maxColumns: 6, + editable: true, + }); + + return ( +
+ { + if (!event.ctrlKey) { + event.defaultMuiPrevented = true; + } + }} + {...data} + /> +
+ ); +} diff --git a/docs/src/pages/components/data-grid/events/DoubleClickWithCtrlToEdit.tsx b/docs/src/pages/components/data-grid/events/DoubleClickWithCtrlToEdit.tsx new file mode 100644 index 000000000000..fa02f6faddc8 --- /dev/null +++ b/docs/src/pages/components/data-grid/events/DoubleClickWithCtrlToEdit.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { DataGrid } from '@material-ui/data-grid'; +import { useDemoData } from '@material-ui/x-grid-data-generator'; + +export default function DoubleClickWithCtrlToEdit() { + const { data } = useDemoData({ + dataSet: 'Commodity', + rowLength: 100, + maxColumns: 6, + editable: true, + }); + + return ( +
+ { + if (!event.ctrlKey) { + event.defaultMuiPrevented = true; + } + }} + {...data} + /> +
+ ); +} diff --git a/docs/src/pages/components/data-grid/events/events.md b/docs/src/pages/components/data-grid/events/events.md index 533098ba25b3..161ae5ce68a8 100644 --- a/docs/src/pages/components/data-grid/events/events.md +++ b/docs/src/pages/components/data-grid/events/events.md @@ -8,7 +8,7 @@ title: Data Grid - Events ## Subscribing to events -You can subscribe to one of the [events emitted](/components/data-grid/events/#catalog-of-events) by calling `apiRef.current.subscribeEvent()` with the name of the event and a handler. The handler will be called with two arguments: a object with information related to the event and, optionally, a `React.SyntheticEvent` object if the event was emitted by a DOM element. +You can subscribe to one of the [events emitted](/components/data-grid/events/#catalog-of-events) by calling `apiRef.current.subscribeEvent()` with the name of the event and a handler. The handler will be called with two arguments: an object with information related to the event and a `MuiEvent` containing the DOM event or the React synthetic event, when available. ```tsx /** @@ -20,14 +20,33 @@ You can subscribe to one of the [events emitted](/components/data-grid/events/#c */ subscribeEvent: ( event: string, - handler: (params: any, event?: React.SyntheticEvent) => void, + handler: (params: any, event: MuiEvent) => void, options?: GridSubscribeEventOptions, ) => () => void; ``` The following demo shows how to subscribe to the `columnResize` event. Try it by resizing the columns. -{{"demo": "pages/components/data-grid/events/SubscribeToEvents.js", "bg": "inline", "defaultCodeOpen": false}} +{{"demo": "pages/components/data-grid/events/SubscribeToEvents.js", "bg": "inline"}} + +## Disabling the default behavior + +Depending on the use case, it might be necessary to disable the default action taken by an event. +The `MuiEvent` passed to the event handler has a `defaultMuiPrevented` property to control when the default behavior can be executed or not. +Set it to `true` to block the default handling of an event and implement your own. + +```tsx +) => { + event.defaultMuiPrevented = true; + }} +/> +``` + +Usually, double clicking a cell will put it into [edit mode](/components/data-grid/editing/). +The following example changes this behavior by also requiring CTRL to be pressed. + +{{"demo": "pages/components/data-grid/events/DoubleClickWithCtrlToEdit.js", "bg": "inline"}} ## Catalog of events diff --git a/packages/grid/_modules_/grid/GridComponentProps.ts b/packages/grid/_modules_/grid/GridComponentProps.ts index d6457fbfba77..886349a27791 100644 --- a/packages/grid/_modules_/grid/GridComponentProps.ts +++ b/packages/grid/_modules_/grid/GridComponentProps.ts @@ -2,7 +2,7 @@ import { GridState } from './hooks/features/core/gridState'; import { GridApiRef } from './models/api/gridApiRef'; import { GridColumns } from './models/colDef/gridColDef'; import { GridSlotsComponent } from './models/gridSlotsComponent'; -import { GridOptions } from './models/gridOptions'; +import { GridOptions, MuiEvent } from './models/gridOptions'; import { GridSlotsComponentsProps } from './models/gridSlotsComponentsProps'; import { GridStateChangeParams } from './models/params/gridStateChangeParams'; import { GridRowIdGetter, GridRowsProp } from './models/gridRows'; @@ -67,7 +67,7 @@ export interface GridComponentProps extends GridOptionsProp { /** * Set a callback fired when the state of the grid is updated. */ - onStateChange?: (params: GridStateChangeParams) => void; // We are overriding the handler in GridOptions to fix the params type and avoid the cycle dependency + onStateChange?: (params: GridStateChangeParams, event: MuiEvent<{}>) => void; // We are overriding the handler in GridOptions to fix the params type and avoid the cycle dependency /** * Set of rows of type [[GridRowsProp]]. */ diff --git a/packages/grid/_modules_/grid/hooks/features/columnResize/useGridColumnResize.tsx b/packages/grid/_modules_/grid/hooks/features/columnResize/useGridColumnResize.tsx index 9fdc0b0d75a0..7e37b1c2cb09 100644 --- a/packages/grid/_modules_/grid/hooks/features/columnResize/useGridColumnResize.tsx +++ b/packages/grid/_modules_/grid/hooks/features/columnResize/useGridColumnResize.tsx @@ -101,7 +101,7 @@ export const useGridColumnResize = ( }); }; - const handleResizeMouseUp = useEventCallback(() => { + const handleResizeMouseUp = useEventCallback((nativeEvent) => { // eslint-disable-next-line @typescript-eslint/no-use-before-define stopListening(); @@ -109,13 +109,17 @@ export const useGridColumnResize = ( clearTimeout(stopResizeEventTimeout.current); stopResizeEventTimeout.current = setTimeout(() => { - apiRef.current.publishEvent(GRID_COLUMN_RESIZE_STOP); - apiRef.current.publishEvent(GRID_COLUMN_WIDTH_CHANGE, { - element: colElementRef.current, - colDef: colDefRef.current, - api: apiRef, - width: colDefRef.current?.width, - }); + apiRef.current.publishEvent(GRID_COLUMN_RESIZE_STOP, null, nativeEvent); + apiRef.current.publishEvent( + GRID_COLUMN_WIDTH_CHANGE, + { + element: colElementRef.current, + colDef: colDefRef.current, + api: apiRef, + width: colDefRef.current?.width, + }, + nativeEvent, + ); }); logger.debug( @@ -126,7 +130,7 @@ export const useGridColumnResize = ( const handleResizeMouseMove = useEventCallback((nativeEvent) => { // Cancel move in case some other element consumed a mouseup event and it was not fired. if (nativeEvent.buttons === 0) { - handleResizeMouseUp(); + handleResizeMouseUp(nativeEvent); return; } @@ -137,12 +141,16 @@ export const useGridColumnResize = ( newWidth = Math.max(colDefRef.current?.minWidth!, newWidth); updateWidth(newWidth); - apiRef.current.publishEvent(GRID_COLUMN_RESIZE, { - element: colElementRef.current, - colDef: colDefRef.current, - api: apiRef, - width: newWidth, - }); + apiRef.current.publishEvent( + GRID_COLUMN_RESIZE, + { + element: colElementRef.current, + colDef: colDefRef.current, + api: apiRef, + width: newWidth, + }, + nativeEvent, + ); }); const handleColumnResizeMouseDown = useEventCallback( @@ -168,7 +176,7 @@ export const useGridColumnResize = ( ) as HTMLDivElement; logger.debug(`Start Resize on col ${colDef.field}`); - apiRef.current.publishEvent(GRID_COLUMN_RESIZE_START, { field: colDef.field }); + apiRef.current.publishEvent(GRID_COLUMN_RESIZE_START, { field: colDef.field }, event); colDefRef.current = colDef; colElementRef.current = apiRef.current!.columnHeadersElementRef?.current!.querySelector( @@ -205,7 +213,7 @@ export const useGridColumnResize = ( clearTimeout(stopResizeEventTimeout.current); stopResizeEventTimeout.current = setTimeout(() => { - apiRef.current.publishEvent(GRID_COLUMN_RESIZE_STOP); + apiRef.current.publishEvent(GRID_COLUMN_RESIZE_STOP, null, nativeEvent); }); logger.debug( @@ -232,12 +240,16 @@ export const useGridColumnResize = ( newWidth = Math.max(colDefRef.current?.minWidth!, newWidth); updateWidth(newWidth); - apiRef.current.publishEvent(GRID_COLUMN_RESIZE, { - element: colElementRef.current, - colDef: colDefRef.current, - api: apiRef, - width: newWidth, - }); + apiRef.current.publishEvent( + GRID_COLUMN_RESIZE, + { + element: colElementRef.current, + colDef: colDefRef.current, + api: apiRef, + width: newWidth, + }, + nativeEvent, + ); }); const handleTouchStart = useEventCallback((event) => { @@ -266,7 +278,7 @@ export const useGridColumnResize = ( const colDef = apiRef.current.getColumn(field); logger.debug(`Start Resize on col ${colDef.field}`); - apiRef.current.publishEvent(GRID_COLUMN_RESIZE_START, { field }); + apiRef.current.publishEvent(GRID_COLUMN_RESIZE_START, { field }, event); colDefRef.current = colDef; colElementRef.current = findHeaderElementFromField( diff --git a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts index e48416de0db1..0e64a7983c44 100644 --- a/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts +++ b/packages/grid/_modules_/grid/hooks/features/focus/useGridFocus.ts @@ -105,7 +105,7 @@ export const useGridFocus = (apiRef: GridApiRef, props: Pick { + (event: DocumentEventMap['click']) => { const isInsideFocusedCell = insideFocusedCell.current; insideFocusedCell.current = false; diff --git a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts index 06b7e8197ef2..e710caa677b3 100644 --- a/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts +++ b/packages/grid/_modules_/grid/hooks/features/keyboard/useGridKeyboard.ts @@ -65,9 +65,6 @@ export const useGridKeyboard = (apiRef: GridApiRef): void => { if ((event.target as any).nodeType === 1 && !isGridCellRoot(event.target as Element)) { return; } - if (event.isPropagationStopped()) { - return; - } // Get the most recent params because the cell mode may have changed by another listener const cellParams = apiRef.current.getCellParams(params.id, params.field); @@ -110,9 +107,6 @@ export const useGridKeyboard = (apiRef: GridApiRef): void => { if (!isGridHeaderCellRoot(event.target as HTMLElement)) { return; } - if (event.isPropagationStopped()) { - return; - } if (isSpaceKey(event.key) && isGridHeaderCellRoot(event.target as HTMLElement)) { event.preventDefault(); } diff --git a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts index 21b98e31cee4..42271ec315ea 100644 --- a/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts +++ b/packages/grid/_modules_/grid/hooks/features/rows/useGridEditRows.ts @@ -49,6 +49,29 @@ export function useGridEditRows( const [, setGridState, forceUpdate] = useGridState(apiRef); const options = useGridSelector(apiRef, optionsSelector); + const commitPropsAndExit = (params: GridCellParams, event: MouseEvent | React.SyntheticEvent) => { + if (params.cellMode === 'view') { + return; + } + apiRef.current.commitCellChange(params, event); + apiRef.current.publishEvent(GRID_CELL_EDIT_EXIT, params, event); + }; + + const handleCellFocusOut = useEventCallback( + (params: GridCellParams, event: MouseEvent | React.SyntheticEvent) => { + commitPropsAndExit(params, event); + }, + ); + + const handleColumnHeaderDragStart = useEventCallback((nativeEvent) => { + const { cell } = apiRef.current.getState().focus; + if (!cell) { + return; + } + const params = apiRef.current.getCellParams(cell.id, cell.field); + commitPropsAndExit(params, nativeEvent); + }); + const setCellMode = React.useCallback( (id, field, mode: GridCellMode) => { const isInEditMode = apiRef.current.getCellMode(id, field) === 'edit'; @@ -81,32 +104,6 @@ export function useGridEditRows( [apiRef, forceUpdate, logger, setGridState], ); - const commitPropsAndExit = (params: GridCellParams) => { - if (params.cellMode === 'view') { - return; - } - apiRef.current.commitCellChange(params); - apiRef.current.publishEvent(GRID_CELL_EDIT_EXIT, params); - }; - - const handleCellFocusOut = useEventCallback( - (params: GridCellParams, event?: MouseEvent | React.SyntheticEvent) => { - if (event && (event as any).defaultMuiPrevented) { - return; - } - commitPropsAndExit(params); - }, - ); - - const handleColumnHeaderDragStart = useEventCallback(() => { - const { cell } = apiRef.current.getState().focus; - if (!cell) { - return; - } - const params = apiRef.current.getCellParams(cell.id, cell.field); - commitPropsAndExit(params); - }); - const getCellMode = React.useCallback( (id, field) => { const editState = apiRef.current.getState().editRows; @@ -158,10 +155,7 @@ export function useGridEditRows( ); const handleEditCellPropsChange = React.useCallback( - (params: GridEditCellPropsParams, event?: React.SyntheticEvent) => { - if (event?.isPropagationStopped()) { - return; - } + (params: GridEditCellPropsParams) => { apiRef.current.setEditCellProps(params); }, [apiRef], @@ -183,7 +177,7 @@ export function useGridEditRows( ); const commitCellChange = React.useCallback( - (params: GridCommitCellChangeParams, event?: React.SyntheticEvent): boolean => { + (params: GridCommitCellChangeParams, event?: MouseEvent | React.SyntheticEvent): boolean => { const { id, field } = params; const model = apiRef.current.getEditRowsModel(); if (!model[id] || !model[id][field]) { @@ -202,11 +196,7 @@ export function useGridEditRows( ); const handleCellEditCommit = React.useCallback( - (params: GridCommitCellChangeParams, event?: React.SyntheticEvent) => { - if (event?.isPropagationStopped()) { - return; - } - + (params: GridCommitCellChangeParams) => { const { id, field } = params; const model = apiRef.current.getEditRowsModel(); const { value } = model[id][field]; @@ -220,7 +210,7 @@ export function useGridEditRows( const handleCellEditEnter = React.useCallback( (params: GridCellParams, event: React.MouseEvent | React.KeyboardEvent) => { - if (!params.isEditable || event.isPropagationStopped()) { + if (!params.isEditable) { return; } @@ -251,7 +241,7 @@ export function useGridEditRows( const handleCellKeyDown = React.useCallback( (params: GridCellParams, event) => { const { id, field, cellMode, isEditable } = params; - if (!isEditable || event.isPropagationStopped()) { + if (!isEditable) { return; } @@ -272,7 +262,7 @@ export function useGridEditRows( return; } } - if (isEditMode && !event.isPropagationStopped() && isCellExitEditModeKeys(event.key)) { + if (isEditMode && isCellExitEditModeKeys(event.key)) { apiRef.current.publishEvent(GRID_CELL_EDIT_EXIT, params, event); } }, @@ -281,7 +271,6 @@ export function useGridEditRows( const handleCellEditExit = React.useCallback( (params: GridCellParams, event?: React.SyntheticEvent) => { - // TODO check if its propagation was stopped setCellMode(params.id, params.field, 'view'); // When dispatched by the document, the event is not passed diff --git a/packages/grid/_modules_/grid/hooks/root/useApi.ts b/packages/grid/_modules_/grid/hooks/root/useApi.ts index 91637e88901b..f30fffbce702 100644 --- a/packages/grid/_modules_/grid/hooks/root/useApi.ts +++ b/packages/grid/_modules_/grid/hooks/root/useApi.ts @@ -4,15 +4,26 @@ import { GridSubscribeEventOptions } from '../../utils/eventEmitter/GridEventEmi import { useLogger } from '../utils/useLogger'; import { GRID_COMPONENT_ERROR, GRID_UNMOUNT } from '../../constants/eventsConstants'; import { useGridApiMethod } from './useGridApiMethod'; +import { MuiEvent } from '../../models/gridOptions'; + +const isSynthenticEvent = (event: any): event is React.SyntheticEvent => { + return event.isPropagationStopped !== undefined; +}; export function useApi(apiRef: GridApiRef): void { const logger = useLogger('useApi'); const publishEvent = React.useCallback( - (name: string, params: any, event?: React.SyntheticEvent) => { - if (!event || !event.isPropagationStopped || !event.isPropagationStopped()) { - apiRef.current.emit(name, params, event); + ( + name: string, + params: any, + event: MuiEvent = {}, + ) => { + event.defaultMuiPrevented = false; + if (event && isSynthenticEvent(event) && event.isPropagationStopped()) { + return; } + apiRef.current.emit(name, params, event); }, [apiRef], ); diff --git a/packages/grid/_modules_/grid/hooks/root/useGridApiEventHandler.ts b/packages/grid/_modules_/grid/hooks/root/useGridApiEventHandler.ts index 25c13aceff45..51fdcae413f4 100644 --- a/packages/grid/_modules_/grid/hooks/root/useGridApiEventHandler.ts +++ b/packages/grid/_modules_/grid/hooks/root/useGridApiEventHandler.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import { MuiEvent } from '../../models/gridOptions'; import { GridApiRef } from '../../models/api/gridApiRef'; import { useLogger } from '../utils/useLogger'; @@ -12,7 +13,15 @@ export function useGridApiEventHandler( React.useEffect(() => { if (handler && eventName) { - return apiRef.current.subscribeEvent(eventName, handler, options); + const enhancedHandler = ( + params: any, + event: MuiEvent, + ) => { + if (!event.defaultMuiPrevented) { + handler(params, event); + } + }; + return apiRef.current.subscribeEvent(eventName, enhancedHandler, options); } return undefined; diff --git a/packages/grid/_modules_/grid/models/api/gridCoreApi.ts b/packages/grid/_modules_/grid/models/api/gridCoreApi.ts index 761a96003bdd..727835f1a625 100644 --- a/packages/grid/_modules_/grid/models/api/gridCoreApi.ts +++ b/packages/grid/_modules_/grid/models/api/gridCoreApi.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import { MuiEvent } from '../gridOptions'; import { GridEventEmitter, GridSubscribeEventOptions, @@ -52,7 +53,10 @@ export interface GridCoreApi extends GridEventEmitter { */ subscribeEvent: ( event: string, - handler: (params: any, event?: React.SyntheticEvent) => void, + handler: ( + params: any, + event: MuiEvent, + ) => void, options?: GridSubscribeEventOptions, ) => () => void; /** @@ -60,7 +64,11 @@ export interface GridCoreApi extends GridEventEmitter { * @param {string} name The name of the event. * @param {...*} args Arguments to be passed to the handlers. */ - publishEvent: (name: string, ...args: any[]) => void; + publishEvent: ( + name: string, + params?: any, + event?: MuiEvent, + ) => void; /** * Displays the error overlay component. * @param {any} props Props to be passed to the `ErrorOverlay` component. diff --git a/packages/grid/_modules_/grid/models/api/gridEditRowApi.ts b/packages/grid/_modules_/grid/models/api/gridEditRowApi.ts index bae5946a536a..d9b99e458fdf 100644 --- a/packages/grid/_modules_/grid/models/api/gridEditRowApi.ts +++ b/packages/grid/_modules_/grid/models/api/gridEditRowApi.ts @@ -60,5 +60,8 @@ export interface GridEditRowApi { * @param {React.SyntheticEvent} event The event to pass forward. * @returns {boolean} A boolean indicating if there is an error. */ - commitCellChange: (params: GridCommitCellChangeParams, event?: React.SyntheticEvent) => boolean; + commitCellChange: ( + params: GridCommitCellChangeParams, + event?: MouseEvent | React.SyntheticEvent, + ) => boolean; } diff --git a/packages/grid/_modules_/grid/models/gridOptions.tsx b/packages/grid/_modules_/grid/models/gridOptions.tsx index e9703b035185..54ad55c33018 100644 --- a/packages/grid/_modules_/grid/models/gridOptions.tsx +++ b/packages/grid/_modules_/grid/models/gridOptions.tsx @@ -27,7 +27,7 @@ import { GridColumnResizeParams } from './params/gridColumnResizeParams'; import { GridColumnVisibilityChangeParams } from './params/gridColumnVisibilityChangeParams'; import { GridClasses } from './gridClasses'; -export type MuiEvent = (E | React.SyntheticEvent) & { +export type MuiEvent = E & { defaultMuiPrevented?: boolean; }; @@ -206,15 +206,21 @@ export interface GridOptions { /** * Callback fired when the edit cell value changes. * @param {GridEditCellPropsParams} params With all properties from [[GridEditCellPropsParams]]. - * @param {React.SyntheticEvent} event The event that caused this prop to be called. + * @param {MuiEvent} event The event that caused this prop to be called. */ - onEditCellPropsChange?: (params: GridEditCellPropsParams, event?: React.SyntheticEvent) => void; + onEditCellPropsChange?: ( + params: GridEditCellPropsParams, + event: MuiEvent, + ) => void; /** * Callback fired when the cell changes are committed. * @param {GridCellEditCommitParams} params With all properties from [[GridCellEditCommitParams]]. - * @param {React.SyntheticEvent} event The event that caused this prop to be called. + * @param {MuiEvent} event The event that caused this prop to be called. */ - onCellEditCommit?: (params: GridCellEditCommitParams, event?: React.SyntheticEvent) => void; + onCellEditCommit?: ( + params: GridCellEditCommitParams, + event: MuiEvent, + ) => void; /** * Callback fired when an exception is thrown in the grid, or when the `showError` API method is called. */ @@ -222,123 +228,150 @@ export interface GridOptions { /** * Callback fired when the active element leaves a cell. * @param param With all properties from [[GridCellParams]]. - * @param event [[React.FocusEvent]]. + * @param event [[MuiEvent]]. */ - onCellBlur?: (params: GridCellParams, event: React.FocusEvent) => void; + onCellBlur?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when a click event comes from a cell element. * @param param With all properties from [[GridCellParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onCellClick?: (params: GridCellParams, event: React.MouseEvent) => void; + onCellClick?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when a double click event comes from a cell element. * @param param With all properties from [[CellParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onCellDoubleClick?: (params: GridCellParams, event: React.MouseEvent) => void; + onCellDoubleClick?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when a cell loses focus. * @param param With all properties from [[GridCellParams]]. - * @param event [[Event]]. + * @param event [[MuiEvent]]. */ - onCellFocusOut?: (params: GridCellParams, event?: MuiEvent) => void; + onCellFocusOut?: ( + params: GridCellParams, + event: MuiEvent, + ) => void; /** * Callback fired when a keydown event comes from a cell element. * @param param With all properties from [[GridCellParams]]. - * @param event [[React.KeyboardEvent]]. + * @param event [[MuiEvent]]. */ - onCellKeyDown?: (params: GridCellParams, event: React.KeyboardEvent) => void; + onCellKeyDown?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when a mouseover event comes from a cell element. * @param param With all properties from [[GridCellParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onCellOver?: (params: GridCellParams, event: React.MouseEvent) => void; + onCellOver?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when a mouseout event comes from a cell element. * @param param With all properties from [[GridCellParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onCellOut?: (params: GridCellParams, event: React.MouseEvent) => void; + onCellOut?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when a mouse enter event comes from a cell element. * @param param With all properties from [[GridCellParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onCellEnter?: (params: GridCellParams, event: React.MouseEvent) => void; + onCellEnter?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when a mouse leave event comes from a cell element. * @param param With all properties from [[GridCellParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onCellLeave?: (params: GridCellParams, event: React.MouseEvent) => void; + onCellLeave?: (params: GridCellParams, event: MuiEvent) => void; /** * Callback fired when the cell mode changed. * @param handler + * @param event [[MuiEvent<{}>]]. */ - onCellModeChange?: (params: GridCellModeChangeParams) => void; + onCellModeChange?: (params: GridCellModeChangeParams, event: MuiEvent<{}>) => void; /** * Callback fired when the cell value changed. * @param handler + * @param event [[MuiEvent<{}>]]. */ - onCellValueChange?: (params: GridEditCellValueParams) => void; + onCellValueChange?: (params: GridEditCellValueParams, event: MuiEvent<{}>) => void; /** * Callback fired when a click event comes from a column header element. * @param param With all properties from [[GridColumnHeaderParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onColumnHeaderClick?: (param: GridColumnHeaderParams, event: React.MouseEvent) => void; + onColumnHeaderClick?: ( + param: GridColumnHeaderParams, + event: MuiEvent, + ) => void; /** * Callback fired when a double click event comes from a column header element. * @param param With all properties from [[GridColumnHeaderParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onColumnHeaderDoubleClick?: (param: GridColumnHeaderParams, event: React.MouseEvent) => void; + onColumnHeaderDoubleClick?: ( + param: GridColumnHeaderParams, + event: MuiEvent, + ) => void; /** * Callback fired when a mouseover event comes from a column header element. * @param param With all properties from [[GridColumnHeaderParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onColumnHeaderOver?: (param: GridColumnHeaderParams, event: React.MouseEvent) => void; + onColumnHeaderOver?: ( + param: GridColumnHeaderParams, + event: MuiEvent, + ) => void; /** * Callback fired when a mouseout event comes from a column header element. * @param param With all properties from [[GridColumnHeaderParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onColumnHeaderOut?: (param: GridColumnHeaderParams, event: React.MouseEvent) => void; + onColumnHeaderOut?: ( + param: GridColumnHeaderParams, + event: MuiEvent, + ) => void; /** * Callback fired when a mouse enter event comes from a column header element. * @param param With all properties from [[GridColumnHeaderParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onColumnHeaderEnter?: (param: GridColumnHeaderParams, event: React.MouseEvent) => void; + onColumnHeaderEnter?: ( + param: GridColumnHeaderParams, + event: MuiEvent, + ) => void; /** * Callback fired when a mouse leave event comes from a column header element. * @param param With all properties from [[GridColumnHeaderParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onColumnHeaderLeave?: (param: GridColumnHeaderParams, event: React.MouseEvent) => void; + onColumnHeaderLeave?: ( + param: GridColumnHeaderParams, + event: MuiEvent, + ) => void; /** * Callback fired when a column is reordered. * @param param With all properties from [[GridColumnHeaderParams]]. + * @param event [[MuiEvent<{}>]]. */ - onColumnOrderChange?: (param: GridColumnOrderChangeParams) => void; + onColumnOrderChange?: (param: GridColumnOrderChangeParams, event: MuiEvent<{}>) => void; /** * Callback fired while a column is being resized. * @param param With all properties from [[GridColumnResizeParams]]. + * @param event [[MuiEvent<{}>]]. */ - onColumnResize?: (param: GridColumnResizeParams) => void; + onColumnResize?: (param: GridColumnResizeParams, event: MuiEvent<{}>) => void; /** * Callback fired when the width of a column is changed. * @param param With all properties from [[GridColumnResizeParams]]. + * @param event [[MuiEvent<{}>]]. */ - onColumnWidthChange?: (param: GridColumnResizeParams) => void; + onColumnWidthChange?: (param: GridColumnResizeParams, event: MuiEvent<{}>) => void; /** * Callback fired when a column visibility changes. * @param param With all properties from [[GridColumnVisibilityChangeParams]]. + * @param event [[MuiEvent<{}>]]. */ - onColumnVisibilityChange?: (param: GridColumnVisibilityChangeParams) => void; + onColumnVisibilityChange?: (param: GridColumnVisibilityChangeParams, event: MuiEvent<{}>) => void; /** * Callback fired when the Filter model changes before the filters are applied. * @param model With all properties from [[GridFilterModel]]. @@ -357,49 +390,51 @@ export interface GridOptions { /** * Callback fired when a click event comes from a row container element. * @param param With all properties from [[GridRowParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onRowClick?: (param: GridRowParams, event: React.MouseEvent) => void; + onRowClick?: (param: GridRowParams, event: MuiEvent) => void; /** * Callback fired when scrolling to the bottom of the grid viewport. + * @param event [[MuiEvent<{}>]]. * @param param */ - onRowsScrollEnd?: (params: GridRowScrollEndParams) => void; + onRowsScrollEnd?: (params: GridRowScrollEndParams, event: MuiEvent<{}>) => void; /** * Callback fired when a double click event comes from a row container element. * @param param With all properties from [[RowParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onRowDoubleClick?: (param: GridRowParams, event: React.MouseEvent) => void; + onRowDoubleClick?: (param: GridRowParams, event: MuiEvent) => void; /** * Callback fired when a mouseover event comes from a row container element. * @param param With all properties from [[GridRowParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onRowOver?: (param: GridRowParams, event: React.MouseEvent) => void; + onRowOver?: (param: GridRowParams, event: MuiEvent) => void; /** * Callback fired when a mouseout event comes from a row container element. * @param param With all properties from [[GridRowParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onRowOut?: (param: GridRowParams, event: React.MouseEvent) => void; + onRowOut?: (param: GridRowParams, event: MuiEvent) => void; /** * Callback fired when a mouse enter event comes from a row container element. * @param param With all properties from [[GridRowParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onRowEnter?: (param: GridRowParams, event: React.MouseEvent) => void; + onRowEnter?: (param: GridRowParams, event: MuiEvent) => void; /** * Callback fired when a mouse leave event comes from a row container element. * @param param With all properties from [[GridRowParams]]. - * @param event [[React.MouseEvent]]. + * @param event [[MuiEvent]]. */ - onRowLeave?: (param: GridRowParams, event: React.MouseEvent) => void; + onRowLeave?: (param: GridRowParams, event: MuiEvent) => void; /** * Callback fired when the grid is resized. * @param param With all properties from [[GridResizeParams]]. + * @param event [[MuiEvent<{}>]]. */ - onResize?: (param: GridResizeParams) => void; + onResize?: (param: GridResizeParams, event: MuiEvent<{}>) => void; /** * Callback fired when the selection state of one or multiple rows changes. * @param selectionModel With all the row ids [[GridRowId]][]. @@ -413,7 +448,7 @@ export interface GridOptions { /** * Callback fired when the state of the grid is updated. */ - onStateChange?: (params: any) => void; + onStateChange?: (params: any, event: MuiEvent<{}>) => void; /** * Set the current page. * @default 1 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 93055a932c67..42f4a7e135ec 100644 --- a/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/editRows.XGrid.test.tsx @@ -101,7 +101,11 @@ describe(' - Edit Rows', () => { }); it('should allow to stop double click using stopPropagation', () => { - render( event.stopPropagation()} />); + render( + (event as React.SyntheticEvent).stopPropagation()} + />, + ); const cell = getCell(1, 0); cell.focus(); fireEvent.doubleClick(cell); @@ -177,7 +181,7 @@ describe(' - Edit Rows', () => { code: 1, target: cell, isPropagationStopped: () => false, - }); + } as any); // fireEvent.keyDown(cell, { key: 'a', code: 1, target: cell }); expect(cell).to.have.class('MuiDataGrid-cell--editable'); @@ -330,28 +334,6 @@ describe(' - Edit Rows', () => { expect(getActiveCell()).to.equal('2-1'); }); - it('should the focus to the new field', () => { - const handleCellBlur = (params, event) => { - if (params.cellMode === 'edit') { - event?.stopPropagation(); - } - }; - render(); - // Turn first cell into edit mode - apiRef!.current.setCellMode(0, 'brand', 'edit'); - - // Turn second cell into edit mode - getCell(1, 0).focus(); - apiRef!.current.setCellMode(1, 'brand', 'edit'); - expect(document.querySelectorAll('input').length).to.equal(2); - - // Try to focus the first cell's input - const input0 = getCell(0, 0).querySelector('input'); - input0!.focus(); - fireEvent.click(input0); - expect(document.activeElement).to.have.property('value', 'Nike'); - }); - it('should apply the valueParser before saving the value', () => { const valueParser = stub().withArgs('62').returns(1962); render( 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 0d25316d7f21..d32f5c7dd02c 100644 --- a/packages/grid/x-grid/src/tests/events.XGrid.test.tsx +++ b/packages/grid/x-grid/src/tests/events.XGrid.test.tsx @@ -17,6 +17,7 @@ import { GridRowsProp, GridColumns, GRID_ROWS_SCROLL, + GRID_CELL_CSS_CLASS, } from '@material-ui/x-grid'; import { getCell, getColumnHeaderCell, getRow } from 'test/utils/helperFn'; import { spy } from 'sinon'; @@ -218,6 +219,30 @@ describe(' - Events Params', () => { expect(eventStack).to.deep.equal([]); }); + it('should allow to prevent the default behavior', () => { + const preventDefault = (params, event) => { + event.defaultMuiPrevented = true; + }; + render(); + const cell = getCell(1, 1); + fireEvent.doubleClick(cell); + expect(cell).not.to.have.class(`${GRID_CELL_CSS_CLASS}--editing`); + }); + + it('should allow to prevent the default behavior while allowing the event to propagate', () => { + const preventDefault = (params, event) => { + event.defaultMuiPrevented = true; + }; + render(); + const cell = getCell(1, 1); + cell.focus(); + fireEvent.doubleClick(cell); + const input = cell.querySelector('input')!; + fireEvent.change(input, { target: { value: 'Lisa' } }); + fireEvent.keyDown(input, { key: 'Enter' }); + expect(cell).to.have.text('Jack'); + }); + it('should select a row by default', () => { const handleSelection = spy(); render(); diff --git a/packages/storybook/src/stories/grid-events.stories.tsx b/packages/storybook/src/stories/grid-events.stories.tsx index 04c115ae4772..a9c2a649f70f 100644 --- a/packages/storybook/src/stories/grid-events.stories.tsx +++ b/packages/storybook/src/stories/grid-events.stories.tsx @@ -73,7 +73,7 @@ export const OnCellClickNotPropagated = () => { const data = useData(2000, 200); const options: GridOptionsProp = { onCellClick: (params, event) => { - event.stopPropagation(); + (event as React.SyntheticEvent).stopPropagation(); action('cell click')(params); }, }; diff --git a/packages/storybook/src/stories/grid-rows.stories.tsx b/packages/storybook/src/stories/grid-rows.stories.tsx index 5229e430e628..9a68be194355 100644 --- a/packages/storybook/src/stories/grid-rows.stories.tsx +++ b/packages/storybook/src/stories/grid-rows.stories.tsx @@ -483,11 +483,11 @@ export function EditRowsControl() { }, []); const onCellEditCommit = React.useCallback( - (params: GridCellEditCommitParams, event?: React.SyntheticEvent) => { + (params: GridCellEditCommitParams, event: MuiEvent) => { const { id, field, value } = params; - event!.persist(); + event.persist(); // we stop propagation as we want to switch back to view mode after we updated the value on the server - event!.stopPropagation(); + event.defaultMuiPrevented = true; let cellUpdate: any = { id }; cellUpdate[field] = value; @@ -607,12 +607,12 @@ export function ValidateEditValueWithApiRefGrid() { const classes = useEditCellStyles(); const onEditCellPropsChange = React.useCallback( - ({ id, field, props }: GridEditCellPropsParams, event?: React.SyntheticEvent) => { + ({ id, field, props }: GridEditCellPropsParams, event: MuiEvent) => { if (field === 'email') { const isValid = validateEmail(props.value); apiRef.current.setEditCellProps({ id, field, props: { ...props, error: !isValid } }); // Prevent the native behavior. - event?.stopPropagation(); + event.defaultMuiPrevented = true; } }, [apiRef], @@ -676,7 +676,10 @@ export function ValidateEditValueServerSide() { const keyStrokeTimeoutRef = React.useRef(); const handleCellEditPropChange = React.useCallback( - async ({ id, field, props }: GridEditCellPropsParams, event) => { + async ( + { id, field, props }: GridEditCellPropsParams, + event: MuiEvent, + ) => { if (field === 'username') { // TODO refactor this block clearTimeout(promiseTimeout); @@ -688,7 +691,7 @@ export function ValidateEditValueServerSide() { apiRef.current.setEditCellProps({ id, field, props: { ...props, error: !isValid } }); }, 200); - event.stopPropagation(); + event.defaultMuiPrevented = true; } }, [apiRef], @@ -742,25 +745,28 @@ export function EditCellUsingExternalButtonGrid() { }, []); const handleDoubleCellClick = React.useCallback( - (params: GridCellParams, event: React.SyntheticEvent) => { - event.stopPropagation(); + (params: GridCellParams, event: MuiEvent) => { + event.defaultMuiPrevented = true; }, [], ); // Prevent from rolling back on escape - const handleCellKeyDown = React.useCallback((params, event: React.KeyboardEvent) => { + const handleCellKeyDown = React.useCallback((params, event: MuiEvent) => { if (['Escape', 'Delete', 'Backspace', 'Enter'].includes(event.key)) { - event.stopPropagation(); + event.defaultMuiPrevented = true; } }, []); // Prevent from committing on focus out - const handleCellFocusOut = React.useCallback((params, event?: MuiEvent) => { - if (params.cellMode === 'edit' && event) { - event.defaultMuiPrevented = true; - } - }, []); + const handleCellFocusOut = React.useCallback( + (params, event: MuiEvent) => { + if (params.cellMode === 'edit' && event) { + event.defaultMuiPrevented = true; + } + }, + [], + ); return ( @@ -807,13 +813,13 @@ export function EditCellWithCellClickGrid() { const apiRef = useGridApiRef(); const handleCellClick = React.useCallback( - (params: GridCellParams, event) => { + (params: GridCellParams, event: MuiEvent) => { // Or you can use the editRowModel prop, but I find it easier // apiRef.current.setCellMode(params.id, params.field, 'edit'); apiRef.current.publishEvent(GRID_CELL_EDIT_ENTER, params, event); // if I want to prevent selection I can do - event.stopPropagation(); + event.defaultMuiPrevented = true; }, [apiRef], ); @@ -832,16 +838,13 @@ export function EditCellWithMessageGrid() { const [message, setMessage] = React.useState(''); React.useEffect(() => { - return apiRef.current.subscribeEvent( - GRID_CELL_EDIT_ENTER, - (params: GridCellParams, event?: React.SyntheticEvent) => { - setMessage(`Editing cell with value: ${params.value} at row: ${params.id}, column: ${ - params.field - }, - triggered by ${event!.type} - `); + return apiRef.current.subscribeEvent(GRID_CELL_EDIT_ENTER, (params: GridCellParams, event) => { + setMessage(`Editing cell with value: ${params.value} at row: ${params.id}, column: ${ + params.field }, - ); + triggered by ${(event as React.SyntheticEvent)!.type} + `); + }); }, [apiRef]); React.useEffect(() => {