@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.
- package/CHANGELOG.md +226 -6
- package/DataGrid/DataGrid.js +25 -19
- package/DataGrid/useDataGridProps.js +0 -1
- package/colDef/gridDateOperators.js +13 -6
- package/colDef/gridSingleSelectColDef.js +6 -15
- package/components/cell/GridEditSingleSelectCell.d.ts +1 -2
- package/components/cell/GridEditSingleSelectCell.js +9 -29
- package/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/components/panel/filterPanel/GridFilterForm.js +44 -9
- package/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/components/panel/filterPanel/GridFilterInputDate.js +25 -8
- package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.d.ts +2 -2
- package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -48
- package/components/panel/filterPanel/GridFilterInputSingleSelect.d.ts +1 -2
- package/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -57
- package/components/panel/filterPanel/filterPanelUtils.d.ts +3 -2
- package/components/panel/filterPanel/filterPanelUtils.js +10 -5
- package/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/hooks/features/rowSelection/utils.d.ts +2 -0
- package/hooks/features/rowSelection/utils.js +8 -0
- package/hooks/utils/useGridAriaAttributes.js +2 -1
- package/index.js +1 -1
- package/legacy/DataGrid/DataGrid.js +25 -19
- package/legacy/DataGrid/useDataGridProps.js +0 -1
- package/legacy/colDef/gridDateOperators.js +13 -13
- package/legacy/colDef/gridSingleSelectColDef.js +6 -15
- package/legacy/components/cell/GridEditSingleSelectCell.js +8 -28
- package/legacy/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/legacy/components/panel/filterPanel/GridFilterForm.js +51 -19
- package/legacy/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/legacy/components/panel/filterPanel/GridFilterInputDate.js +27 -8
- package/legacy/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -53
- package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -59
- package/legacy/components/panel/filterPanel/filterPanelUtils.js +10 -6
- package/legacy/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/legacy/hooks/features/rowSelection/utils.js +8 -0
- package/legacy/hooks/utils/useGridAriaAttributes.js +2 -1
- package/legacy/index.js +1 -1
- package/models/props/DataGridProps.d.ts +26 -25
- package/modern/DataGrid/DataGrid.js +25 -19
- package/modern/DataGrid/useDataGridProps.js +0 -1
- package/modern/colDef/gridDateOperators.js +13 -6
- package/modern/colDef/gridSingleSelectColDef.js +6 -15
- package/modern/components/cell/GridEditSingleSelectCell.js +9 -29
- package/modern/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/modern/components/panel/filterPanel/GridFilterForm.js +44 -9
- package/modern/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/modern/components/panel/filterPanel/GridFilterInputDate.js +24 -6
- package/modern/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -47
- package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -56
- package/modern/components/panel/filterPanel/filterPanelUtils.js +10 -5
- package/modern/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/modern/hooks/features/rowSelection/utils.js +8 -0
- package/modern/hooks/utils/useGridAriaAttributes.js +2 -1
- package/modern/index.js +1 -1
- package/node/DataGrid/DataGrid.js +25 -19
- package/node/DataGrid/useDataGridProps.js +0 -1
- package/node/colDef/gridDateOperators.js +13 -6
- package/node/colDef/gridSingleSelectColDef.js +5 -14
- package/node/components/cell/GridEditSingleSelectCell.js +8 -28
- package/node/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/node/components/panel/filterPanel/GridFilterForm.js +44 -9
- package/node/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/node/components/panel/filterPanel/GridFilterInputDate.js +24 -6
- package/node/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -46
- package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -55
- package/node/components/panel/filterPanel/filterPanelUtils.js +12 -7
- package/node/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/node/hooks/features/rowSelection/utils.js +14 -0
- package/node/hooks/utils/useGridAriaAttributes.js +2 -1
- package/node/index.js +1 -1
- package/package.json +3 -3
|
@@ -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";
|
|
@@ -131,23 +132,39 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
131
132
|
const hasLogicOperatorColumn = hasMultipleFilters && logicOperators.length > 0;
|
|
132
133
|
const baseFormControlProps = ((_rootProps$slotProps = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps.baseFormControl) || {};
|
|
133
134
|
const baseSelectProps = ((_rootProps$slotProps2 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps2.baseSelect) || {};
|
|
134
|
-
const isBaseSelectNative = (_baseSelectProps$nati = baseSelectProps.native) != null ? _baseSelectProps$nati :
|
|
135
|
+
const isBaseSelectNative = (_baseSelectProps$nati = baseSelectProps.native) != null ? _baseSelectProps$nati : false;
|
|
135
136
|
const baseInputLabelProps = ((_rootProps$slotProps3 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps3.baseInputLabel) || {};
|
|
136
137
|
const baseSelectOptionProps = ((_rootProps$slotProps4 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps4.baseSelectOption) || {};
|
|
137
138
|
const {
|
|
138
139
|
InputComponentProps
|
|
139
140
|
} = valueInputProps,
|
|
140
141
|
valueInputPropsOther = _objectWithoutPropertiesLoose(valueInputProps, _excluded2);
|
|
141
|
-
const
|
|
142
|
+
const {
|
|
143
|
+
filteredColumns,
|
|
144
|
+
selectedField
|
|
145
|
+
} = React.useMemo(() => {
|
|
146
|
+
let itemField = item.field;
|
|
142
147
|
if (filterColumns === undefined || typeof filterColumns !== 'function') {
|
|
143
|
-
return
|
|
148
|
+
return {
|
|
149
|
+
filteredColumns: filterableColumns,
|
|
150
|
+
selectedField: itemField
|
|
151
|
+
};
|
|
144
152
|
}
|
|
145
153
|
const filteredFields = filterColumns({
|
|
146
154
|
field: item.field,
|
|
147
155
|
columns: filterableColumns,
|
|
148
156
|
currentFilters: (filterModel == null ? void 0 : filterModel.items) || []
|
|
149
157
|
});
|
|
150
|
-
return
|
|
158
|
+
return {
|
|
159
|
+
filteredColumns: filterableColumns.filter(column => {
|
|
160
|
+
const isFieldIncluded = filteredFields.includes(column.field);
|
|
161
|
+
if (column.field === item.field && !isFieldIncluded) {
|
|
162
|
+
itemField = undefined;
|
|
163
|
+
}
|
|
164
|
+
return isFieldIncluded;
|
|
165
|
+
}),
|
|
166
|
+
selectedField: itemField
|
|
167
|
+
};
|
|
151
168
|
}, [filterColumns, filterModel == null ? void 0 : filterModel.items, filterableColumns, item.field]);
|
|
152
169
|
const sortedFilteredColumns = React.useMemo(() => {
|
|
153
170
|
switch (columnsSort) {
|
|
@@ -179,11 +196,29 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
179
196
|
const newOperator = column.filterOperators.find(operator => operator.value === item.operator) || column.filterOperators[0];
|
|
180
197
|
|
|
181
198
|
// Erase filter value if the input component or filtered column type is modified
|
|
182
|
-
const
|
|
199
|
+
const eraseFilterValue = !newOperator.InputComponent || newOperator.InputComponent !== (currentOperator == null ? void 0 : currentOperator.InputComponent) || column.type !== currentColumn.type;
|
|
200
|
+
let filterValue = eraseFilterValue ? undefined : item.value;
|
|
201
|
+
|
|
202
|
+
// Check filter value against the new valueOptions
|
|
203
|
+
if (column.type === 'singleSelect' && filterValue !== undefined) {
|
|
204
|
+
const colDef = column;
|
|
205
|
+
const valueOptions = getValueOptions(colDef);
|
|
206
|
+
if (Array.isArray(filterValue)) {
|
|
207
|
+
filterValue = filterValue.filter(val => {
|
|
208
|
+
return (
|
|
209
|
+
// Only keep values that are in the new value options
|
|
210
|
+
getValueFromValueOptions(val, valueOptions, colDef == null ? void 0 : colDef.getOptionValue) !== undefined
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
} else if (getValueFromValueOptions(item.value, valueOptions, colDef == null ? void 0 : colDef.getOptionValue) === undefined) {
|
|
214
|
+
// Reset the filter value if it is not in the new value options
|
|
215
|
+
filterValue = undefined;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
183
218
|
applyFilterChanges(_extends({}, item, {
|
|
184
219
|
field,
|
|
185
220
|
operator: newOperator.value,
|
|
186
|
-
value:
|
|
221
|
+
value: filterValue
|
|
187
222
|
}));
|
|
188
223
|
}, [apiRef, applyFilterChanges, item, currentColumn, currentOperator]);
|
|
189
224
|
const changeOperator = React.useCallback(event => {
|
|
@@ -259,7 +294,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
259
294
|
inputProps: {
|
|
260
295
|
'aria-label': apiRef.current.getLocaleText('filterPanelLogicOperator')
|
|
261
296
|
},
|
|
262
|
-
value: multiFilterOperator,
|
|
297
|
+
value: multiFilterOperator != null ? multiFilterOperator : '',
|
|
263
298
|
onChange: changeLogicOperator,
|
|
264
299
|
disabled: !!disableMultiFilterOperator || logicOperators.length === 1,
|
|
265
300
|
native: isBaseSelectNative
|
|
@@ -284,7 +319,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
284
319
|
labelId: columnSelectLabelId,
|
|
285
320
|
id: columnSelectId,
|
|
286
321
|
label: apiRef.current.getLocaleText('filterPanelColumns'),
|
|
287
|
-
value:
|
|
322
|
+
value: selectedField != null ? selectedField : '',
|
|
288
323
|
onChange: changeColumn,
|
|
289
324
|
native: isBaseSelectNative
|
|
290
325
|
}, (_rootProps$slotProps7 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps7.baseSelect, {
|
|
@@ -330,7 +365,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
330
365
|
item: item,
|
|
331
366
|
applyValue: applyFilterChanges,
|
|
332
367
|
focusElementRef: valueRef
|
|
333
|
-
}, currentOperator.InputComponentProps, InputComponentProps)) : null
|
|
368
|
+
}, currentOperator.InputComponentProps, InputComponentProps), item.field) : null
|
|
334
369
|
}))]
|
|
335
370
|
}));
|
|
336
371
|
});
|
|
@@ -33,7 +33,7 @@ function GridFilterInputBoolean(props) {
|
|
|
33
33
|
const labelId = useId();
|
|
34
34
|
const selectId = useId();
|
|
35
35
|
const baseSelectProps = ((_rootProps$slotProps = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps.baseSelect) || {};
|
|
36
|
-
const isSelectNative = (_baseSelectProps$nati = baseSelectProps.native) != null ? _baseSelectProps$nati :
|
|
36
|
+
const isSelectNative = (_baseSelectProps$nati = baseSelectProps.native) != null ? _baseSelectProps$nati : false;
|
|
37
37
|
const baseSelectOptionProps = ((_rootProps$slotProps2 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps2.baseSelectOption) || {};
|
|
38
38
|
const onFilterChange = React.useCallback(event => {
|
|
39
39
|
const value = event.target.value;
|
|
@@ -7,8 +7,25 @@ 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
|
-
var
|
|
28
|
+
var _rootProps$slotProps;
|
|
12
29
|
const {
|
|
13
30
|
item,
|
|
14
31
|
applyValue,
|
|
@@ -22,26 +39,26 @@ function GridFilterInputDate(props) {
|
|
|
22
39
|
} = props,
|
|
23
40
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
24
41
|
const filterTimeout = useTimeout();
|
|
25
|
-
const [filterValueState, setFilterValueState] = React.useState((
|
|
42
|
+
const [filterValueState, setFilterValueState] = React.useState(() => convertFilterItemValueToInputValue(item.value, type));
|
|
26
43
|
const [applying, setIsApplying] = React.useState(false);
|
|
27
44
|
const id = useId();
|
|
28
45
|
const rootProps = useGridRootProps();
|
|
29
46
|
const onFilterChange = React.useCallback(event => {
|
|
47
|
+
filterTimeout.clear();
|
|
30
48
|
const value = event.target.value;
|
|
31
|
-
setFilterValueState(
|
|
49
|
+
setFilterValueState(value);
|
|
32
50
|
setIsApplying(true);
|
|
33
51
|
filterTimeout.start(rootProps.filterDebounceMs, () => {
|
|
34
52
|
applyValue(_extends({}, item, {
|
|
35
|
-
value
|
|
53
|
+
value: new Date(value)
|
|
36
54
|
}));
|
|
37
55
|
setIsApplying(false);
|
|
38
56
|
});
|
|
39
57
|
}, [applyValue, item, rootProps.filterDebounceMs, filterTimeout]);
|
|
40
58
|
React.useEffect(() => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}, [item.value]);
|
|
59
|
+
const value = convertFilterItemValueToInputValue(item.value, type);
|
|
60
|
+
setFilterValueState(value);
|
|
61
|
+
}, [item.value, type]);
|
|
45
62
|
return /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({
|
|
46
63
|
fullWidth: true,
|
|
47
64
|
id: id,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { AutocompleteProps } from '@mui/material/Autocomplete';
|
|
3
3
|
import { GridFilterInputValueProps } from './GridFilterInputValueProps';
|
|
4
|
-
import type {
|
|
5
|
-
export interface GridFilterInputMultipleSingleSelectProps extends Omit<AutocompleteProps<ValueOptions, true, false, true>, 'options' | 'renderInput' | 'onChange' | 'value' | 'id' | 'filterOptions' | 'isOptionEqualToValue' | 'multiple' | 'color' | 'getOptionLabel'>,
|
|
4
|
+
import type { ValueOptions } from '../../../models/colDef/gridColDef';
|
|
5
|
+
export interface GridFilterInputMultipleSingleSelectProps extends Omit<AutocompleteProps<ValueOptions, true, false, true>, 'options' | 'renderInput' | 'onChange' | 'value' | 'id' | 'filterOptions' | 'isOptionEqualToValue' | 'multiple' | 'color' | 'getOptionLabel'>, GridFilterInputValueProps {
|
|
6
6
|
type?: 'singleSelect';
|
|
7
7
|
}
|
|
8
8
|
declare function GridFilterInputMultipleSingleSelect(props: GridFilterInputMultipleSingleSelectProps): React.JSX.Element;
|
|
@@ -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"
|
|
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();
|
|
@@ -20,9 +20,7 @@ function GridFilterInputMultipleSingleSelect(props) {
|
|
|
20
20
|
error,
|
|
21
21
|
helperText,
|
|
22
22
|
size,
|
|
23
|
-
variant = 'standard'
|
|
24
|
-
getOptionLabel: getOptionLabelProp,
|
|
25
|
-
getOptionValue: getOptionValueProp
|
|
23
|
+
variant = 'standard'
|
|
26
24
|
} = props,
|
|
27
25
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
28
26
|
const TextFieldProps = {
|
|
@@ -41,24 +39,12 @@ function GridFilterInputMultipleSingleSelect(props) {
|
|
|
41
39
|
resolvedColumn = column;
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
|
-
const getOptionValue =
|
|
45
|
-
const getOptionLabel =
|
|
42
|
+
const getOptionValue = (_resolvedColumn = resolvedColumn) == null ? void 0 : _resolvedColumn.getOptionValue;
|
|
43
|
+
const getOptionLabel = (_resolvedColumn2 = resolvedColumn) == null ? void 0 : _resolvedColumn2.getOptionLabel;
|
|
46
44
|
const isOptionEqualToValue = React.useCallback((option, value) => getOptionValue(option) === getOptionValue(value), [getOptionValue]);
|
|
47
45
|
const resolvedValueOptions = React.useMemo(() => {
|
|
48
|
-
|
|
49
|
-
if (!((_resolvedColumn3 = resolvedColumn) != null && _resolvedColumn3.valueOptions)) {
|
|
50
|
-
return [];
|
|
51
|
-
}
|
|
52
|
-
if (typeof resolvedColumn.valueOptions === 'function') {
|
|
53
|
-
return resolvedColumn.valueOptions({
|
|
54
|
-
field: resolvedColumn.field
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
return resolvedColumn.valueOptions;
|
|
46
|
+
return getValueOptions(resolvedColumn) || [];
|
|
58
47
|
}, [resolvedColumn]);
|
|
59
|
-
const resolvedFormattedValueOptions = React.useMemo(() => {
|
|
60
|
-
return resolvedValueOptions == null ? void 0 : resolvedValueOptions.map(getOptionValue);
|
|
61
|
-
}, [resolvedValueOptions, getOptionValue]);
|
|
62
48
|
|
|
63
49
|
// The value is computed from the item.value and used directly
|
|
64
50
|
// If it was done by a useEffect/useState, the Autocomplete could receive incoherent value and options
|
|
@@ -66,23 +52,8 @@ function GridFilterInputMultipleSingleSelect(props) {
|
|
|
66
52
|
if (!Array.isArray(item.value)) {
|
|
67
53
|
return [];
|
|
68
54
|
}
|
|
69
|
-
if (resolvedValueOptions !== undefined) {
|
|
70
|
-
const itemValueIndexes = item.value.map(element => {
|
|
71
|
-
// Gets the index matching between values and valueOptions
|
|
72
|
-
return resolvedFormattedValueOptions == null ? void 0 : resolvedFormattedValueOptions.findIndex(formattedOption => formattedOption === element);
|
|
73
|
-
});
|
|
74
|
-
return itemValueIndexes.filter(index => index >= 0).map(index => resolvedValueOptions[index]);
|
|
75
|
-
}
|
|
76
55
|
return item.value;
|
|
77
|
-
}, [item.value
|
|
78
|
-
React.useEffect(() => {
|
|
79
|
-
if (!Array.isArray(item.value) || filteredValues.length !== item.value.length) {
|
|
80
|
-
// Updates the state if the filter value has been cleaned by the component
|
|
81
|
-
applyValue(_extends({}, item, {
|
|
82
|
-
value: filteredValues.map(getOptionValue)
|
|
83
|
-
}));
|
|
84
|
-
}
|
|
85
|
-
}, [item, filteredValues, applyValue, getOptionValue]);
|
|
56
|
+
}, [item.value]);
|
|
86
57
|
const handleChange = React.useCallback((event, value) => {
|
|
87
58
|
applyValue(_extends({}, item, {
|
|
88
59
|
value: value.map(getOptionValue)
|
|
@@ -128,18 +99,6 @@ process.env.NODE_ENV !== "production" ? GridFilterInputMultipleSingleSelect.prop
|
|
|
128
99
|
}).isRequired,
|
|
129
100
|
applyValue: PropTypes.func.isRequired,
|
|
130
101
|
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
|
|
131
|
-
/**
|
|
132
|
-
* Used to determine the label displayed for a given value option.
|
|
133
|
-
* @param {ValueOptions} value The current value option.
|
|
134
|
-
* @returns {string} The text to be displayed.
|
|
135
|
-
*/
|
|
136
|
-
getOptionLabel: PropTypes.func,
|
|
137
|
-
/**
|
|
138
|
-
* Used to determine the value used for a value option.
|
|
139
|
-
* @param {ValueOptions} value The current value option.
|
|
140
|
-
* @returns {string} The value to be used.
|
|
141
|
-
*/
|
|
142
|
-
getOptionValue: PropTypes.func,
|
|
143
102
|
item: PropTypes.shape({
|
|
144
103
|
field: PropTypes.string.isRequired,
|
|
145
104
|
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { TextFieldProps } from '@mui/material/TextField';
|
|
3
3
|
import { GridFilterInputValueProps } from './GridFilterInputValueProps';
|
|
4
|
-
|
|
5
|
-
export type GridFilterInputSingleSelectProps = GridFilterInputValueProps & TextFieldProps & Pick<GridSingleSelectColDef, 'getOptionLabel' | 'getOptionValue'> & {
|
|
4
|
+
export type GridFilterInputSingleSelectProps = GridFilterInputValueProps & TextFieldProps & {
|
|
6
5
|
clearButton?: React.ReactNode | null;
|
|
7
6
|
/**
|
|
8
7
|
* It is `true` if the filter either has a value or an operator with no value
|
|
@@ -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", "
|
|
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 =
|
|
25
|
-
field
|
|
26
|
-
})] : ['', ...(valueOptions || [])];
|
|
21
|
+
const iterableColumnValues = ['', ...(getValueOptions(column) || [])];
|
|
27
22
|
return iterableColumnValues.map(option => {
|
|
28
23
|
const value = getOptionValue(option);
|
|
29
|
-
|
|
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,
|
|
@@ -50,19 +48,17 @@ function GridFilterInputSingleSelect(props) {
|
|
|
50
48
|
type,
|
|
51
49
|
apiRef,
|
|
52
50
|
focusElementRef,
|
|
53
|
-
getOptionLabel: getOptionLabelProp,
|
|
54
|
-
getOptionValue: getOptionValueProp,
|
|
55
51
|
placeholder,
|
|
56
52
|
tabIndex,
|
|
57
53
|
label: labelProp,
|
|
58
54
|
clearButton
|
|
59
55
|
} = props,
|
|
60
56
|
others = _objectWithoutPropertiesLoose(props, _excluded);
|
|
61
|
-
const
|
|
57
|
+
const filterValue = (_item$value = item.value) != null ? _item$value : '';
|
|
62
58
|
const id = useId();
|
|
63
59
|
const labelId = useId();
|
|
64
60
|
const rootProps = useGridRootProps();
|
|
65
|
-
const isSelectNative = (_rootProps$slotProps$ = (_rootProps$slotProps = rootProps.slotProps) == null || (_rootProps$slotProps = _rootProps$slotProps.baseSelect) == null ? void 0 : _rootProps$slotProps.native) != null ? _rootProps$slotProps$ :
|
|
61
|
+
const isSelectNative = (_rootProps$slotProps$ = (_rootProps$slotProps = rootProps.slotProps) == null || (_rootProps$slotProps = _rootProps$slotProps.baseSelect) == null ? void 0 : _rootProps$slotProps.native) != null ? _rootProps$slotProps$ : false;
|
|
66
62
|
let resolvedColumn = null;
|
|
67
63
|
if (item.field) {
|
|
68
64
|
const column = apiRef.current.getColumn(item.field);
|
|
@@ -70,53 +66,27 @@ function GridFilterInputSingleSelect(props) {
|
|
|
70
66
|
resolvedColumn = column;
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
|
-
const getOptionValue =
|
|
74
|
-
const getOptionLabel =
|
|
69
|
+
const getOptionValue = (_resolvedColumn = resolvedColumn) == null ? void 0 : _resolvedColumn.getOptionValue;
|
|
70
|
+
const getOptionLabel = (_resolvedColumn2 = resolvedColumn) == null ? void 0 : _resolvedColumn2.getOptionLabel;
|
|
75
71
|
const currentValueOptions = React.useMemo(() => {
|
|
76
|
-
|
|
77
|
-
return undefined;
|
|
78
|
-
}
|
|
79
|
-
return typeof resolvedColumn.valueOptions === 'function' ? resolvedColumn.valueOptions({
|
|
80
|
-
field: resolvedColumn.field
|
|
81
|
-
}) : resolvedColumn.valueOptions;
|
|
72
|
+
return getValueOptions(resolvedColumn);
|
|
82
73
|
}, [resolvedColumn]);
|
|
83
74
|
const onFilterChange = React.useCallback(event => {
|
|
84
75
|
let value = event.target.value;
|
|
85
76
|
|
|
86
77
|
// NativeSelect casts the value to a string.
|
|
87
78
|
value = getValueFromValueOptions(value, currentValueOptions, getOptionValue);
|
|
88
|
-
setFilterValueState(String(value));
|
|
89
79
|
applyValue(_extends({}, item, {
|
|
90
80
|
value
|
|
91
81
|
}));
|
|
92
82
|
}, [currentValueOptions, getOptionValue, applyValue, item]);
|
|
93
|
-
React.useEffect(() => {
|
|
94
|
-
var _itemValue;
|
|
95
|
-
let itemValue;
|
|
96
|
-
if (currentValueOptions !== undefined) {
|
|
97
|
-
// sanitize if valueOptions are provided
|
|
98
|
-
itemValue = getValueFromValueOptions(item.value, currentValueOptions, getOptionValue);
|
|
99
|
-
if (itemValue !== item.value) {
|
|
100
|
-
applyValue(_extends({}, item, {
|
|
101
|
-
value: itemValue
|
|
102
|
-
}));
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
itemValue = item.value;
|
|
107
|
-
}
|
|
108
|
-
itemValue = (_itemValue = itemValue) != null ? _itemValue : '';
|
|
109
|
-
setFilterValueState(String(itemValue));
|
|
110
|
-
}, [item, currentValueOptions, applyValue, getOptionValue]);
|
|
111
|
-
if (!isSingleSelectColDef(resolvedColumn)) {
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
83
|
if (!isSingleSelectColDef(resolvedColumn)) {
|
|
115
84
|
return null;
|
|
116
85
|
}
|
|
117
86
|
const label = labelProp != null ? labelProp : apiRef.current.getLocaleText('filterPanelInputLabel');
|
|
118
87
|
return /*#__PURE__*/_jsxs(SingleSelectOperatorContainer, {
|
|
119
88
|
children: [/*#__PURE__*/_jsxs(rootProps.slots.baseFormControl, {
|
|
89
|
+
fullWidth: true,
|
|
120
90
|
children: [/*#__PURE__*/_jsx(rootProps.slots.baseInputLabel, _extends({}, (_rootProps$slotProps2 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps2.baseInputLabel, {
|
|
121
91
|
id: labelId,
|
|
122
92
|
htmlFor: id,
|
|
@@ -127,7 +97,7 @@ function GridFilterInputSingleSelect(props) {
|
|
|
127
97
|
id: id,
|
|
128
98
|
label: label,
|
|
129
99
|
labelId: labelId,
|
|
130
|
-
value:
|
|
100
|
+
value: filterValue,
|
|
131
101
|
onChange: onFilterChange,
|
|
132
102
|
variant: "standard",
|
|
133
103
|
type: type || 'text',
|
|
@@ -161,18 +131,6 @@ process.env.NODE_ENV !== "production" ? GridFilterInputSingleSelect.propTypes =
|
|
|
161
131
|
applyValue: PropTypes.func.isRequired,
|
|
162
132
|
clearButton: PropTypes.node,
|
|
163
133
|
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
|
|
164
|
-
/**
|
|
165
|
-
* Used to determine the label displayed for a given value option.
|
|
166
|
-
* @param {ValueOptions} value The current value option.
|
|
167
|
-
* @returns {string} The text to be displayed.
|
|
168
|
-
*/
|
|
169
|
-
getOptionLabel: PropTypes.func,
|
|
170
|
-
/**
|
|
171
|
-
* Used to determine the value used for a value option.
|
|
172
|
-
* @param {ValueOptions} value The current value option.
|
|
173
|
-
* @returns {string} The value to be used.
|
|
174
|
-
*/
|
|
175
|
-
getOptionValue: PropTypes.func,
|
|
176
134
|
/**
|
|
177
135
|
* It is `true` if the filter either has a value or an operator with no value
|
|
178
136
|
* required is selected (e.g. `isEmpty`)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { GridColDef, GridSingleSelectColDef
|
|
1
|
+
import type { GridColDef, GridSingleSelectColDef } from '../../../models/colDef/gridColDef';
|
|
2
|
+
import type { GridValueOptionsParams } from '../../../models/params/gridValueOptionsParams';
|
|
2
3
|
export declare function isSingleSelectColDef(colDef: GridColDef | null): colDef is GridSingleSelectColDef;
|
|
4
|
+
export declare function getValueOptions(column: GridSingleSelectColDef, additionalParams?: Omit<GridValueOptionsParams, 'field'>): import("../../../models/colDef/gridColDef").ValueOptions[] | undefined;
|
|
3
5
|
export declare function getValueFromValueOptions(value: string, valueOptions: any[] | undefined, getOptionValue: NonNullable<GridSingleSelectColDef['getOptionValue']>): any;
|
|
4
|
-
export declare const getLabelFromValueOption: (valueOption: ValueOptions) => string;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
1
2
|
export function isSingleSelectColDef(colDef) {
|
|
2
3
|
return (colDef == null ? void 0 : 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
|
+
}
|
|
@@ -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;
|
|
@@ -60,11 +61,10 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
60
61
|
});
|
|
61
62
|
const {
|
|
62
63
|
checkboxSelection,
|
|
63
|
-
disableMultipleRowSelection,
|
|
64
64
|
disableRowSelectionOnClick,
|
|
65
65
|
isRowSelectable: propIsRowSelectable
|
|
66
66
|
} = props;
|
|
67
|
-
const canHaveMultipleSelection =
|
|
67
|
+
const canHaveMultipleSelection = isMultipleRowSelectionEnabled(props);
|
|
68
68
|
const visibleRows = useGridVisibleRows(apiRef, props);
|
|
69
69
|
const expandMouseRowRangeSelection = React.useCallback(id => {
|
|
70
70
|
var _lastRowToggled$curre;
|
|
@@ -95,7 +95,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
95
95
|
* API METHODS
|
|
96
96
|
*/
|
|
97
97
|
const setRowSelectionModel = React.useCallback(model => {
|
|
98
|
-
if (props.signature === GridSignature.DataGrid && !
|
|
98
|
+
if (props.signature === GridSignature.DataGrid && !canHaveMultipleSelection && Array.isArray(model) && model.length > 1) {
|
|
99
99
|
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'));
|
|
100
100
|
}
|
|
101
101
|
const currentModel = gridRowSelectionStateSelector(apiRef.current.state);
|
|
@@ -106,7 +106,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
106
106
|
}));
|
|
107
107
|
apiRef.current.forceUpdate();
|
|
108
108
|
}
|
|
109
|
-
}, [apiRef, logger, props.rowSelection, props.signature,
|
|
109
|
+
}, [apiRef, logger, props.rowSelection, props.signature, canHaveMultipleSelection]);
|
|
110
110
|
const isRowSelected = React.useCallback(id => gridRowSelectionStateSelector(apiRef.current.state).includes(id), [apiRef]);
|
|
111
111
|
const isRowSelectable = React.useCallback(id => {
|
|
112
112
|
if (propIsRowSelectable && !propIsRowSelectable(apiRef.current.getRowParams(id))) {
|
|
@@ -258,12 +258,12 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
258
258
|
if (rowNode.type === 'pinnedRow') {
|
|
259
259
|
return;
|
|
260
260
|
}
|
|
261
|
-
if (event.shiftKey &&
|
|
261
|
+
if (event.shiftKey && canHaveMultipleSelection) {
|
|
262
262
|
expandMouseRowRangeSelection(params.id);
|
|
263
263
|
} else {
|
|
264
264
|
handleSingleRowSelection(params.id, event);
|
|
265
265
|
}
|
|
266
|
-
}, [disableRowSelectionOnClick, canHaveMultipleSelection,
|
|
266
|
+
}, [disableRowSelectionOnClick, canHaveMultipleSelection, apiRef, expandMouseRowRangeSelection, handleSingleRowSelection]);
|
|
267
267
|
const preventSelectionOnShift = React.useCallback((params, event) => {
|
|
268
268
|
if (canHaveMultipleSelection && event.shiftKey) {
|
|
269
269
|
var _window$getSelection;
|
|
@@ -271,12 +271,12 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
271
271
|
}
|
|
272
272
|
}, [canHaveMultipleSelection]);
|
|
273
273
|
const handleRowSelectionCheckboxChange = React.useCallback((params, event) => {
|
|
274
|
-
if (event.nativeEvent.shiftKey) {
|
|
274
|
+
if (canHaveMultipleSelection && event.nativeEvent.shiftKey) {
|
|
275
275
|
expandMouseRowRangeSelection(params.id);
|
|
276
276
|
} else {
|
|
277
|
-
apiRef.current.selectRow(params.id, params.value);
|
|
277
|
+
apiRef.current.selectRow(params.id, params.value, !canHaveMultipleSelection);
|
|
278
278
|
}
|
|
279
|
-
}, [apiRef, expandMouseRowRangeSelection]);
|
|
279
|
+
}, [apiRef, expandMouseRowRangeSelection, canHaveMultipleSelection]);
|
|
280
280
|
const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
|
|
281
281
|
const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
|
|
282
282
|
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
|
var _rootProps$experiment;
|
|
9
10
|
const apiRef = useGridPrivateApiContext();
|
|
@@ -20,6 +21,6 @@ export const useGridAriaAttributes = () => {
|
|
|
20
21
|
role,
|
|
21
22
|
'aria-colcount': visibleColumns.length,
|
|
22
23
|
'aria-rowcount': headerGroupingMaxDepth + 1 + pinnedRowsCount + totalRowCount,
|
|
23
|
-
'aria-multiselectable':
|
|
24
|
+
'aria-multiselectable': isMultipleRowSelectionEnabled(rootProps)
|
|
24
25
|
};
|
|
25
26
|
};
|
package/index.js
CHANGED