@carbon/ibm-products 1.12.0 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. package/css/index-full-carbon.css +60 -13
  2. package/css/index-full-carbon.css.map +1 -1
  3. package/css/index-full-carbon.min.css +6 -6
  4. package/css/index-full-carbon.min.css.map +1 -1
  5. package/css/index-without-carbon-released-only.css +14 -6
  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 +60 -13
  10. package/css/index-without-carbon.css.map +1 -1
  11. package/css/index-without-carbon.min.css +5 -5
  12. package/css/index-without-carbon.min.css.map +1 -1
  13. package/css/index.css +60 -13
  14. package/css/index.css.map +1 -1
  15. package/css/index.min.css +6 -6
  16. package/css/index.min.css.map +1 -1
  17. package/es/components/ActionBar/ActionBar.js +3 -1
  18. package/es/components/ActionBar/ActionBarOverflowItems.js +5 -3
  19. package/es/components/AddSelect/AddSelectList.js +27 -1
  20. package/es/components/AddSelect/AddSelectSidebar.js +15 -5
  21. package/es/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +2 -0
  22. package/es/components/DataSpreadsheet/DataSpreadsheet.js +87 -31
  23. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +87 -33
  24. package/es/components/DataSpreadsheet/hooks/useSpreadsheetOutsideClick.js +6 -4
  25. package/es/components/HTTPErrors/assets/HTTPErrorSvg403.js +2 -3
  26. package/es/components/HTTPErrors/assets/HTTPErrorSvg404.js +2 -3
  27. package/es/components/HTTPErrors/assets/HTTPErrorSvgOther.js +2 -3
  28. package/es/components/TagSet/TagSet.js +12 -3
  29. package/es/components/UserProfileImage/UserProfileImage.js +37 -9
  30. package/lib/components/ActionBar/ActionBar.js +3 -1
  31. package/lib/components/ActionBar/ActionBarOverflowItems.js +5 -3
  32. package/lib/components/AddSelect/AddSelectList.js +28 -1
  33. package/lib/components/AddSelect/AddSelectSidebar.js +15 -11
  34. package/lib/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +2 -0
  35. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +89 -30
  36. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +86 -33
  37. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetOutsideClick.js +6 -3
  38. package/lib/components/HTTPErrors/assets/HTTPErrorSvg403.js +2 -3
  39. package/lib/components/HTTPErrors/assets/HTTPErrorSvg404.js +2 -3
  40. package/lib/components/HTTPErrors/assets/HTTPErrorSvgOther.js +2 -3
  41. package/lib/components/TagSet/TagSet.js +12 -3
  42. package/lib/components/UserProfileImage/UserProfileImage.js +37 -9
  43. package/package.json +9 -9
  44. package/scss/components/AddSelect/_add-select.scss +14 -2
  45. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +37 -5
  46. package/scss/components/HTTPErrors/_http-errors.scss +16 -16
  47. package/scss/components/PageHeader/_page-header.scss +4 -0
@@ -49,8 +49,10 @@ var ActionBarOverflowItems = function ActionBarOverflowItems(_ref) {
49
49
  className: (0, _classnames.default)(blockClass, className),
50
50
  direction: "bottom",
51
51
  flipped: true,
52
+ iconDescription: overflowAriaLabel // also needs setting to avoid a11y "Accessible name does not match or contain the visible label text"
53
+ ,
52
54
  menuOptionsClass: (0, _classnames.default)("".concat(blockClass, "__options"), menuOptionsClass)
53
- }, _react.default.Children.map(overflowItems, function (item) {
55
+ }, _react.default.Children.map(overflowItems, function (item, index) {
54
56
  // This uses a copy of a menu item option
55
57
  // NOTE: Cannot use a real Tooltip icon below as it uses a <button /> the
56
58
  // div equivalent below is based on Carbon 10.25.0
@@ -58,10 +60,10 @@ var ActionBarOverflowItems = function ActionBarOverflowItems(_ref) {
58
60
  className: "".concat(blockClass, "__item"),
59
61
  itemText: /*#__PURE__*/_react.default.createElement("div", {
60
62
  className: "".concat(blockClass, "__item-content"),
61
- "aria-describedby": "".concat(internalId, "--item-label")
63
+ "aria-describedby": "".concat(internalId.current, "-").concat(index, "--item-label")
62
64
  }, /*#__PURE__*/_react.default.createElement("span", {
63
65
  className: "".concat(blockClass, "__item-label"),
64
- id: "".concat(internalId, "--item-label")
66
+ id: "".concat(internalId.current, "-").concat(index, "--item-label")
65
67
  }, item.props.iconDescription), /*#__PURE__*/_react.default.createElement(item.props.renderIcon, null))
66
68
  });
67
69
  }));
@@ -21,6 +21,8 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
21
21
 
22
22
  var _classnames = _interopRequireDefault(require("classnames"));
23
23
 
24
+ var _UserProfileImage = require("../UserProfileImage");
25
+
24
26
  var _settings = require("../../settings");
25
27
 
26
28
  //
@@ -121,6 +123,27 @@ var AddSelectList = function AddSelectList(_ref) {
121
123
  return multiSelection.includes(id);
122
124
  };
123
125
 
126
+ var getAvatarProps = function getAvatarProps(_ref3) {
127
+ var src = _ref3.src,
128
+ alt = _ref3.alt,
129
+ icon = _ref3.icon,
130
+ backgroundColor = _ref3.backgroundColor;
131
+ return {
132
+ className: "".concat(blockClass, "-cell-avatar"),
133
+ size: 'lg',
134
+ theme: 'light',
135
+ image: src,
136
+ imageDescription: alt,
137
+ icon: icon,
138
+ backgroundColor: backgroundColor
139
+ };
140
+ };
141
+
142
+ var getItemIcon = function getItemIcon(_ref4) {
143
+ var Icon = _ref4.icon;
144
+ return /*#__PURE__*/_react.default.createElement(Icon, null);
145
+ };
146
+
124
147
  return /*#__PURE__*/_react.default.createElement("div", {
125
148
  className: "".concat(blockClass, "-wrapper")
126
149
  }, /*#__PURE__*/_react.default.createElement(_carbonComponentsReact.StructuredListWrapper, {
@@ -147,12 +170,16 @@ var AddSelectList = function AddSelectList(_ref) {
147
170
  checked: isSelected(item.id),
148
171
  className: "".concat(blockClass, "-checkbox-wrapper")
149
172
  }), /*#__PURE__*/_react.default.createElement("div", {
173
+ className: "".concat(blockClass, "-checkbox-label-wrapper")
174
+ }, item.avatar && /*#__PURE__*/_react.default.createElement(_UserProfileImage.UserProfileImage, getAvatarProps(item.avatar)), item.icon && /*#__PURE__*/_react.default.createElement("div", {
175
+ className: "".concat(blockClass, "-cell-icon")
176
+ }, getItemIcon(item)), /*#__PURE__*/_react.default.createElement("div", {
150
177
  className: "".concat(blockClass, "-checkbox-label-text")
151
178
  }, /*#__PURE__*/_react.default.createElement("span", {
152
179
  className: "".concat(blockClass, "-cell-title")
153
180
  }, item.title), item.subtitle && /*#__PURE__*/_react.default.createElement("span", {
154
181
  className: "".concat(blockClass, "-cell-subtitle")
155
- }, item.subtitle))), (modifiers === null || modifiers === void 0 ? void 0 : (_modifiers$options = modifiers.options) === null || _modifiers$options === void 0 ? void 0 : _modifiers$options.length) && /*#__PURE__*/_react.default.createElement(_carbonComponentsReact.Dropdown, {
182
+ }, item.subtitle)))), (modifiers === null || modifiers === void 0 ? void 0 : (_modifiers$options = modifiers.options) === null || _modifiers$options === void 0 ? void 0 : _modifiers$options.length) && /*#__PURE__*/_react.default.createElement(_carbonComponentsReact.Dropdown, {
156
183
  id: "".concat(item.id, "-modifier"),
157
184
  type: "inline",
158
185
  items: modifiers === null || modifiers === void 0 ? void 0 : modifiers.options,
@@ -7,6 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.AddSelectSidebar = void 0;
9
9
 
10
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
+
10
12
  var _react = _interopRequireDefault(require("react"));
11
13
 
12
14
  var _carbonComponentsReact = require("carbon-components-react");
@@ -19,12 +21,7 @@ var _NoDataEmptyState = require("../../components/EmptyStates/NoDataEmptyState")
19
21
 
20
22
  var _settings = require("../../settings");
21
23
 
22
- //
23
- // Copyright IBM Corp. 2022
24
- //
25
- // This source code is licensed under the Apache-2.0 license found in the
26
- // LICENSE file in the root directory of this source tree.
27
- //
24
+ var _excluded = ["icon", "avatar"];
28
25
  var componentName = 'AddSelectSidebar';
29
26
 
30
27
  var AddSelectSidebar = function AddSelectSidebar(_ref) {
@@ -44,11 +41,18 @@ var AddSelectSidebar = function AddSelectSidebar(_ref) {
44
41
  setMultiSelection(newSelections);
45
42
  };
46
43
 
47
- var sidebarItems = multiSelection.map(function (selectedId) {
48
- return items.find(function (item) {
49
- return item.id === selectedId;
50
- });
51
- });
44
+ var sidebarItems = multiSelection.reduce(function (acc, cur) {
45
+ var selectedItem = items.find(function (item) {
46
+ return item.id === cur;
47
+ }); // certain properties should not be displayed in the sidebar
48
+ // eslint-disable-next-line no-unused-vars
49
+
50
+ var icon = selectedItem.icon,
51
+ avatar = selectedItem.avatar,
52
+ newItem = (0, _objectWithoutProperties2.default)(selectedItem, _excluded);
53
+ acc.push(newItem);
54
+ return acc;
55
+ }, []);
52
56
 
53
57
  var getTitle = function getTitle(_ref2) {
54
58
  var title = _ref2.title,
@@ -93,6 +93,8 @@ var BreadcrumbWithOverflow = function BreadcrumbWithOverflow(_ref) {
93
93
  key: "breadcrumb-overflow-".concat(internalId.current)
94
94
  }, /*#__PURE__*/_react.default.createElement(_carbonComponentsReact.OverflowMenu, {
95
95
  ariaLabel: overflowAriaLabel,
96
+ iconDescription: overflowAriaLabel // also needs setting to avoid a11y "Accessible name does not match or contain the visible label text"
97
+ ,
96
98
  renderIcon: _iconsReact.OverflowMenuHorizontal32,
97
99
  className: "".concat(blockClass, "__overflow-menu"),
98
100
  menuOptionsClass: "".concat(blockClass, "__overflow-menu-options")
@@ -23,6 +23,8 @@ var _react = _interopRequireWildcard(require("react"));
23
23
 
24
24
  var _reactTable = require("react-table");
25
25
 
26
+ var _layout = require("@carbon/layout");
27
+
26
28
  var _propTypes = _interopRequireDefault(require("prop-types"));
27
29
 
28
30
  var _classnames = _interopRequireDefault(require("classnames"));
@@ -57,7 +59,9 @@ var _handleMultipleKeys = require("./utils/handleMultipleKeys");
57
59
 
58
60
  var _handleHeaderCellSelection = require("./utils/handleHeaderCellSelection");
59
61
 
60
- var _excluded = ["cellSize", "className", "columns", "data", "onDataUpdate", "id", "onActiveCellChange", "onSelectionAreaChange"];
62
+ var _removeCellSelections = require("./utils/removeCellSelections");
63
+
64
+ var _excluded = ["cellSize", "className", "columns", "data", "defaultEmptyRowCount", "onDataUpdate", "id", "onActiveCellChange", "onSelectionAreaChange"];
61
65
 
62
66
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
63
67
 
@@ -76,6 +80,7 @@ var defaults = {
76
80
  cellSize: 'standard',
77
81
  columns: Object.freeze([]),
78
82
  data: Object.freeze([]),
83
+ defaultEmptyRowCount: 16,
79
84
  onDataUpdate: Object.freeze(function () {}),
80
85
  onActiveCellChange: Object.freeze(function () {}),
81
86
  onSelectionAreaChange: Object.freeze(function () {})
@@ -92,6 +97,8 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
92
97
  columns = _ref$columns === void 0 ? defaults.columns : _ref$columns,
93
98
  _ref$data = _ref.data,
94
99
  data = _ref$data === void 0 ? defaults.data : _ref$data,
100
+ _ref$defaultEmptyRowC = _ref.defaultEmptyRowCount,
101
+ defaultEmptyRowCount = _ref$defaultEmptyRowC === void 0 ? defaults.defaultEmptyRowCount : _ref$defaultEmptyRowC,
95
102
  _ref$onDataUpdate = _ref.onDataUpdate,
96
103
  onDataUpdate = _ref$onDataUpdate === void 0 ? defaults.onDataUpdate : _ref$onDataUpdate,
97
104
  id = _ref.id,
@@ -157,6 +164,7 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
157
164
 
158
165
  var activeKeys = (0, _react.useRef)([]);
159
166
  var activeCellRef = (0, _react.useRef)();
167
+ var cellEditorRulerRef = (0, _react.useRef)();
160
168
  var defaultColumn = (0, _react.useMemo)(function () {
161
169
  return {
162
170
  width: 150,
@@ -204,22 +212,7 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
204
212
  setCellEditorValue('');
205
213
  setIsEditing(false);
206
214
  cellEditorRef.current.style.display = 'none';
207
- }, []); // Removes the cell selection elements
208
-
209
- var removeCellSelections = (0, _react.useCallback)(function (matcher) {
210
- if (matcher && typeof matcher === 'string') {
211
- var selectionToRemove = spreadsheetRef.current.querySelector("[data-matcher-id=\"".concat(matcher, "\"]"));
212
-
213
- if (selectionToRemove) {
214
- selectionToRemove.remove();
215
- }
216
- } else {
217
- var cellSelections = spreadsheetRef.current.querySelectorAll(".".concat(blockClass, "__selection-area--element"));
218
- (0, _toConsumableArray2.default)(cellSelections).forEach(function (element) {
219
- return element.remove();
220
- });
221
- }
222
- }, [spreadsheetRef]); // Remove cell editor if the active cell coordinates change and save with new cell data, this will
215
+ }, []); // Remove cell editor if the active cell coordinates change and save with new cell data, this will
223
216
  // happen if you click on another cell while isEditing is true
224
217
 
225
218
  (0, _react.useEffect)(function () {
@@ -229,6 +222,7 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
229
222
  var cellProps = rows[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row].cells[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column];
230
223
  removeCellEditor();
231
224
  updateData(prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row, cellProps.column.id);
225
+ cellEditorRulerRef.current.textContent = '';
232
226
  }
233
227
 
234
228
  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)) {
@@ -277,7 +271,7 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
277
271
  setActiveCellCoordinates: setActiveCellCoordinates,
278
272
  setSelectionAreas: setSelectionAreas,
279
273
  removeActiveCell: removeActiveCell,
280
- removeCellSelections: removeCellSelections,
274
+ removeCellSelections: _removeCellSelections.removeCellSelections,
281
275
  setContainerHasFocus: setContainerHasFocus,
282
276
  activeKeys: activeKeys,
283
277
  removeCellEditor: removeCellEditor
@@ -346,7 +340,7 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
346
340
  if (selectionAreas !== null && selectionAreas !== void 0 && selectionAreas.length && key !== 'Shift' && !activeKeys.current.includes('Shift')) {
347
341
  setSelectionAreas([]);
348
342
  setSelectionAreaData([]);
349
- removeCellSelections({
343
+ (0, _removeCellSelections.removeCellSelections)({
350
344
  spreadsheetRef: spreadsheetRef
351
345
  });
352
346
  }
@@ -522,13 +516,14 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
522
516
  }
523
517
  }
524
518
  }
525
- }, [updateActiveCellCoordinates, handleInitialArrowPress, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, isEditing, removeCellEditor, removeCellSelections, selectionAreas]);
519
+ }, [updateActiveCellCoordinates, handleInitialArrowPress, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, isEditing, removeCellEditor, selectionAreas]);
526
520
 
527
521
  var startEditMode = function startEditMode() {
528
522
  setIsEditing(true);
529
523
  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;
530
524
  var activeCellValue = activeCellFullData ? Object.values(activeCellFullData.row.values)[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column] : null;
531
525
  setCellEditorValue(activeCellValue);
526
+ cellEditorRulerRef.current.textContent = activeCellValue;
532
527
  };
533
528
 
534
529
  var handleActiveCellClick = function handleActiveCellClick() {
@@ -594,11 +589,10 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
594
589
 
595
590
  var handleActiveCellDoubleClick = function handleActiveCellDoubleClick() {
596
591
  startEditMode();
597
- }; // Update the data
598
-
592
+ };
599
593
 
600
- var handleEditSubmit = function handleEditSubmit(event) {
601
- var key = event.key;
594
+ var updateSelectionAreaOnCellEditSubmit = function updateSelectionAreaOnCellEditSubmit(_ref5) {
595
+ var type = _ref5.type;
602
596
 
603
597
  var submitEditChanges = function submitEditChanges() {
604
598
  var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates;
@@ -607,8 +601,33 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
607
601
  updateData(prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row, cellProps.column.id);
608
602
  };
609
603
 
604
+ (0, _removeCellSelections.removeCellSelections)({
605
+ spreadsheetRef: spreadsheetRef
606
+ });
607
+ submitEditChanges();
608
+ var tempMatcher = (0, _uuidv.default)();
609
+ var newSelectionArea = {
610
+ row: type === 'Enter' ? activeCellCoordinates.row === rows.length - 1 ? activeCellCoordinates.row : activeCellCoordinates.row + 1 : activeCellCoordinates.row,
611
+ column: type === 'Tab' ? activeCellCoordinates.column === columns.length - 1 ? activeCellCoordinates.column : activeCellCoordinates.column + 1 : activeCellCoordinates.column
612
+ };
613
+ setSelectionAreas([{
614
+ point1: newSelectionArea,
615
+ point2: newSelectionArea,
616
+ matcher: tempMatcher,
617
+ areaCreated: false
618
+ }]);
619
+ setCurrentMatcher(tempMatcher);
620
+ cellEditorRulerRef.current.textContent = '';
621
+ }; // Update the data
622
+
623
+
624
+ var handleEditSubmit = function handleEditSubmit(event) {
625
+ var key = event.key;
626
+
610
627
  if (key === 'Enter') {
611
- submitEditChanges();
628
+ updateSelectionAreaOnCellEditSubmit({
629
+ type: 'Enter'
630
+ });
612
631
  setActiveCellCoordinates(function (prev) {
613
632
  return _objectSpread(_objectSpread({}, prev), {}, {
614
633
  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
@@ -619,7 +638,9 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
619
638
 
620
639
  if (key === 'Tab') {
621
640
  event.preventDefault();
622
- submitEditChanges();
641
+ updateSelectionAreaOnCellEditSubmit({
642
+ type: 'Tab'
643
+ });
623
644
  setActiveCellCoordinates(function (prev) {
624
645
  return _objectSpread(_objectSpread({}, prev), {}, {
625
646
  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
@@ -647,14 +668,39 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
647
668
 
648
669
  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';
649
670
  (_cellEditorRef$curren = cellEditorRef.current) === null || _cellEditorRef$curren === void 0 ? void 0 : _cellEditorRef$curren.focus();
671
+ var rulerWidth = cellEditorRulerRef.current.offsetWidth;
672
+ var cellWidth = activeCellRef.current.offsetWidth;
673
+
674
+ if (rulerWidth >= cellWidth) {
675
+ var widthMultiplier = Math.floor(rulerWidth / cellWidth) + 1;
676
+ var startingColumnPosition = activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column;
677
+ var startingRowPosition = activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row;
678
+ var totalColumns = columns.length;
679
+ var totalRows = rows.length;
680
+ var totalMultiplierPossible = totalColumns - startingColumnPosition;
681
+ var totalCellEditorMaxHeight = (totalRows - startingRowPosition) * defaultColumn.rowHeight;
682
+ cellEditorRef.current.style.maxHeight = (0, _layout.px)(totalCellEditorMaxHeight);
683
+ cellEditorRef.current.style.width = (0, _layout.px)(cellWidth * (widthMultiplier <= totalMultiplierPossible ? widthMultiplier : totalMultiplierPossible));
684
+ cellEditorRef.current.style.height = (0, _layout.px)(cellEditorRef.current.scrollHeight); // adds dynamic height to cell editor
685
+ // Cell editor has reached max height, we need to add the scrolling back.
686
+ // We also need to subtract 1 to account for the fact that the cell editor
687
+ // is placed one pixel below the cell being edited to account for the border
688
+
689
+ if (cellEditorRef.current.clientHeight === totalCellEditorMaxHeight - 1) {
690
+ cellEditorRef.current.style.overflow = 'auto';
691
+ } else {
692
+ cellEditorRef.current.style.overflow = 'hidden';
693
+ }
694
+ }
650
695
  }
651
696
 
652
697
  if (!isEditing) {
698
+ cellEditorRef.current.style.overflow = 'hidden';
653
699
  cellEditorRef.current.style.display = 'none';
654
700
  cellEditorRef.current.blur();
655
701
  activeCellRef.current.focus();
656
702
  }
657
- }, [isEditing, activeCellCoordinates, rows]);
703
+ }, [isEditing, activeCellCoordinates, rows, cellEditorValue, columns.length, defaultColumn]);
658
704
 
659
705
  var handleKeyUp = function handleKeyUp(event) {
660
706
  var _activeKeys$current3;
@@ -671,7 +717,7 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
671
717
  };
672
718
 
673
719
  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({}, rest, getTableProps(), (0, _devtools.getDevtoolsProps)(componentName), {
674
- className: (0, _classnames.default)(blockClass, className, (0, _defineProperty2.default)({}, "".concat(blockClass, "__container-has-focus"), containerHasFocus)),
720
+ className: (0, _classnames.default)(blockClass, className, "".concat(blockClass, "--interactive-cell-element"), (0, _defineProperty2.default)({}, "".concat(blockClass, "__container-has-focus"), containerHasFocus)),
675
721
  ref: spreadsheetRef,
676
722
  role: "grid",
677
723
  tabIndex: 0,
@@ -707,8 +753,10 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
707
753
  selectionAreas: selectionAreas,
708
754
  setSelectionAreas: setSelectionAreas,
709
755
  cellSize: cellSize,
756
+ headerGroups: headerGroups,
710
757
  defaultColumn: defaultColumn,
711
758
  getTableBodyProps: getTableBodyProps,
759
+ onDataUpdate: onDataUpdate,
712
760
  onActiveCellChange: onActiveCellChange,
713
761
  onSelectionAreaChange: onSelectionAreaChange,
714
762
  prepareRow: prepareRow,
@@ -719,7 +767,8 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
719
767
  scrollBarSize: scrollBarSize,
720
768
  totalColumnsWidth: totalColumnsWidth,
721
769
  id: id,
722
- columns: columns
770
+ columns: columns,
771
+ defaultEmptyRowCount: defaultEmptyRowCount
723
772
  }), /*#__PURE__*/_react.default.createElement("button", {
724
773
  onClick: handleActiveCellClick,
725
774
  onKeyDown: handleActiveCellKeyDown,
@@ -731,12 +780,17 @@ var DataSpreadsheet = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref
731
780
  value: cellEditorValue,
732
781
  onKeyDown: handleEditSubmit,
733
782
  onChange: function onChange(event) {
734
- return setCellEditorValue(event.target.value);
783
+ setCellEditorValue(event.target.value);
784
+ cellEditorRulerRef.current.textContent = event.target.value;
735
785
  },
736
786
  ref: cellEditorRef,
737
787
  labelText: "",
738
788
  "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,
739
789
  className: (0, _classnames.default)("".concat(blockClass, "__cell-editor"), "".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__cell-editor--").concat(cellSize), (0, _defineProperty2.default)({}, "".concat(blockClass, "__cell-editor--active"), isEditing))
790
+ }), /*#__PURE__*/_react.default.createElement("pre", {
791
+ "aria-hidden": true,
792
+ ref: cellEditorRulerRef,
793
+ className: "".concat(blockClass, "__cell-editor-ruler")
740
794
  }));
741
795
  }); // Return a placeholder if not released and not enabled by feature flag
742
796
 
@@ -775,6 +829,11 @@ DataSpreadsheet.propTypes = {
775
829
  */
776
830
  data: _propTypes.default.arrayOf(_propTypes.default.shape),
777
831
 
832
+ /**
833
+ * Sets the number of empty rows to be created when there is no data provided
834
+ */
835
+ defaultEmptyRowCount: _propTypes.default.number,
836
+
778
837
  /**
779
838
  * The spreadsheet id
780
839
  */
@@ -23,6 +23,8 @@ var _reactWindow = require("react-window");
23
23
 
24
24
  var _classnames = _interopRequireDefault(require("classnames"));
25
25
 
26
+ var _layout = require("@carbon/layout");
27
+
26
28
  var _settings = require("../../settings");
27
29
 
28
30
  var _deepCloneObject = require("../../global/js/utils/deepCloneObject");
@@ -54,8 +56,11 @@ var DataSpreadsheetBody = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, re
54
56
  var columns = _ref.columns,
55
57
  activeCellCoordinates = _ref.activeCellCoordinates,
56
58
  defaultColumn = _ref.defaultColumn,
59
+ defaultEmptyRowCount = _ref.defaultEmptyRowCount,
57
60
  getTableBodyProps = _ref.getTableBodyProps,
61
+ headerGroups = _ref.headerGroups,
58
62
  id = _ref.id,
63
+ onDataUpdate = _ref.onDataUpdate,
59
64
  prepareRow = _ref.prepareRow,
60
65
  rows = _ref.rows,
61
66
  selectionAreaData = _ref.selectionAreaData,
@@ -74,7 +79,11 @@ var DataSpreadsheetBody = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, re
74
79
  var previousState = (0, _hooks.usePreviousValue)({
75
80
  selectionAreaData: selectionAreaData,
76
81
  clickAndHoldActive: clickAndHoldActive
77
- }); // Call the `onSelectionAreaChange` handler to send selection area data
82
+ }); // Set custom css property containing the spreadsheet total width
83
+
84
+ (0, _react.useEffect)(function () {
85
+ ref === null || ref === void 0 ? void 0 : ref.current.style.setProperty("--".concat(blockClass, "--total-width"), (0, _layout.px)(totalColumnsWidth + scrollBarSize));
86
+ }, [ref, scrollBarSize, totalColumnsWidth]); // Call the `onSelectionAreaChange` handler to send selection area data
78
87
  // back to the consumer
79
88
 
80
89
  (0, _react.useEffect)(function () {
@@ -303,42 +312,71 @@ var DataSpreadsheetBody = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, re
303
312
  setSelectionAreaData: setSelectionAreaData
304
313
  });
305
314
  };
306
- }, [columns, ref, setSelectionAreas, setCurrentMatcher, setActiveCellCoordinates, activeCellCoordinates, rows, setSelectionAreaData]); // Renders each row/cell in the spreadsheet body
315
+ }, [columns, ref, setSelectionAreas, setCurrentMatcher, setActiveCellCoordinates, activeCellCoordinates, rows, setSelectionAreaData]); // Builds the empty rows and calls `onDataUpdate` to set the new empty rows
316
+ // using defaultEmptyRowCount to determine how many empty rows are created.
317
+
318
+ (0, _react.useEffect)(function () {
319
+ if (!(rows !== null && rows !== void 0 && rows.length)) {
320
+ var buildEmptyRows = function buildEmptyRows() {
321
+ var emptyRowData = [];
322
+ (0, _toConsumableArray2.default)(Array(defaultEmptyRowCount)).map(function () {
323
+ var _headerGroups$;
324
+
325
+ var emptyCell = {};
326
+ (_headerGroups$ = headerGroups[0]) === null || _headerGroups$ === void 0 ? void 0 : _headerGroups$.headers.map(function (header) {
327
+ emptyCell[header.id] = null;
328
+ });
329
+ emptyRowData.push(emptyCell);
330
+ });
331
+ onDataUpdate(emptyRowData);
332
+ };
333
+
334
+ buildEmptyRows();
335
+ }
336
+ }, [rows, headerGroups, defaultEmptyRowCount, onDataUpdate]);
337
+
338
+ var RenderEmptyRows = function RenderEmptyRows() {
339
+ return /*#__PURE__*/_react.default.createElement("div", null);
340
+ }; // Renders each row/cell in the spreadsheet body
341
+
307
342
 
308
343
  var RenderRow = (0, _react.useCallback)(function (_ref3) {
309
344
  var index = _ref3.index,
310
345
  style = _ref3.style;
311
346
  var row = rows[index];
312
- prepareRow(row);
313
- return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({}, row.getRowProps({
314
- style: style
315
- }), {
316
- className: (0, _classnames.default)("".concat(blockClass, "__tr")),
317
- "data-row-index": index
318
- }), /*#__PURE__*/_react.default.createElement("button", {
319
- tabIndex: -1,
320
- "data-row-index": index,
321
- "data-column-index": "header",
322
- type: "button",
323
- onClick: handleRowHeaderClick(index),
324
- className: (0, _classnames.default)("".concat(blockClass, "__td"), "".concat(blockClass, "__td-th"), "".concat(blockClass, "--interactive-cell-element"), (0, _defineProperty2.default)({}, "".concat(blockClass, "__td-th--active-header"), (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === index || (0, _checkActiveHeaderCell.checkActiveHeaderCell)(index, selectionAreas, 'row'))),
325
- style: {
326
- width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth
327
- }
328
- }, index + 1), row.cells.map(function (cell, index) {
329
- return /*#__PURE__*/_react.default.createElement("button", (0, _extends2.default)({
347
+
348
+ if (rows && rows.length) {
349
+ prepareRow(row);
350
+ return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({}, row.getRowProps({
351
+ style: style
352
+ }), {
353
+ className: (0, _classnames.default)("".concat(blockClass, "__tr")),
354
+ "data-row-index": index
355
+ }), /*#__PURE__*/_react.default.createElement("button", {
330
356
  tabIndex: -1,
331
- "data-row-index": cell.row.index,
332
- "data-column-index": index
333
- }, cell.getCellProps(), {
334
- className: (0, _classnames.default)("".concat(blockClass, "__td"), "".concat(blockClass, "__body--td"), "".concat(blockClass, "--interactive-cell-element")),
335
- key: "cell_".concat(index),
336
- onMouseDown: handleBodyCellClick(cell, index),
337
- onMouseOver: handleBodyCellHover(cell, index),
338
- onFocus: function onFocus() {},
339
- type: "button"
340
- }), cell.render('Cell'));
341
- }));
357
+ "data-row-index": index,
358
+ "data-column-index": "header",
359
+ type: "button",
360
+ onClick: handleRowHeaderClick(index),
361
+ className: (0, _classnames.default)("".concat(blockClass, "__td"), "".concat(blockClass, "__td-th"), "".concat(blockClass, "--interactive-cell-element"), (0, _defineProperty2.default)({}, "".concat(blockClass, "__td-th--active-header"), (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === index || (0, _checkActiveHeaderCell.checkActiveHeaderCell)(index, selectionAreas, 'row'))),
362
+ style: {
363
+ width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth
364
+ }
365
+ }, index + 1), row.cells.map(function (cell, index) {
366
+ return /*#__PURE__*/_react.default.createElement("button", (0, _extends2.default)({
367
+ tabIndex: -1,
368
+ "data-row-index": cell.row.index,
369
+ "data-column-index": index
370
+ }, cell.getCellProps(), {
371
+ className: (0, _classnames.default)("".concat(blockClass, "__td"), "".concat(blockClass, "__body--td"), "".concat(blockClass, "--interactive-cell-element")),
372
+ key: "cell_".concat(index),
373
+ onMouseDown: handleBodyCellClick(cell, index),
374
+ onMouseOver: handleBodyCellHover(cell, index),
375
+ onFocus: function onFocus() {},
376
+ type: "button"
377
+ }), cell.render('Cell'));
378
+ }));
379
+ }
342
380
  }, [prepareRow, rows, defaultColumn.rowHeaderWidth, activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, selectionAreas, handleRowHeaderClick, handleBodyCellClick, handleBodyCellHover]);
343
381
  var spreadsheetBodyRef = (0, _react.useRef)();
344
382
  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
@@ -347,10 +385,10 @@ var DataSpreadsheetBody = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, re
347
385
  }, getTableBodyProps()), /*#__PURE__*/_react.default.createElement(_reactWindow.FixedSizeList, {
348
386
  className: (0, _classnames.default)("".concat(blockClass, "__list--container"), "".concat(blockClass, "__list--container--").concat(id)),
349
387
  height: 400,
350
- itemCount: rows.length,
388
+ itemCount: rows.length || defaultEmptyRowCount,
351
389
  itemSize: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight,
352
390
  width: totalColumnsWidth + scrollBarSize
353
- }, RenderRow));
391
+ }, rows !== null && rows !== void 0 && rows.length ? RenderRow : RenderEmptyRows));
354
392
  });
355
393
  exports.DataSpreadsheetBody = DataSpreadsheetBody;
356
394
  DataSpreadsheetBody.propTypes = {
@@ -386,11 +424,21 @@ DataSpreadsheetBody.propTypes = {
386
424
  width: _propTypes.default.number
387
425
  }),
388
426
 
427
+ /**
428
+ * Sets the number of empty rows to be created when there is no data provided
429
+ */
430
+ defaultEmptyRowCount: _propTypes.default.number,
431
+
389
432
  /**
390
433
  * Function to set table body prop values
391
434
  */
392
435
  getTableBodyProps: _propTypes.default.func,
393
436
 
437
+ /**
438
+ * Headers provided from useTable hook
439
+ */
440
+ headerGroups: _propTypes.default.arrayOf(_propTypes.default.object),
441
+
394
442
  /**
395
443
  * The spreadsheet id
396
444
  */
@@ -401,6 +449,11 @@ DataSpreadsheetBody.propTypes = {
401
449
  */
402
450
  onActiveCellChange: _propTypes.default.func,
403
451
 
452
+ /**
453
+ * The event handler that is called to set the rows for the empty spreadsheet
454
+ */
455
+ onDataUpdate: _propTypes.default.func,
456
+
404
457
  /**
405
458
  * The event handler that is called when the selection areas change
406
459
  */
@@ -9,6 +9,8 @@ var _react = require("react");
9
9
 
10
10
  var _settings = require("../../../settings");
11
11
 
12
+ var _removeCellSelections = require("../utils/removeCellSelections");
13
+
12
14
  /**
13
15
  * Copyright IBM Corp. 2022, 2022
14
16
  *
@@ -23,7 +25,6 @@ var useSpreadsheetOutsideClick = function useSpreadsheetOutsideClick(_ref) {
23
25
  setActiveCellCoordinates = _ref.setActiveCellCoordinates,
24
26
  setSelectionAreas = _ref.setSelectionAreas,
25
27
  removeActiveCell = _ref.removeActiveCell,
26
- removeCellSelections = _ref.removeCellSelections,
27
28
  setContainerHasFocus = _ref.setContainerHasFocus,
28
29
  activeKeys = _ref.activeKeys,
29
30
  removeCellEditor = _ref.removeCellEditor;
@@ -36,7 +37,9 @@ var useSpreadsheetOutsideClick = function useSpreadsheetOutsideClick(_ref) {
36
37
  setActiveCellCoordinates(null);
37
38
  setSelectionAreas([]);
38
39
  removeActiveCell();
39
- removeCellSelections();
40
+ (0, _removeCellSelections.removeCellSelections)({
41
+ spreadsheetRef: spreadsheetRef
42
+ });
40
43
  setContainerHasFocus(false);
41
44
  removeCellEditor();
42
45
  activeKeys.current = [];
@@ -46,7 +49,7 @@ var useSpreadsheetOutsideClick = function useSpreadsheetOutsideClick(_ref) {
46
49
  return function () {
47
50
  document.removeEventListener('click', handleOutsideClick);
48
51
  };
49
- }, [spreadsheetRef, removeActiveCell, removeCellSelections, activeKeys, blockClass, setActiveCellCoordinates, setContainerHasFocus, setSelectionAreas, removeCellEditor]);
52
+ }, [spreadsheetRef, removeActiveCell, activeKeys, blockClass, setActiveCellCoordinates, setContainerHasFocus, setSelectionAreas, removeCellEditor]);
50
53
  };
51
54
 
52
55
  exports.useSpreadsheetOutsideClick = useSpreadsheetOutsideClick;
@@ -24,10 +24,9 @@ var HTTPErrorSvg403 = function HTTPErrorSvg403(_ref) {
24
24
  return /*#__PURE__*/_react.default.createElement("svg", {
25
25
  xmlns: "http://www.w3.org/2000/svg",
26
26
  xmlnsXlink: "http://www.w3.org/1999/xlink",
27
- width: 1584,
28
- height: 916,
29
27
  viewBox: "0 0 1584 916",
30
- className: className
28
+ className: className,
29
+ preserveAspectRatio: "xMinYMax meet"
31
30
  }, /*#__PURE__*/_react.default.createElement("defs", null, /*#__PURE__*/_react.default.createElement("clipPath", {
32
31
  id: "prefix__clip-path"
33
32
  }, /*#__PURE__*/_react.default.createElement("path", {
@@ -24,10 +24,9 @@ var HTTPErrorSvg404 = function HTTPErrorSvg404(_ref) {
24
24
  return /*#__PURE__*/_react.default.createElement("svg", {
25
25
  xmlns: "http://www.w3.org/2000/svg",
26
26
  xmlnsXlink: "http://www.w3.org/1999/xlink",
27
- width: 1584,
28
- height: 916,
29
27
  viewBox: "0 0 1584 916",
30
- className: className
28
+ className: className,
29
+ preserveAspectRatio: "xMinYMax meet"
31
30
  }, /*#__PURE__*/_react.default.createElement("defs", null, /*#__PURE__*/_react.default.createElement("clipPath", {
32
31
  id: "prefix__clip-path"
33
32
  }, /*#__PURE__*/_react.default.createElement("path", {