@carbon/ibm-products 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. package/css/index-full-carbon.css +76 -30
  2. package/css/index-full-carbon.css.map +1 -1
  3. package/css/index-full-carbon.min.css +3 -3
  4. package/css/index-full-carbon.min.css.map +1 -1
  5. package/css/index-without-carbon-released-only.css +10 -4
  6. package/css/index-without-carbon-released-only.css.map +1 -1
  7. package/css/index-without-carbon-released-only.min.css +1 -1
  8. package/css/index-without-carbon-released-only.min.css.map +1 -1
  9. package/css/index-without-carbon.css +76 -30
  10. package/css/index-without-carbon.css.map +1 -1
  11. package/css/index-without-carbon.min.css +3 -3
  12. package/css/index-without-carbon.min.css.map +1 -1
  13. package/css/index.css +76 -30
  14. package/css/index.css.map +1 -1
  15. package/css/index.min.css +3 -3
  16. package/css/index.min.css.map +1 -1
  17. package/es/components/AddSelect/AddSelect.js +88 -87
  18. package/es/components/AddSelect/AddSelectColumn.js +143 -6
  19. package/es/components/AddSelect/AddSelectSidebar.js +1 -14
  20. package/es/components/AddSelect/add-select-utils.js +64 -0
  21. package/es/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +2 -1
  22. package/es/components/DataSpreadsheet/DataSpreadsheet.js +255 -140
  23. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +37 -38
  24. package/es/components/DataSpreadsheet/DataSpreadsheetHeader.js +55 -6
  25. package/es/components/DataSpreadsheet/hooks/useMoveActiveCell.js +27 -0
  26. package/es/components/DataSpreadsheet/hooks/useResetSpreadsheetFocus.js +28 -0
  27. package/es/components/DataSpreadsheet/hooks/useSpreadsheetOutsideClick.js +41 -0
  28. package/es/components/DataSpreadsheet/{checkActiveHeaderCell.js → utils/checkActiveHeaderCell.js} +1 -1
  29. package/es/components/DataSpreadsheet/{createActiveCellFn.js → utils/createActiveCellFn.js} +20 -9
  30. package/es/components/DataSpreadsheet/{createCellSelectionArea.js → utils/createCellSelectionArea.js} +8 -4
  31. package/es/components/DataSpreadsheet/{generateData.js → utils/generateData.js} +6 -0
  32. package/es/components/DataSpreadsheet/{getCellSize.js → utils/getCellSize.js} +0 -0
  33. package/es/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +46 -0
  34. package/es/components/DataSpreadsheet/utils/handleMultipleKeys.js +82 -0
  35. package/es/components/DataSpreadsheet/utils/removeCellSelections.js +30 -0
  36. package/es/components/InlineEdit/InlineEdit.js +49 -8
  37. package/es/components/OptionsTile/OptionsTile.js +20 -20
  38. package/es/components/OptionsTile/index.js +1 -1
  39. package/es/components/PageHeader/PageHeader.js +35 -32
  40. package/es/components/PageHeader/PageHeaderTitle.js +2 -1
  41. package/es/components/PageHeader/PageHeaderUtils.js +21 -22
  42. package/lib/components/AddSelect/AddSelect.js +91 -87
  43. package/lib/components/AddSelect/AddSelectColumn.js +144 -4
  44. package/lib/components/AddSelect/AddSelectSidebar.js +7 -14
  45. package/lib/components/AddSelect/add-select-utils.js +78 -0
  46. package/lib/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +2 -1
  47. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +263 -142
  48. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +39 -36
  49. package/lib/components/DataSpreadsheet/DataSpreadsheetHeader.js +62 -8
  50. package/lib/components/DataSpreadsheet/hooks/useMoveActiveCell.js +37 -0
  51. package/lib/components/DataSpreadsheet/hooks/useResetSpreadsheetFocus.js +39 -0
  52. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetOutsideClick.js +52 -0
  53. package/lib/components/DataSpreadsheet/{checkActiveHeaderCell.js → utils/checkActiveHeaderCell.js} +1 -1
  54. package/lib/components/DataSpreadsheet/{createActiveCellFn.js → utils/createActiveCellFn.js} +20 -9
  55. package/lib/components/DataSpreadsheet/{createCellSelectionArea.js → utils/createCellSelectionArea.js} +8 -4
  56. package/lib/components/DataSpreadsheet/{generateData.js → utils/generateData.js} +6 -0
  57. package/lib/components/DataSpreadsheet/{getCellSize.js → utils/getCellSize.js} +0 -0
  58. package/lib/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +59 -0
  59. package/lib/components/DataSpreadsheet/utils/handleMultipleKeys.js +92 -0
  60. package/lib/components/DataSpreadsheet/utils/removeCellSelections.js +41 -0
  61. package/lib/components/InlineEdit/InlineEdit.js +52 -10
  62. package/lib/components/OptionsTile/OptionsTile.js +19 -19
  63. package/lib/components/PageHeader/PageHeader.js +35 -32
  64. package/lib/components/PageHeader/PageHeaderTitle.js +2 -1
  65. package/lib/components/PageHeader/PageHeaderUtils.js +21 -22
  66. package/package.json +2 -2
  67. package/scss/components/AddSelect/_add-select.scss +16 -0
  68. package/scss/components/BreadcrumbWithOverflow/_breadcrumb-with-overflow.scss +7 -3
  69. package/scss/components/CreateSidePanel/_create-side-panel.scss +1 -1
  70. package/scss/components/CreateSidePanel/_storybook-styles.scss +1 -1
  71. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +14 -1
  72. package/scss/components/EditSidePanel/_edit-side-panel.scss +9 -0
  73. package/scss/components/EditSidePanel/_storybook-styles.scss +1 -1
  74. package/scss/components/InlineEdit/_inline-edit.scss +31 -37
  75. package/scss/components/OptionsTile/_index.scss +1 -1
  76. package/scss/components/OptionsTile/_options-tile.scss +17 -17
  77. package/scss/components/OptionsTile/_storybook-styles.scss +4 -4
  78. package/scss/components/PageHeader/_page-header.scss +3 -2
  79. package/scss/components/SidePanel/_side-panel.scss +8 -8
@@ -13,10 +13,10 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
13
13
 
14
14
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
15
15
 
16
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
17
-
18
16
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
19
17
 
18
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
+
20
20
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
21
21
 
22
22
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
@@ -29,27 +29,39 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
29
29
 
30
30
  var _classnames = _interopRequireDefault(require("classnames"));
31
31
 
32
- var _devtools = require("../../global/js/utils/devtools");
32
+ var _carbonComponentsReact = require("carbon-components-react");
33
33
 
34
34
  var _settings = require("../../settings");
35
35
 
36
- var _getScrollbarWidth = require("../../global/js/utils/getScrollbarWidth");
37
-
38
36
  var _DataSpreadsheetBody = require("./DataSpreadsheetBody");
39
37
 
40
- var _getCellSize = require("./getCellSize");
41
-
42
38
  var _DataSpreadsheetHeader = require("./DataSpreadsheetHeader");
43
39
 
44
- var _hooks = require("../../global/js/hooks");
40
+ var _devtools = require("../../global/js/utils/devtools");
41
+
42
+ var _getScrollbarWidth = require("../../global/js/utils/getScrollbarWidth");
45
43
 
46
- var _createActiveCellFn = require("./createActiveCellFn");
44
+ var _hooks = require("../../global/js/hooks");
47
45
 
48
46
  var _deepCloneObject = require("../../global/js/utils/deepCloneObject");
49
47
 
50
48
  var _uuidv = _interopRequireDefault(require("../../global/js/utils/uuidv4"));
51
49
 
52
- var _excluded = ["cellSize", "className", "columns", "data", "id", "onActiveCellChange"];
50
+ var _useResetSpreadsheetFocus = require("./hooks/useResetSpreadsheetFocus");
51
+
52
+ var _useSpreadsheetOutsideClick = require("./hooks/useSpreadsheetOutsideClick");
53
+
54
+ var _useMoveActiveCell = require("./hooks/useMoveActiveCell");
55
+
56
+ var _createActiveCellFn = require("./utils/createActiveCellFn");
57
+
58
+ var _getCellSize = require("./utils/getCellSize");
59
+
60
+ var _handleMultipleKeys = require("./utils/handleMultipleKeys");
61
+
62
+ var _handleHeaderCellSelection = require("./utils/handleHeaderCellSelection");
63
+
64
+ var _excluded = ["cellSize", "className", "columns", "data", "onDataUpdate", "id", "onActiveCellChange"];
53
65
 
54
66
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
55
67
 
@@ -67,7 +79,8 @@ var componentName = 'DataSpreadsheet'; // Default values for props
67
79
  var defaults = {
68
80
  cellSize: 'standard',
69
81
  columns: Object.freeze([]),
70
- data: Object.freeze([])
82
+ data: Object.freeze([]),
83
+ onDataUpdate: Object.freeze(function () {})
71
84
  };
72
85
  /**
73
86
  * DataSpreadsheet: used to organize and display large amounts of structured data, separated by columns and rows in a grid-like format.
@@ -81,9 +94,13 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
81
94
  columns = _ref$columns === void 0 ? defaults.columns : _ref$columns,
82
95
  _ref$data = _ref.data,
83
96
  data = _ref$data === void 0 ? defaults.data : _ref$data,
97
+ _ref$onDataUpdate = _ref.onDataUpdate,
98
+ onDataUpdate = _ref$onDataUpdate === void 0 ? defaults.onDataUpdate : _ref$onDataUpdate,
84
99
  id = _ref.id,
85
100
  onActiveCellChange = _ref.onActiveCellChange,
86
101
  rest = (0, _objectWithoutProperties2.default)(_ref, _excluded);
102
+ var localRef = (0, _react.useRef)();
103
+ var spreadsheetRef = ref || localRef;
87
104
  var focusedElement = (0, _hooks.useActiveElement)();
88
105
 
89
106
  var _useState = (0, _react.useState)(false),
@@ -111,12 +128,24 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
111
128
  currentMatcher = _useState10[0],
112
129
  setCurrentMatcher = _useState10[1];
113
130
 
131
+ var _useState11 = (0, _react.useState)(false),
132
+ _useState12 = (0, _slicedToArray2.default)(_useState11, 2),
133
+ isEditing = _useState12[0],
134
+ setIsEditing = _useState12[1];
135
+
136
+ var _useState13 = (0, _react.useState)(''),
137
+ _useState14 = (0, _slicedToArray2.default)(_useState13, 2),
138
+ cellEditorValue = _useState14[0],
139
+ setCellEditorValue = _useState14[1];
140
+
114
141
  var previousState = (0, _hooks.usePreviousValue)({
115
142
  activeCellCoordinates: activeCellCoordinates
116
143
  });
117
144
  var cellSizeValue = (0, _getCellSize.getCellSize)(cellSize);
145
+ var cellEditorRef = (0, _react.useRef)();
118
146
  var currentMatcherRef = (0, _react.useRef)();
119
147
  var activeKeys = (0, _react.useRef)([]);
148
+ var activeCellRef = (0, _react.useRef)();
120
149
  var defaultColumn = (0, _react.useMemo)(function () {
121
150
  return {
122
151
  width: 150,
@@ -138,28 +167,33 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
138
167
  headerGroups = _useTable.headerGroups,
139
168
  rows = _useTable.rows,
140
169
  totalColumnsWidth = _useTable.totalColumnsWidth,
141
- prepareRow = _useTable.prepareRow; // Reset everything when spreadsheet loses focus
170
+ prepareRow = _useTable.prepareRow; // Update the spreadsheet data after editing a cell
142
171
 
143
172
 
144
- (0, _react.useEffect)(function () {
145
- if (!focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
146
- setContainerHasFocus(false);
147
- removeActiveCell();
148
- activeKeys.current = [];
149
- }
173
+ var updateData = (0, _react.useCallback)(function (rowIndex, columnId) {
174
+ onDataUpdate(function (prev) {
175
+ return prev.map(function (row, index) {
176
+ if (index === rowIndex) {
177
+ return _objectSpread(_objectSpread({}, prev[rowIndex]), {}, (0, _defineProperty2.default)({}, columnId, cellEditorValue));
178
+ }
150
179
 
151
- if (focusedElement.classList.contains(blockClass) || focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
152
- setContainerHasFocus(true);
153
- }
154
- }, [focusedElement, removeActiveCell]); // Removes the active cell element
180
+ return row;
181
+ });
182
+ });
183
+ }, [cellEditorValue, onDataUpdate]); // Removes the active cell element
155
184
 
156
185
  var removeActiveCell = (0, _react.useCallback)(function () {
157
186
  var activeCellHighlight = spreadsheetRef.current.querySelector(".".concat(blockClass, "__active-cell--highlight"));
158
187
 
159
188
  if (activeCellHighlight) {
160
- activeCellHighlight.remove();
189
+ activeCellHighlight.style.display = 'none';
161
190
  }
162
- }, [spreadsheetRef]); // Removes the cell selection elements
191
+ }, [spreadsheetRef]);
192
+ var removeCellEditor = (0, _react.useCallback)(function () {
193
+ setCellEditorValue('');
194
+ setIsEditing(false);
195
+ cellEditorRef.current.style.display = 'none';
196
+ }, []); // Removes the cell selection elements
163
197
 
164
198
  var removeCellSelections = (0, _react.useCallback)(function (matcher) {
165
199
  if (matcher && typeof matcher === 'string') {
@@ -174,27 +208,21 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
174
208
  return element.remove();
175
209
  });
176
210
  }
177
- }, [spreadsheetRef]); // Click outside useEffect
211
+ }, [spreadsheetRef]); // Remove cell editor if the active cell coordinates change and save with new cell data, this will
212
+ // happen if you click on another cell while isEditing is true
178
213
 
179
214
  (0, _react.useEffect)(function () {
180
- var handleOutsideClick = function handleOutsideClick(event) {
181
- if (!spreadsheetRef.current || spreadsheetRef.current.contains(event.target) || event.target.classList.contains("".concat(blockClass, "__active-cell--highlight"))) {
182
- return;
183
- }
184
-
185
- setActiveCellCoordinates(null);
186
- setSelectionAreas([]);
187
- removeActiveCell();
188
- removeCellSelections();
189
- setContainerHasFocus(false);
190
- activeKeys.current = [];
191
- };
215
+ var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates;
192
216
 
193
- document.addEventListener('click', handleOutsideClick);
194
- return function () {
195
- document.removeEventListener('click', handleOutsideClick);
196
- };
197
- }, [spreadsheetRef, removeActiveCell, removeCellSelections]);
217
+ if (((prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row) !== (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) || (prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column) !== (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column)) && isEditing) {
218
+ var cellProps = rows[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row].cells[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column];
219
+ removeCellEditor();
220
+ updateData(prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row, cellProps.column.id);
221
+ }
222
+ }, [activeCellCoordinates, previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates, updateData, rows, isEditing, removeCellEditor]);
223
+ var handleActiveCellMouseEnter = (0, _react.useCallback)(function () {
224
+ handleActiveCellMouseEnterCallback(selectionAreas, clickAndHoldActive);
225
+ }, [clickAndHoldActive, selectionAreas, handleActiveCellMouseEnterCallback]);
198
226
  var createActiveCell = (0, _react.useCallback)(function (_ref2) {
199
227
  var placementElement = _ref2.placementElement,
200
228
  coords = _ref2.coords,
@@ -202,11 +230,6 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
202
230
  addToHeader = _ref2$addToHeader === void 0 ? false : _ref2$addToHeader;
203
231
  var activeCellFullData = typeof (coords === null || coords === void 0 ? void 0 : coords.column) === 'number' && typeof (coords === null || coords === void 0 ? void 0 : coords.row) === 'number' ? rows[coords === null || coords === void 0 ? void 0 : coords.row].cells[coords === null || coords === void 0 ? void 0 : coords.column] : null;
204
232
  var activeCellValue = activeCellFullData ? Object.values(activeCellFullData.row.values)[coords === null || coords === void 0 ? void 0 : coords.column] : null;
205
-
206
- var handleActiveCellMouseEnter = function handleActiveCellMouseEnter() {
207
- handleActiveCellMouseEnterCallback(selectionAreas, clickAndHoldActive);
208
- };
209
-
210
233
  var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates; // Only create an active cell if the activeCellCoordinates have changed
211
234
 
212
235
  if ((prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row) !== (coords === null || coords === void 0 ? void 0 : coords.row) || (prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column) !== (coords === null || coords === void 0 ? void 0 : coords.column)) {
@@ -218,10 +241,34 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
218
241
  blockClass: blockClass,
219
242
  onActiveCellChange: onActiveCellChange,
220
243
  activeCellValue: activeCellValue,
221
- handleActiveCellMouseEnter: handleActiveCellMouseEnter
244
+ activeCellRef: activeCellRef,
245
+ cellEditorRef: cellEditorRef,
246
+ defaultColumn: defaultColumn
222
247
  });
223
248
  }
224
- }, [spreadsheetRef, rows, onActiveCellChange, clickAndHoldActive, handleActiveCellMouseEnterCallback, selectionAreas, previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates]);
249
+ }, [spreadsheetRef, rows, onActiveCellChange, previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates, defaultColumn]);
250
+ (0, _useResetSpreadsheetFocus.useResetSpreadsheetFocus)({
251
+ activeKeys: activeKeys,
252
+ focusedElement: focusedElement,
253
+ removeActiveCell: removeActiveCell,
254
+ setContainerHasFocus: setContainerHasFocus
255
+ });
256
+ (0, _useSpreadsheetOutsideClick.useSpreadsheetOutsideClick)({
257
+ spreadsheetRef: spreadsheetRef,
258
+ setActiveCellCoordinates: setActiveCellCoordinates,
259
+ setSelectionAreas: setSelectionAreas,
260
+ removeActiveCell: removeActiveCell,
261
+ removeCellSelections: removeCellSelections,
262
+ setContainerHasFocus: setContainerHasFocus,
263
+ activeKeys: activeKeys,
264
+ removeCellEditor: removeCellEditor
265
+ });
266
+ (0, _useMoveActiveCell.useMoveActiveCell)({
267
+ spreadsheetRef: spreadsheetRef,
268
+ activeCellCoordinates: activeCellCoordinates,
269
+ containerHasFocus: containerHasFocus,
270
+ createActiveCell: createActiveCell
271
+ });
225
272
  var handleInitialArrowPress = (0, _react.useCallback)(function () {
226
273
  // If activeCellCoordinates is null then we need to set an initial value
227
274
  // which will place the activeCell on the select all cell/button
@@ -253,75 +300,6 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
253
300
  setCurrentMatcher(tempMatcher);
254
301
  }
255
302
  }, []);
256
- var handleMultipleKeys = (0, _react.useCallback)(function () {
257
- var _selectionAreasClone$;
258
-
259
- var activeKeyValues = activeKeys.current;
260
- var selectionAreasClone = (0, _deepCloneObject.deepCloneObject)(selectionAreas);
261
- var indexOfCurrentArea = selectionAreasClone.findIndex(function (item) {
262
- return item.matcher === currentMatcher;
263
- });
264
- var pointToUpdate = (_selectionAreasClone$ = selectionAreasClone[indexOfCurrentArea]) !== null && _selectionAreasClone$ !== void 0 && _selectionAreasClone$.point2 ? selectionAreasClone[indexOfCurrentArea].point2 : selectionAreasClone[indexOfCurrentArea].point1; // Down + Shift
265
-
266
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowDown')) {
267
- if (rows.length - 1 === pointToUpdate.row) {
268
- return;
269
- }
270
-
271
- var newPoint = {
272
- row: pointToUpdate.row + 1,
273
- column: pointToUpdate.column
274
- };
275
- selectionAreasClone[indexOfCurrentArea].point2 = newPoint;
276
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
277
- setSelectionAreas(selectionAreasClone);
278
- } // Right + Shift
279
-
280
-
281
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowRight')) {
282
- if (columns.length - 1 === pointToUpdate.column) {
283
- return;
284
- }
285
-
286
- var _newPoint = {
287
- row: pointToUpdate.row,
288
- column: pointToUpdate.column + 1
289
- };
290
- selectionAreasClone[indexOfCurrentArea].point2 = _newPoint;
291
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
292
- setSelectionAreas(selectionAreasClone);
293
- } // Up + Shift
294
-
295
-
296
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowUp')) {
297
- if (pointToUpdate.row === 0) {
298
- return;
299
- }
300
-
301
- var _newPoint2 = {
302
- row: pointToUpdate.row - 1,
303
- column: pointToUpdate.column
304
- };
305
- selectionAreasClone[indexOfCurrentArea].point2 = _newPoint2;
306
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
307
- setSelectionAreas(selectionAreasClone);
308
- } // Left + Shift
309
-
310
-
311
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowLeft')) {
312
- if (pointToUpdate.column === 0) {
313
- return;
314
- }
315
-
316
- var _newPoint3 = {
317
- row: pointToUpdate.row,
318
- column: pointToUpdate.column - 1
319
- };
320
- selectionAreasClone[indexOfCurrentArea].point2 = _newPoint3;
321
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
322
- setSelectionAreas(selectionAreasClone);
323
- }
324
- }, [selectionAreas, currentMatcher, columns, rows]);
325
303
  var handleKeyPress = (0, _react.useCallback)(function (event) {
326
304
  var _activeKeys$current, _activeKeys$current2;
327
305
 
@@ -332,15 +310,25 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
332
310
  } // Prevent arrow keys, home key, and end key from scrolling the page when the data spreadsheet container has focus
333
311
 
334
312
 
335
- if (['End', 'Home', 'ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1) {
313
+ if (['End', 'Home', 'ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1 && !isEditing) {
336
314
  event.preventDefault();
315
+ }
316
+
317
+ if (['Tab'].indexOf(key) > -1 && isEditing) {
318
+ return;
337
319
  } // Clear out all cell selection areas if user uses any arrow key, except if the shift key is being held
338
320
 
339
321
 
340
322
  if (['ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1) {
323
+ if (isEditing) {
324
+ return;
325
+ }
326
+
341
327
  if (selectionAreas !== null && selectionAreas !== void 0 && selectionAreas.length && key !== 'Shift' && !activeKeys.current.includes('Shift')) {
342
328
  setSelectionAreas([]);
343
- removeCellSelections();
329
+ removeCellSelections({
330
+ spreadsheetRef: spreadsheetRef
331
+ });
344
332
  }
345
333
  } // Update list of activeKeys
346
334
 
@@ -351,7 +339,14 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
351
339
  }
352
340
 
353
341
  if (((_activeKeys$current2 = activeKeys.current) === null || _activeKeys$current2 === void 0 ? void 0 : _activeKeys$current2.length) > 1) {
354
- handleMultipleKeys();
342
+ (0, _handleMultipleKeys.handleMultipleKeys)({
343
+ activeKeys: activeKeys,
344
+ selectionAreas: selectionAreas,
345
+ currentMatcher: currentMatcher,
346
+ rows: rows,
347
+ setSelectionAreas: setSelectionAreas,
348
+ columns: columns
349
+ });
355
350
  } // Allow arrow key navigation if there are less than two activeKeys OR
356
351
  // if one of the activeCellCoordinates is in a header position
357
352
 
@@ -363,6 +358,7 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
363
358
  {
364
359
  setSelectionAreas([]);
365
360
  removeActiveCell();
361
+ removeCellEditor();
366
362
  setContainerHasFocus(false);
367
363
  setActiveCellCoordinates(null);
368
364
  break;
@@ -506,11 +502,96 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
506
502
  }
507
503
  }
508
504
  }
509
- }, [updateActiveCellCoordinates, handleInitialArrowPress, handleMultipleKeys, activeCellCoordinates, selectionAreas === null || selectionAreas === void 0 ? void 0 : selectionAreas.length, removeCellSelections, removeActiveCell, columns.length, rows.length]); // Only update if there are cell selection areas
505
+ }, [updateActiveCellCoordinates, handleInitialArrowPress, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, isEditing, removeCellEditor, removeCellSelections, selectionAreas]);
506
+
507
+ var startEditMode = function startEditMode() {
508
+ setIsEditing(true);
509
+ var activeCellFullData = typeof (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'number' && typeof (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'number' ? rows[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row].cells[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column] : null;
510
+ var activeCellValue = activeCellFullData ? Object.values(activeCellFullData.row.values)[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column] : null;
511
+ setCellEditorValue(activeCellValue);
512
+ }; // Go into edit mode if 'Enter' key is pressed on activeCellRef
513
+
514
+
515
+ var handleActiveCellKeyDown = function handleActiveCellKeyDown(event) {
516
+ var key = event.key;
517
+
518
+ if (key === 'Enter') {
519
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) !== 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) !== 'header') {
520
+ startEditMode();
521
+ }
522
+
523
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' || (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header') {
524
+ var handleHeaderCellProps = {
525
+ activeCellCoordinates: activeCellCoordinates,
526
+ rows: rows,
527
+ columns: columns,
528
+ setActiveCellCoordinates: setActiveCellCoordinates,
529
+ setCurrentMatcher: setCurrentMatcher,
530
+ setSelectionAreas: setSelectionAreas,
531
+ spreadsheetRef: spreadsheetRef,
532
+ isKeyboard: true
533
+ }; // Select an entire column
534
+
535
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header') {
536
+ (0, _handleHeaderCellSelection.handleHeaderCellSelection)(_objectSpread({
537
+ type: 'column'
538
+ }, handleHeaderCellProps));
539
+ } // Select an entire row
540
+
541
+
542
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header') {
543
+ (0, _handleHeaderCellSelection.handleHeaderCellSelection)(_objectSpread({
544
+ type: 'row'
545
+ }, handleHeaderCellProps));
546
+ }
547
+ }
548
+ }
549
+ }; // Go into edit mode if double click is detected on activeCellRef
550
+
551
+
552
+ var handleActiveCellDoubleClick = function handleActiveCellDoubleClick() {
553
+ startEditMode();
554
+ }; // Update the data
555
+
556
+
557
+ var handleEditSubmit = function handleEditSubmit(event) {
558
+ var key = event.key;
559
+
560
+ var submitEditChanges = function submitEditChanges() {
561
+ var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates;
562
+ var cellProps = rows[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row].cells[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column];
563
+ removeCellEditor();
564
+ updateData(prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row, cellProps.column.id);
565
+ };
566
+
567
+ if (key === 'Enter') {
568
+ submitEditChanges();
569
+ setActiveCellCoordinates(function (prev) {
570
+ return _objectSpread(_objectSpread({}, prev), {}, {
571
+ row: prev.row === rows.length - 1 ? prev.row : prev.row + 1 // do not move to next cell below if we're already in the last row
572
+
573
+ });
574
+ });
575
+ }
576
+
577
+ if (key === 'Tab') {
578
+ event.preventDefault();
579
+ submitEditChanges();
580
+ setActiveCellCoordinates(function (prev) {
581
+ return _objectSpread(_objectSpread({}, prev), {}, {
582
+ column: prev.column === columns.length - 1 ? prev.column : prev.column + 1 // do not move to next cell below if we're already in the last column
583
+
584
+ });
585
+ });
586
+ }
587
+
588
+ return;
589
+ }; // Only update if there are cell selection areas
510
590
  // Find point object that matches currentMatcher and remove the second point
511
591
  // because hovering over the active cell while clicking and holding should
512
592
  // remove the previously existing selection area
513
593
 
594
+
514
595
  var handleActiveCellMouseEnterCallback = (0, _react.useCallback)(function (areas, clickHold) {
515
596
  var freshMatcherValue = currentMatcherRef.current;
516
597
 
@@ -532,28 +613,41 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
532
613
  if ((0, _typeof2.default)(selectionAreaClone[indexOfItemToUpdate].point2) === 'object' && selectionAreaClone[indexOfItemToUpdate].areaCreated) {
533
614
  selectionAreaClone[indexOfItemToUpdate].point2 = null;
534
615
  selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
535
- removeCellSelections(freshMatcherValue);
616
+ removeCellSelections({
617
+ matcher: freshMatcherValue,
618
+ spreadsheetRef: spreadsheetRef
619
+ });
536
620
  return selectionAreaClone;
537
621
  }
538
622
 
539
623
  return prev;
540
624
  });
541
625
  }
542
- }, [removeCellSelections]); // Adds active cell highlight to correct cell onKeyDown
543
-
626
+ }, [spreadsheetRef, removeCellSelections]);
544
627
  (0, _react.useEffect)(function () {
545
- var activeCellPlacementElement = spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.current.querySelector("[data-row-index=\"".concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, "\"][data-column-index=\"").concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column, "\"]"));
546
- var shouldPlaceActiveCellInHeader = (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' && true;
547
- var selectAllElement = spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.current.querySelector("[data-row-index=\"header\"][data-column-index=\"header\"]");
548
-
549
- if (containerHasFocus) {
550
- createActiveCell({
551
- placementElement: activeCellCoordinates ? activeCellPlacementElement : selectAllElement,
552
- coords: activeCellCoordinates,
553
- addToHeader: shouldPlaceActiveCellInHeader
554
- });
628
+ if (isEditing) {
629
+ var _rows$activeCellCoord, _cellProps$column, _cellEditorRef$curren;
630
+
631
+ var cellProps = (_rows$activeCellCoord = rows[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row]) === null || _rows$activeCellCoord === void 0 ? void 0 : _rows$activeCellCoord.cells[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column];
632
+ var activeCellLeftPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.left;
633
+ var activeCellTopPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.top;
634
+ cellEditorRef.current.style.left = activeCellLeftPosition;
635
+ cellEditorRef.current.style.top = activeCellTopPosition;
636
+ cellEditorRef.current.style.display = 'block';
637
+ cellEditorRef.current.style.width = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.width;
638
+ cellEditorRef.current.style.height = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.height;
639
+ cellEditorRef.current.style.paddingTop = "".concat((parseInt(activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.height) - 16) / 2, "px"); // calculate paddingTop based on cellHeight which could be variable depending on the cellSize prop
640
+
641
+ cellEditorRef.current.style.textAlign = (cellProps === null || cellProps === void 0 ? void 0 : (_cellProps$column = cellProps.column) === null || _cellProps$column === void 0 ? void 0 : _cellProps$column.placement) === 'right' ? 'right' : 'left';
642
+ (_cellEditorRef$curren = cellEditorRef.current) === null || _cellEditorRef$curren === void 0 ? void 0 : _cellEditorRef$curren.focus();
643
+ }
644
+
645
+ if (!isEditing) {
646
+ cellEditorRef.current.style.display = 'none';
647
+ cellEditorRef.current.blur();
648
+ activeCellRef.current.focus();
555
649
  }
556
- }, [activeCellCoordinates, spreadsheetRef, createActiveCell, containerHasFocus]);
650
+ }, [isEditing, activeCellCoordinates, rows]);
557
651
 
558
652
  var handleKeyUp = function handleKeyUp(event) {
559
653
  var _activeKeys$current3;
@@ -569,8 +663,6 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
569
663
  }
570
664
  };
571
665
 
572
- var localRef = (0, _react.useRef)();
573
- var spreadsheetRef = ref || localRef;
574
666
  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({}, rest, getTableProps(), (0, _devtools.getDevtoolsProps)(componentName), {
575
667
  className: (0, _classnames.default)(blockClass, className, (0, _defineProperty2.default)({}, "".concat(blockClass, "__container-has-focus"), containerHasFocus)),
576
668
  ref: spreadsheetRef,
@@ -584,14 +676,20 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
584
676
  return setContainerHasFocus(true);
585
677
  }
586
678
  }), /*#__PURE__*/_react.default.createElement(_DataSpreadsheetHeader.DataSpreadsheetHeader, {
679
+ ref: spreadsheetRef,
587
680
  activeCellCoordinates: activeCellCoordinates,
588
681
  cellSizeValue: cellSizeValue,
682
+ columns: columns,
589
683
  defaultColumn: defaultColumn,
590
684
  headerGroups: headerGroups,
591
- selectionAreas: selectionAreas
685
+ rows: rows,
686
+ selectionAreas: selectionAreas,
687
+ setActiveCellCoordinates: setActiveCellCoordinates,
688
+ setSelectionAreas: setSelectionAreas,
689
+ setCurrentMatcher: setCurrentMatcher
592
690
  }), /*#__PURE__*/_react.default.createElement(_DataSpreadsheetBody.DataSpreadsheetBody, {
593
691
  activeCellCoordinates: activeCellCoordinates,
594
- ref: currentMatcherRef,
692
+ ref: spreadsheetRef,
595
693
  clickAndHoldActive: clickAndHoldActive,
596
694
  setClickAndHoldActive: setClickAndHoldActive,
597
695
  currentMatcher: currentMatcher,
@@ -608,7 +706,25 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
608
706
  setActiveCellCoordinates: setActiveCellCoordinates,
609
707
  scrollBarSize: scrollBarSize,
610
708
  totalColumnsWidth: totalColumnsWidth,
611
- id: id
709
+ id: id,
710
+ columns: columns
711
+ }), /*#__PURE__*/_react.default.createElement("button", {
712
+ onKeyDown: handleActiveCellKeyDown,
713
+ onMouseEnter: handleActiveCellMouseEnter,
714
+ onDoubleClick: handleActiveCellDoubleClick,
715
+ ref: activeCellRef,
716
+ className: (0, _classnames.default)("".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__active-cell--highlight")),
717
+ type: "button"
718
+ }), /*#__PURE__*/_react.default.createElement(_carbonComponentsReact.TextArea, {
719
+ value: cellEditorValue,
720
+ onKeyDown: handleEditSubmit,
721
+ onChange: function onChange(event) {
722
+ return setCellEditorValue(event.target.value);
723
+ },
724
+ ref: cellEditorRef,
725
+ labelText: "",
726
+ "aria-labelledby": activeCellCoordinates ? "[data-row-index=\"".concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, "\"][data-column-index=\"").concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column, "\"]") : null,
727
+ className: (0, _classnames.default)("".concat(blockClass, "__cell-editor"), "".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__cell-editor--").concat(cellSize), (0, _defineProperty2.default)({}, "".concat(blockClass, "__cell-editor--active"), isEditing))
612
728
  }));
613
729
  }); // Return a placeholder if not released and not enabled by feature flag
614
730
 
@@ -655,7 +771,12 @@ DataSpreadsheet.propTypes = {
655
771
  /**
656
772
  * The event handler that is called when the active cell changes
657
773
  */
658
- onActiveCellChange: _propTypes.default.func
774
+ onActiveCellChange: _propTypes.default.func,
775
+
776
+ /**
777
+ * The setter fn for the data prop
778
+ */
779
+ onDataUpdate: _propTypes.default.func
659
780
  /* TODO: add types and DocGen for all props. */
660
781
 
661
782
  };