@mui/x-data-grid 7.0.0-alpha.5 → 7.0.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +226 -6
  2. package/DataGrid/DataGrid.js +25 -19
  3. package/DataGrid/useDataGridProps.js +0 -1
  4. package/colDef/gridDateOperators.js +13 -6
  5. package/colDef/gridSingleSelectColDef.js +6 -15
  6. package/components/cell/GridEditSingleSelectCell.d.ts +1 -2
  7. package/components/cell/GridEditSingleSelectCell.js +9 -29
  8. package/components/columnSelection/GridHeaderCheckbox.js +3 -1
  9. package/components/panel/filterPanel/GridFilterForm.js +44 -9
  10. package/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  11. package/components/panel/filterPanel/GridFilterInputDate.js +25 -8
  12. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.d.ts +2 -2
  13. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -48
  14. package/components/panel/filterPanel/GridFilterInputSingleSelect.d.ts +1 -2
  15. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -57
  16. package/components/panel/filterPanel/filterPanelUtils.d.ts +3 -2
  17. package/components/panel/filterPanel/filterPanelUtils.js +10 -5
  18. package/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  19. package/hooks/features/rowSelection/utils.d.ts +2 -0
  20. package/hooks/features/rowSelection/utils.js +8 -0
  21. package/hooks/utils/useGridAriaAttributes.js +2 -1
  22. package/index.js +1 -1
  23. package/legacy/DataGrid/DataGrid.js +25 -19
  24. package/legacy/DataGrid/useDataGridProps.js +0 -1
  25. package/legacy/colDef/gridDateOperators.js +13 -13
  26. package/legacy/colDef/gridSingleSelectColDef.js +6 -15
  27. package/legacy/components/cell/GridEditSingleSelectCell.js +8 -28
  28. package/legacy/components/columnSelection/GridHeaderCheckbox.js +3 -1
  29. package/legacy/components/panel/filterPanel/GridFilterForm.js +51 -19
  30. package/legacy/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  31. package/legacy/components/panel/filterPanel/GridFilterInputDate.js +27 -8
  32. package/legacy/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -53
  33. package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -59
  34. package/legacy/components/panel/filterPanel/filterPanelUtils.js +10 -6
  35. package/legacy/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  36. package/legacy/hooks/features/rowSelection/utils.js +8 -0
  37. package/legacy/hooks/utils/useGridAriaAttributes.js +2 -1
  38. package/legacy/index.js +1 -1
  39. package/models/props/DataGridProps.d.ts +26 -25
  40. package/modern/DataGrid/DataGrid.js +25 -19
  41. package/modern/DataGrid/useDataGridProps.js +0 -1
  42. package/modern/colDef/gridDateOperators.js +13 -6
  43. package/modern/colDef/gridSingleSelectColDef.js +6 -15
  44. package/modern/components/cell/GridEditSingleSelectCell.js +9 -29
  45. package/modern/components/columnSelection/GridHeaderCheckbox.js +3 -1
  46. package/modern/components/panel/filterPanel/GridFilterForm.js +44 -9
  47. package/modern/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  48. package/modern/components/panel/filterPanel/GridFilterInputDate.js +24 -6
  49. package/modern/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -47
  50. package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -56
  51. package/modern/components/panel/filterPanel/filterPanelUtils.js +10 -5
  52. package/modern/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  53. package/modern/hooks/features/rowSelection/utils.js +8 -0
  54. package/modern/hooks/utils/useGridAriaAttributes.js +2 -1
  55. package/modern/index.js +1 -1
  56. package/node/DataGrid/DataGrid.js +25 -19
  57. package/node/DataGrid/useDataGridProps.js +0 -1
  58. package/node/colDef/gridDateOperators.js +13 -6
  59. package/node/colDef/gridSingleSelectColDef.js +5 -14
  60. package/node/components/cell/GridEditSingleSelectCell.js +8 -28
  61. package/node/components/columnSelection/GridHeaderCheckbox.js +3 -1
  62. package/node/components/panel/filterPanel/GridFilterForm.js +44 -9
  63. package/node/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  64. package/node/components/panel/filterPanel/GridFilterInputDate.js +24 -6
  65. package/node/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -46
  66. package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -55
  67. package/node/components/panel/filterPanel/filterPanelUtils.js +12 -7
  68. package/node/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  69. package/node/hooks/features/rowSelection/utils.js +14 -0
  70. package/node/hooks/utils/useGridAriaAttributes.js +2 -1
  71. package/node/index.js +1 -1
  72. package/package.json +3 -3
@@ -1,12 +1,15 @@
1
1
  import { GridFilterInputDate } from '../components/panel/filterPanel/GridFilterInputDate';
2
- const dateRegex = /(\d+)-(\d+)-(\d+)/;
3
- const dateTimeRegex = /(\d+)-(\d+)-(\d+)T(\d+):(\d+)/;
4
2
  function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
5
3
  if (!filterItem.value) {
6
4
  return null;
7
5
  }
8
- const [year, month, day, hour, minute] = filterItem.value.match(showTime ? dateTimeRegex : dateRegex).slice(1).map(Number);
9
- const time = new Date(year, month - 1, day, hour || 0, minute || 0).getTime();
6
+ const date = new Date(filterItem.value);
7
+ if (showTime) {
8
+ date.setSeconds(0, 0);
9
+ } else {
10
+ date.setHours(0, 0, 0, 0);
11
+ }
12
+ const time = date.getTime();
10
13
  return value => {
11
14
  if (!value) {
12
15
  return false;
@@ -17,8 +20,12 @@ function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
17
20
 
18
21
  // Make a copy of the date to not reset the hours in the original object
19
22
  const dateCopy = new Date(value);
20
- const timeToCompare = dateCopy.setHours(showTime ? value.getHours() : 0, showTime ? value.getMinutes() : 0, 0, 0);
21
- return compareFn(timeToCompare, time);
23
+ if (showTime) {
24
+ dateCopy.setSeconds(0, 0);
25
+ } else {
26
+ dateCopy.setHours(0, 0, 0, 0);
27
+ }
28
+ return compareFn(dateCopy.getTime(), time);
22
29
  };
23
30
  }
24
31
  export const getGridDateOperators = showTime => [{
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { GRID_STRING_COL_DEF } from './gridStringColDef';
3
3
  import { renderEditSingleSelectCell } from '../components/cell/GridEditSingleSelectCell';
4
4
  import { getGridSingleSelectOperators } from './gridSingleSelectOperators';
5
- import { isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
5
+ import { getValueOptions, isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
6
6
  import { isObject } from '../utils/utils';
7
7
  const isArrayOfObjects = options => {
8
8
  return typeof options[0] === 'object';
@@ -28,16 +28,10 @@ export const GRID_SINGLE_SELECT_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
28
28
  if (!isSingleSelectColDef(colDef)) {
29
29
  return '';
30
30
  }
31
- let valueOptions;
32
- if (typeof colDef.valueOptions === 'function') {
33
- valueOptions = colDef.valueOptions({
34
- id,
35
- row: id ? api.getRow(id) : null,
36
- field
37
- });
38
- } else {
39
- valueOptions = colDef.valueOptions;
40
- }
31
+ const valueOptions = getValueOptions(colDef, {
32
+ id,
33
+ row: id ? api.getRow(id) : null
34
+ });
41
35
  if (value == null) {
42
36
  return '';
43
37
  }
@@ -55,10 +49,7 @@ export const GRID_SINGLE_SELECT_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
55
49
  // @ts-ignore
56
50
  pastedValueParser: (value, params) => {
57
51
  const colDef = params.colDef;
58
- const colDefValueOptions = colDef.valueOptions;
59
- const valueOptions = typeof colDefValueOptions === 'function' ? colDefValueOptions({
60
- field: colDef.field
61
- }) : colDefValueOptions || [];
52
+ const valueOptions = getValueOptions(colDef) || [];
62
53
  const getOptionValue = colDef.getOptionValue;
63
54
  const valueOption = valueOptions.find(option => {
64
55
  if (getOptionValue(option) === value) {
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange", "initialOpen", "getOptionLabel", "getOptionValue"],
3
+ const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange", "initialOpen"],
4
4
  _excluded2 = ["MenuProps"];
5
5
  import * as React from 'react';
6
6
  import PropTypes from 'prop-types';
@@ -9,7 +9,7 @@ import { GridCellEditStopReasons } from '../../models/params/gridEditCellParams'
9
9
  import { isEscapeKey } from '../../utils/keyboardUtils';
10
10
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
11
11
  import { GridEditModes } from '../../models/gridEditRowModel';
12
- import { getValueFromValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
12
+ import { getValueFromValueOptions, getValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
13
13
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
14
14
  import { createElement as _createElement } from "react";
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -27,9 +27,7 @@ function GridEditSingleSelectCell(props) {
27
27
  hasFocus,
28
28
  error,
29
29
  onValueChange,
30
- initialOpen = rootProps.editMode === GridEditModes.Cell,
31
- getOptionLabel: getOptionLabelProp,
32
- getOptionValue: getOptionValueProp
30
+ initialOpen = rootProps.editMode === GridEditModes.Cell
33
31
  } = props,
34
32
  other = _objectWithoutPropertiesLoose(props, _excluded);
35
33
  const apiRef = useGridApiContext();
@@ -51,21 +49,15 @@ function GridEditSingleSelectCell(props) {
51
49
  if (!isSingleSelectColDef(colDef)) {
52
50
  return null;
53
51
  }
54
- let valueOptions;
55
- if (typeof colDef?.valueOptions === 'function') {
56
- valueOptions = colDef?.valueOptions({
57
- id,
58
- row,
59
- field
60
- });
61
- } else {
62
- valueOptions = colDef?.valueOptions;
63
- }
52
+ const valueOptions = getValueOptions(colDef, {
53
+ id,
54
+ row
55
+ });
64
56
  if (!valueOptions) {
65
57
  return null;
66
58
  }
67
- const getOptionValue = getOptionValueProp || colDef.getOptionValue;
68
- const getOptionLabel = getOptionLabelProp || colDef.getOptionLabel;
59
+ const getOptionValue = colDef.getOptionValue;
60
+ const getOptionLabel = colDef.getOptionLabel;
69
61
  const handleChange = async event => {
70
62
  if (!isSingleSelectColDef(colDef) || !valueOptions) {
71
63
  return;
@@ -154,18 +146,6 @@ process.env.NODE_ENV !== "production" ? GridEditSingleSelectCell.propTypes = {
154
146
  * The cell value formatted with the column valueFormatter.
155
147
  */
156
148
  formattedValue: PropTypes.any,
157
- /**
158
- * Used to determine the label displayed for a given value option.
159
- * @param {ValueOptions} value The current value option.
160
- * @returns {string} The text to be displayed.
161
- */
162
- getOptionLabel: PropTypes.func,
163
- /**
164
- * Used to determine the value used for a value option.
165
- * @param {ValueOptions} value The current value option.
166
- * @returns {string} The value to be used.
167
- */
168
- getOptionValue: PropTypes.func,
169
149
  /**
170
150
  * If true, the cell is the active element.
171
151
  */
@@ -4,6 +4,7 @@ const _excluded = ["field", "colDef"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { unstable_composeClasses as composeClasses } from '@mui/utils';
7
+ import { isMultipleRowSelectionEnabled } from '../../hooks/features/rowSelection/utils';
7
8
  import { useGridSelector } from '../../hooks/utils/useGridSelector';
8
9
  import { gridTabIndexColumnHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector';
9
10
  import { gridRowSelectionStateSelector } from '../../hooks/features/rowSelection/gridRowSelectionSelector';
@@ -102,7 +103,8 @@ const GridHeaderCheckbox = /*#__PURE__*/React.forwardRef(function GridHeaderChec
102
103
  'aria-label': label
103
104
  },
104
105
  tabIndex: tabIndex,
105
- onKeyDown: handleKeyDown
106
+ onKeyDown: handleKeyDown,
107
+ disabled: !isMultipleRowSelectionEnabled(rootProps)
106
108
  }, rootProps.slotProps?.baseCheckbox, other));
107
109
  });
108
110
  process.env.NODE_ENV !== "production" ? GridHeaderCheckbox.propTypes = {
@@ -14,6 +14,7 @@ import { GridLogicOperator } from '../../../models/gridFilterItem';
14
14
  import { useGridApiContext } from '../../../hooks/utils/useGridApiContext';
15
15
  import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
16
16
  import { getDataGridUtilityClass } from '../../../constants/gridClasses';
17
+ import { getValueFromValueOptions, getValueOptions } from './filterPanelUtils';
17
18
  import { jsx as _jsx } from "react/jsx-runtime";
18
19
  import { createElement as _createElement } from "react";
19
20
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -130,23 +131,39 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
130
131
  const hasLogicOperatorColumn = hasMultipleFilters && logicOperators.length > 0;
131
132
  const baseFormControlProps = rootProps.slotProps?.baseFormControl || {};
132
133
  const baseSelectProps = rootProps.slotProps?.baseSelect || {};
133
- const isBaseSelectNative = baseSelectProps.native ?? true;
134
+ const isBaseSelectNative = baseSelectProps.native ?? false;
134
135
  const baseInputLabelProps = rootProps.slotProps?.baseInputLabel || {};
135
136
  const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};
136
137
  const {
137
138
  InputComponentProps
138
139
  } = valueInputProps,
139
140
  valueInputPropsOther = _objectWithoutPropertiesLoose(valueInputProps, _excluded2);
140
- const filteredColumns = React.useMemo(() => {
141
+ const {
142
+ filteredColumns,
143
+ selectedField
144
+ } = React.useMemo(() => {
145
+ let itemField = item.field;
141
146
  if (filterColumns === undefined || typeof filterColumns !== 'function') {
142
- return filterableColumns;
147
+ return {
148
+ filteredColumns: filterableColumns,
149
+ selectedField: itemField
150
+ };
143
151
  }
144
152
  const filteredFields = filterColumns({
145
153
  field: item.field,
146
154
  columns: filterableColumns,
147
155
  currentFilters: filterModel?.items || []
148
156
  });
149
- return filterableColumns.filter(column => filteredFields.includes(column.field));
157
+ return {
158
+ filteredColumns: filterableColumns.filter(column => {
159
+ const isFieldIncluded = filteredFields.includes(column.field);
160
+ if (column.field === item.field && !isFieldIncluded) {
161
+ itemField = undefined;
162
+ }
163
+ return isFieldIncluded;
164
+ }),
165
+ selectedField: itemField
166
+ };
150
167
  }, [filterColumns, filterModel?.items, filterableColumns, item.field]);
151
168
  const sortedFilteredColumns = React.useMemo(() => {
152
169
  switch (columnsSort) {
@@ -177,11 +194,29 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
177
194
  const newOperator = column.filterOperators.find(operator => operator.value === item.operator) || column.filterOperators[0];
178
195
 
179
196
  // Erase filter value if the input component or filtered column type is modified
180
- const eraseItemValue = !newOperator.InputComponent || newOperator.InputComponent !== currentOperator?.InputComponent || column.type !== currentColumn.type;
197
+ const eraseFilterValue = !newOperator.InputComponent || newOperator.InputComponent !== currentOperator?.InputComponent || column.type !== currentColumn.type;
198
+ let filterValue = eraseFilterValue ? undefined : item.value;
199
+
200
+ // Check filter value against the new valueOptions
201
+ if (column.type === 'singleSelect' && filterValue !== undefined) {
202
+ const colDef = column;
203
+ const valueOptions = getValueOptions(colDef);
204
+ if (Array.isArray(filterValue)) {
205
+ filterValue = filterValue.filter(val => {
206
+ return (
207
+ // Only keep values that are in the new value options
208
+ getValueFromValueOptions(val, valueOptions, colDef?.getOptionValue) !== undefined
209
+ );
210
+ });
211
+ } else if (getValueFromValueOptions(item.value, valueOptions, colDef?.getOptionValue) === undefined) {
212
+ // Reset the filter value if it is not in the new value options
213
+ filterValue = undefined;
214
+ }
215
+ }
181
216
  applyFilterChanges(_extends({}, item, {
182
217
  field,
183
218
  operator: newOperator.value,
184
- value: eraseItemValue ? undefined : item.value
219
+ value: filterValue
185
220
  }));
186
221
  }, [apiRef, applyFilterChanges, item, currentColumn, currentOperator]);
187
222
  const changeOperator = React.useCallback(event => {
@@ -256,7 +291,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
256
291
  inputProps: {
257
292
  'aria-label': apiRef.current.getLocaleText('filterPanelLogicOperator')
258
293
  },
259
- value: multiFilterOperator,
294
+ value: multiFilterOperator ?? '',
260
295
  onChange: changeLogicOperator,
261
296
  disabled: !!disableMultiFilterOperator || logicOperators.length === 1,
262
297
  native: isBaseSelectNative
@@ -281,7 +316,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
281
316
  labelId: columnSelectLabelId,
282
317
  id: columnSelectId,
283
318
  label: apiRef.current.getLocaleText('filterPanelColumns'),
284
- value: item.field || '',
319
+ value: selectedField ?? '',
285
320
  onChange: changeColumn,
286
321
  native: isBaseSelectNative
287
322
  }, rootProps.slotProps?.baseSelect, {
@@ -327,7 +362,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
327
362
  item: item,
328
363
  applyValue: applyFilterChanges,
329
364
  focusElementRef: valueRef
330
- }, currentOperator.InputComponentProps, InputComponentProps)) : null
365
+ }, currentOperator.InputComponentProps, InputComponentProps), item.field) : null
331
366
  }))]
332
367
  }));
333
368
  });
@@ -32,7 +32,7 @@ function GridFilterInputBoolean(props) {
32
32
  const labelId = useId();
33
33
  const selectId = useId();
34
34
  const baseSelectProps = rootProps.slotProps?.baseSelect || {};
35
- const isSelectNative = baseSelectProps.native ?? true;
35
+ const isSelectNative = baseSelectProps.native ?? false;
36
36
  const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};
37
37
  const onFilterChange = React.useCallback(event => {
38
38
  const value = event.target.value;
@@ -7,6 +7,23 @@ import { unstable_useId as useId } from '@mui/utils';
7
7
  import { useTimeout } from '../../../hooks/utils/useTimeout';
8
8
  import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
+ function convertFilterItemValueToInputValue(itemValue, inputType) {
11
+ if (itemValue == null) {
12
+ return '';
13
+ }
14
+ const dateCopy = new Date(itemValue);
15
+ // The date picker expects the date to be in the local timezone.
16
+ // But .toISOString() converts it to UTC with zero offset.
17
+ // So we need to subtract the timezone offset.
18
+ dateCopy.setMinutes(dateCopy.getMinutes() - dateCopy.getTimezoneOffset());
19
+ if (inputType === 'date') {
20
+ return dateCopy.toISOString().substring(0, 10);
21
+ }
22
+ if (inputType === 'datetime-local') {
23
+ return dateCopy.toISOString().substring(0, 19);
24
+ }
25
+ return dateCopy.toISOString().substring(0, 10);
26
+ }
10
27
  function GridFilterInputDate(props) {
11
28
  const {
12
29
  item,
@@ -21,25 +38,26 @@ function GridFilterInputDate(props) {
21
38
  } = props,
22
39
  other = _objectWithoutPropertiesLoose(props, _excluded);
23
40
  const filterTimeout = useTimeout();
24
- const [filterValueState, setFilterValueState] = React.useState(item.value ?? '');
41
+ const [filterValueState, setFilterValueState] = React.useState(() => convertFilterItemValueToInputValue(item.value, type));
25
42
  const [applying, setIsApplying] = React.useState(false);
26
43
  const id = useId();
27
44
  const rootProps = useGridRootProps();
28
45
  const onFilterChange = React.useCallback(event => {
46
+ filterTimeout.clear();
29
47
  const value = event.target.value;
30
- setFilterValueState(String(value));
48
+ setFilterValueState(value);
31
49
  setIsApplying(true);
32
50
  filterTimeout.start(rootProps.filterDebounceMs, () => {
33
51
  applyValue(_extends({}, item, {
34
- value
52
+ value: new Date(value)
35
53
  }));
36
54
  setIsApplying(false);
37
55
  });
38
56
  }, [applyValue, item, rootProps.filterDebounceMs, filterTimeout]);
39
57
  React.useEffect(() => {
40
- const itemValue = item.value ?? '';
41
- setFilterValueState(String(itemValue));
42
- }, [item.value]);
58
+ const value = convertFilterItemValueToInputValue(item.value, type);
59
+ setFilterValueState(value);
60
+ }, [item.value, type]);
43
61
  return /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({
44
62
  fullWidth: true,
45
63
  id: id,
@@ -1,11 +1,11 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "color", "error", "helperText", "size", "variant", "getOptionLabel", "getOptionValue"];
3
+ const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "color", "error", "helperText", "size", "variant"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
7
7
  import { unstable_useId as useId } from '@mui/utils';
8
- import { isSingleSelectColDef } from './filterPanelUtils';
8
+ import { getValueOptions, isSingleSelectColDef } from './filterPanelUtils';
9
9
  import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
11
  const filter = createFilterOptions();
@@ -19,9 +19,7 @@ function GridFilterInputMultipleSingleSelect(props) {
19
19
  error,
20
20
  helperText,
21
21
  size,
22
- variant = 'standard',
23
- getOptionLabel: getOptionLabelProp,
24
- getOptionValue: getOptionValueProp
22
+ variant = 'standard'
25
23
  } = props,
26
24
  other = _objectWithoutPropertiesLoose(props, _excluded);
27
25
  const TextFieldProps = {
@@ -40,23 +38,12 @@ function GridFilterInputMultipleSingleSelect(props) {
40
38
  resolvedColumn = column;
41
39
  }
42
40
  }
43
- const getOptionValue = getOptionValueProp || resolvedColumn?.getOptionValue;
44
- const getOptionLabel = getOptionLabelProp || resolvedColumn?.getOptionLabel;
41
+ const getOptionValue = resolvedColumn?.getOptionValue;
42
+ const getOptionLabel = resolvedColumn?.getOptionLabel;
45
43
  const isOptionEqualToValue = React.useCallback((option, value) => getOptionValue(option) === getOptionValue(value), [getOptionValue]);
46
44
  const resolvedValueOptions = React.useMemo(() => {
47
- if (!resolvedColumn?.valueOptions) {
48
- return [];
49
- }
50
- if (typeof resolvedColumn.valueOptions === 'function') {
51
- return resolvedColumn.valueOptions({
52
- field: resolvedColumn.field
53
- });
54
- }
55
- return resolvedColumn.valueOptions;
45
+ return getValueOptions(resolvedColumn) || [];
56
46
  }, [resolvedColumn]);
57
- const resolvedFormattedValueOptions = React.useMemo(() => {
58
- return resolvedValueOptions?.map(getOptionValue);
59
- }, [resolvedValueOptions, getOptionValue]);
60
47
 
61
48
  // The value is computed from the item.value and used directly
62
49
  // If it was done by a useEffect/useState, the Autocomplete could receive incoherent value and options
@@ -64,23 +51,8 @@ function GridFilterInputMultipleSingleSelect(props) {
64
51
  if (!Array.isArray(item.value)) {
65
52
  return [];
66
53
  }
67
- if (resolvedValueOptions !== undefined) {
68
- const itemValueIndexes = item.value.map(element => {
69
- // Gets the index matching between values and valueOptions
70
- return resolvedFormattedValueOptions?.findIndex(formattedOption => formattedOption === element);
71
- });
72
- return itemValueIndexes.filter(index => index >= 0).map(index => resolvedValueOptions[index]);
73
- }
74
54
  return item.value;
75
- }, [item.value, resolvedValueOptions, resolvedFormattedValueOptions]);
76
- React.useEffect(() => {
77
- if (!Array.isArray(item.value) || filteredValues.length !== item.value.length) {
78
- // Updates the state if the filter value has been cleaned by the component
79
- applyValue(_extends({}, item, {
80
- value: filteredValues.map(getOptionValue)
81
- }));
82
- }
83
- }, [item, filteredValues, applyValue, getOptionValue]);
55
+ }, [item.value]);
84
56
  const handleChange = React.useCallback((event, value) => {
85
57
  applyValue(_extends({}, item, {
86
58
  value: value.map(getOptionValue)
@@ -123,18 +95,6 @@ process.env.NODE_ENV !== "production" ? GridFilterInputMultipleSingleSelect.prop
123
95
  }).isRequired,
124
96
  applyValue: PropTypes.func.isRequired,
125
97
  focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
126
- /**
127
- * Used to determine the label displayed for a given value option.
128
- * @param {ValueOptions} value The current value option.
129
- * @returns {string} The text to be displayed.
130
- */
131
- getOptionLabel: PropTypes.func,
132
- /**
133
- * Used to determine the value used for a value option.
134
- * @param {ValueOptions} value The current value option.
135
- * @returns {string} The value to be used.
136
- */
137
- getOptionValue: PropTypes.func,
138
98
  item: PropTypes.shape({
139
99
  field: PropTypes.string.isRequired,
140
100
  id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
@@ -1,32 +1,30 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "getOptionLabel", "getOptionValue", "placeholder", "tabIndex", "label", "isFilterActive", "clearButton", "InputLabelProps"];
3
+ const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "placeholder", "tabIndex", "label", "isFilterActive", "clearButton", "InputLabelProps"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { unstable_useId as useId } from '@mui/utils';
7
7
  import { styled } from '@mui/material/styles';
8
8
  import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
9
- import { getValueFromValueOptions, isSingleSelectColDef } from './filterPanelUtils';
9
+ import { getValueFromValueOptions, getValueOptions, isSingleSelectColDef } from './filterPanelUtils';
10
10
  import { createElement as _createElement } from "react";
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
12
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
13
  const renderSingleSelectOptions = ({
14
- column: {
15
- valueOptions,
16
- field
17
- },
14
+ column,
18
15
  OptionComponent,
19
16
  getOptionLabel,
20
17
  getOptionValue,
21
18
  isSelectNative,
22
19
  baseSelectOptionProps
23
20
  }) => {
24
- const iterableColumnValues = typeof valueOptions === 'function' ? ['', ...valueOptions({
25
- field
26
- })] : ['', ...(valueOptions || [])];
21
+ const iterableColumnValues = ['', ...(getValueOptions(column) || [])];
27
22
  return iterableColumnValues.map(option => {
28
23
  const value = getOptionValue(option);
29
- const label = getOptionLabel(option);
24
+ let label = getOptionLabel(option);
25
+ if (label === '') {
26
+ label = ' '; // To force the height of the empty option
27
+ }
30
28
  return /*#__PURE__*/_createElement(OptionComponent, _extends({}, baseSelectOptionProps, {
31
29
  native: isSelectNative,
32
30
  key: value,
@@ -49,19 +47,17 @@ function GridFilterInputSingleSelect(props) {
49
47
  type,
50
48
  apiRef,
51
49
  focusElementRef,
52
- getOptionLabel: getOptionLabelProp,
53
- getOptionValue: getOptionValueProp,
54
50
  placeholder,
55
51
  tabIndex,
56
52
  label: labelProp,
57
53
  clearButton
58
54
  } = props,
59
55
  others = _objectWithoutPropertiesLoose(props, _excluded);
60
- const [filterValueState, setFilterValueState] = React.useState(item.value ?? '');
56
+ const filterValue = item.value ?? '';
61
57
  const id = useId();
62
58
  const labelId = useId();
63
59
  const rootProps = useGridRootProps();
64
- const isSelectNative = rootProps.slotProps?.baseSelect?.native ?? true;
60
+ const isSelectNative = rootProps.slotProps?.baseSelect?.native ?? false;
65
61
  let resolvedColumn = null;
66
62
  if (item.field) {
67
63
  const column = apiRef.current.getColumn(item.field);
@@ -69,52 +65,27 @@ function GridFilterInputSingleSelect(props) {
69
65
  resolvedColumn = column;
70
66
  }
71
67
  }
72
- const getOptionValue = getOptionValueProp || resolvedColumn?.getOptionValue;
73
- const getOptionLabel = getOptionLabelProp || resolvedColumn?.getOptionLabel;
68
+ const getOptionValue = resolvedColumn?.getOptionValue;
69
+ const getOptionLabel = resolvedColumn?.getOptionLabel;
74
70
  const currentValueOptions = React.useMemo(() => {
75
- if (!resolvedColumn) {
76
- return undefined;
77
- }
78
- return typeof resolvedColumn.valueOptions === 'function' ? resolvedColumn.valueOptions({
79
- field: resolvedColumn.field
80
- }) : resolvedColumn.valueOptions;
71
+ return getValueOptions(resolvedColumn);
81
72
  }, [resolvedColumn]);
82
73
  const onFilterChange = React.useCallback(event => {
83
74
  let value = event.target.value;
84
75
 
85
76
  // NativeSelect casts the value to a string.
86
77
  value = getValueFromValueOptions(value, currentValueOptions, getOptionValue);
87
- setFilterValueState(String(value));
88
78
  applyValue(_extends({}, item, {
89
79
  value
90
80
  }));
91
81
  }, [currentValueOptions, getOptionValue, applyValue, item]);
92
- React.useEffect(() => {
93
- let itemValue;
94
- if (currentValueOptions !== undefined) {
95
- // sanitize if valueOptions are provided
96
- itemValue = getValueFromValueOptions(item.value, currentValueOptions, getOptionValue);
97
- if (itemValue !== item.value) {
98
- applyValue(_extends({}, item, {
99
- value: itemValue
100
- }));
101
- return;
102
- }
103
- } else {
104
- itemValue = item.value;
105
- }
106
- itemValue = itemValue ?? '';
107
- setFilterValueState(String(itemValue));
108
- }, [item, currentValueOptions, applyValue, getOptionValue]);
109
- if (!isSingleSelectColDef(resolvedColumn)) {
110
- return null;
111
- }
112
82
  if (!isSingleSelectColDef(resolvedColumn)) {
113
83
  return null;
114
84
  }
115
85
  const label = labelProp ?? apiRef.current.getLocaleText('filterPanelInputLabel');
116
86
  return /*#__PURE__*/_jsxs(SingleSelectOperatorContainer, {
117
87
  children: [/*#__PURE__*/_jsxs(rootProps.slots.baseFormControl, {
88
+ fullWidth: true,
118
89
  children: [/*#__PURE__*/_jsx(rootProps.slots.baseInputLabel, _extends({}, rootProps.slotProps?.baseInputLabel, {
119
90
  id: labelId,
120
91
  htmlFor: id,
@@ -125,7 +96,7 @@ function GridFilterInputSingleSelect(props) {
125
96
  id: id,
126
97
  label: label,
127
98
  labelId: labelId,
128
- value: filterValueState,
99
+ value: filterValue,
129
100
  onChange: onFilterChange,
130
101
  variant: "standard",
131
102
  type: type || 'text',
@@ -159,18 +130,6 @@ process.env.NODE_ENV !== "production" ? GridFilterInputSingleSelect.propTypes =
159
130
  applyValue: PropTypes.func.isRequired,
160
131
  clearButton: PropTypes.node,
161
132
  focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
162
- /**
163
- * Used to determine the label displayed for a given value option.
164
- * @param {ValueOptions} value The current value option.
165
- * @returns {string} The text to be displayed.
166
- */
167
- getOptionLabel: PropTypes.func,
168
- /**
169
- * Used to determine the value used for a value option.
170
- * @param {ValueOptions} value The current value option.
171
- * @returns {string} The value to be used.
172
- */
173
- getOptionValue: PropTypes.func,
174
133
  /**
175
134
  * It is `true` if the filter either has a value or an operator with no value
176
135
  * required is selected (e.g. `isEmpty`)
@@ -1,6 +1,15 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
1
2
  export function isSingleSelectColDef(colDef) {
2
3
  return colDef?.type === 'singleSelect';
3
4
  }
5
+ export function getValueOptions(column, additionalParams) {
6
+ if (!column) {
7
+ return undefined;
8
+ }
9
+ return typeof column.valueOptions === 'function' ? column.valueOptions(_extends({
10
+ field: column.field
11
+ }, additionalParams)) : column.valueOptions;
12
+ }
4
13
  export function getValueFromValueOptions(value, valueOptions, getOptionValue) {
5
14
  if (valueOptions === undefined) {
6
15
  return undefined;
@@ -10,8 +19,4 @@ export function getValueFromValueOptions(value, valueOptions, getOptionValue) {
10
19
  return String(optionValue) === String(value);
11
20
  });
12
21
  return getOptionValue(result);
13
- }
14
- export const getLabelFromValueOption = valueOption => {
15
- const label = typeof valueOption === 'object' ? valueOption.label : valueOption;
16
- return label != null ? String(label) : '';
17
- };
22
+ }