@carbon/ibm-products 1.7.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. package/css/index-full-carbon.css +27 -130
  2. package/css/index-full-carbon.css.map +1 -1
  3. package/css/index-full-carbon.min.css +2 -2
  4. package/css/index-full-carbon.min.css.map +1 -1
  5. package/css/index-without-carbon.css +27 -130
  6. package/css/index-without-carbon.css.map +1 -1
  7. package/css/index-without-carbon.min.css +2 -2
  8. package/css/index-without-carbon.min.css.map +1 -1
  9. package/css/index.css +27 -130
  10. package/css/index.css.map +1 -1
  11. package/css/index.min.css +2 -2
  12. package/css/index.min.css.map +1 -1
  13. package/es/components/APIKeyModal/APIKeyModal.js +10 -13
  14. package/es/components/ActionBar/ActionBar.js +0 -3
  15. package/es/components/ActionBar/ActionBarItem.js +2 -6
  16. package/es/components/ActionSet/ActionSet.js +10 -12
  17. package/es/components/AddSelect/AddSelect.js +7 -5
  18. package/es/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +0 -3
  19. package/es/components/ButtonMenu/ButtonMenu.js +6 -4
  20. package/es/components/ButtonMenu/ButtonMenuItem.js +1 -2
  21. package/es/components/Card/Card.js +31 -21
  22. package/es/components/Card/CardFooter.js +14 -10
  23. package/es/components/Card/CardHeader.js +8 -6
  24. package/es/components/Cascade/Cascade.js +5 -4
  25. package/es/components/ComboButton/ComboButton.js +0 -4
  26. package/es/components/ComboButton/ComboButtonItem/index.js +0 -5
  27. package/es/components/CreateFullPage/CreateFullPageStep.js +15 -8
  28. package/es/components/CreateModal/CreateModal.js +1 -4
  29. package/es/components/CreateTearsheet/CreateTearsheet.js +10 -11
  30. package/es/components/CreateTearsheet/CreateTearsheetStep.js +18 -14
  31. package/es/components/DataSpreadsheet/DataSpreadsheet.js +340 -80
  32. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +138 -0
  33. package/es/components/DataSpreadsheet/DataSpreadsheetHeader.js +64 -0
  34. package/es/components/DataSpreadsheet/createActiveCellFn.js +45 -0
  35. package/es/components/DataSpreadsheet/getCellSize.js +30 -0
  36. package/es/components/EditSidePanel/EditSidePanel.js +9 -10
  37. package/es/components/EmptyStates/EmptyState.js +7 -6
  38. package/es/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.js +4 -8
  39. package/es/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.js +4 -8
  40. package/es/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.js +4 -8
  41. package/es/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.js +4 -8
  42. package/es/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.js +4 -8
  43. package/es/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.js +4 -8
  44. package/es/components/ExampleComponent/ExampleComponent.js +12 -13
  45. package/es/components/ExportModal/ExportModal.js +13 -9
  46. package/es/components/ExpressiveCard/ExpressiveCard.js +0 -8
  47. package/es/components/ImportModal/ImportModal.js +7 -5
  48. package/es/components/InlineEdit/InlineEdit.js +11 -13
  49. package/es/components/LoadingBar/LoadingBar.js +13 -17
  50. package/es/components/ModifiedTabs/ModifiedTabLabelNew.js +0 -4
  51. package/es/components/ModifiedTabs/ModifiedTabLabelWithClose.js +0 -5
  52. package/es/components/ModifiedTabs/ModifiedTabs.js +24 -18
  53. package/es/components/NotificationsPanel/NotificationsPanel.js +109 -86
  54. package/es/components/OptionsTile/OptionsTile.js +6 -9
  55. package/es/components/PageHeader/PageHeader.js +10 -7
  56. package/es/components/ProductiveCard/ProductiveCard.js +23 -12
  57. package/es/components/RemoveModal/RemoveModal.js +0 -3
  58. package/es/components/SidePanel/SidePanel.js +22 -17
  59. package/es/components/TagSet/TagSet.js +13 -9
  60. package/es/components/TagSet/TagSetModal.js +16 -12
  61. package/es/components/TagSet/TagSetOverflow.js +21 -13
  62. package/es/components/Tearsheet/Tearsheet.js +27 -18
  63. package/es/components/Tearsheet/TearsheetNarrow.js +18 -15
  64. package/es/components/Toolbar/ToolbarButton.js +0 -3
  65. package/es/components/WebTerminal/WebTerminal.js +17 -18
  66. package/es/components/index.js +0 -1
  67. package/es/global/js/hooks/index.js +1 -0
  68. package/es/global/js/hooks/useActiveElement.js +27 -0
  69. package/es/global/js/utils/Wrap.js +7 -5
  70. package/lib/components/APIKeyModal/APIKeyModal.js +10 -13
  71. package/lib/components/ActionBar/ActionBar.js +0 -3
  72. package/lib/components/ActionBar/ActionBarItem.js +2 -6
  73. package/lib/components/ActionSet/ActionSet.js +10 -12
  74. package/lib/components/AddSelect/AddSelect.js +7 -5
  75. package/lib/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +0 -3
  76. package/lib/components/ButtonMenu/ButtonMenu.js +6 -4
  77. package/lib/components/ButtonMenu/ButtonMenuItem.js +1 -2
  78. package/lib/components/Card/Card.js +31 -21
  79. package/lib/components/Card/CardFooter.js +14 -10
  80. package/lib/components/Card/CardHeader.js +8 -6
  81. package/lib/components/Cascade/Cascade.js +5 -4
  82. package/lib/components/ComboButton/ComboButton.js +0 -4
  83. package/lib/components/ComboButton/ComboButtonItem/index.js +0 -5
  84. package/lib/components/CreateFullPage/CreateFullPageStep.js +17 -14
  85. package/lib/components/CreateModal/CreateModal.js +1 -4
  86. package/lib/components/CreateTearsheet/CreateTearsheet.js +10 -11
  87. package/lib/components/CreateTearsheet/CreateTearsheetStep.js +20 -20
  88. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +342 -75
  89. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +161 -0
  90. package/lib/components/DataSpreadsheet/DataSpreadsheetHeader.js +80 -0
  91. package/lib/components/DataSpreadsheet/createActiveCellFn.js +56 -0
  92. package/lib/components/DataSpreadsheet/getCellSize.js +39 -0
  93. package/lib/components/EditSidePanel/EditSidePanel.js +9 -10
  94. package/lib/components/EmptyStates/EmptyState.js +9 -8
  95. package/lib/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.js +3 -7
  96. package/lib/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.js +3 -7
  97. package/lib/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.js +3 -7
  98. package/lib/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.js +3 -7
  99. package/lib/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.js +3 -7
  100. package/lib/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.js +3 -7
  101. package/lib/components/ExampleComponent/ExampleComponent.js +12 -13
  102. package/lib/components/ExportModal/ExportModal.js +13 -9
  103. package/lib/components/ExpressiveCard/ExpressiveCard.js +0 -8
  104. package/lib/components/ImportModal/ImportModal.js +7 -5
  105. package/lib/components/InlineEdit/InlineEdit.js +11 -13
  106. package/lib/components/LoadingBar/LoadingBar.js +13 -17
  107. package/lib/components/ModifiedTabs/ModifiedTabLabelNew.js +0 -4
  108. package/lib/components/ModifiedTabs/ModifiedTabLabelWithClose.js +0 -5
  109. package/lib/components/ModifiedTabs/ModifiedTabs.js +24 -18
  110. package/lib/components/NotificationsPanel/NotificationsPanel.js +109 -86
  111. package/lib/components/OptionsTile/OptionsTile.js +6 -9
  112. package/lib/components/PageHeader/PageHeader.js +9 -6
  113. package/lib/components/ProductiveCard/ProductiveCard.js +24 -18
  114. package/lib/components/RemoveModal/RemoveModal.js +0 -3
  115. package/lib/components/SidePanel/SidePanel.js +22 -17
  116. package/lib/components/TagSet/TagSet.js +13 -9
  117. package/lib/components/TagSet/TagSetModal.js +17 -13
  118. package/lib/components/TagSet/TagSetOverflow.js +24 -19
  119. package/lib/components/Tearsheet/Tearsheet.js +26 -17
  120. package/lib/components/Tearsheet/TearsheetNarrow.js +18 -15
  121. package/lib/components/Toolbar/ToolbarButton.js +0 -3
  122. package/lib/components/WebTerminal/WebTerminal.js +17 -18
  123. package/lib/components/index.js +0 -8
  124. package/lib/global/js/hooks/index.js +8 -0
  125. package/lib/global/js/hooks/useActiveElement.js +39 -0
  126. package/lib/global/js/utils/Wrap.js +7 -5
  127. package/package.json +8 -8
  128. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +26 -3
  129. package/scss/components/InlineEdit/_inline-edit.scss +5 -0
  130. package/scss/components/_index.scss +0 -1
  131. package/es/components/CancelableTextEdit/CancelableTextEdit.js +0 -245
  132. package/es/components/CancelableTextEdit/index.js +0 -7
  133. package/lib/components/CancelableTextEdit/CancelableTextEdit.js +0 -265
  134. package/lib/components/CancelableTextEdit/index.js +0 -13
  135. package/scss/components/CancelableTextEdit/_cancelable-text-edit.scss +0 -212
  136. package/scss/components/CancelableTextEdit/_index.scss +0 -8
  137. package/scss/components/CancelableTextEdit/_storybook-styles.scss +0 -8
@@ -1,6 +1,12 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
4
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["className", "columns", "data"];
5
+ var _excluded = ["cellSize", "className", "columns", "data", "id", "onActiveCellChange"];
6
+
7
+ 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; }
8
+
9
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
10
 
5
11
  /**
6
12
  * Copyright IBM Corp. 2022, 2022
@@ -9,36 +15,65 @@ var _excluded = ["className", "columns", "data"];
9
15
  * LICENSE file in the root directory of this source tree.
10
16
  */
11
17
  // Import portions of React that are needed.
12
- import React, { useMemo } from 'react';
13
- import { useBlockLayout, useTable } from 'react-table';
14
- import { FixedSizeList } from 'react-window'; // Other standard imports.
18
+ import React, { useMemo, useRef, useEffect, useState, useCallback } from 'react';
19
+ import { useBlockLayout, useTable } from 'react-table'; // Other standard imports.
15
20
 
16
21
  import PropTypes from 'prop-types';
17
22
  import cx from 'classnames';
18
23
  import { getDevtoolsProps } from '../../global/js/utils/devtools';
19
- import { pkg
20
- /*, carbon */
21
- } from '../../settings';
22
- import { getScrollbarWidth } from '../../global/js/utils/getScrollbarWidth'; // The block part of our conventional BEM class names (blockClass__E--M).
24
+ import { pkg } from '../../settings';
25
+ import { getScrollbarWidth } from '../../global/js/utils/getScrollbarWidth';
26
+ import { DataSpreadsheetBody } from './DataSpreadsheetBody';
27
+ import { getCellSize } from './getCellSize';
28
+ import { DataSpreadsheetHeader } from './DataSpreadsheetHeader';
29
+ import { useActiveElement } from '../../global/js/hooks';
30
+ import { createActiveCellFn } from './createActiveCellFn'; // cspell:words rowcount colcount
31
+ // The block part of our conventional BEM class names (blockClass__E--M).
23
32
 
24
33
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
25
- var componentName = 'DataSpreadsheet';
34
+ var componentName = 'DataSpreadsheet'; // Default values for props
35
+
36
+ var defaults = {
37
+ cellSize: 'standard',
38
+ columns: Object.freeze([]),
39
+ data: Object.freeze([])
40
+ };
26
41
  /**
27
42
  * DataSpreadsheet: used to organize and display large amounts of structured data, separated by columns and rows in a grid-like format.
28
43
  */
29
44
 
30
45
  export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
31
- var className = _ref.className,
32
- columns = _ref.columns,
33
- data = _ref.data,
46
+ var _ref$cellSize = _ref.cellSize,
47
+ cellSize = _ref$cellSize === void 0 ? defaults.cellSize : _ref$cellSize,
48
+ className = _ref.className,
49
+ _ref$columns = _ref.columns,
50
+ columns = _ref$columns === void 0 ? defaults.columns : _ref$columns,
51
+ _ref$data = _ref.data,
52
+ data = _ref$data === void 0 ? defaults.data : _ref$data,
53
+ id = _ref.id,
54
+ onActiveCellChange = _ref.onActiveCellChange,
34
55
  rest = _objectWithoutProperties(_ref, _excluded);
35
56
 
57
+ var focusedElement = useActiveElement();
58
+
59
+ var _useState = useState(false),
60
+ _useState2 = _slicedToArray(_useState, 2),
61
+ containerHasFocus = _useState2[0],
62
+ setContainerHasFocus = _useState2[1];
63
+
64
+ var _useState3 = useState(null),
65
+ _useState4 = _slicedToArray(_useState3, 2),
66
+ activeCellCoordinates = _useState4[0],
67
+ setActiveCellCoordinates = _useState4[1];
68
+
69
+ var cellSizeValue = getCellSize(cellSize);
36
70
  var defaultColumn = useMemo(function () {
37
71
  return {
38
72
  width: 150,
39
- rowHeaderWidth: 64
73
+ rowHeaderWidth: 64,
74
+ rowHeight: cellSizeValue
40
75
  };
41
- }, []);
76
+ }, [cellSizeValue]);
42
77
  var scrollBarSize = useMemo(function () {
43
78
  return getScrollbarWidth();
44
79
  }, []);
@@ -53,65 +88,283 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
53
88
  headerGroups = _useTable.headerGroups,
54
89
  rows = _useTable.rows,
55
90
  totalColumnsWidth = _useTable.totalColumnsWidth,
56
- prepareRow = _useTable.prepareRow;
57
-
58
- var RenderRow = React.useCallback(function (_ref2) {
59
- var index = _ref2.index,
60
- style = _ref2.style;
61
- var row = rows[index];
62
- prepareRow(row);
63
- return /*#__PURE__*/React.createElement("div", _extends({}, row.getRowProps({
64
- style: style
65
- }), {
66
- className: "tr",
67
- "data-row-index": index
68
- }), /*#__PURE__*/React.createElement("button", {
69
- type: "button",
70
- className: cx("".concat(blockClass, "__td"), "".concat(blockClass, "__td-th")),
71
- style: {
72
- width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth,
73
- display: 'flex',
74
- justifyContent: 'flex-end',
75
- alignItems: 'center'
91
+ prepareRow = _useTable.prepareRow; // Reset everything when spreadsheet loses focus
92
+
93
+
94
+ useEffect(function () {
95
+ if (!focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
96
+ setContainerHasFocus(false);
97
+ removeActiveCell();
98
+ }
99
+
100
+ if (focusedElement.classList.contains(blockClass) || focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
101
+ setContainerHasFocus(true);
102
+ }
103
+ }, [focusedElement, removeActiveCell]); // Removes the active cell element
104
+
105
+ var removeActiveCell = useCallback(function () {
106
+ var activeCellHighlight = spreadsheetRef.current.querySelector(".".concat(blockClass, "__active-cell--highlight"));
107
+
108
+ if (activeCellHighlight) {
109
+ activeCellHighlight.remove();
110
+ }
111
+ }, [spreadsheetRef]); // Click outside useEffect
112
+
113
+ useEffect(function () {
114
+ var handleOutsideClick = function handleOutsideClick(event) {
115
+ if (!spreadsheetRef.current || spreadsheetRef.current.contains(event.target) || event.target.classList.contains("".concat(blockClass, "__active-cell--highlight"))) {
116
+ return;
76
117
  }
77
- }, index + 1), row.cells.map(function (cell, index) {
78
- return /*#__PURE__*/React.createElement("button", _extends({
79
- key: "cell_".concat(index)
80
- }, cell.getCellProps(), {
81
- type: "button",
82
- className: "".concat(blockClass, "__td")
83
- }), cell.render('Cell'));
84
- }));
85
- }, [prepareRow, rows, defaultColumn.rowHeaderWidth]);
118
+
119
+ removeActiveCell();
120
+ setContainerHasFocus(false);
121
+ setActiveCellCoordinates(null);
122
+ };
123
+
124
+ document.addEventListener('click', handleOutsideClick);
125
+ return function () {
126
+ document.removeEventListener('click', handleOutsideClick);
127
+ };
128
+ }, [spreadsheetRef, removeActiveCell]);
129
+ var createActiveCell = useCallback(function (_ref2) {
130
+ var placementElement = _ref2.placementElement,
131
+ coords = _ref2.coords,
132
+ _ref2$addToHeader = _ref2.addToHeader,
133
+ addToHeader = _ref2$addToHeader === void 0 ? false : _ref2$addToHeader;
134
+ 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;
135
+ var activeCellValue = activeCellFullData ? Object.values(activeCellFullData.row.values)[coords === null || coords === void 0 ? void 0 : coords.column] : null;
136
+ createActiveCellFn({
137
+ placementElement: placementElement,
138
+ coords: coords,
139
+ addToHeader: addToHeader,
140
+ contextRef: spreadsheetRef,
141
+ blockClass: blockClass,
142
+ onActiveCellChange: onActiveCellChange,
143
+ activeCellValue: activeCellValue
144
+ });
145
+ }, [spreadsheetRef, rows, onActiveCellChange]);
146
+ var handleInitialArrowPress = useCallback(function () {
147
+ // If activeCellCoordinates is null then we need to set an initial value
148
+ // which will place the activeCell on the select all cell/button
149
+ if (!activeCellCoordinates) {
150
+ setActiveCellCoordinates({
151
+ column: 'header',
152
+ row: 'header'
153
+ });
154
+ }
155
+
156
+ return;
157
+ }, [activeCellCoordinates]);
158
+
159
+ var updateActiveCellCoordinates = function updateActiveCellCoordinates(_ref3) {
160
+ var coords = _ref3.coords,
161
+ updatedValue = _ref3.updatedValue;
162
+ setActiveCellCoordinates(_objectSpread(_objectSpread({}, coords), updatedValue));
163
+ };
164
+
165
+ var handleKeyPress = useCallback(function (event) {
166
+ var keyCode = event.keyCode; // Command keys need to be returned as there is default browser behavior with these keys
167
+
168
+ if (keyCode === 91 || keyCode === 93) {
169
+ return;
170
+ } // Prevent arrow keys, home key, and end key from scrolling the page when the data spreadsheet container has focus
171
+
172
+
173
+ if ([35, 36, 37, 38, 39, 40].indexOf(keyCode) > -1) {
174
+ event.preventDefault();
175
+ }
176
+
177
+ switch (keyCode) {
178
+ // Tab
179
+ case 9:
180
+ {
181
+ removeActiveCell();
182
+ setContainerHasFocus(false);
183
+ setActiveCellCoordinates(null);
184
+ break;
185
+ }
186
+ // Left
187
+
188
+ case 37:
189
+ {
190
+ handleInitialArrowPress();
191
+
192
+ var coordinatesClone = _objectSpread({}, activeCellCoordinates);
193
+
194
+ if (coordinatesClone.column === 'header') {
195
+ return;
196
+ }
197
+
198
+ if (typeof coordinatesClone.column === 'number') {
199
+ if (coordinatesClone.column === 0) {
200
+ updateActiveCellCoordinates({
201
+ coords: coordinatesClone,
202
+ updatedValue: {
203
+ column: 'header'
204
+ }
205
+ });
206
+ return;
207
+ }
208
+
209
+ updateActiveCellCoordinates({
210
+ coords: coordinatesClone,
211
+ updatedValue: {
212
+ column: coordinatesClone.column - 1
213
+ }
214
+ });
215
+ }
216
+
217
+ break;
218
+ }
219
+ // Up
220
+
221
+ case 38:
222
+ {
223
+ handleInitialArrowPress();
224
+
225
+ var _coordinatesClone = _objectSpread({}, activeCellCoordinates);
226
+
227
+ if (_coordinatesClone.row === 'header') {
228
+ return;
229
+ }
230
+
231
+ if (typeof _coordinatesClone.row === 'number') {
232
+ // set row back to header if we are at index 0
233
+ if (_coordinatesClone.row === 0) {
234
+ updateActiveCellCoordinates({
235
+ coords: _coordinatesClone,
236
+ updatedValue: {
237
+ row: 'header'
238
+ }
239
+ });
240
+ return;
241
+ } // if we are at any other index than 0, subtract 1 from current row index
242
+
243
+
244
+ updateActiveCellCoordinates({
245
+ coords: _coordinatesClone,
246
+ updatedValue: {
247
+ row: _coordinatesClone.row - 1
248
+ }
249
+ });
250
+ }
251
+
252
+ break;
253
+ }
254
+ // Right
255
+
256
+ case 39:
257
+ {
258
+ handleInitialArrowPress();
259
+
260
+ var _coordinatesClone2 = _objectSpread({}, activeCellCoordinates);
261
+
262
+ if (_coordinatesClone2.column === 'header') {
263
+ updateActiveCellCoordinates({
264
+ coords: _coordinatesClone2,
265
+ updatedValue: {
266
+ column: 0
267
+ }
268
+ });
269
+ }
270
+
271
+ if (typeof _coordinatesClone2.column === 'number') {
272
+ // Prevent active cell coordinates from updating if the active
273
+ // cell is in the last column, ie we can't go any further to the right
274
+ if (columns.length - 1 === _coordinatesClone2.column) {
275
+ return;
276
+ }
277
+
278
+ updateActiveCellCoordinates({
279
+ coords: _coordinatesClone2,
280
+ updatedValue: {
281
+ column: _coordinatesClone2.column + 1
282
+ }
283
+ });
284
+ }
285
+
286
+ break;
287
+ }
288
+ // Down
289
+
290
+ case 40:
291
+ {
292
+ handleInitialArrowPress();
293
+
294
+ var _coordinatesClone3 = _objectSpread({}, activeCellCoordinates);
295
+
296
+ if (_coordinatesClone3.row === 'header') {
297
+ updateActiveCellCoordinates({
298
+ coords: _coordinatesClone3,
299
+ updatedValue: {
300
+ row: 0
301
+ }
302
+ });
303
+ }
304
+
305
+ if (typeof _coordinatesClone3.row === 'number') {
306
+ // Prevent active cell coordinates from updating if the active
307
+ // cell is in the last row, ie we can't go any further down since
308
+ // we are in the last row
309
+ if (rows.length - 1 === _coordinatesClone3.row) {
310
+ return;
311
+ }
312
+
313
+ updateActiveCellCoordinates({
314
+ coords: _coordinatesClone3,
315
+ updatedValue: {
316
+ row: _coordinatesClone3.row + 1
317
+ }
318
+ });
319
+ }
320
+
321
+ break;
322
+ }
323
+ }
324
+ }, [handleInitialArrowPress, activeCellCoordinates, removeActiveCell, columns.length, rows.length]); // Adds active cell highlight to correct cell onKeyDown
325
+
326
+ useEffect(function () {
327
+ 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, "\"]"));
328
+ var shouldPlaceActiveCellInHeader = (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' && true;
329
+ var selectAllElement = spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.current.querySelector("[data-row-index=\"header\"][data-column-index=\"header\"]");
330
+
331
+ if (containerHasFocus) {
332
+ createActiveCell({
333
+ placementElement: activeCellCoordinates ? activeCellPlacementElement : selectAllElement,
334
+ coords: activeCellCoordinates,
335
+ addToHeader: shouldPlaceActiveCellInHeader
336
+ });
337
+ }
338
+ }, [activeCellCoordinates, spreadsheetRef, createActiveCell, containerHasFocus]);
339
+ var localRef = useRef();
340
+ var spreadsheetRef = ref || localRef;
86
341
  return /*#__PURE__*/React.createElement("div", _extends({}, rest, getTableProps(), getDevtoolsProps(componentName), {
87
- className: cx(blockClass, className),
88
- ref: ref,
89
- role: "grid"
90
- }), /*#__PURE__*/React.createElement("div", null, headerGroups.map(function (headerGroup, index) {
91
- return /*#__PURE__*/React.createElement("div", _extends({
92
- key: "header_".concat(index)
93
- }, headerGroup.getHeaderGroupProps(), {
94
- className: "".concat(blockClass, "__tr")
95
- }), /*#__PURE__*/React.createElement("button", {
96
- type: "button",
97
- className: "".concat(blockClass, "__th"),
98
- style: {
99
- width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth
100
- }
101
- }, "\xA0"), headerGroup.headers.map(function (column, index) {
102
- return /*#__PURE__*/React.createElement("button", _extends({
103
- key: "column_".concat(index)
104
- }, column.getHeaderProps(), {
105
- type: "button",
106
- className: "".concat(blockClass, "__th")
107
- }), column.render('Header'));
108
- }));
109
- })), /*#__PURE__*/React.createElement("div", getTableBodyProps(), /*#__PURE__*/React.createElement(FixedSizeList, {
110
- height: 400,
111
- itemCount: rows.length,
112
- itemSize: 36,
113
- width: totalColumnsWidth + scrollBarSize
114
- }, RenderRow)));
342
+ className: cx(blockClass, className, _defineProperty({}, "".concat(blockClass, "__container-has-focus"), containerHasFocus)),
343
+ ref: spreadsheetRef,
344
+ role: "grid",
345
+ tabIndex: 0,
346
+ "aria-rowcount": (rows === null || rows === void 0 ? void 0 : rows.length) || 0,
347
+ "aria-colcount": (columns === null || columns === void 0 ? void 0 : columns.length) || 0,
348
+ onKeyDown: handleKeyPress,
349
+ onFocus: function onFocus() {
350
+ return setContainerHasFocus(true);
351
+ }
352
+ }), /*#__PURE__*/React.createElement(DataSpreadsheetHeader, {
353
+ cellSizeValue: cellSizeValue,
354
+ defaultColumn: defaultColumn,
355
+ headerGroups: headerGroups
356
+ }), /*#__PURE__*/React.createElement(DataSpreadsheetBody, {
357
+ cellSize: cellSize,
358
+ defaultColumn: defaultColumn,
359
+ getTableBodyProps: getTableBodyProps,
360
+ onActiveCellChange: onActiveCellChange,
361
+ prepareRow: prepareRow,
362
+ rows: rows,
363
+ setActiveCellCoordinates: setActiveCellCoordinates,
364
+ scrollBarSize: scrollBarSize,
365
+ totalColumnsWidth: totalColumnsWidth,
366
+ id: id
367
+ }));
115
368
  }); // Return a placeholder if not released and not enabled by feature flag
116
369
 
117
370
  DataSpreadsheet = pkg.checkComponentEnabled(DataSpreadsheet, componentName); // The display name of the component, used by React. Note that displayName
@@ -122,6 +375,11 @@ DataSpreadsheet.displayName = componentName; // The types and DocGen commentary
122
375
  // See https://www.npmjs.com/package/prop-types#usage.
123
376
 
124
377
  DataSpreadsheet.propTypes = {
378
+ /**
379
+ * Specifies the cell height
380
+ */
381
+ cellSize: PropTypes.oneOf(['compact', 'standard', 'medium', 'large']),
382
+
125
383
  /**
126
384
  * Provide an optional class to be applied to the containing node.
127
385
  */
@@ -140,15 +398,17 @@ DataSpreadsheet.propTypes = {
140
398
  /**
141
399
  * The spreadsheet data that will be rendered in the body of the spreadsheet component
142
400
  */
143
- data: PropTypes.arrayOf(PropTypes.shape)
144
- /* TODO: add types and DocGen for all props. */
401
+ data: PropTypes.arrayOf(PropTypes.shape),
402
+
403
+ /**
404
+ * The spreadsheet id
405
+ */
406
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
145
407
 
146
- }; // Default values for component props. Default values are not required for
147
- // props that are required, nor for props where the component can apply
148
- // 'undefined' values reasonably. Default values should be provided when the
149
- // component needs to make a choice or assumption when a prop is not supplied.
408
+ /**
409
+ * The event handler that is called when the active cell changes
410
+ */
411
+ onActiveCellChange: PropTypes.func
412
+ /* TODO: add types and DocGen for all props. */
150
413
 
151
- DataSpreadsheet.defaultProps = {
152
- data: [],
153
- columns: []
154
414
  };
@@ -0,0 +1,138 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+
3
+ /**
4
+ * Copyright IBM Corp. 2022, 2022
5
+ *
6
+ * This source code is licensed under the Apache-2.0 license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ import React, { useRef, useCallback, useEffect } from 'react';
10
+ import PropTypes from 'prop-types';
11
+ import { FixedSizeList } from 'react-window';
12
+ import cx from 'classnames';
13
+ import { pkg } from '../../settings';
14
+ var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
15
+ export var DataSpreadsheetBody = function DataSpreadsheetBody(_ref) {
16
+ var defaultColumn = _ref.defaultColumn,
17
+ getTableBodyProps = _ref.getTableBodyProps,
18
+ id = _ref.id,
19
+ prepareRow = _ref.prepareRow,
20
+ rows = _ref.rows,
21
+ setActiveCellCoordinates = _ref.setActiveCellCoordinates,
22
+ scrollBarSize = _ref.scrollBarSize,
23
+ totalColumnsWidth = _ref.totalColumnsWidth;
24
+ // Make sure that if the cellSize prop changes, the active
25
+ // cell also gets updated with the new size
26
+ useEffect(function () {
27
+ var listContainer = spreadsheetBodyRef === null || spreadsheetBodyRef === void 0 ? void 0 : spreadsheetBodyRef.current;
28
+ var activeCellButton = listContainer.querySelector(".".concat(blockClass, "__active-cell--highlight"));
29
+
30
+ if (activeCellButton) {
31
+ activeCellButton.style.height = "".concat(defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight, "px");
32
+ }
33
+ }, [defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight]); // onClick fn for each cell in the data spreadsheet body,
34
+ // adds the active cell highlight
35
+
36
+ var handleBodyCellClick = useCallback(function (cell, columnIndex) {
37
+ setActiveCellCoordinates({
38
+ row: cell.row.index,
39
+ column: columnIndex
40
+ });
41
+ }, [setActiveCellCoordinates]); // Renders each cell in the spreadsheet body
42
+
43
+ var RenderRow = useCallback(function (_ref2) {
44
+ var index = _ref2.index,
45
+ style = _ref2.style;
46
+ var row = rows[index];
47
+ prepareRow(row);
48
+ return /*#__PURE__*/React.createElement("div", _extends({}, row.getRowProps({
49
+ style: style
50
+ }), {
51
+ className: cx("".concat(blockClass, "__tr")),
52
+ "data-row-index": index
53
+ }), /*#__PURE__*/React.createElement("button", {
54
+ tabIndex: -1,
55
+ "data-row-index": index,
56
+ "data-column-index": "header",
57
+ type: "button",
58
+ className: cx("".concat(blockClass, "__td"), "".concat(blockClass, "__td-th"), "".concat(blockClass, "--interactive-cell-element")),
59
+ style: {
60
+ width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth
61
+ }
62
+ }, index + 1), row.cells.map(function (cell, index) {
63
+ return /*#__PURE__*/React.createElement("button", _extends({
64
+ tabIndex: -1,
65
+ "data-row-index": cell.row.index,
66
+ "data-column-index": index
67
+ }, cell.getCellProps(), {
68
+ className: cx("".concat(blockClass, "__td"), "".concat(blockClass, "--interactive-cell-element")),
69
+ key: "cell_".concat(index),
70
+ onClick: function onClick() {
71
+ return handleBodyCellClick(cell, index);
72
+ },
73
+ type: "button"
74
+ }), cell.render('Cell'));
75
+ }));
76
+ }, [prepareRow, rows, defaultColumn.rowHeaderWidth, handleBodyCellClick]);
77
+ var spreadsheetBodyRef = useRef();
78
+ return /*#__PURE__*/React.createElement("div", _extends({
79
+ ref: spreadsheetBodyRef,
80
+ className: cx("".concat(blockClass, "__body--container"))
81
+ }, getTableBodyProps()), /*#__PURE__*/React.createElement(FixedSizeList, {
82
+ className: cx("".concat(blockClass, "__list--container"), "".concat(blockClass, "__list--container--").concat(id)),
83
+ height: 400,
84
+ itemCount: rows.length,
85
+ itemSize: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight,
86
+ width: totalColumnsWidth + scrollBarSize
87
+ }, RenderRow));
88
+ };
89
+ DataSpreadsheetBody.propTypes = {
90
+ /**
91
+ * Default spreadsheet sizing values
92
+ */
93
+ defaultColumn: PropTypes.shape({
94
+ rowHeight: PropTypes.number,
95
+ rowHeaderWidth: PropTypes.number,
96
+ width: PropTypes.number
97
+ }),
98
+
99
+ /**
100
+ * Function to set table body prop values
101
+ */
102
+ getTableBodyProps: PropTypes.func,
103
+
104
+ /**
105
+ * The spreadsheet id
106
+ */
107
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
108
+
109
+ /**
110
+ * The event handler that is called when the active cell changes
111
+ */
112
+ onActiveCellChange: PropTypes.func,
113
+
114
+ /**
115
+ * Prepare row function from react-table
116
+ */
117
+ prepareRow: PropTypes.func,
118
+
119
+ /**
120
+ * All of the spreadsheet row data
121
+ */
122
+ rows: PropTypes.arrayOf(PropTypes.object),
123
+
124
+ /**
125
+ * The scrollbar width
126
+ */
127
+ scrollBarSize: PropTypes.number,
128
+
129
+ /**
130
+ * Setter fn for activeCellCoordinates state value
131
+ */
132
+ setActiveCellCoordinates: PropTypes.func,
133
+
134
+ /**
135
+ * The total columns width
136
+ */
137
+ totalColumnsWidth: PropTypes.number
138
+ };
@@ -0,0 +1,64 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+
3
+ /**
4
+ * Copyright IBM Corp. 2022, 2022
5
+ *
6
+ * This source code is licensed under the Apache-2.0 license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ import React from 'react';
10
+ import PropTypes from 'prop-types';
11
+ import cx from 'classnames';
12
+ import { pkg } from '../../settings';
13
+ var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
14
+ export var DataSpreadsheetHeader = function DataSpreadsheetHeader(_ref) {
15
+ var defaultColumn = _ref.defaultColumn,
16
+ headerGroups = _ref.headerGroups;
17
+ return /*#__PURE__*/React.createElement("div", {
18
+ className: cx("".concat(blockClass, "__header--container"))
19
+ }, headerGroups.map(function (headerGroup, index) {
20
+ return /*#__PURE__*/React.createElement("div", _extends({
21
+ key: "header_".concat(index)
22
+ }, headerGroup.getHeaderGroupProps(), {
23
+ className: "".concat(blockClass, "__tr")
24
+ }), /*#__PURE__*/React.createElement("button", {
25
+ "data-row-index": "header",
26
+ "data-column-index": "header",
27
+ type: "button",
28
+ tabIndex: -1,
29
+ className: cx("".concat(blockClass, "__th"), "".concat(blockClass, "--interactive-cell-element")),
30
+ style: {
31
+ width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth,
32
+ height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight
33
+ }
34
+ }, "\xA0"), headerGroup.headers.map(function (column, index) {
35
+ return /*#__PURE__*/React.createElement("button", _extends({
36
+ key: "column_".concat(index),
37
+ "data-row-index": "header",
38
+ "data-column-index": index,
39
+ tabIndex: -1,
40
+ style: {
41
+ height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight
42
+ }
43
+ }, column.getHeaderProps(), {
44
+ className: cx("".concat(blockClass, "__th"), "".concat(blockClass, "--interactive-cell-element")),
45
+ type: "button"
46
+ }), column.render('Header'));
47
+ }));
48
+ }));
49
+ };
50
+ DataSpreadsheetHeader.propTypes = {
51
+ /**
52
+ * Default spreadsheet sizing values
53
+ */
54
+ defaultColumn: PropTypes.shape({
55
+ rowHeight: PropTypes.number,
56
+ rowHeaderWidth: PropTypes.number,
57
+ width: PropTypes.number
58
+ }),
59
+
60
+ /**
61
+ * Headers provided from useTable hook
62
+ */
63
+ headerGroups: PropTypes.arrayOf(PropTypes.object)
64
+ };