@carbon/ibm-products 1.10.0 → 1.11.2

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 (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
  };