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

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 (81) hide show
  1. package/CHANGELOG.md +408 -6
  2. package/DataGrid/DataGrid.js +31 -21
  3. package/DataGrid/useDataGridProps.js +0 -1
  4. package/colDef/gridDateOperators.js +13 -6
  5. package/colDef/gridSingleSelectColDef.js +6 -15
  6. package/components/GridPagination.d.ts +2 -2
  7. package/components/cell/GridEditSingleSelectCell.d.ts +1 -2
  8. package/components/cell/GridEditSingleSelectCell.js +9 -29
  9. package/components/columnSelection/GridHeaderCheckbox.js +3 -1
  10. package/components/panel/filterPanel/GridFilterForm.js +44 -9
  11. package/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  12. package/components/panel/filterPanel/GridFilterInputDate.js +25 -8
  13. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.d.ts +2 -2
  14. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -48
  15. package/components/panel/filterPanel/GridFilterInputSingleSelect.d.ts +1 -2
  16. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -57
  17. package/components/panel/filterPanel/filterPanelUtils.d.ts +3 -2
  18. package/components/panel/filterPanel/filterPanelUtils.js +10 -5
  19. package/hooks/features/filter/gridFilterUtils.js +21 -24
  20. package/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  21. package/hooks/features/rowSelection/utils.d.ts +2 -0
  22. package/hooks/features/rowSelection/utils.js +8 -0
  23. package/hooks/utils/useGridAriaAttributes.js +2 -1
  24. package/index.js +1 -1
  25. package/legacy/DataGrid/DataGrid.js +31 -21
  26. package/legacy/DataGrid/useDataGridProps.js +0 -1
  27. package/legacy/colDef/gridDateOperators.js +13 -13
  28. package/legacy/colDef/gridSingleSelectColDef.js +6 -15
  29. package/legacy/components/cell/GridEditSingleSelectCell.js +8 -28
  30. package/legacy/components/columnSelection/GridHeaderCheckbox.js +3 -1
  31. package/legacy/components/panel/filterPanel/GridFilterForm.js +51 -19
  32. package/legacy/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  33. package/legacy/components/panel/filterPanel/GridFilterInputDate.js +27 -8
  34. package/legacy/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -53
  35. package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -59
  36. package/legacy/components/panel/filterPanel/filterPanelUtils.js +10 -6
  37. package/legacy/hooks/features/filter/gridFilterUtils.js +20 -17
  38. package/legacy/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  39. package/legacy/hooks/features/rowSelection/utils.js +8 -0
  40. package/legacy/hooks/utils/useGridAriaAttributes.js +2 -1
  41. package/legacy/index.js +1 -1
  42. package/legacy/locales/csCZ.js +2 -2
  43. package/locales/csCZ.js +2 -2
  44. package/models/props/DataGridProps.d.ts +26 -26
  45. package/modern/DataGrid/DataGrid.js +31 -21
  46. package/modern/DataGrid/useDataGridProps.js +0 -1
  47. package/modern/colDef/gridDateOperators.js +13 -6
  48. package/modern/colDef/gridSingleSelectColDef.js +6 -15
  49. package/modern/components/cell/GridEditSingleSelectCell.js +9 -29
  50. package/modern/components/columnSelection/GridHeaderCheckbox.js +3 -1
  51. package/modern/components/panel/filterPanel/GridFilterForm.js +44 -9
  52. package/modern/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  53. package/modern/components/panel/filterPanel/GridFilterInputDate.js +24 -6
  54. package/modern/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -47
  55. package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -56
  56. package/modern/components/panel/filterPanel/filterPanelUtils.js +10 -5
  57. package/modern/hooks/features/filter/gridFilterUtils.js +21 -24
  58. package/modern/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  59. package/modern/hooks/features/rowSelection/utils.js +8 -0
  60. package/modern/hooks/utils/useGridAriaAttributes.js +2 -1
  61. package/modern/index.js +1 -1
  62. package/modern/locales/csCZ.js +2 -2
  63. package/node/DataGrid/DataGrid.js +31 -21
  64. package/node/DataGrid/useDataGridProps.js +0 -1
  65. package/node/colDef/gridDateOperators.js +13 -6
  66. package/node/colDef/gridSingleSelectColDef.js +5 -14
  67. package/node/components/cell/GridEditSingleSelectCell.js +8 -28
  68. package/node/components/columnSelection/GridHeaderCheckbox.js +3 -1
  69. package/node/components/panel/filterPanel/GridFilterForm.js +44 -9
  70. package/node/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  71. package/node/components/panel/filterPanel/GridFilterInputDate.js +24 -6
  72. package/node/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -46
  73. package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -55
  74. package/node/components/panel/filterPanel/filterPanelUtils.js +12 -7
  75. package/node/hooks/features/filter/gridFilterUtils.js +21 -23
  76. package/node/hooks/features/rowSelection/useGridRowSelection.js +9 -9
  77. package/node/hooks/features/rowSelection/utils.js +14 -0
  78. package/node/hooks/utils/useGridAriaAttributes.js +2 -1
  79. package/node/index.js +1 -1
  80. package/node/locales/csCZ.js +2 -2
  81. package/package.json +4 -4
@@ -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
+ }
@@ -4,15 +4,17 @@ import { getDefaultGridFilterModel } from './gridFilterState';
4
4
  import { buildWarning } from '../../../utils/warning';
5
5
  import { getPublicApiRef } from '../../../utils/getPublicApiRef';
6
6
  import { gridColumnFieldsSelector, gridColumnLookupSelector, gridVisibleColumnFieldsSelector } from '../columns';
7
-
8
- // Fixes https://github.com/mui/mui-x/issues/10056
9
- const globalScope = typeof window === 'undefined' ? globalThis : window;
10
- const evalCode = globalScope[atob('ZXZhbA==')];
11
7
  let hasEval;
12
- try {
13
- hasEval = evalCode('true');
14
- } catch (_) {
15
- hasEval = false;
8
+ function getHasEval() {
9
+ if (hasEval !== undefined) {
10
+ return hasEval;
11
+ }
12
+ try {
13
+ hasEval = new Function('return true')();
14
+ } catch (_) {
15
+ hasEval = false;
16
+ }
17
+ return hasEval;
16
18
  }
17
19
  /**
18
20
  * Adds default values to the optional fields of a filter items.
@@ -139,7 +141,7 @@ const buildAggregatedFilterItemsApplier = (filterModel, apiRef, disableEval) =>
139
141
  if (appliers.length === 0) {
140
142
  return null;
141
143
  }
142
- if (!hasEval || disableEval) {
144
+ if (disableEval || !getHasEval()) {
143
145
  // This is the original logic, which is used if `eval()` is not supported (aka prevented by CSP).
144
146
  return (row, shouldApplyFilter) => {
145
147
  const resultPerItemId = {};
@@ -153,25 +155,20 @@ const buildAggregatedFilterItemsApplier = (filterModel, apiRef, disableEval) =>
153
155
  };
154
156
  }
155
157
 
156
- // We generate a new function with `eval()` to avoid expensive patterns for JS engines
158
+ // We generate a new function with `new Function()` to avoid expensive patterns for JS engines
157
159
  // such as a dynamic object assignment, e.g. `{ [dynamicKey]: value }`.
158
- const filterItemTemplate = `(function filterItem$$(getRowId, appliers, row, shouldApplyFilter) {
159
- ${appliers.map((applier, i) => `const shouldApply${i} = !shouldApplyFilter || shouldApplyFilter(${JSON.stringify(applier.item.field)});`).join('\n')}
160
+ const filterItemCore = new Function('appliers', 'row', 'shouldApplyFilter', `"use strict";
161
+ ${appliers.map((applier, i) => `const shouldApply${i} = !shouldApplyFilter || shouldApplyFilter(${JSON.stringify(applier.item.field)});`).join('\n')}
160
162
 
161
- const result$$ = {
162
- ${appliers.map((applier, i) => `${JSON.stringify(String(applier.item.id))}:
163
- !shouldApply${i} ?
164
- false :
165
- appliers[${i}].fn(row),
166
- `).join('\n')}};
163
+ const result$$ = {
164
+ ${appliers.map((applier, i) => ` ${JSON.stringify(String(applier.item.id))}: !shouldApply${i} ? false : appliers[${i}].fn(row),`).join('\n')}
165
+ };
167
166
 
168
- return result$$;
169
- })`;
170
- const filterItemCore = evalCode(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
171
- const filterItem = (row, shouldApplyItem) => {
172
- return filterItemCore(apiRef.current.getRowId, appliers, row, shouldApplyItem);
173
- };
167
+ return result$$;`.replaceAll('$$', String(filterItemsApplierId)));
174
168
  filterItemsApplierId += 1;
169
+
170
+ // Assign to the arrow function a name to help debugging
171
+ const filterItem = (row, shouldApplyItem) => filterItemCore(appliers, row, shouldApplyItem);
175
172
  return filterItem;
176
173
  };
177
174
  export const shouldQuickFilterExcludeHiddenColumns = filterModel => {
@@ -15,6 +15,7 @@ import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
15
15
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../../../constants/gridDetailPanelToggleField';
16
16
  import { gridClasses } from '../../../constants/gridClasses';
17
17
  import { isEventTargetInPortal } from '../../../utils/domUtils';
18
+ import { isMultipleRowSelectionEnabled } from './utils';
18
19
  const getSelectionModelPropValue = (selectionModelProp, prevSelectionModel) => {
19
20
  if (selectionModelProp == null) {
20
21
  return selectionModelProp;
@@ -57,11 +58,10 @@ export const useGridRowSelection = (apiRef, props) => {
57
58
  });
58
59
  const {
59
60
  checkboxSelection,
60
- disableMultipleRowSelection,
61
61
  disableRowSelectionOnClick,
62
62
  isRowSelectable: propIsRowSelectable
63
63
  } = props;
64
- const canHaveMultipleSelection = !disableMultipleRowSelection || checkboxSelection;
64
+ const canHaveMultipleSelection = isMultipleRowSelectionEnabled(props);
65
65
  const visibleRows = useGridVisibleRows(apiRef, props);
66
66
  const expandMouseRowRangeSelection = React.useCallback(id => {
67
67
  let endId = id;
@@ -91,7 +91,7 @@ export const useGridRowSelection = (apiRef, props) => {
91
91
  * API METHODS
92
92
  */
93
93
  const setRowSelectionModel = React.useCallback(model => {
94
- if (props.signature === GridSignature.DataGrid && !props.checkboxSelection && Array.isArray(model) && model.length > 1) {
94
+ if (props.signature === GridSignature.DataGrid && !canHaveMultipleSelection && Array.isArray(model) && model.length > 1) {
95
95
  throw new Error(['MUI: `rowSelectionModel` can only contain 1 item in DataGrid.', 'You need to upgrade to DataGridPro or DataGridPremium component to unlock multiple selection.'].join('\n'));
96
96
  }
97
97
  const currentModel = gridRowSelectionStateSelector(apiRef.current.state);
@@ -102,7 +102,7 @@ export const useGridRowSelection = (apiRef, props) => {
102
102
  }));
103
103
  apiRef.current.forceUpdate();
104
104
  }
105
- }, [apiRef, logger, props.rowSelection, props.signature, props.checkboxSelection]);
105
+ }, [apiRef, logger, props.rowSelection, props.signature, canHaveMultipleSelection]);
106
106
  const isRowSelected = React.useCallback(id => gridRowSelectionStateSelector(apiRef.current.state).includes(id), [apiRef]);
107
107
  const isRowSelectable = React.useCallback(id => {
108
108
  if (propIsRowSelectable && !propIsRowSelectable(apiRef.current.getRowParams(id))) {
@@ -253,24 +253,24 @@ export const useGridRowSelection = (apiRef, props) => {
253
253
  if (rowNode.type === 'pinnedRow') {
254
254
  return;
255
255
  }
256
- if (event.shiftKey && (canHaveMultipleSelection || checkboxSelection)) {
256
+ if (event.shiftKey && canHaveMultipleSelection) {
257
257
  expandMouseRowRangeSelection(params.id);
258
258
  } else {
259
259
  handleSingleRowSelection(params.id, event);
260
260
  }
261
- }, [disableRowSelectionOnClick, canHaveMultipleSelection, checkboxSelection, apiRef, expandMouseRowRangeSelection, handleSingleRowSelection]);
261
+ }, [disableRowSelectionOnClick, canHaveMultipleSelection, apiRef, expandMouseRowRangeSelection, handleSingleRowSelection]);
262
262
  const preventSelectionOnShift = React.useCallback((params, event) => {
263
263
  if (canHaveMultipleSelection && event.shiftKey) {
264
264
  window.getSelection()?.removeAllRanges();
265
265
  }
266
266
  }, [canHaveMultipleSelection]);
267
267
  const handleRowSelectionCheckboxChange = React.useCallback((params, event) => {
268
- if (event.nativeEvent.shiftKey) {
268
+ if (canHaveMultipleSelection && event.nativeEvent.shiftKey) {
269
269
  expandMouseRowRangeSelection(params.id);
270
270
  } else {
271
- apiRef.current.selectRow(params.id, params.value);
271
+ apiRef.current.selectRow(params.id, params.value, !canHaveMultipleSelection);
272
272
  }
273
- }, [apiRef, expandMouseRowRangeSelection]);
273
+ }, [apiRef, expandMouseRowRangeSelection, canHaveMultipleSelection]);
274
274
  const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
275
275
  const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
276
276
  const rowsToBeSelected = shouldLimitSelectionToCurrentPage ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
@@ -0,0 +1,8 @@
1
+ import { GridSignature } from '../../utils/useGridApiEventHandler';
2
+ export function isMultipleRowSelectionEnabled(props) {
3
+ if (props.signature === GridSignature.DataGrid) {
4
+ // DataGrid Community has multiple row selection enabled only if checkbox selection is enabled.
5
+ return props.checkboxSelection && props.disableMultipleRowSelection !== true;
6
+ }
7
+ return !props.disableMultipleRowSelection;
8
+ }
@@ -4,6 +4,7 @@ import { useGridRootProps } from './useGridRootProps';
4
4
  import { gridColumnGroupsHeaderMaxDepthSelector } from '../features/columnGrouping/gridColumnGroupsSelector';
5
5
  import { gridPinnedRowsCountSelector, gridRowCountSelector } from '../features/rows/gridRowsSelector';
6
6
  import { useGridPrivateApiContext } from './useGridPrivateApiContext';
7
+ import { isMultipleRowSelectionEnabled } from '../features/rowSelection/utils';
7
8
  export const useGridAriaAttributes = () => {
8
9
  const apiRef = useGridPrivateApiContext();
9
10
  const rootProps = useGridRootProps();
@@ -19,6 +20,6 @@ export const useGridAriaAttributes = () => {
19
20
  role,
20
21
  'aria-colcount': visibleColumns.length,
21
22
  'aria-rowcount': headerGroupingMaxDepth + 1 + pinnedRowsCount + totalRowCount,
22
- 'aria-multiselectable': !rootProps.disableMultipleRowSelection
23
+ 'aria-multiselectable': isMultipleRowSelectionEnabled(rootProps)
23
24
  };
24
25
  };
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.0.0-alpha.5
2
+ * @mui/x-data-grid v7.0.0-alpha.7
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -159,8 +159,8 @@ const csCZGrid = {
159
159
  treeDataCollapse: 'skrýt potomky',
160
160
  // Grouping columns
161
161
  groupingColumnHeaderName: 'Skupina',
162
- groupColumn: name => `Zeskupit podle ${name}`,
163
- unGroupColumn: name => `Přestat zeskupovat podle ${name}`,
162
+ groupColumn: name => `Seskupit podle ${name}`,
163
+ unGroupColumn: name => `Přestat seskupovat podle ${name}`,
164
164
  // Master/detail
165
165
  detailPanelToggle: 'Přepnout detail panelu',
166
166
  expandDetailPanel: 'Rozbalit',