@mui/x-data-grid 6.19.5 → 6.19.8

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 (38) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/components/GridPagination.d.ts +6 -5
  3. package/components/GridPagination.js +12 -3
  4. package/components/cell/GridActionsCellItem.d.ts +8 -25
  5. package/components/cell/GridActionsCellItem.js +4 -0
  6. package/hooks/features/clipboard/useGridClipboard.js +4 -2
  7. package/hooks/features/export/serializers/csvSerializer.d.ts +2 -0
  8. package/hooks/features/export/serializers/csvSerializer.js +23 -12
  9. package/hooks/features/export/useGridCsvExport.js +3 -2
  10. package/hooks/features/rowSelection/useGridRowSelection.js +3 -2
  11. package/hooks/features/rows/useGridRows.js +8 -4
  12. package/index.js +1 -1
  13. package/legacy/components/GridPagination.js +12 -3
  14. package/legacy/components/cell/GridActionsCellItem.js +4 -0
  15. package/legacy/hooks/features/clipboard/useGridClipboard.js +4 -2
  16. package/legacy/hooks/features/export/serializers/csvSerializer.js +23 -12
  17. package/legacy/hooks/features/export/useGridCsvExport.js +3 -2
  18. package/legacy/hooks/features/rowSelection/useGridRowSelection.js +3 -2
  19. package/legacy/hooks/features/rows/useGridRows.js +8 -4
  20. package/legacy/index.js +1 -1
  21. package/models/gridExport.d.ts +6 -0
  22. package/modern/components/GridPagination.js +12 -3
  23. package/modern/components/cell/GridActionsCellItem.js +4 -0
  24. package/modern/hooks/features/clipboard/useGridClipboard.js +4 -2
  25. package/modern/hooks/features/export/serializers/csvSerializer.js +23 -12
  26. package/modern/hooks/features/export/useGridCsvExport.js +2 -1
  27. package/modern/hooks/features/rowSelection/useGridRowSelection.js +3 -2
  28. package/modern/hooks/features/rows/useGridRows.js +8 -4
  29. package/modern/index.js +1 -1
  30. package/node/components/GridPagination.js +10 -2
  31. package/node/components/cell/GridActionsCellItem.js +4 -0
  32. package/node/hooks/features/clipboard/useGridClipboard.js +4 -2
  33. package/node/hooks/features/export/serializers/csvSerializer.js +23 -12
  34. package/node/hooks/features/export/useGridCsvExport.js +2 -1
  35. package/node/hooks/features/rowSelection/useGridRowSelection.js +2 -1
  36. package/node/hooks/features/rows/useGridRows.js +8 -4
  37. package/node/index.js +1 -1
  38. package/package.json +1 -1
@@ -2,13 +2,16 @@ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
2
  import _createClass from "@babel/runtime/helpers/esm/createClass";
3
3
  import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../../colDef';
4
4
  import { buildWarning } from '../../../../utils/warning';
5
- function sanitizeCellValue(value, delimiterCharacter) {
5
+ function sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes) {
6
6
  if (typeof value === 'string') {
7
7
  // Make sure value containing delimiter or line break won't be split into multiple rows
8
8
  if ([delimiterCharacter, '\n', '\r', '"'].some(function (delimiter) {
9
9
  return value.includes(delimiter);
10
10
  })) {
11
- return "\"".concat(value.replace(/"/g, '""'), "\"");
11
+ if (shouldAppendQuotes) {
12
+ return "\"".concat(value.replace(/"/g, '""'), "\"");
13
+ }
14
+ return "".concat(value.replace(/"/g, '""'));
12
15
  }
13
16
  return value;
14
17
  }
@@ -16,7 +19,8 @@ function sanitizeCellValue(value, delimiterCharacter) {
16
19
  }
17
20
  export var serializeCellValue = function serializeCellValue(cellParams, options) {
18
21
  var delimiterCharacter = options.delimiterCharacter,
19
- ignoreValueFormatter = options.ignoreValueFormatter;
22
+ ignoreValueFormatter = options.ignoreValueFormatter,
23
+ shouldAppendQuotes = options.shouldAppendQuotes;
20
24
  var value;
21
25
  if (ignoreValueFormatter) {
22
26
  var _cellParams$value2;
@@ -34,7 +38,7 @@ export var serializeCellValue = function serializeCellValue(cellParams, options)
34
38
  } else {
35
39
  value = cellParams.formattedValue;
36
40
  }
37
- return sanitizeCellValue(value, delimiterCharacter);
41
+ return sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes);
38
42
  };
39
43
  var objectFormattedValueWarning = buildWarning(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
40
44
  var CSVRow = /*#__PURE__*/function () {
@@ -54,7 +58,7 @@ var CSVRow = /*#__PURE__*/function () {
54
58
  if (value === null || value === undefined) {
55
59
  this.rowString += '';
56
60
  } else if (typeof this.options.sanitizeCellValue === 'function') {
57
- this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
61
+ this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter, this.options.shouldAppendQuotes);
58
62
  } else {
59
63
  this.rowString += value;
60
64
  }
@@ -73,9 +77,11 @@ var serializeRow = function serializeRow(_ref) {
73
77
  columns = _ref.columns,
74
78
  getCellParams = _ref.getCellParams,
75
79
  delimiterCharacter = _ref.delimiterCharacter,
76
- ignoreValueFormatter = _ref.ignoreValueFormatter;
80
+ ignoreValueFormatter = _ref.ignoreValueFormatter,
81
+ shouldAppendQuotes = _ref.shouldAppendQuotes;
77
82
  var row = new CSVRow({
78
- delimiterCharacter: delimiterCharacter
83
+ delimiterCharacter: delimiterCharacter,
84
+ shouldAppendQuotes: shouldAppendQuotes
79
85
  });
80
86
  columns.forEach(function (column) {
81
87
  var cellParams = getCellParams(id, column.field);
@@ -86,7 +92,8 @@ var serializeRow = function serializeRow(_ref) {
86
92
  }
87
93
  row.addValue(serializeCellValue(cellParams, {
88
94
  delimiterCharacter: delimiterCharacter,
89
- ignoreValueFormatter: ignoreValueFormatter
95
+ ignoreValueFormatter: ignoreValueFormatter,
96
+ shouldAppendQuotes: shouldAppendQuotes
90
97
  }));
91
98
  });
92
99
  return row.getRowString();
@@ -98,14 +105,16 @@ export function buildCSV(options) {
98
105
  includeHeaders = options.includeHeaders,
99
106
  includeColumnGroupsHeaders = options.includeColumnGroupsHeaders,
100
107
  ignoreValueFormatter = options.ignoreValueFormatter,
101
- apiRef = options.apiRef;
108
+ apiRef = options.apiRef,
109
+ shouldAppendQuotes = options.shouldAppendQuotes;
102
110
  var CSVBody = rowIds.reduce(function (acc, id) {
103
111
  return "".concat(acc).concat(serializeRow({
104
112
  id: id,
105
113
  columns: columns,
106
114
  getCellParams: apiRef.current.getCellParams,
107
115
  delimiterCharacter: delimiterCharacter,
108
- ignoreValueFormatter: ignoreValueFormatter
116
+ ignoreValueFormatter: ignoreValueFormatter,
117
+ shouldAppendQuotes: shouldAppendQuotes
109
118
  }), "\r\n");
110
119
  }, '').trim();
111
120
  if (!includeHeaders) {
@@ -127,7 +136,8 @@ export function buildCSV(options) {
127
136
  var _loop = function _loop(i) {
128
137
  var headerGroupRow = new CSVRow({
129
138
  delimiterCharacter: delimiterCharacter,
130
- sanitizeCellValue: sanitizeCellValue
139
+ sanitizeCellValue: sanitizeCellValue,
140
+ shouldAppendQuotes: shouldAppendQuotes
131
141
  });
132
142
  headerRows.push(headerGroupRow);
133
143
  filteredColumns.forEach(function (column) {
@@ -142,7 +152,8 @@ export function buildCSV(options) {
142
152
  }
143
153
  var mainHeaderRow = new CSVRow({
144
154
  delimiterCharacter: delimiterCharacter,
145
- sanitizeCellValue: sanitizeCellValue
155
+ sanitizeCellValue: sanitizeCellValue,
156
+ shouldAppendQuotes: shouldAppendQuotes
146
157
  });
147
158
  filteredColumns.forEach(function (column) {
148
159
  mainHeaderRow.addValue(column.headerName || column.field);
@@ -21,7 +21,7 @@ export var useGridCsvExport = function useGridCsvExport(apiRef, props) {
21
21
  var ignoreValueFormatterProp = props.unstable_ignoreValueFormatterDuringExport;
22
22
  var ignoreValueFormatter = (_typeof(ignoreValueFormatterProp) === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.csvExport : ignoreValueFormatterProp) || false;
23
23
  var getDataAsCsv = React.useCallback(function () {
24
- var _options$getRowsToExp, _options$includeHeade, _options$includeColum;
24
+ var _options$getRowsToExp, _options$includeHeade, _options$includeColum, _options$shouldAppend;
25
25
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
26
26
  logger.debug("Get data as CSV");
27
27
  var exportedColumns = getColumnsToExport({
@@ -39,7 +39,8 @@ export var useGridCsvExport = function useGridCsvExport(apiRef, props) {
39
39
  includeHeaders: (_options$includeHeade = options.includeHeaders) != null ? _options$includeHeade : true,
40
40
  includeColumnGroupsHeaders: (_options$includeColum = options.includeColumnGroupsHeaders) != null ? _options$includeColum : true,
41
41
  ignoreValueFormatter: ignoreValueFormatter,
42
- apiRef: apiRef
42
+ apiRef: apiRef,
43
+ shouldAppendQuotes: (_options$shouldAppend = options.shouldAppendQuotes) != null ? _options$shouldAppend : true
43
44
  });
44
45
  }, [logger, apiRef, ignoreValueFormatter]);
45
46
  var exportDataAsCsv = React.useCallback(function (options) {
@@ -8,7 +8,7 @@ import { gridRowsLookupSelector } from '../rows/gridRowsSelector';
8
8
  import { gridRowSelectionStateSelector, selectedGridRowsSelector, selectedIdsLookupSelector } from './gridRowSelectionSelector';
9
9
  import { gridPaginatedVisibleSortedGridRowIdsSelector } from '../pagination';
10
10
  import { gridFocusCellSelector } from '../focus/gridFocusStateSelector';
11
- import { gridExpandedSortedRowIdsSelector } from '../filter/gridFilterSelector';
11
+ import { gridExpandedSortedRowIdsSelector, gridFilterModelSelector } from '../filter/gridFilterSelector';
12
12
  import { GRID_CHECKBOX_SELECTION_COL_DEF, GRID_ACTIONS_COLUMN_TYPE } from '../../../colDef';
13
13
  import { GridCellModes } from '../../../models/gridEditRowModel';
14
14
  import { isKeyboardEvent, isNavigationKey } from '../../../utils/keyboardUtils';
@@ -303,7 +303,8 @@ export var useGridRowSelection = function useGridRowSelection(apiRef, props) {
303
303
  var handleHeaderSelectionCheckboxChange = React.useCallback(function (params) {
304
304
  var shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
305
305
  var rowsToBeSelected = shouldLimitSelectionToCurrentPage ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
306
- apiRef.current.selectRows(rowsToBeSelected, params.value);
306
+ var filterModel = gridFilterModelSelector(apiRef);
307
+ apiRef.current.selectRows(rowsToBeSelected, params.value, (filterModel == null ? void 0 : filterModel.items.length) > 0);
307
308
  }, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
308
309
  var handleCellKeyDown = React.useCallback(function (params, event) {
309
310
  // Get the most recent cell mode because it may have been changed by another listener
@@ -277,15 +277,18 @@ export var useGridRows = function useGridRows(apiRef, props) {
277
277
  var dataRowIdToIdLookup = _extends({}, gridRowsDataRowIdToIdLookupSelector(apiRef));
278
278
  var rootGroup = tree[GRID_ROOT_GROUP_ID];
279
279
  var rootGroupChildren = _toConsumableArray(rootGroup.children);
280
+ var seenIds = new Set();
280
281
  for (var i = 0; i < newRows.length; i += 1) {
281
282
  var rowModel = newRows[i];
282
283
  var rowId = getRowIdFromRowModel(rowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
283
284
  var _rootGroupChildren$sp = rootGroupChildren.splice(firstRowToRender + i, 1, rowId),
284
285
  _rootGroupChildren$sp2 = _slicedToArray(_rootGroupChildren$sp, 1),
285
- replacedRowId = _rootGroupChildren$sp2[0];
286
- delete dataRowIdToModelLookup[replacedRowId];
287
- delete dataRowIdToIdLookup[replacedRowId];
288
- delete tree[replacedRowId];
286
+ removedRowId = _rootGroupChildren$sp2[0];
287
+ if (!seenIds.has(removedRowId)) {
288
+ delete dataRowIdToModelLookup[removedRowId];
289
+ delete dataRowIdToIdLookup[removedRowId];
290
+ delete tree[removedRowId];
291
+ }
289
292
  var rowTreeNodeConfig = {
290
293
  id: rowId,
291
294
  depth: 0,
@@ -296,6 +299,7 @@ export var useGridRows = function useGridRows(apiRef, props) {
296
299
  dataRowIdToModelLookup[rowId] = rowModel;
297
300
  dataRowIdToIdLookup[rowId] = rowId;
298
301
  tree[rowId] = rowTreeNodeConfig;
302
+ seenIds.add(rowId);
299
303
  }
300
304
  tree[GRID_ROOT_GROUP_ID] = _extends({}, rootGroup, {
301
305
  children: rootGroupChildren
package/legacy/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.19.5
2
+ * @mui/x-data-grid v6.19.8
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -88,6 +88,12 @@ export interface GridCsvExportOptions extends GridFileExportOptions {
88
88
  * @returns {GridRowId[]} The list of row ids to export.
89
89
  */
90
90
  getRowsToExport?: (params: GridCsvGetRowsToExportParams) => GridRowId[];
91
+ /**
92
+ * @ignore
93
+ * If `false`, the quotes will not be appended to the cell value.
94
+ * @default true
95
+ */
96
+ shouldAppendQuotes?: boolean;
91
97
  }
92
98
  /**
93
99
  * The options to apply on the Print export.
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
+ import PropTypes from 'prop-types';
3
4
  import TablePagination, { tablePaginationClasses } from '@mui/material/TablePagination';
4
5
  import { styled } from '@mui/material/styles';
5
6
  import { useGridSelector } from '../hooks/utils/useGridSelector';
@@ -27,7 +28,7 @@ const GridPaginationRoot = styled(TablePagination)(({
27
28
 
28
29
  // A mutable version of a readonly array.
29
30
 
30
- export const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(props, ref) {
31
+ const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(props, ref) {
31
32
  const apiRef = useGridApiContext();
32
33
  const rootProps = useGridRootProps();
33
34
  const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
@@ -59,7 +60,7 @@ export const GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginat
59
60
  const warnedOnceMissingInPageSizeOptions = React.useRef(false);
60
61
  const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
61
62
  if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
62
- console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\``, `Add it to show the pagination select.`].join('\n'));
63
+ console.warn([`MUI X: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\`.`, `Add it to show the pagination select.`].join('\n'));
63
64
  warnedOnceMissingInPageSizeOptions.current = true;
64
65
  }
65
66
  }
@@ -78,4 +79,12 @@ export const GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginat
78
79
  onPageChange: handlePageChange,
79
80
  onRowsPerPageChange: handlePageSizeChange
80
81
  }, apiRef.current.getLocaleText('MuiTablePagination'), props));
81
- });
82
+ });
83
+ process.env.NODE_ENV !== "production" ? GridPagination.propTypes = {
84
+ // ----------------------------- Warning --------------------------------
85
+ // | These PropTypes are generated from the TypeScript type definitions |
86
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
87
+ // ----------------------------------------------------------------------
88
+ component: PropTypes.elementType
89
+ } : void 0;
90
+ export { GridPagination };
@@ -62,6 +62,10 @@ process.env.NODE_ENV !== "production" ? GridActionsCellItem.propTypes = {
62
62
  // | These PropTypes are generated from the TypeScript type definitions |
63
63
  // | To update them edit the TypeScript types and run "yarn proptypes" |
64
64
  // ----------------------------------------------------------------------
65
+ /**
66
+ * from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component
67
+ */
68
+ component: PropTypes.elementType,
65
69
  icon: PropTypes.element,
66
70
  label: PropTypes.string.isRequired,
67
71
  showInMenu: PropTypes.bool
@@ -67,7 +67,8 @@ export const useGridClipboard = (apiRef, props) => {
67
67
  textToCopy = apiRef.current.getDataAsCsv({
68
68
  includeHeaders: false,
69
69
  // TODO: make it configurable
70
- delimiter: clipboardCopyCellDelimiter
70
+ delimiter: clipboardCopyCellDelimiter,
71
+ shouldAppendQuotes: false
71
72
  });
72
73
  } else {
73
74
  const focusedCell = gridFocusCellSelector(apiRef);
@@ -75,7 +76,8 @@ export const useGridClipboard = (apiRef, props) => {
75
76
  const cellParams = apiRef.current.getCellParams(focusedCell.id, focusedCell.field);
76
77
  textToCopy = serializeCellValue(cellParams, {
77
78
  delimiterCharacter: clipboardCopyCellDelimiter,
78
- ignoreValueFormatter
79
+ ignoreValueFormatter,
80
+ shouldAppendQuotes: false
79
81
  });
80
82
  }
81
83
  }
@@ -1,10 +1,13 @@
1
1
  import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../../colDef';
2
2
  import { buildWarning } from '../../../../utils/warning';
3
- function sanitizeCellValue(value, delimiterCharacter) {
3
+ function sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes) {
4
4
  if (typeof value === 'string') {
5
5
  // Make sure value containing delimiter or line break won't be split into multiple rows
6
6
  if ([delimiterCharacter, '\n', '\r', '"'].some(delimiter => value.includes(delimiter))) {
7
- return `"${value.replace(/"/g, '""')}"`;
7
+ if (shouldAppendQuotes) {
8
+ return `"${value.replace(/"/g, '""')}"`;
9
+ }
10
+ return `${value.replace(/"/g, '""')}`;
8
11
  }
9
12
  return value;
10
13
  }
@@ -13,7 +16,8 @@ function sanitizeCellValue(value, delimiterCharacter) {
13
16
  export const serializeCellValue = (cellParams, options) => {
14
17
  const {
15
18
  delimiterCharacter,
16
- ignoreValueFormatter
19
+ ignoreValueFormatter,
20
+ shouldAppendQuotes
17
21
  } = options;
18
22
  let value;
19
23
  if (ignoreValueFormatter) {
@@ -30,7 +34,7 @@ export const serializeCellValue = (cellParams, options) => {
30
34
  } else {
31
35
  value = cellParams.formattedValue;
32
36
  }
33
- return sanitizeCellValue(value, delimiterCharacter);
37
+ return sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes);
34
38
  };
35
39
  const objectFormattedValueWarning = buildWarning(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
36
40
  class CSVRow {
@@ -47,7 +51,7 @@ class CSVRow {
47
51
  if (value === null || value === undefined) {
48
52
  this.rowString += '';
49
53
  } else if (typeof this.options.sanitizeCellValue === 'function') {
50
- this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
54
+ this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter, this.options.shouldAppendQuotes);
51
55
  } else {
52
56
  this.rowString += value;
53
57
  }
@@ -62,10 +66,12 @@ const serializeRow = ({
62
66
  columns,
63
67
  getCellParams,
64
68
  delimiterCharacter,
65
- ignoreValueFormatter
69
+ ignoreValueFormatter,
70
+ shouldAppendQuotes
66
71
  }) => {
67
72
  const row = new CSVRow({
68
- delimiterCharacter
73
+ delimiterCharacter,
74
+ shouldAppendQuotes
69
75
  });
70
76
  columns.forEach(column => {
71
77
  const cellParams = getCellParams(id, column.field);
@@ -76,7 +82,8 @@ const serializeRow = ({
76
82
  }
77
83
  row.addValue(serializeCellValue(cellParams, {
78
84
  delimiterCharacter,
79
- ignoreValueFormatter
85
+ ignoreValueFormatter,
86
+ shouldAppendQuotes
80
87
  }));
81
88
  });
82
89
  return row.getRowString();
@@ -89,14 +96,16 @@ export function buildCSV(options) {
89
96
  includeHeaders,
90
97
  includeColumnGroupsHeaders,
91
98
  ignoreValueFormatter,
92
- apiRef
99
+ apiRef,
100
+ shouldAppendQuotes
93
101
  } = options;
94
102
  const CSVBody = rowIds.reduce((acc, id) => `${acc}${serializeRow({
95
103
  id,
96
104
  columns,
97
105
  getCellParams: apiRef.current.getCellParams,
98
106
  delimiterCharacter,
99
- ignoreValueFormatter
107
+ ignoreValueFormatter,
108
+ shouldAppendQuotes
100
109
  })}\r\n`, '').trim();
101
110
  if (!includeHeaders) {
102
111
  return CSVBody;
@@ -115,7 +124,8 @@ export function buildCSV(options) {
115
124
  for (let i = 0; i < maxColumnGroupsDepth; i += 1) {
116
125
  const headerGroupRow = new CSVRow({
117
126
  delimiterCharacter,
118
- sanitizeCellValue
127
+ sanitizeCellValue,
128
+ shouldAppendQuotes
119
129
  });
120
130
  headerRows.push(headerGroupRow);
121
131
  filteredColumns.forEach(column => {
@@ -127,7 +137,8 @@ export function buildCSV(options) {
127
137
  }
128
138
  const mainHeaderRow = new CSVRow({
129
139
  delimiterCharacter,
130
- sanitizeCellValue
140
+ sanitizeCellValue,
141
+ shouldAppendQuotes
131
142
  });
132
143
  filteredColumns.forEach(column => {
133
144
  mainHeaderRow.addValue(column.headerName || column.field);
@@ -35,7 +35,8 @@ export const useGridCsvExport = (apiRef, props) => {
35
35
  includeHeaders: options.includeHeaders ?? true,
36
36
  includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
37
37
  ignoreValueFormatter,
38
- apiRef
38
+ apiRef,
39
+ shouldAppendQuotes: options.shouldAppendQuotes ?? true
39
40
  });
40
41
  }, [logger, apiRef, ignoreValueFormatter]);
41
42
  const exportDataAsCsv = React.useCallback(options => {
@@ -7,7 +7,7 @@ import { gridRowsLookupSelector } from '../rows/gridRowsSelector';
7
7
  import { gridRowSelectionStateSelector, selectedGridRowsSelector, selectedIdsLookupSelector } from './gridRowSelectionSelector';
8
8
  import { gridPaginatedVisibleSortedGridRowIdsSelector } from '../pagination';
9
9
  import { gridFocusCellSelector } from '../focus/gridFocusStateSelector';
10
- import { gridExpandedSortedRowIdsSelector } from '../filter/gridFilterSelector';
10
+ import { gridExpandedSortedRowIdsSelector, gridFilterModelSelector } from '../filter/gridFilterSelector';
11
11
  import { GRID_CHECKBOX_SELECTION_COL_DEF, GRID_ACTIONS_COLUMN_TYPE } from '../../../colDef';
12
12
  import { GridCellModes } from '../../../models/gridEditRowModel';
13
13
  import { isKeyboardEvent, isNavigationKey } from '../../../utils/keyboardUtils';
@@ -274,7 +274,8 @@ export const useGridRowSelection = (apiRef, props) => {
274
274
  const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
275
275
  const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
276
276
  const rowsToBeSelected = shouldLimitSelectionToCurrentPage ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
277
- apiRef.current.selectRows(rowsToBeSelected, params.value);
277
+ const filterModel = gridFilterModelSelector(apiRef);
278
+ apiRef.current.selectRows(rowsToBeSelected, params.value, filterModel?.items.length > 0);
278
279
  }, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
279
280
  const handleCellKeyDown = React.useCallback((params, event) => {
280
281
  // Get the most recent cell mode because it may have been changed by another listener
@@ -260,13 +260,16 @@ export const useGridRows = (apiRef, props) => {
260
260
  const dataRowIdToIdLookup = _extends({}, gridRowsDataRowIdToIdLookupSelector(apiRef));
261
261
  const rootGroup = tree[GRID_ROOT_GROUP_ID];
262
262
  const rootGroupChildren = [...rootGroup.children];
263
+ const seenIds = new Set();
263
264
  for (let i = 0; i < newRows.length; i += 1) {
264
265
  const rowModel = newRows[i];
265
266
  const rowId = getRowIdFromRowModel(rowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
266
- const [replacedRowId] = rootGroupChildren.splice(firstRowToRender + i, 1, rowId);
267
- delete dataRowIdToModelLookup[replacedRowId];
268
- delete dataRowIdToIdLookup[replacedRowId];
269
- delete tree[replacedRowId];
267
+ const [removedRowId] = rootGroupChildren.splice(firstRowToRender + i, 1, rowId);
268
+ if (!seenIds.has(removedRowId)) {
269
+ delete dataRowIdToModelLookup[removedRowId];
270
+ delete dataRowIdToIdLookup[removedRowId];
271
+ delete tree[removedRowId];
272
+ }
270
273
  const rowTreeNodeConfig = {
271
274
  id: rowId,
272
275
  depth: 0,
@@ -277,6 +280,7 @@ export const useGridRows = (apiRef, props) => {
277
280
  dataRowIdToModelLookup[rowId] = rowModel;
278
281
  dataRowIdToIdLookup[rowId] = rowId;
279
282
  tree[rowId] = rowTreeNodeConfig;
283
+ seenIds.add(rowId);
280
284
  }
281
285
  tree[GRID_ROOT_GROUP_ID] = _extends({}, rootGroup, {
282
286
  children: rootGroupChildren
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.19.5
2
+ * @mui/x-data-grid v6.19.8
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.GridPagination = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var React = _interopRequireWildcard(require("react"));
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
11
  var _TablePagination = _interopRequireWildcard(require("@mui/material/TablePagination"));
11
12
  var _styles = require("@mui/material/styles");
12
13
  var _useGridSelector = require("../hooks/utils/useGridSelector");
@@ -68,7 +69,7 @@ const GridPagination = exports.GridPagination = /*#__PURE__*/React.forwardRef(fu
68
69
  const warnedOnceMissingInPageSizeOptions = React.useRef(false);
69
70
  const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
70
71
  if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
71
- console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\``, `Add it to show the pagination select.`].join('\n'));
72
+ console.warn([`MUI X: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\`.`, `Add it to show the pagination select.`].join('\n'));
72
73
  warnedOnceMissingInPageSizeOptions.current = true;
73
74
  }
74
75
  }
@@ -87,4 +88,11 @@ const GridPagination = exports.GridPagination = /*#__PURE__*/React.forwardRef(fu
87
88
  onPageChange: handlePageChange,
88
89
  onRowsPerPageChange: handlePageSizeChange
89
90
  }, apiRef.current.getLocaleText('MuiTablePagination'), props));
90
- });
91
+ });
92
+ process.env.NODE_ENV !== "production" ? GridPagination.propTypes = {
93
+ // ----------------------------- Warning --------------------------------
94
+ // | These PropTypes are generated from the TypeScript type definitions |
95
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
96
+ // ----------------------------------------------------------------------
97
+ component: _propTypes.default.elementType
98
+ } : void 0;
@@ -70,6 +70,10 @@ process.env.NODE_ENV !== "production" ? GridActionsCellItem.propTypes = {
70
70
  // | These PropTypes are generated from the TypeScript type definitions |
71
71
  // | To update them edit the TypeScript types and run "yarn proptypes" |
72
72
  // ----------------------------------------------------------------------
73
+ /**
74
+ * from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component
75
+ */
76
+ component: _propTypes.default.elementType,
73
77
  icon: _propTypes.default.element,
74
78
  label: _propTypes.default.string.isRequired,
75
79
  showInMenu: _propTypes.default.bool
@@ -75,7 +75,8 @@ const useGridClipboard = (apiRef, props) => {
75
75
  textToCopy = apiRef.current.getDataAsCsv({
76
76
  includeHeaders: false,
77
77
  // TODO: make it configurable
78
- delimiter: clipboardCopyCellDelimiter
78
+ delimiter: clipboardCopyCellDelimiter,
79
+ shouldAppendQuotes: false
79
80
  });
80
81
  } else {
81
82
  const focusedCell = (0, _gridFocusStateSelector.gridFocusCellSelector)(apiRef);
@@ -83,7 +84,8 @@ const useGridClipboard = (apiRef, props) => {
83
84
  const cellParams = apiRef.current.getCellParams(focusedCell.id, focusedCell.field);
84
85
  textToCopy = (0, _csvSerializer.serializeCellValue)(cellParams, {
85
86
  delimiterCharacter: clipboardCopyCellDelimiter,
86
- ignoreValueFormatter
87
+ ignoreValueFormatter,
88
+ shouldAppendQuotes: false
87
89
  });
88
90
  }
89
91
  }
@@ -7,11 +7,14 @@ exports.buildCSV = buildCSV;
7
7
  exports.serializeCellValue = void 0;
8
8
  var _colDef = require("../../../../colDef");
9
9
  var _warning = require("../../../../utils/warning");
10
- function sanitizeCellValue(value, delimiterCharacter) {
10
+ function sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes) {
11
11
  if (typeof value === 'string') {
12
12
  // Make sure value containing delimiter or line break won't be split into multiple rows
13
13
  if ([delimiterCharacter, '\n', '\r', '"'].some(delimiter => value.includes(delimiter))) {
14
- return `"${value.replace(/"/g, '""')}"`;
14
+ if (shouldAppendQuotes) {
15
+ return `"${value.replace(/"/g, '""')}"`;
16
+ }
17
+ return `${value.replace(/"/g, '""')}`;
15
18
  }
16
19
  return value;
17
20
  }
@@ -20,7 +23,8 @@ function sanitizeCellValue(value, delimiterCharacter) {
20
23
  const serializeCellValue = (cellParams, options) => {
21
24
  const {
22
25
  delimiterCharacter,
23
- ignoreValueFormatter
26
+ ignoreValueFormatter,
27
+ shouldAppendQuotes
24
28
  } = options;
25
29
  let value;
26
30
  if (ignoreValueFormatter) {
@@ -37,7 +41,7 @@ const serializeCellValue = (cellParams, options) => {
37
41
  } else {
38
42
  value = cellParams.formattedValue;
39
43
  }
40
- return sanitizeCellValue(value, delimiterCharacter);
44
+ return sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes);
41
45
  };
42
46
  exports.serializeCellValue = serializeCellValue;
43
47
  const objectFormattedValueWarning = (0, _warning.buildWarning)(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
@@ -55,7 +59,7 @@ class CSVRow {
55
59
  if (value === null || value === undefined) {
56
60
  this.rowString += '';
57
61
  } else if (typeof this.options.sanitizeCellValue === 'function') {
58
- this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
62
+ this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter, this.options.shouldAppendQuotes);
59
63
  } else {
60
64
  this.rowString += value;
61
65
  }
@@ -70,10 +74,12 @@ const serializeRow = ({
70
74
  columns,
71
75
  getCellParams,
72
76
  delimiterCharacter,
73
- ignoreValueFormatter
77
+ ignoreValueFormatter,
78
+ shouldAppendQuotes
74
79
  }) => {
75
80
  const row = new CSVRow({
76
- delimiterCharacter
81
+ delimiterCharacter,
82
+ shouldAppendQuotes
77
83
  });
78
84
  columns.forEach(column => {
79
85
  const cellParams = getCellParams(id, column.field);
@@ -84,7 +90,8 @@ const serializeRow = ({
84
90
  }
85
91
  row.addValue(serializeCellValue(cellParams, {
86
92
  delimiterCharacter,
87
- ignoreValueFormatter
93
+ ignoreValueFormatter,
94
+ shouldAppendQuotes
88
95
  }));
89
96
  });
90
97
  return row.getRowString();
@@ -97,14 +104,16 @@ function buildCSV(options) {
97
104
  includeHeaders,
98
105
  includeColumnGroupsHeaders,
99
106
  ignoreValueFormatter,
100
- apiRef
107
+ apiRef,
108
+ shouldAppendQuotes
101
109
  } = options;
102
110
  const CSVBody = rowIds.reduce((acc, id) => `${acc}${serializeRow({
103
111
  id,
104
112
  columns,
105
113
  getCellParams: apiRef.current.getCellParams,
106
114
  delimiterCharacter,
107
- ignoreValueFormatter
115
+ ignoreValueFormatter,
116
+ shouldAppendQuotes
108
117
  })}\r\n`, '').trim();
109
118
  if (!includeHeaders) {
110
119
  return CSVBody;
@@ -123,7 +132,8 @@ function buildCSV(options) {
123
132
  for (let i = 0; i < maxColumnGroupsDepth; i += 1) {
124
133
  const headerGroupRow = new CSVRow({
125
134
  delimiterCharacter,
126
- sanitizeCellValue
135
+ sanitizeCellValue,
136
+ shouldAppendQuotes
127
137
  });
128
138
  headerRows.push(headerGroupRow);
129
139
  filteredColumns.forEach(column => {
@@ -135,7 +145,8 @@ function buildCSV(options) {
135
145
  }
136
146
  const mainHeaderRow = new CSVRow({
137
147
  delimiterCharacter,
138
- sanitizeCellValue
148
+ sanitizeCellValue,
149
+ shouldAppendQuotes
139
150
  });
140
151
  filteredColumns.forEach(column => {
141
152
  mainHeaderRow.addValue(column.headerName || column.field);
@@ -43,7 +43,8 @@ const useGridCsvExport = (apiRef, props) => {
43
43
  includeHeaders: options.includeHeaders ?? true,
44
44
  includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
45
45
  ignoreValueFormatter,
46
- apiRef
46
+ apiRef,
47
+ shouldAppendQuotes: options.shouldAppendQuotes ?? true
47
48
  });
48
49
  }, [logger, apiRef, ignoreValueFormatter]);
49
50
  const exportDataAsCsv = React.useCallback(options => {
@@ -284,7 +284,8 @@ const useGridRowSelection = (apiRef, props) => {
284
284
  const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
285
285
  const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
286
286
  const rowsToBeSelected = shouldLimitSelectionToCurrentPage ? (0, _pagination.gridPaginatedVisibleSortedGridRowIdsSelector)(apiRef) : (0, _gridFilterSelector.gridExpandedSortedRowIdsSelector)(apiRef);
287
- apiRef.current.selectRows(rowsToBeSelected, params.value);
287
+ const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
288
+ apiRef.current.selectRows(rowsToBeSelected, params.value, filterModel?.items.length > 0);
288
289
  }, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
289
290
  const handleCellKeyDown = React.useCallback((params, event) => {
290
291
  // Get the most recent cell mode because it may have been changed by another listener