@carbon/ibm-products 1.10.0 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. package/css/index-full-carbon.css +249 -218
  2. package/css/index-full-carbon.css.map +1 -1
  3. package/css/index-full-carbon.min.css +5 -5
  4. package/css/index-full-carbon.min.css.map +1 -1
  5. package/css/index-without-carbon-released-only.css +21 -4
  6. package/css/index-without-carbon-released-only.css.map +1 -1
  7. package/css/index-without-carbon-released-only.min.css +2 -2
  8. package/css/index-without-carbon-released-only.min.css.map +1 -1
  9. package/css/index-without-carbon.css +102 -212
  10. package/css/index-without-carbon.css.map +1 -1
  11. package/css/index-without-carbon.min.css +4 -4
  12. package/css/index-without-carbon.min.css.map +1 -1
  13. package/css/index.css +219 -212
  14. package/css/index.css.map +1 -1
  15. package/css/index.min.css +5 -5
  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 +193 -19
  19. package/es/components/AddSelect/AddSelectList.js +5 -5
  20. package/es/components/AddSelect/AddSelectSidebar.js +3 -15
  21. package/es/components/AddSelect/add-select-utils.js +64 -0
  22. package/es/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +2 -1
  23. package/es/components/ButtonMenu/ButtonMenu.js +11 -3
  24. package/es/components/CreateFullPage/CreateFullPageStep.js +4 -4
  25. package/es/components/CreateTearsheet/CreateTearsheetStep.js +4 -4
  26. package/es/components/DataSpreadsheet/DataSpreadsheet.js +255 -140
  27. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +37 -38
  28. package/es/components/DataSpreadsheet/DataSpreadsheetHeader.js +55 -6
  29. package/es/components/DataSpreadsheet/hooks/useMoveActiveCell.js +27 -0
  30. package/es/components/DataSpreadsheet/hooks/useResetSpreadsheetFocus.js +28 -0
  31. package/es/components/DataSpreadsheet/hooks/useSpreadsheetOutsideClick.js +41 -0
  32. package/es/components/DataSpreadsheet/{checkActiveHeaderCell.js → utils/checkActiveHeaderCell.js} +1 -1
  33. package/es/components/DataSpreadsheet/{createActiveCellFn.js → utils/createActiveCellFn.js} +20 -9
  34. package/es/components/DataSpreadsheet/{createCellSelectionArea.js → utils/createCellSelectionArea.js} +8 -4
  35. package/es/components/DataSpreadsheet/{generateData.js → utils/generateData.js} +6 -0
  36. package/es/components/DataSpreadsheet/{getCellSize.js → utils/getCellSize.js} +0 -0
  37. package/es/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +46 -0
  38. package/es/components/DataSpreadsheet/utils/handleMultipleKeys.js +82 -0
  39. package/es/components/DataSpreadsheet/utils/removeCellSelections.js +30 -0
  40. package/es/components/InlineEdit/InlineEdit.js +49 -8
  41. package/es/components/OptionsTile/OptionsTile.js +20 -20
  42. package/es/components/OptionsTile/index.js +1 -1
  43. package/es/components/PageHeader/PageHeader.js +35 -32
  44. package/es/components/PageHeader/PageHeaderTitle.js +2 -1
  45. package/es/components/PageHeader/PageHeaderUtils.js +21 -22
  46. package/es/components/index.js +0 -1
  47. package/es/global/js/package-settings.js +1 -2
  48. package/lib/components/AddSelect/AddSelect.js +91 -87
  49. package/lib/components/AddSelect/AddSelectColumn.js +193 -16
  50. package/lib/components/AddSelect/AddSelectList.js +5 -5
  51. package/lib/components/AddSelect/AddSelectSidebar.js +9 -15
  52. package/lib/components/AddSelect/add-select-utils.js +78 -0
  53. package/lib/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +2 -1
  54. package/lib/components/ButtonMenu/ButtonMenu.js +11 -3
  55. package/lib/components/CreateFullPage/CreateFullPageStep.js +4 -4
  56. package/lib/components/CreateTearsheet/CreateTearsheetStep.js +4 -4
  57. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +263 -142
  58. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +39 -36
  59. package/lib/components/DataSpreadsheet/DataSpreadsheetHeader.js +62 -8
  60. package/lib/components/DataSpreadsheet/hooks/useMoveActiveCell.js +37 -0
  61. package/lib/components/DataSpreadsheet/hooks/useResetSpreadsheetFocus.js +39 -0
  62. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetOutsideClick.js +52 -0
  63. package/lib/components/DataSpreadsheet/{checkActiveHeaderCell.js → utils/checkActiveHeaderCell.js} +1 -1
  64. package/lib/components/DataSpreadsheet/{createActiveCellFn.js → utils/createActiveCellFn.js} +20 -9
  65. package/lib/components/DataSpreadsheet/{createCellSelectionArea.js → utils/createCellSelectionArea.js} +8 -4
  66. package/lib/components/DataSpreadsheet/{generateData.js → utils/generateData.js} +6 -0
  67. package/lib/components/DataSpreadsheet/{getCellSize.js → utils/getCellSize.js} +0 -0
  68. package/lib/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +59 -0
  69. package/lib/components/DataSpreadsheet/utils/handleMultipleKeys.js +92 -0
  70. package/lib/components/DataSpreadsheet/utils/removeCellSelections.js +41 -0
  71. package/lib/components/InlineEdit/InlineEdit.js +52 -10
  72. package/lib/components/OptionsTile/OptionsTile.js +19 -19
  73. package/lib/components/PageHeader/PageHeader.js +35 -32
  74. package/lib/components/PageHeader/PageHeaderTitle.js +2 -1
  75. package/lib/components/PageHeader/PageHeaderUtils.js +21 -22
  76. package/lib/components/index.js +0 -8
  77. package/lib/global/js/package-settings.js +1 -2
  78. package/package.json +13 -13
  79. package/scss/components/AddSelect/_add-select.scss +20 -0
  80. package/scss/components/BreadcrumbWithOverflow/_breadcrumb-with-overflow.scss +7 -3
  81. package/scss/components/CreateSidePanel/_create-side-panel.scss +1 -1
  82. package/scss/components/CreateSidePanel/_storybook-styles.scss +1 -1
  83. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +14 -1
  84. package/scss/components/EditSidePanel/_edit-side-panel.scss +9 -0
  85. package/scss/components/EditSidePanel/_storybook-styles.scss +1 -1
  86. package/scss/components/InlineEdit/_inline-edit.scss +35 -37
  87. package/scss/components/ModifiedTabs/_modified-tabs.scss +5 -0
  88. package/scss/components/NotificationsPanel/_notifications-panel.scss +7 -3
  89. package/scss/components/OptionsTile/_index.scss +1 -1
  90. package/scss/components/OptionsTile/_options-tile.scss +17 -17
  91. package/scss/components/OptionsTile/_storybook-styles.scss +4 -4
  92. package/scss/components/PageHeader/_page-header.scss +3 -2
  93. package/scss/components/SidePanel/_side-panel.scss +8 -8
  94. package/scss/components/Tearsheet/_tearsheet.scss +4 -0
  95. package/scss/components/_index.scss +0 -1
  96. package/es/components/LoadingBar/LoadingBar.js +0 -156
  97. package/es/components/LoadingBar/index.js +0 -7
  98. package/lib/components/LoadingBar/LoadingBar.js +0 -170
  99. package/lib/components/LoadingBar/index.js +0 -13
  100. package/scss/components/LoadingBar/_index.scss +0 -8
  101. package/scss/components/LoadingBar/_loading-bar.scss +0 -224
  102. package/scss/components/LoadingBar/_storybook-styles.scss +0 -14
@@ -1,10 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _typeof from "@babel/runtime/helpers/typeof";
3
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
3
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
5
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
6
6
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
7
- var _excluded = ["cellSize", "className", "columns", "data", "id", "onActiveCellChange"];
7
+ var _excluded = ["cellSize", "className", "columns", "data", "onDataUpdate", "id", "onActiveCellChange"];
8
8
 
9
9
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
10
10
 
@@ -17,22 +17,28 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
17
17
  * LICENSE file in the root directory of this source tree.
18
18
  */
19
19
  // Import portions of React that are needed.
20
- import React, { useMemo, useRef, useEffect, useState, useCallback } from 'react';
20
+ import React, { useMemo, useRef, useState, useCallback, useEffect } from 'react';
21
21
  import { useBlockLayout, useTable } from 'react-table'; // Other standard imports.
22
22
 
23
23
  import PropTypes from 'prop-types';
24
24
  import cx from 'classnames';
25
- import { getDevtoolsProps } from '../../global/js/utils/devtools';
25
+ import { TextArea } from 'carbon-components-react';
26
26
  import { pkg } from '../../settings';
27
- import { getScrollbarWidth } from '../../global/js/utils/getScrollbarWidth';
28
27
  import { DataSpreadsheetBody } from './DataSpreadsheetBody';
29
- import { getCellSize } from './getCellSize';
30
28
  import { DataSpreadsheetHeader } from './DataSpreadsheetHeader';
29
+ import { getDevtoolsProps } from '../../global/js/utils/devtools';
30
+ import { getScrollbarWidth } from '../../global/js/utils/getScrollbarWidth';
31
31
  import { useActiveElement } from '../../global/js/hooks';
32
- import { createActiveCellFn } from './createActiveCellFn';
33
32
  import { deepCloneObject } from '../../global/js/utils/deepCloneObject';
34
33
  import { usePreviousValue } from '../../global/js/hooks';
35
- import uuidv4 from '../../global/js/utils/uuidv4'; // cspell:words rowcount colcount
34
+ import uuidv4 from '../../global/js/utils/uuidv4';
35
+ import { useResetSpreadsheetFocus } from './hooks/useResetSpreadsheetFocus';
36
+ import { useSpreadsheetOutsideClick } from './hooks/useSpreadsheetOutsideClick';
37
+ import { useMoveActiveCell } from './hooks/useMoveActiveCell';
38
+ import { createActiveCellFn } from './utils/createActiveCellFn';
39
+ import { getCellSize } from './utils/getCellSize';
40
+ import { handleMultipleKeys } from './utils/handleMultipleKeys';
41
+ import { handleHeaderCellSelection } from './utils/handleHeaderCellSelection'; // cspell:words rowcount colcount
36
42
  // The block part of our conventional BEM class names (blockClass__E--M).
37
43
 
38
44
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
@@ -41,7 +47,8 @@ var componentName = 'DataSpreadsheet'; // Default values for props
41
47
  var defaults = {
42
48
  cellSize: 'standard',
43
49
  columns: Object.freeze([]),
44
- data: Object.freeze([])
50
+ data: Object.freeze([]),
51
+ onDataUpdate: Object.freeze(function () {})
45
52
  };
46
53
  /**
47
54
  * DataSpreadsheet: used to organize and display large amounts of structured data, separated by columns and rows in a grid-like format.
@@ -55,10 +62,14 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
55
62
  columns = _ref$columns === void 0 ? defaults.columns : _ref$columns,
56
63
  _ref$data = _ref.data,
57
64
  data = _ref$data === void 0 ? defaults.data : _ref$data,
65
+ _ref$onDataUpdate = _ref.onDataUpdate,
66
+ onDataUpdate = _ref$onDataUpdate === void 0 ? defaults.onDataUpdate : _ref$onDataUpdate,
58
67
  id = _ref.id,
59
68
  onActiveCellChange = _ref.onActiveCellChange,
60
69
  rest = _objectWithoutProperties(_ref, _excluded);
61
70
 
71
+ var localRef = useRef();
72
+ var spreadsheetRef = ref || localRef;
62
73
  var focusedElement = useActiveElement();
63
74
 
64
75
  var _useState = useState(false),
@@ -86,12 +97,24 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
86
97
  currentMatcher = _useState10[0],
87
98
  setCurrentMatcher = _useState10[1];
88
99
 
100
+ var _useState11 = useState(false),
101
+ _useState12 = _slicedToArray(_useState11, 2),
102
+ isEditing = _useState12[0],
103
+ setIsEditing = _useState12[1];
104
+
105
+ var _useState13 = useState(''),
106
+ _useState14 = _slicedToArray(_useState13, 2),
107
+ cellEditorValue = _useState14[0],
108
+ setCellEditorValue = _useState14[1];
109
+
89
110
  var previousState = usePreviousValue({
90
111
  activeCellCoordinates: activeCellCoordinates
91
112
  });
92
113
  var cellSizeValue = getCellSize(cellSize);
114
+ var cellEditorRef = useRef();
93
115
  var currentMatcherRef = useRef();
94
116
  var activeKeys = useRef([]);
117
+ var activeCellRef = useRef();
95
118
  var defaultColumn = useMemo(function () {
96
119
  return {
97
120
  width: 150,
@@ -113,28 +136,33 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
113
136
  headerGroups = _useTable.headerGroups,
114
137
  rows = _useTable.rows,
115
138
  totalColumnsWidth = _useTable.totalColumnsWidth,
116
- prepareRow = _useTable.prepareRow; // Reset everything when spreadsheet loses focus
139
+ prepareRow = _useTable.prepareRow; // Update the spreadsheet data after editing a cell
117
140
 
118
141
 
119
- useEffect(function () {
120
- if (!focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
121
- setContainerHasFocus(false);
122
- removeActiveCell();
123
- activeKeys.current = [];
124
- }
142
+ var updateData = useCallback(function (rowIndex, columnId) {
143
+ onDataUpdate(function (prev) {
144
+ return prev.map(function (row, index) {
145
+ if (index === rowIndex) {
146
+ return _objectSpread(_objectSpread({}, prev[rowIndex]), {}, _defineProperty({}, columnId, cellEditorValue));
147
+ }
125
148
 
126
- if (focusedElement.classList.contains(blockClass) || focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
127
- setContainerHasFocus(true);
128
- }
129
- }, [focusedElement, removeActiveCell]); // Removes the active cell element
149
+ return row;
150
+ });
151
+ });
152
+ }, [cellEditorValue, onDataUpdate]); // Removes the active cell element
130
153
 
131
154
  var removeActiveCell = useCallback(function () {
132
155
  var activeCellHighlight = spreadsheetRef.current.querySelector(".".concat(blockClass, "__active-cell--highlight"));
133
156
 
134
157
  if (activeCellHighlight) {
135
- activeCellHighlight.remove();
158
+ activeCellHighlight.style.display = 'none';
136
159
  }
137
- }, [spreadsheetRef]); // Removes the cell selection elements
160
+ }, [spreadsheetRef]);
161
+ var removeCellEditor = useCallback(function () {
162
+ setCellEditorValue('');
163
+ setIsEditing(false);
164
+ cellEditorRef.current.style.display = 'none';
165
+ }, []); // Removes the cell selection elements
138
166
 
139
167
  var removeCellSelections = useCallback(function (matcher) {
140
168
  if (matcher && typeof matcher === 'string') {
@@ -150,27 +178,21 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
150
178
  return element.remove();
151
179
  });
152
180
  }
153
- }, [spreadsheetRef]); // Click outside useEffect
181
+ }, [spreadsheetRef]); // Remove cell editor if the active cell coordinates change and save with new cell data, this will
182
+ // happen if you click on another cell while isEditing is true
154
183
 
155
184
  useEffect(function () {
156
- var handleOutsideClick = function handleOutsideClick(event) {
157
- if (!spreadsheetRef.current || spreadsheetRef.current.contains(event.target) || event.target.classList.contains("".concat(blockClass, "__active-cell--highlight"))) {
158
- return;
159
- }
185
+ var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates;
160
186
 
161
- setActiveCellCoordinates(null);
162
- setSelectionAreas([]);
163
- removeActiveCell();
164
- removeCellSelections();
165
- setContainerHasFocus(false);
166
- activeKeys.current = [];
167
- };
168
-
169
- document.addEventListener('click', handleOutsideClick);
170
- return function () {
171
- document.removeEventListener('click', handleOutsideClick);
172
- };
173
- }, [spreadsheetRef, removeActiveCell, removeCellSelections]);
187
+ 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) {
188
+ var cellProps = rows[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row].cells[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column];
189
+ removeCellEditor();
190
+ updateData(prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row, cellProps.column.id);
191
+ }
192
+ }, [activeCellCoordinates, previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates, updateData, rows, isEditing, removeCellEditor]);
193
+ var handleActiveCellMouseEnter = useCallback(function () {
194
+ handleActiveCellMouseEnterCallback(selectionAreas, clickAndHoldActive);
195
+ }, [clickAndHoldActive, selectionAreas, handleActiveCellMouseEnterCallback]);
174
196
  var createActiveCell = useCallback(function (_ref2) {
175
197
  var placementElement = _ref2.placementElement,
176
198
  coords = _ref2.coords,
@@ -178,11 +200,6 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
178
200
  addToHeader = _ref2$addToHeader === void 0 ? false : _ref2$addToHeader;
179
201
  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;
180
202
  var activeCellValue = activeCellFullData ? Object.values(activeCellFullData.row.values)[coords === null || coords === void 0 ? void 0 : coords.column] : null;
181
-
182
- var handleActiveCellMouseEnter = function handleActiveCellMouseEnter() {
183
- handleActiveCellMouseEnterCallback(selectionAreas, clickAndHoldActive);
184
- };
185
-
186
203
  var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates; // Only create an active cell if the activeCellCoordinates have changed
187
204
 
188
205
  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)) {
@@ -194,10 +211,34 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
194
211
  blockClass: blockClass,
195
212
  onActiveCellChange: onActiveCellChange,
196
213
  activeCellValue: activeCellValue,
197
- handleActiveCellMouseEnter: handleActiveCellMouseEnter
214
+ activeCellRef: activeCellRef,
215
+ cellEditorRef: cellEditorRef,
216
+ defaultColumn: defaultColumn
198
217
  });
199
218
  }
200
- }, [spreadsheetRef, rows, onActiveCellChange, clickAndHoldActive, handleActiveCellMouseEnterCallback, selectionAreas, previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates]);
219
+ }, [spreadsheetRef, rows, onActiveCellChange, previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates, defaultColumn]);
220
+ useResetSpreadsheetFocus({
221
+ activeKeys: activeKeys,
222
+ focusedElement: focusedElement,
223
+ removeActiveCell: removeActiveCell,
224
+ setContainerHasFocus: setContainerHasFocus
225
+ });
226
+ useSpreadsheetOutsideClick({
227
+ spreadsheetRef: spreadsheetRef,
228
+ setActiveCellCoordinates: setActiveCellCoordinates,
229
+ setSelectionAreas: setSelectionAreas,
230
+ removeActiveCell: removeActiveCell,
231
+ removeCellSelections: removeCellSelections,
232
+ setContainerHasFocus: setContainerHasFocus,
233
+ activeKeys: activeKeys,
234
+ removeCellEditor: removeCellEditor
235
+ });
236
+ useMoveActiveCell({
237
+ spreadsheetRef: spreadsheetRef,
238
+ activeCellCoordinates: activeCellCoordinates,
239
+ containerHasFocus: containerHasFocus,
240
+ createActiveCell: createActiveCell
241
+ });
201
242
  var handleInitialArrowPress = useCallback(function () {
202
243
  // If activeCellCoordinates is null then we need to set an initial value
203
244
  // which will place the activeCell on the select all cell/button
@@ -229,75 +270,6 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
229
270
  setCurrentMatcher(tempMatcher);
230
271
  }
231
272
  }, []);
232
- var handleMultipleKeys = useCallback(function () {
233
- var _selectionAreasClone$;
234
-
235
- var activeKeyValues = activeKeys.current;
236
- var selectionAreasClone = deepCloneObject(selectionAreas);
237
- var indexOfCurrentArea = selectionAreasClone.findIndex(function (item) {
238
- return item.matcher === currentMatcher;
239
- });
240
- var pointToUpdate = (_selectionAreasClone$ = selectionAreasClone[indexOfCurrentArea]) !== null && _selectionAreasClone$ !== void 0 && _selectionAreasClone$.point2 ? selectionAreasClone[indexOfCurrentArea].point2 : selectionAreasClone[indexOfCurrentArea].point1; // Down + Shift
241
-
242
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowDown')) {
243
- if (rows.length - 1 === pointToUpdate.row) {
244
- return;
245
- }
246
-
247
- var newPoint = {
248
- row: pointToUpdate.row + 1,
249
- column: pointToUpdate.column
250
- };
251
- selectionAreasClone[indexOfCurrentArea].point2 = newPoint;
252
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
253
- setSelectionAreas(selectionAreasClone);
254
- } // Right + Shift
255
-
256
-
257
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowRight')) {
258
- if (columns.length - 1 === pointToUpdate.column) {
259
- return;
260
- }
261
-
262
- var _newPoint = {
263
- row: pointToUpdate.row,
264
- column: pointToUpdate.column + 1
265
- };
266
- selectionAreasClone[indexOfCurrentArea].point2 = _newPoint;
267
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
268
- setSelectionAreas(selectionAreasClone);
269
- } // Up + Shift
270
-
271
-
272
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowUp')) {
273
- if (pointToUpdate.row === 0) {
274
- return;
275
- }
276
-
277
- var _newPoint2 = {
278
- row: pointToUpdate.row - 1,
279
- column: pointToUpdate.column
280
- };
281
- selectionAreasClone[indexOfCurrentArea].point2 = _newPoint2;
282
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
283
- setSelectionAreas(selectionAreasClone);
284
- } // Left + Shift
285
-
286
-
287
- if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowLeft')) {
288
- if (pointToUpdate.column === 0) {
289
- return;
290
- }
291
-
292
- var _newPoint3 = {
293
- row: pointToUpdate.row,
294
- column: pointToUpdate.column - 1
295
- };
296
- selectionAreasClone[indexOfCurrentArea].point2 = _newPoint3;
297
- selectionAreasClone[indexOfCurrentArea].areaCreated = false;
298
- setSelectionAreas(selectionAreasClone);
299
- }
300
- }, [selectionAreas, currentMatcher, columns, rows]);
301
273
  var handleKeyPress = useCallback(function (event) {
302
274
  var _activeKeys$current, _activeKeys$current2;
303
275
 
@@ -308,15 +280,25 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
308
280
  } // Prevent arrow keys, home key, and end key from scrolling the page when the data spreadsheet container has focus
309
281
 
310
282
 
311
- if (['End', 'Home', 'ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1) {
283
+ if (['End', 'Home', 'ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1 && !isEditing) {
312
284
  event.preventDefault();
285
+ }
286
+
287
+ if (['Tab'].indexOf(key) > -1 && isEditing) {
288
+ return;
313
289
  } // Clear out all cell selection areas if user uses any arrow key, except if the shift key is being held
314
290
 
315
291
 
316
292
  if (['ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1) {
293
+ if (isEditing) {
294
+ return;
295
+ }
296
+
317
297
  if (selectionAreas !== null && selectionAreas !== void 0 && selectionAreas.length && key !== 'Shift' && !activeKeys.current.includes('Shift')) {
318
298
  setSelectionAreas([]);
319
- removeCellSelections();
299
+ removeCellSelections({
300
+ spreadsheetRef: spreadsheetRef
301
+ });
320
302
  }
321
303
  } // Update list of activeKeys
322
304
 
@@ -328,7 +310,14 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
328
310
  }
329
311
 
330
312
  if (((_activeKeys$current2 = activeKeys.current) === null || _activeKeys$current2 === void 0 ? void 0 : _activeKeys$current2.length) > 1) {
331
- handleMultipleKeys();
313
+ handleMultipleKeys({
314
+ activeKeys: activeKeys,
315
+ selectionAreas: selectionAreas,
316
+ currentMatcher: currentMatcher,
317
+ rows: rows,
318
+ setSelectionAreas: setSelectionAreas,
319
+ columns: columns
320
+ });
332
321
  } // Allow arrow key navigation if there are less than two activeKeys OR
333
322
  // if one of the activeCellCoordinates is in a header position
334
323
 
@@ -340,6 +329,7 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
340
329
  {
341
330
  setSelectionAreas([]);
342
331
  removeActiveCell();
332
+ removeCellEditor();
343
333
  setContainerHasFocus(false);
344
334
  setActiveCellCoordinates(null);
345
335
  break;
@@ -483,11 +473,96 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
483
473
  }
484
474
  }
485
475
  }
486
- }, [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
476
+ }, [updateActiveCellCoordinates, handleInitialArrowPress, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, isEditing, removeCellEditor, removeCellSelections, selectionAreas]);
477
+
478
+ var startEditMode = function startEditMode() {
479
+ setIsEditing(true);
480
+ 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;
481
+ var activeCellValue = activeCellFullData ? Object.values(activeCellFullData.row.values)[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column] : null;
482
+ setCellEditorValue(activeCellValue);
483
+ }; // Go into edit mode if 'Enter' key is pressed on activeCellRef
484
+
485
+
486
+ var handleActiveCellKeyDown = function handleActiveCellKeyDown(event) {
487
+ var key = event.key;
488
+
489
+ if (key === 'Enter') {
490
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) !== 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) !== 'header') {
491
+ startEditMode();
492
+ }
493
+
494
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' || (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header') {
495
+ var handleHeaderCellProps = {
496
+ activeCellCoordinates: activeCellCoordinates,
497
+ rows: rows,
498
+ columns: columns,
499
+ setActiveCellCoordinates: setActiveCellCoordinates,
500
+ setCurrentMatcher: setCurrentMatcher,
501
+ setSelectionAreas: setSelectionAreas,
502
+ spreadsheetRef: spreadsheetRef,
503
+ isKeyboard: true
504
+ }; // Select an entire column
505
+
506
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header') {
507
+ handleHeaderCellSelection(_objectSpread({
508
+ type: 'column'
509
+ }, handleHeaderCellProps));
510
+ } // Select an entire row
511
+
512
+
513
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header') {
514
+ handleHeaderCellSelection(_objectSpread({
515
+ type: 'row'
516
+ }, handleHeaderCellProps));
517
+ }
518
+ }
519
+ }
520
+ }; // Go into edit mode if double click is detected on activeCellRef
521
+
522
+
523
+ var handleActiveCellDoubleClick = function handleActiveCellDoubleClick() {
524
+ startEditMode();
525
+ }; // Update the data
526
+
527
+
528
+ var handleEditSubmit = function handleEditSubmit(event) {
529
+ var key = event.key;
530
+
531
+ var submitEditChanges = function submitEditChanges() {
532
+ var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates;
533
+ var cellProps = rows[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row].cells[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column];
534
+ removeCellEditor();
535
+ updateData(prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row, cellProps.column.id);
536
+ };
537
+
538
+ if (key === 'Enter') {
539
+ submitEditChanges();
540
+ setActiveCellCoordinates(function (prev) {
541
+ return _objectSpread(_objectSpread({}, prev), {}, {
542
+ 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
543
+
544
+ });
545
+ });
546
+ }
547
+
548
+ if (key === 'Tab') {
549
+ event.preventDefault();
550
+ submitEditChanges();
551
+ setActiveCellCoordinates(function (prev) {
552
+ return _objectSpread(_objectSpread({}, prev), {}, {
553
+ 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
554
+
555
+ });
556
+ });
557
+ }
558
+
559
+ return;
560
+ }; // Only update if there are cell selection areas
487
561
  // Find point object that matches currentMatcher and remove the second point
488
562
  // because hovering over the active cell while clicking and holding should
489
563
  // remove the previously existing selection area
490
564
 
565
+
491
566
  var handleActiveCellMouseEnterCallback = useCallback(function (areas, clickHold) {
492
567
  var freshMatcherValue = currentMatcherRef.current;
493
568
 
@@ -509,28 +584,41 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
509
584
  if (_typeof(selectionAreaClone[indexOfItemToUpdate].point2) === 'object' && selectionAreaClone[indexOfItemToUpdate].areaCreated) {
510
585
  selectionAreaClone[indexOfItemToUpdate].point2 = null;
511
586
  selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
512
- removeCellSelections(freshMatcherValue);
587
+ removeCellSelections({
588
+ matcher: freshMatcherValue,
589
+ spreadsheetRef: spreadsheetRef
590
+ });
513
591
  return selectionAreaClone;
514
592
  }
515
593
 
516
594
  return prev;
517
595
  });
518
596
  }
519
- }, [removeCellSelections]); // Adds active cell highlight to correct cell onKeyDown
520
-
597
+ }, [spreadsheetRef, removeCellSelections]);
521
598
  useEffect(function () {
522
- 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, "\"]"));
523
- var shouldPlaceActiveCellInHeader = (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' && true;
524
- var selectAllElement = spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.current.querySelector("[data-row-index=\"header\"][data-column-index=\"header\"]");
525
-
526
- if (containerHasFocus) {
527
- createActiveCell({
528
- placementElement: activeCellCoordinates ? activeCellPlacementElement : selectAllElement,
529
- coords: activeCellCoordinates,
530
- addToHeader: shouldPlaceActiveCellInHeader
531
- });
599
+ if (isEditing) {
600
+ var _rows$activeCellCoord, _cellProps$column, _cellEditorRef$curren;
601
+
602
+ 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];
603
+ var activeCellLeftPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.left;
604
+ var activeCellTopPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.top;
605
+ cellEditorRef.current.style.left = activeCellLeftPosition;
606
+ cellEditorRef.current.style.top = activeCellTopPosition;
607
+ cellEditorRef.current.style.display = 'block';
608
+ cellEditorRef.current.style.width = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.width;
609
+ cellEditorRef.current.style.height = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.height;
610
+ 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
611
+
612
+ 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';
613
+ (_cellEditorRef$curren = cellEditorRef.current) === null || _cellEditorRef$curren === void 0 ? void 0 : _cellEditorRef$curren.focus();
614
+ }
615
+
616
+ if (!isEditing) {
617
+ cellEditorRef.current.style.display = 'none';
618
+ cellEditorRef.current.blur();
619
+ activeCellRef.current.focus();
532
620
  }
533
- }, [activeCellCoordinates, spreadsheetRef, createActiveCell, containerHasFocus]);
621
+ }, [isEditing, activeCellCoordinates, rows]);
534
622
 
535
623
  var handleKeyUp = function handleKeyUp(event) {
536
624
  var _activeKeys$current3;
@@ -547,8 +635,6 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
547
635
  }
548
636
  };
549
637
 
550
- var localRef = useRef();
551
- var spreadsheetRef = ref || localRef;
552
638
  return /*#__PURE__*/React.createElement("div", _extends({}, rest, getTableProps(), getDevtoolsProps(componentName), {
553
639
  className: cx(blockClass, className, _defineProperty({}, "".concat(blockClass, "__container-has-focus"), containerHasFocus)),
554
640
  ref: spreadsheetRef,
@@ -562,14 +648,20 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
562
648
  return setContainerHasFocus(true);
563
649
  }
564
650
  }), /*#__PURE__*/React.createElement(DataSpreadsheetHeader, {
651
+ ref: spreadsheetRef,
565
652
  activeCellCoordinates: activeCellCoordinates,
566
653
  cellSizeValue: cellSizeValue,
654
+ columns: columns,
567
655
  defaultColumn: defaultColumn,
568
656
  headerGroups: headerGroups,
569
- selectionAreas: selectionAreas
657
+ rows: rows,
658
+ selectionAreas: selectionAreas,
659
+ setActiveCellCoordinates: setActiveCellCoordinates,
660
+ setSelectionAreas: setSelectionAreas,
661
+ setCurrentMatcher: setCurrentMatcher
570
662
  }), /*#__PURE__*/React.createElement(DataSpreadsheetBody, {
571
663
  activeCellCoordinates: activeCellCoordinates,
572
- ref: currentMatcherRef,
664
+ ref: spreadsheetRef,
573
665
  clickAndHoldActive: clickAndHoldActive,
574
666
  setClickAndHoldActive: setClickAndHoldActive,
575
667
  currentMatcher: currentMatcher,
@@ -586,7 +678,25 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
586
678
  setActiveCellCoordinates: setActiveCellCoordinates,
587
679
  scrollBarSize: scrollBarSize,
588
680
  totalColumnsWidth: totalColumnsWidth,
589
- id: id
681
+ id: id,
682
+ columns: columns
683
+ }), /*#__PURE__*/React.createElement("button", {
684
+ onKeyDown: handleActiveCellKeyDown,
685
+ onMouseEnter: handleActiveCellMouseEnter,
686
+ onDoubleClick: handleActiveCellDoubleClick,
687
+ ref: activeCellRef,
688
+ className: cx("".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__active-cell--highlight")),
689
+ type: "button"
690
+ }), /*#__PURE__*/React.createElement(TextArea, {
691
+ value: cellEditorValue,
692
+ onKeyDown: handleEditSubmit,
693
+ onChange: function onChange(event) {
694
+ return setCellEditorValue(event.target.value);
695
+ },
696
+ ref: cellEditorRef,
697
+ labelText: "",
698
+ "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,
699
+ className: cx("".concat(blockClass, "__cell-editor"), "".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__cell-editor--").concat(cellSize), _defineProperty({}, "".concat(blockClass, "__cell-editor--active"), isEditing))
590
700
  }));
591
701
  }); // Return a placeholder if not released and not enabled by feature flag
592
702
 
@@ -631,7 +741,12 @@ DataSpreadsheet.propTypes = {
631
741
  /**
632
742
  * The event handler that is called when the active cell changes
633
743
  */
634
- onActiveCellChange: PropTypes.func
744
+ onActiveCellChange: PropTypes.func,
745
+
746
+ /**
747
+ * The setter fn for the data prop
748
+ */
749
+ onDataUpdate: PropTypes.func
635
750
  /* TODO: add types and DocGen for all props. */
636
751
 
637
752
  };