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