Skip to content

Commit

Permalink
[DataGrid] Use non-native Selects by default (#11330)
Browse files Browse the repository at this point in the history
  • Loading branch information
cherniavskii authored Dec 15, 2023
1 parent a6f1170 commit 6ae6d37
Show file tree
Hide file tree
Showing 18 changed files with 174 additions and 303 deletions.
26 changes: 0 additions & 26 deletions docs/data/data-grid/filtering-recipes/UseNonNativeSelect.js

This file was deleted.

26 changes: 0 additions & 26 deletions docs/data/data-grid/filtering-recipes/UseNonNativeSelect.tsx

This file was deleted.

This file was deleted.

6 changes: 0 additions & 6 deletions docs/data/data-grid/filtering-recipes/filtering-recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,3 @@ Currently if you want to use the [Quick filter](/x/react-data-grid/filtering/qui
A common use case is to have certain components positioned outside of the grid. Because of the way the grid context works this might not be a straightforward thing to do. The example below illustrates how this use case can be achieved.

{{"demo": "QuickFilterOutsideOfGrid.js", "bg": "inline", "defaultCodeOpen": false}}

## Use non-native select in filter panel

If you do not want to use the native select in the filtering panel you can switch it to the `@mui/material/Select` component by using the `slotProps` property.

{{"demo": "UseNonNativeSelect.js", "bg": "inline", "defaultCodeOpen": false}}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ Below are described the steps you need to make to migrate from v6 to v7.

- The deprecated props `components` and `componentsProps` have been removed. Use `slots` and `slotProps` instead. See [components section](/x/react-data-grid/components/) for more details.
- The `slots.preferencesPanel` slot and the `slotProps.preferencesPanel` prop were removed. Use `slots.panel` and `slotProps.panel` instead.
- The `getOptionValue` and `getOptionLabel` props were removed from the following components:

- `GridEditSingleSelectCell`
- `GridFilterInputSingleSelect`
- `GridFilterInputMultipleSingleSelect`

Use the `getOptionValue` and `getOptionLabel` properties on the `singleSelect` column definition instead:

```tsx
const column: GridColDef = {
type: 'singleSelect',
field: 'country',
valueOptions: [
{ code: 'BR', name: 'Brazil' },
{ code: 'FR', name: 'France' },
],
getOptionValue: (value: any) => value.code,
getOptionLabel: (value: any) => value.name,
};
```

### State access

Expand Down Expand Up @@ -208,6 +228,8 @@ Below are described the steps you need to make to migrate from v6 to v7.
| `unstable_gridHeaderFilteringStateSelector` | `gridHeaderFilteringStateSelector` |
| `unstable_gridTabIndexColumnHeaderFilterSelector` | `gridTabIndexColumnHeaderFilterSelector` |

- The filter panel no longer uses the native version of the [`Select`](https://mui.com/material-ui/react-select/) component for all components.

<!-- ### Editing
- -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
getColumnHeadersTextContent,
getColumnValues,
getCell,
getSelectByName,
} from 'test/utils/helperFn';
import { expect } from 'chai';
import {
Expand Down Expand Up @@ -2121,7 +2122,7 @@ describe('<DataGridPremium /> - Row grouping', () => {
/>,
);

fireEvent.change(screen.getByRole('combobox', { name: 'Operator' }), {
fireEvent.change(getSelectByName('Operator'), {
target: { value: '>' },
});
fireEvent.change(screen.getByRole('spinbutton', { name: 'Value' }), {
Expand All @@ -2147,7 +2148,7 @@ describe('<DataGridPremium /> - Row grouping', () => {
/>,
);

fireEvent.change(screen.getByRole('combobox', { name: 'Operator' }), {
fireEvent.change(getSelectByName('Operator'), {
target: { value: '>' },
});
fireEvent.change(screen.getByRole('spinbutton', { name: 'Value' }), {
Expand Down Expand Up @@ -2375,7 +2376,7 @@ describe('<DataGridPremium /> - Row grouping', () => {
/>,
);

fireEvent.change(screen.getByRole('combobox', { name: 'Operator' }), {
fireEvent.change(getSelectByName('Operator'), {
target: { value: '>' },
});
fireEvent.change(screen.getByRole('spinbutton', { name: 'Value' }), {
Expand All @@ -2402,7 +2403,7 @@ describe('<DataGridPremium /> - Row grouping', () => {
/>,
);

fireEvent.change(screen.getByRole('combobox', { name: 'Operator' }), {
fireEvent.change(getSelectByName('Operator'), {
target: { value: '>' },
});
fireEvent.change(screen.getByRole('spinbutton', { name: 'Value' }), {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,10 @@ const GridHeaderFilterCell = React.forwardRef<HTMLDivElement, GridHeaderFilterCe
break;
case 'Enter':
if (isEditing) {
apiRef.current.stopHeaderFilterEditMode();
break;
if (!event.defaultPrevented) {
apiRef.current.stopHeaderFilterEditMode();
break;
}
}
if (event.metaKey || event.ctrlKey) {
headerFilterMenuRef.current = buttonRef.current;
Expand Down Expand Up @@ -192,7 +194,7 @@ const GridHeaderFilterCell = React.forwardRef<HTMLDivElement, GridHeaderFilterCe
const onMouseDown = React.useCallback(
(event: React.MouseEvent) => {
if (!hasFocus) {
if (inputRef.current && inputRef.current.contains(event.target as HTMLElement)) {
if (inputRef.current?.contains?.(event.target as HTMLElement)) {
inputRef.current.focus();
}
apiRef.current.setColumnHeaderFilterFocus(colDef.field, event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,22 +531,6 @@ describe('<DataGridPro /> - Edit components', () => {
});
});

it('should apply getOptionLabel to the options provided', () => {
defaultData.columns[0].renderEditCell = (params) => {
return renderEditSingleSelectCell({
...params,
getOptionLabel: (value) => (value as string).toLowerCase(),
});
};
render(<TestCase />);

const cell = getCell(0, 0);
fireEvent.doubleClick(cell);

expect(screen.queryAllByRole('option')[0]).to.have.text('nike');
expect(screen.queryAllByRole('option')[1]).to.have.text('adidas');
});

it('should pass the value prop to the select', async () => {
render(<TestCase />);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { createRenderer, fireEvent, screen, act, within } from '@mui-internal/te
import { expect } from 'chai';
import * as React from 'react';
import { spy } from 'sinon';
import { getColumnHeaderCell, getColumnValues } from 'test/utils/helperFn';
import { getColumnHeaderCell, getColumnValues, getSelectInput } from 'test/utils/helperFn';

const SUBMIT_FILTER_STROKE_TIME = DATA_GRID_PRO_PROPS_DEFAULT_VALUES.filterDebounceMs;

Expand Down Expand Up @@ -170,10 +170,10 @@ describe('<DataGridPro /> - Filter', () => {
/>,
);

const selectListOfColumns = document.querySelectorAll<HTMLElement>(
'.MuiDataGrid-filterFormColumnInput',
)[0];
const availableColumns = within(selectListOfColumns).getAllByRole('option');
const select = screen.getByRole('combobox', { name: 'Columns' });
fireEvent.mouseDown(select);
const listbox = screen.getByRole('listbox', { name: 'Columns' });
const availableColumns = within(listbox).getAllByRole('option');
expect(availableColumns.length).to.equal(1);
});

Expand Down Expand Up @@ -437,10 +437,12 @@ describe('<DataGridPro /> - Filter', () => {

// The first combo is hidden and we include hidden elements to make the query faster
// https://github.com/testing-library/dom-testing-library/issues/820#issuecomment-726936225
const select = screen.queryAllByRole('combobox', { name: 'Logic operator', hidden: true })[
isJSDOM ? 1 : 0 // https://github.com/testing-library/dom-testing-library/issues/846
];
fireEvent.change(select, { target: { value: 'or' } });
const input = getSelectInput(
screen.queryAllByRole('combobox', { name: 'Logic operator', hidden: true })[
isJSDOM ? 1 : 0 // https://github.com/testing-library/dom-testing-library/issues/846
],
);
fireEvent.change(input!, { target: { value: 'or' } });
expect(onFilterModelChange.callCount).to.equal(1);
expect(onFilterModelChange.lastCall.args[1].reason).to.equal('changeLogicOperator');
expect(getColumnValues(0)).to.deep.equal([]);
Expand Down
21 changes: 7 additions & 14 deletions packages/grid/x-data-grid/src/colDef/gridSingleSelectColDef.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { GRID_STRING_COL_DEF } from './gridStringColDef';
import { GridSingleSelectColDef, ValueOptions } from '../models/colDef/gridColDef';
import { renderEditSingleSelectCell } from '../components/cell/GridEditSingleSelectCell';
import { getGridSingleSelectOperators } from './gridSingleSelectOperators';
import { isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
import {
getValueOptions,
isSingleSelectColDef,
} from '../components/panel/filterPanel/filterPanelUtils';
import { isObject } from '../utils/utils';

const isArrayOfObjects = (options: any): options is Array<Record<string, any>> => {
Expand Down Expand Up @@ -30,13 +33,7 @@ export const GRID_SINGLE_SELECT_COL_DEF: Omit<GridSingleSelectColDef, 'field'> =
return '';
}

let valueOptions: Array<ValueOptions>;
if (typeof colDef.valueOptions === 'function') {
valueOptions = colDef.valueOptions!({ id, row: id ? api.getRow(id) : null, field });
} else {
valueOptions = colDef.valueOptions!;
}

const valueOptions = getValueOptions(colDef, { id, row: id ? api.getRow(id) : null });
if (value == null) {
return '';
}
Expand All @@ -56,12 +53,8 @@ export const GRID_SINGLE_SELECT_COL_DEF: Omit<GridSingleSelectColDef, 'field'> =
filterOperators: getGridSingleSelectOperators(),
// @ts-ignore
pastedValueParser: (value, params) => {
const colDef = params.colDef;
const colDefValueOptions = (colDef as GridSingleSelectColDef).valueOptions;
const valueOptions =
typeof colDefValueOptions === 'function'
? colDefValueOptions({ field: colDef.field })
: colDefValueOptions || [];
const colDef = params.colDef as GridSingleSelectColDef;
const valueOptions = getValueOptions(colDef) || [];
const getOptionValue = (colDef as GridSingleSelectColDef).getOptionValue!;
const valueOption = valueOptions.find((option) => {
if (getOptionValue(option) === value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ import { GridRenderEditCellParams } from '../../models/params/gridCellParams';
import { isEscapeKey } from '../../utils/keyboardUtils';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { GridEditModes } from '../../models/gridEditRowModel';
import { GridSingleSelectColDef, ValueOptions } from '../../models/colDef/gridColDef';
import {
getValueFromValueOptions,
getValueOptions,
isSingleSelectColDef,
} from '../panel/filterPanel/filterPanelUtils';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';

export interface GridEditSingleSelectCellProps
extends GridRenderEditCellParams,
Omit<SelectProps, 'id' | 'tabIndex' | 'value'>,
Pick<GridSingleSelectColDef, 'getOptionLabel' | 'getOptionValue'> {
Omit<SelectProps, 'id' | 'tabIndex' | 'value'> {
/**
* Callback called when the value is changed by the user.
* @param {SelectChangeEvent<any>} event The event source of the callback.
Expand Down Expand Up @@ -56,8 +55,6 @@ function GridEditSingleSelectCell(props: GridEditSingleSelectCellProps) {
error,
onValueChange,
initialOpen = rootProps.editMode === GridEditModes.Cell,
getOptionLabel: getOptionLabelProp,
getOptionValue: getOptionValueProp,
...other
} = props;

Expand All @@ -80,19 +77,13 @@ function GridEditSingleSelectCell(props: GridEditSingleSelectCellProps) {
return null;
}

let valueOptions: Array<ValueOptions> | undefined;
if (typeof colDef?.valueOptions === 'function') {
valueOptions = colDef?.valueOptions({ id, row, field });
} else {
valueOptions = colDef?.valueOptions;
}

const valueOptions = getValueOptions(colDef, { id, row });
if (!valueOptions) {
return null;
}

const getOptionValue = getOptionValueProp || colDef.getOptionValue!;
const getOptionLabel = getOptionLabelProp || colDef.getOptionLabel!;
const getOptionValue = colDef.getOptionValue!;
const getOptionLabel = colDef.getOptionLabel!;

const handleChange: SelectProps['onChange'] = async (event) => {
if (!isSingleSelectColDef(colDef) || !valueOptions) {
Expand Down Expand Up @@ -204,18 +195,6 @@ GridEditSingleSelectCell.propTypes = {
* The cell value formatted with the column valueFormatter.
*/
formattedValue: PropTypes.any,
/**
* Used to determine the label displayed for a given value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The text to be displayed.
*/
getOptionLabel: PropTypes.func,
/**
* Used to determine the value used for a value option.
* @param {ValueOptions} value The current value option.
* @returns {string} The value to be used.
*/
getOptionValue: PropTypes.func,
/**
* If true, the cell is the active element.
*/
Expand Down
Loading

0 comments on commit 6ae6d37

Please sign in to comment.