@carbon/ibm-products 1.7.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. package/css/index-full-carbon.css +227 -5762
  2. package/css/index-full-carbon.css.map +1 -1
  3. package/css/index-full-carbon.min.css +5 -5
  4. package/css/index-full-carbon.min.css.map +1 -1
  5. package/css/index-without-carbon-released-only.css +46 -3426
  6. package/css/index-without-carbon-released-only.css.map +1 -1
  7. package/css/index-without-carbon-released-only.min.css +3 -3
  8. package/css/index-without-carbon-released-only.min.css.map +1 -1
  9. package/css/index-without-carbon.css +195 -4028
  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 +195 -4029
  14. package/css/index.css.map +1 -1
  15. package/css/index.min.css +5 -5
  16. package/css/index.min.css.map +1 -1
  17. package/es/components/APIKeyModal/APIKeyModal.js +10 -13
  18. package/es/components/ActionBar/ActionBar.js +0 -3
  19. package/es/components/ActionBar/ActionBarItem.js +2 -6
  20. package/es/components/ActionSet/ActionSet.js +10 -12
  21. package/es/components/AddSelect/AddSelect.js +120 -25
  22. package/es/components/AddSelect/AddSelectBreadcrumbs.js +4 -4
  23. package/es/components/AddSelect/AddSelectColumn.js +58 -0
  24. package/es/components/AddSelect/AddSelectList.js +67 -8
  25. package/es/components/AddSelect/AddSelectSidebar.js +7 -1
  26. package/es/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +0 -3
  27. package/es/components/ButtonMenu/ButtonMenu.js +7 -5
  28. package/es/components/ButtonMenu/ButtonMenuItem.js +1 -2
  29. package/es/components/Card/Card.js +31 -21
  30. package/es/components/Card/CardFooter.js +14 -10
  31. package/es/components/Card/CardHeader.js +8 -6
  32. package/es/components/Cascade/Cascade.js +5 -4
  33. package/es/components/ComboButton/ComboButton.js +0 -4
  34. package/es/components/ComboButton/ComboButtonItem/index.js +0 -5
  35. package/es/components/CreateFullPage/CreateFullPageStep.js +15 -8
  36. package/es/components/CreateModal/CreateModal.js +1 -4
  37. package/es/components/CreateTearsheet/CreateTearsheet.js +10 -11
  38. package/es/components/CreateTearsheet/CreateTearsheetStep.js +18 -14
  39. package/es/components/DataSpreadsheet/DataSpreadsheet.js +563 -80
  40. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +366 -0
  41. package/es/components/DataSpreadsheet/DataSpreadsheetHeader.js +81 -0
  42. package/es/components/DataSpreadsheet/checkActiveHeaderCell.js +34 -0
  43. package/es/components/DataSpreadsheet/createActiveCellFn.js +47 -0
  44. package/es/components/DataSpreadsheet/createCellSelectionArea.js +45 -0
  45. package/es/components/DataSpreadsheet/getCellSize.js +30 -0
  46. package/es/components/EditSidePanel/EditSidePanel.js +9 -10
  47. package/es/components/EmptyStates/EmptyState.js +7 -6
  48. package/es/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.js +4 -8
  49. package/es/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.js +4 -8
  50. package/es/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.js +4 -8
  51. package/es/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.js +4 -8
  52. package/es/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.js +4 -8
  53. package/es/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.js +4 -8
  54. package/es/components/ExampleComponent/ExampleComponent.js +12 -13
  55. package/es/components/ExportModal/ExportModal.js +13 -9
  56. package/es/components/ExpressiveCard/ExpressiveCard.js +0 -8
  57. package/es/components/ImportModal/ImportModal.js +7 -5
  58. package/es/components/InlineEdit/InlineEdit.js +44 -46
  59. package/es/components/LoadingBar/LoadingBar.js +13 -17
  60. package/es/components/ModifiedTabs/ModifiedTabLabelNew.js +0 -4
  61. package/es/components/ModifiedTabs/ModifiedTabLabelWithClose.js +0 -5
  62. package/es/components/ModifiedTabs/ModifiedTabs.js +24 -18
  63. package/es/components/NotificationsPanel/NotificationsPanel.js +109 -86
  64. package/es/components/OptionsTile/OptionsTile.js +17 -10
  65. package/es/components/PageHeader/PageHeader.js +58 -47
  66. package/es/components/PageHeader/PageHeaderUtils.js +3 -7
  67. package/es/components/ProductiveCard/ProductiveCard.js +23 -12
  68. package/es/components/RemoveModal/RemoveModal.js +0 -3
  69. package/es/components/SidePanel/SidePanel.js +22 -17
  70. package/es/components/TagSet/TagSet.js +25 -12
  71. package/es/components/TagSet/TagSetModal.js +16 -12
  72. package/es/components/TagSet/TagSetOverflow.js +21 -13
  73. package/es/components/Tearsheet/Tearsheet.js +27 -18
  74. package/es/components/Tearsheet/TearsheetNarrow.js +18 -15
  75. package/es/components/Toolbar/ToolbarButton.js +0 -3
  76. package/es/components/UserProfileImage/UserProfileImage.js +2 -1
  77. package/es/components/WebTerminal/WebTerminal.js +17 -18
  78. package/es/components/index.js +0 -1
  79. package/es/global/js/hooks/index.js +1 -0
  80. package/es/global/js/hooks/useActiveElement.js +27 -0
  81. package/es/global/js/utils/DisplayBox.js +31 -0
  82. package/es/global/js/utils/Wrap.js +7 -5
  83. package/es/global/js/utils/deepCloneObject.js +26 -0
  84. package/lib/components/APIKeyModal/APIKeyModal.js +10 -13
  85. package/lib/components/ActionBar/ActionBar.js +0 -3
  86. package/lib/components/ActionBar/ActionBarItem.js +2 -6
  87. package/lib/components/ActionSet/ActionSet.js +10 -12
  88. package/lib/components/AddSelect/AddSelect.js +118 -24
  89. package/lib/components/AddSelect/AddSelectBreadcrumbs.js +2 -3
  90. package/lib/components/AddSelect/AddSelectColumn.js +79 -0
  91. package/lib/components/AddSelect/AddSelectList.js +65 -8
  92. package/lib/components/AddSelect/AddSelectSidebar.js +7 -1
  93. package/lib/components/BreadcrumbWithOverflow/BreadcrumbWithOverflow.js +0 -3
  94. package/lib/components/ButtonMenu/ButtonMenu.js +7 -5
  95. package/lib/components/ButtonMenu/ButtonMenuItem.js +1 -2
  96. package/lib/components/Card/Card.js +31 -21
  97. package/lib/components/Card/CardFooter.js +14 -10
  98. package/lib/components/Card/CardHeader.js +8 -6
  99. package/lib/components/Cascade/Cascade.js +5 -4
  100. package/lib/components/ComboButton/ComboButton.js +0 -4
  101. package/lib/components/ComboButton/ComboButtonItem/index.js +0 -5
  102. package/lib/components/CreateFullPage/CreateFullPageStep.js +17 -14
  103. package/lib/components/CreateModal/CreateModal.js +1 -4
  104. package/lib/components/CreateTearsheet/CreateTearsheet.js +10 -11
  105. package/lib/components/CreateTearsheet/CreateTearsheetStep.js +20 -20
  106. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +567 -77
  107. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +391 -0
  108. package/lib/components/DataSpreadsheet/DataSpreadsheetHeader.js +99 -0
  109. package/lib/components/DataSpreadsheet/checkActiveHeaderCell.js +45 -0
  110. package/lib/components/DataSpreadsheet/createActiveCellFn.js +58 -0
  111. package/lib/components/DataSpreadsheet/createCellSelectionArea.js +56 -0
  112. package/lib/components/DataSpreadsheet/getCellSize.js +39 -0
  113. package/lib/components/EditSidePanel/EditSidePanel.js +9 -10
  114. package/lib/components/EmptyStates/EmptyState.js +9 -8
  115. package/lib/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.js +3 -7
  116. package/lib/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.js +3 -7
  117. package/lib/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.js +3 -7
  118. package/lib/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.js +3 -7
  119. package/lib/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.js +3 -7
  120. package/lib/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.js +3 -7
  121. package/lib/components/ExampleComponent/ExampleComponent.js +12 -13
  122. package/lib/components/ExportModal/ExportModal.js +13 -9
  123. package/lib/components/ExpressiveCard/ExpressiveCard.js +0 -8
  124. package/lib/components/ImportModal/ImportModal.js +7 -5
  125. package/lib/components/InlineEdit/InlineEdit.js +43 -45
  126. package/lib/components/LoadingBar/LoadingBar.js +13 -17
  127. package/lib/components/ModifiedTabs/ModifiedTabLabelNew.js +0 -4
  128. package/lib/components/ModifiedTabs/ModifiedTabLabelWithClose.js +0 -5
  129. package/lib/components/ModifiedTabs/ModifiedTabs.js +24 -18
  130. package/lib/components/NotificationsPanel/NotificationsPanel.js +109 -86
  131. package/lib/components/OptionsTile/OptionsTile.js +17 -10
  132. package/lib/components/PageHeader/PageHeader.js +56 -46
  133. package/lib/components/PageHeader/PageHeaderUtils.js +3 -7
  134. package/lib/components/ProductiveCard/ProductiveCard.js +24 -18
  135. package/lib/components/RemoveModal/RemoveModal.js +0 -3
  136. package/lib/components/SidePanel/SidePanel.js +22 -17
  137. package/lib/components/TagSet/TagSet.js +26 -12
  138. package/lib/components/TagSet/TagSetModal.js +17 -13
  139. package/lib/components/TagSet/TagSetOverflow.js +24 -19
  140. package/lib/components/Tearsheet/Tearsheet.js +26 -17
  141. package/lib/components/Tearsheet/TearsheetNarrow.js +18 -15
  142. package/lib/components/Toolbar/ToolbarButton.js +0 -3
  143. package/lib/components/UserProfileImage/UserProfileImage.js +2 -1
  144. package/lib/components/WebTerminal/WebTerminal.js +17 -18
  145. package/lib/components/index.js +0 -8
  146. package/lib/global/js/hooks/index.js +8 -0
  147. package/lib/global/js/hooks/useActiveElement.js +39 -0
  148. package/lib/global/js/utils/DisplayBox.js +46 -0
  149. package/lib/global/js/utils/Wrap.js +7 -5
  150. package/lib/global/js/utils/deepCloneObject.js +37 -0
  151. package/package.json +18 -18
  152. package/scss/components/{CancelableTextEdit/_index.scss → ActionBar/_storybook-styles.scss} +2 -2
  153. package/scss/components/ActionSet/_storybook-styles.scss +1 -3
  154. package/scss/components/AddSelect/_add-select.scss +83 -14
  155. package/scss/components/{CancelableTextEdit → BreadcrumbWithOverflow}/_storybook-styles.scss +2 -2
  156. package/scss/components/ButtonSetWithOverflow/_storybook-styles.scss +8 -0
  157. package/scss/components/CreateInfluencer/_create-influencer.scss +2 -0
  158. package/scss/components/CreateModal/_create-modal.scss +1 -0
  159. package/scss/components/CreateTearsheet/_create-tearsheet.scss +1 -0
  160. package/scss/components/CreateTearsheetNarrow/_create-tearsheet-narrow.scss +1 -0
  161. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +53 -7
  162. package/scss/components/InlineEdit/_inline-edit.scss +36 -15
  163. package/scss/components/InlineEdit/_storybook-styles.scss +2 -0
  164. package/scss/components/LoadingBar/_loading-bar.scss +13 -0
  165. package/scss/components/NotificationsPanel/_notifications-panel.scss +3 -0
  166. package/scss/components/PageHeader/_page-header.scss +2 -0
  167. package/scss/components/SidePanel/_side-panel.scss +11 -4
  168. package/scss/components/StatusIcon/_status-icon.scss +1 -0
  169. package/scss/components/TagSet/_storybook-styles.scss +8 -0
  170. package/scss/components/Tearsheet/_tearsheet.scss +1 -2
  171. package/scss/components/UserProfileImage/_user-profile-image.scss +9 -0
  172. package/scss/components/WebTerminal/_web-terminal.scss +2 -0
  173. package/scss/components/_index.scss +0 -1
  174. package/scss/global/styles/_display-box.scss +62 -0
  175. package/es/components/CancelableTextEdit/CancelableTextEdit.js +0 -245
  176. package/es/components/CancelableTextEdit/index.js +0 -7
  177. package/lib/components/CancelableTextEdit/CancelableTextEdit.js +0 -265
  178. package/lib/components/CancelableTextEdit/index.js +0 -13
  179. package/scss/components/CancelableTextEdit/_cancelable-text-edit.scss +0 -212
@@ -1,6 +1,14 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _typeof from "@babel/runtime/helpers/typeof";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
5
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
6
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["className", "columns", "data"];
7
+ var _excluded = ["cellSize", "className", "columns", "data", "id", "onActiveCellChange"];
8
+
9
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
10
+
11
+ 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
12
 
5
13
  /**
6
14
  * Copyright IBM Corp. 2022, 2022
@@ -9,36 +17,88 @@ var _excluded = ["className", "columns", "data"];
9
17
  * LICENSE file in the root directory of this source tree.
10
18
  */
11
19
  // 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.
20
+ import React, { useMemo, useRef, useEffect, useState, useCallback } from 'react';
21
+ import { useBlockLayout, useTable } from 'react-table'; // Other standard imports.
15
22
 
16
23
  import PropTypes from 'prop-types';
17
24
  import cx from 'classnames';
18
25
  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).
26
+ import { pkg } from '../../settings';
27
+ import { getScrollbarWidth } from '../../global/js/utils/getScrollbarWidth';
28
+ import { DataSpreadsheetBody } from './DataSpreadsheetBody';
29
+ import { getCellSize } from './getCellSize';
30
+ import { DataSpreadsheetHeader } from './DataSpreadsheetHeader';
31
+ import { useActiveElement } from '../../global/js/hooks';
32
+ import { createActiveCellFn } from './createActiveCellFn';
33
+ import { deepCloneObject } from '../../global/js/utils/deepCloneObject';
34
+ import { usePreviousValue } from '../../global/js/hooks';
35
+ import uuidv4 from '../../global/js/utils/uuidv4'; // cspell:words rowcount colcount
36
+ // The block part of our conventional BEM class names (blockClass__E--M).
23
37
 
24
38
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
25
- var componentName = 'DataSpreadsheet';
39
+ var componentName = 'DataSpreadsheet'; // Default values for props
40
+
41
+ var defaults = {
42
+ cellSize: 'standard',
43
+ columns: Object.freeze([]),
44
+ data: Object.freeze([])
45
+ };
26
46
  /**
27
47
  * DataSpreadsheet: used to organize and display large amounts of structured data, separated by columns and rows in a grid-like format.
28
48
  */
29
49
 
30
50
  export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
31
- var className = _ref.className,
32
- columns = _ref.columns,
33
- data = _ref.data,
51
+ var _ref$cellSize = _ref.cellSize,
52
+ cellSize = _ref$cellSize === void 0 ? defaults.cellSize : _ref$cellSize,
53
+ className = _ref.className,
54
+ _ref$columns = _ref.columns,
55
+ columns = _ref$columns === void 0 ? defaults.columns : _ref$columns,
56
+ _ref$data = _ref.data,
57
+ data = _ref$data === void 0 ? defaults.data : _ref$data,
58
+ id = _ref.id,
59
+ onActiveCellChange = _ref.onActiveCellChange,
34
60
  rest = _objectWithoutProperties(_ref, _excluded);
35
61
 
62
+ var focusedElement = useActiveElement();
63
+
64
+ var _useState = useState(false),
65
+ _useState2 = _slicedToArray(_useState, 2),
66
+ containerHasFocus = _useState2[0],
67
+ setContainerHasFocus = _useState2[1];
68
+
69
+ var _useState3 = useState(null),
70
+ _useState4 = _slicedToArray(_useState3, 2),
71
+ activeCellCoordinates = _useState4[0],
72
+ setActiveCellCoordinates = _useState4[1];
73
+
74
+ var _useState5 = useState([]),
75
+ _useState6 = _slicedToArray(_useState5, 2),
76
+ selectionAreas = _useState6[0],
77
+ setSelectionAreas = _useState6[1];
78
+
79
+ var _useState7 = useState(false),
80
+ _useState8 = _slicedToArray(_useState7, 2),
81
+ clickAndHoldActive = _useState8[0],
82
+ setClickAndHoldActive = _useState8[1];
83
+
84
+ var _useState9 = useState(''),
85
+ _useState10 = _slicedToArray(_useState9, 2),
86
+ currentMatcher = _useState10[0],
87
+ setCurrentMatcher = _useState10[1];
88
+
89
+ var previousState = usePreviousValue({
90
+ activeCellCoordinates: activeCellCoordinates
91
+ });
92
+ var cellSizeValue = getCellSize(cellSize);
93
+ var currentMatcherRef = useRef();
94
+ var activeKeys = useRef([]);
36
95
  var defaultColumn = useMemo(function () {
37
96
  return {
38
97
  width: 150,
39
- rowHeaderWidth: 64
98
+ rowHeaderWidth: 64,
99
+ rowHeight: cellSizeValue
40
100
  };
41
- }, []);
101
+ }, [cellSizeValue]);
42
102
  var scrollBarSize = useMemo(function () {
43
103
  return getScrollbarWidth();
44
104
  }, []);
@@ -53,65 +113,481 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
53
113
  headerGroups = _useTable.headerGroups,
54
114
  rows = _useTable.rows,
55
115
  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'
116
+ prepareRow = _useTable.prepareRow; // Reset everything when spreadsheet loses focus
117
+
118
+
119
+ useEffect(function () {
120
+ if (!focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
121
+ setContainerHasFocus(false);
122
+ removeActiveCell();
123
+ activeKeys.current = [];
124
+ }
125
+
126
+ if (focusedElement.classList.contains(blockClass) || focusedElement.classList.contains("".concat(blockClass, "--interactive-cell-element"))) {
127
+ setContainerHasFocus(true);
128
+ }
129
+ }, [focusedElement, removeActiveCell]); // Removes the active cell element
130
+
131
+ var removeActiveCell = useCallback(function () {
132
+ var activeCellHighlight = spreadsheetRef.current.querySelector(".".concat(blockClass, "__active-cell--highlight"));
133
+
134
+ if (activeCellHighlight) {
135
+ activeCellHighlight.remove();
136
+ }
137
+ }, [spreadsheetRef]); // Removes the cell selection elements
138
+
139
+ var removeCellSelections = useCallback(function (matcher) {
140
+ if (matcher && typeof matcher === 'string') {
141
+ var selectionToRemove = spreadsheetRef.current.querySelector("[data-matcher-id=\"".concat(matcher, "\"]"));
142
+
143
+ if (selectionToRemove) {
144
+ selectionToRemove.remove();
76
145
  }
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]);
86
- 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
146
+ } else {
147
+ var cellSelections = spreadsheetRef.current.querySelectorAll(".".concat(blockClass, "__selection-area--element"));
148
+
149
+ _toConsumableArray(cellSelections).forEach(function (element) {
150
+ return element.remove();
151
+ });
152
+ }
153
+ }, [spreadsheetRef]); // Click outside useEffect
154
+
155
+ useEffect(function () {
156
+ var handleOutsideClick = function handleOutsideClick(event) {
157
+ if (!spreadsheetRef.current || spreadsheetRef.current.contains(event.target) || event.target.classList.contains("".concat(blockClass, "__active-cell--highlight"))) {
158
+ return;
159
+ }
160
+
161
+ setActiveCellCoordinates(null);
162
+ setSelectionAreas([]);
163
+ removeActiveCell();
164
+ removeCellSelections();
165
+ setContainerHasFocus(false);
166
+ activeKeys.current = [];
167
+ };
168
+
169
+ document.addEventListener('click', handleOutsideClick);
170
+ return function () {
171
+ document.removeEventListener('click', handleOutsideClick);
172
+ };
173
+ }, [spreadsheetRef, removeActiveCell, removeCellSelections]);
174
+ var createActiveCell = useCallback(function (_ref2) {
175
+ var placementElement = _ref2.placementElement,
176
+ coords = _ref2.coords,
177
+ _ref2$addToHeader = _ref2.addToHeader,
178
+ addToHeader = _ref2$addToHeader === void 0 ? false : _ref2$addToHeader;
179
+ var activeCellFullData = typeof (coords === null || coords === void 0 ? void 0 : coords.column) === 'number' && typeof (coords === null || coords === void 0 ? void 0 : coords.row) === 'number' ? rows[coords === null || coords === void 0 ? void 0 : coords.row].cells[coords === null || coords === void 0 ? void 0 : coords.column] : null;
180
+ var activeCellValue = activeCellFullData ? Object.values(activeCellFullData.row.values)[coords === null || coords === void 0 ? void 0 : coords.column] : null;
181
+
182
+ var handleActiveCellMouseEnter = function handleActiveCellMouseEnter() {
183
+ handleActiveCellMouseEnterCallback(selectionAreas, clickAndHoldActive);
184
+ };
185
+
186
+ var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates; // Only create an active cell if the activeCellCoordinates have changed
187
+
188
+ if ((prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row) !== (coords === null || coords === void 0 ? void 0 : coords.row) || (prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column) !== (coords === null || coords === void 0 ? void 0 : coords.column)) {
189
+ createActiveCellFn({
190
+ placementElement: placementElement,
191
+ coords: coords,
192
+ addToHeader: addToHeader,
193
+ contextRef: spreadsheetRef,
194
+ blockClass: blockClass,
195
+ onActiveCellChange: onActiveCellChange,
196
+ activeCellValue: activeCellValue,
197
+ handleActiveCellMouseEnter: handleActiveCellMouseEnter
198
+ });
199
+ }
200
+ }, [spreadsheetRef, rows, onActiveCellChange, clickAndHoldActive, handleActiveCellMouseEnterCallback, selectionAreas, previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates]);
201
+ var handleInitialArrowPress = useCallback(function () {
202
+ // If activeCellCoordinates is null then we need to set an initial value
203
+ // which will place the activeCell on the select all cell/button
204
+ if (!activeCellCoordinates) {
205
+ setActiveCellCoordinates({
206
+ column: 'header',
207
+ row: 'header'
208
+ });
209
+ }
210
+
211
+ return;
212
+ }, [activeCellCoordinates]);
213
+ var updateActiveCellCoordinates = useCallback(function (_ref3) {
214
+ var coords = _ref3.coords,
215
+ updatedValue = _ref3.updatedValue;
216
+
217
+ var newActiveCell = _objectSpread(_objectSpread({}, coords), updatedValue);
218
+
219
+ setActiveCellCoordinates(newActiveCell); // Only run if the active cell is _not_ a header cell. This will add a point1 object
220
+ // to selectionAreas every time the active cell changes, allowing us to create cell
221
+ // selections using keyboard
222
+
223
+ if (newActiveCell.row !== 'header' && newActiveCell.column !== 'header') {
224
+ var tempMatcher = uuidv4();
225
+ setSelectionAreas([{
226
+ point1: newActiveCell,
227
+ matcher: tempMatcher
228
+ }]);
229
+ setCurrentMatcher(tempMatcher);
230
+ }
231
+ }, []);
232
+ var handleMultipleKeys = useCallback(function () {
233
+ var _selectionAreasClone$;
234
+
235
+ var activeKeyValues = activeKeys.current;
236
+ var selectionAreasClone = deepCloneObject(selectionAreas);
237
+ var indexOfCurrentArea = selectionAreasClone.findIndex(function (item) {
238
+ return item.matcher === currentMatcher;
239
+ });
240
+ var pointToUpdate = (_selectionAreasClone$ = selectionAreasClone[indexOfCurrentArea]) !== null && _selectionAreasClone$ !== void 0 && _selectionAreasClone$.point2 ? selectionAreasClone[indexOfCurrentArea].point2 : selectionAreasClone[indexOfCurrentArea].point1; // Down + Shift
241
+
242
+ if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowDown')) {
243
+ if (rows.length - 1 === pointToUpdate.row) {
244
+ return;
245
+ }
246
+
247
+ var newPoint = {
248
+ row: pointToUpdate.row + 1,
249
+ column: pointToUpdate.column
250
+ };
251
+ selectionAreasClone[indexOfCurrentArea].point2 = newPoint;
252
+ selectionAreasClone[indexOfCurrentArea].areaCreated = false;
253
+ setSelectionAreas(selectionAreasClone);
254
+ } // Right + Shift
255
+
256
+
257
+ if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowRight')) {
258
+ if (columns.length - 1 === pointToUpdate.column) {
259
+ return;
260
+ }
261
+
262
+ var _newPoint = {
263
+ row: pointToUpdate.row,
264
+ column: pointToUpdate.column + 1
265
+ };
266
+ selectionAreasClone[indexOfCurrentArea].point2 = _newPoint;
267
+ selectionAreasClone[indexOfCurrentArea].areaCreated = false;
268
+ setSelectionAreas(selectionAreasClone);
269
+ } // Up + Shift
270
+
271
+
272
+ if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowUp')) {
273
+ if (pointToUpdate.row === 0) {
274
+ return;
275
+ }
276
+
277
+ var _newPoint2 = {
278
+ row: pointToUpdate.row - 1,
279
+ column: pointToUpdate.column
280
+ };
281
+ selectionAreasClone[indexOfCurrentArea].point2 = _newPoint2;
282
+ selectionAreasClone[indexOfCurrentArea].areaCreated = false;
283
+ setSelectionAreas(selectionAreasClone);
284
+ } // Left + Shift
285
+
286
+
287
+ if (activeKeyValues.includes('Shift') && activeKeyValues.includes('ArrowLeft')) {
288
+ if (pointToUpdate.column === 0) {
289
+ return;
290
+ }
291
+
292
+ var _newPoint3 = {
293
+ row: pointToUpdate.row,
294
+ column: pointToUpdate.column - 1
295
+ };
296
+ selectionAreasClone[indexOfCurrentArea].point2 = _newPoint3;
297
+ selectionAreasClone[indexOfCurrentArea].areaCreated = false;
298
+ setSelectionAreas(selectionAreasClone);
299
+ }
300
+ }, [selectionAreas, currentMatcher, columns, rows]);
301
+ var handleKeyPress = useCallback(function (event) {
302
+ var _activeKeys$current, _activeKeys$current2;
303
+
304
+ var key = event.key; // Command keys need to be returned as there is default browser behavior with these keys
305
+
306
+ if (key === 'Meta' || key === 'Control') {
307
+ return;
308
+ } // Prevent arrow keys, home key, and end key from scrolling the page when the data spreadsheet container has focus
309
+
310
+
311
+ if (['End', 'Home', 'ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1) {
312
+ event.preventDefault();
313
+ } // Clear out all cell selection areas if user uses any arrow key, except if the shift key is being held
314
+
315
+
316
+ if (['ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown'].indexOf(key) > -1) {
317
+ if (selectionAreas !== null && selectionAreas !== void 0 && selectionAreas.length && key !== 'Shift' && !activeKeys.current.includes('Shift')) {
318
+ setSelectionAreas([]);
319
+ removeCellSelections();
100
320
  }
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)));
321
+ } // Update list of activeKeys
322
+
323
+
324
+ if (!((_activeKeys$current = activeKeys.current) !== null && _activeKeys$current !== void 0 && _activeKeys$current.includes(key))) {
325
+ var activeClone = _toConsumableArray(activeKeys.current);
326
+
327
+ activeKeys.current = [].concat(_toConsumableArray(activeClone), [key]);
328
+ }
329
+
330
+ if (((_activeKeys$current2 = activeKeys.current) === null || _activeKeys$current2 === void 0 ? void 0 : _activeKeys$current2.length) > 1) {
331
+ handleMultipleKeys();
332
+ } // Allow arrow key navigation if there are less than two activeKeys OR
333
+ // if one of the activeCellCoordinates is in a header position
334
+
335
+
336
+ if (!activeKeys.current.includes('Shift') || activeCellCoordinates.row === 'header' || activeCellCoordinates.column === 'header') {
337
+ switch (key) {
338
+ // Tab
339
+ case 'Tab':
340
+ {
341
+ setSelectionAreas([]);
342
+ removeActiveCell();
343
+ setContainerHasFocus(false);
344
+ setActiveCellCoordinates(null);
345
+ break;
346
+ }
347
+ // Left
348
+
349
+ case 'ArrowLeft':
350
+ {
351
+ handleInitialArrowPress();
352
+
353
+ var coordinatesClone = _objectSpread({}, activeCellCoordinates);
354
+
355
+ if (coordinatesClone.column === 'header') {
356
+ return;
357
+ }
358
+
359
+ if (typeof coordinatesClone.column === 'number') {
360
+ if (coordinatesClone.column === 0) {
361
+ updateActiveCellCoordinates({
362
+ coords: coordinatesClone,
363
+ updatedValue: {
364
+ column: 'header'
365
+ }
366
+ });
367
+ return;
368
+ }
369
+
370
+ updateActiveCellCoordinates({
371
+ coords: coordinatesClone,
372
+ updatedValue: {
373
+ column: coordinatesClone.column - 1
374
+ }
375
+ });
376
+ }
377
+
378
+ break;
379
+ }
380
+ // Up
381
+
382
+ case 'ArrowUp':
383
+ {
384
+ handleInitialArrowPress();
385
+
386
+ var _coordinatesClone = _objectSpread({}, activeCellCoordinates);
387
+
388
+ if (_coordinatesClone.row === 'header') {
389
+ return;
390
+ }
391
+
392
+ if (typeof _coordinatesClone.row === 'number') {
393
+ // set row back to header if we are at index 0
394
+ if (_coordinatesClone.row === 0) {
395
+ updateActiveCellCoordinates({
396
+ coords: _coordinatesClone,
397
+ updatedValue: {
398
+ row: 'header'
399
+ }
400
+ });
401
+ return;
402
+ } // if we are at any other index than 0, subtract 1 from current row index
403
+
404
+
405
+ updateActiveCellCoordinates({
406
+ coords: _coordinatesClone,
407
+ updatedValue: {
408
+ row: _coordinatesClone.row - 1
409
+ }
410
+ });
411
+ }
412
+
413
+ break;
414
+ }
415
+ // Right
416
+
417
+ case 'ArrowRight':
418
+ {
419
+ handleInitialArrowPress();
420
+
421
+ var _coordinatesClone2 = _objectSpread({}, activeCellCoordinates);
422
+
423
+ if (_coordinatesClone2.column === 'header') {
424
+ updateActiveCellCoordinates({
425
+ coords: _coordinatesClone2,
426
+ updatedValue: {
427
+ column: 0
428
+ }
429
+ });
430
+ }
431
+
432
+ if (typeof _coordinatesClone2.column === 'number') {
433
+ // Prevent active cell coordinates from updating if the active
434
+ // cell is in the last column, ie we can't go any further to the right
435
+ if (columns.length - 1 === _coordinatesClone2.column) {
436
+ return;
437
+ }
438
+
439
+ updateActiveCellCoordinates({
440
+ coords: _coordinatesClone2,
441
+ updatedValue: {
442
+ column: _coordinatesClone2.column + 1
443
+ }
444
+ });
445
+ }
446
+
447
+ break;
448
+ }
449
+ // Down
450
+
451
+ case 'ArrowDown':
452
+ {
453
+ handleInitialArrowPress();
454
+
455
+ var _coordinatesClone3 = _objectSpread({}, activeCellCoordinates);
456
+
457
+ if (_coordinatesClone3.row === 'header') {
458
+ updateActiveCellCoordinates({
459
+ coords: _coordinatesClone3,
460
+ updatedValue: {
461
+ row: 0
462
+ }
463
+ });
464
+ }
465
+
466
+ if (typeof _coordinatesClone3.row === 'number') {
467
+ // Prevent active cell coordinates from updating if the active
468
+ // cell is in the last row, ie we can't go any further down since
469
+ // we are in the last row
470
+ if (rows.length - 1 === _coordinatesClone3.row) {
471
+ return;
472
+ }
473
+
474
+ updateActiveCellCoordinates({
475
+ coords: _coordinatesClone3,
476
+ updatedValue: {
477
+ row: _coordinatesClone3.row + 1
478
+ }
479
+ });
480
+ }
481
+
482
+ break;
483
+ }
484
+ }
485
+ }
486
+ }, [updateActiveCellCoordinates, handleInitialArrowPress, handleMultipleKeys, activeCellCoordinates, selectionAreas === null || selectionAreas === void 0 ? void 0 : selectionAreas.length, removeCellSelections, removeActiveCell, columns.length, rows.length]); // Only update if there are cell selection areas
487
+ // Find point object that matches currentMatcher and remove the second point
488
+ // because hovering over the active cell while clicking and holding should
489
+ // remove the previously existing selection area
490
+
491
+ var handleActiveCellMouseEnterCallback = useCallback(function (areas, clickHold) {
492
+ var freshMatcherValue = currentMatcherRef.current;
493
+
494
+ if (!freshMatcherValue) {
495
+ return;
496
+ }
497
+
498
+ if (areas && areas.length && clickHold && freshMatcherValue) {
499
+ setSelectionAreas(function (prev) {
500
+ var selectionAreaClone = deepCloneObject(prev);
501
+ var indexOfItemToUpdate = selectionAreaClone.findIndex(function (item) {
502
+ return item.matcher === freshMatcherValue;
503
+ });
504
+
505
+ if (indexOfItemToUpdate === -1) {
506
+ return prev;
507
+ }
508
+
509
+ if (_typeof(selectionAreaClone[indexOfItemToUpdate].point2) === 'object' && selectionAreaClone[indexOfItemToUpdate].areaCreated) {
510
+ selectionAreaClone[indexOfItemToUpdate].point2 = null;
511
+ selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
512
+ removeCellSelections(freshMatcherValue);
513
+ return selectionAreaClone;
514
+ }
515
+
516
+ return prev;
517
+ });
518
+ }
519
+ }, [removeCellSelections]); // Adds active cell highlight to correct cell onKeyDown
520
+
521
+ useEffect(function () {
522
+ var activeCellPlacementElement = spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.current.querySelector("[data-row-index=\"".concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, "\"][data-column-index=\"").concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column, "\"]"));
523
+ var shouldPlaceActiveCellInHeader = (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' && true;
524
+ var selectAllElement = spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.current.querySelector("[data-row-index=\"header\"][data-column-index=\"header\"]");
525
+
526
+ if (containerHasFocus) {
527
+ createActiveCell({
528
+ placementElement: activeCellCoordinates ? activeCellPlacementElement : selectAllElement,
529
+ coords: activeCellCoordinates,
530
+ addToHeader: shouldPlaceActiveCellInHeader
531
+ });
532
+ }
533
+ }, [activeCellCoordinates, spreadsheetRef, createActiveCell, containerHasFocus]);
534
+
535
+ var handleKeyUp = function handleKeyUp(event) {
536
+ var _activeKeys$current3;
537
+
538
+ var key = event.key; // Remove key from active keys array on key up
539
+
540
+ if ((_activeKeys$current3 = activeKeys.current) !== null && _activeKeys$current3 !== void 0 && _activeKeys$current3.includes(key)) {
541
+ var activeKeysClone = _toConsumableArray(activeKeys.current);
542
+
543
+ var filteredKeysClone = activeKeysClone.filter(function (item) {
544
+ return item !== key;
545
+ });
546
+ activeKeys.current = filteredKeysClone;
547
+ }
548
+ };
549
+
550
+ var localRef = useRef();
551
+ var spreadsheetRef = ref || localRef;
552
+ return /*#__PURE__*/React.createElement("div", _extends({}, rest, getTableProps(), getDevtoolsProps(componentName), {
553
+ className: cx(blockClass, className, _defineProperty({}, "".concat(blockClass, "__container-has-focus"), containerHasFocus)),
554
+ ref: spreadsheetRef,
555
+ role: "grid",
556
+ tabIndex: 0,
557
+ "aria-rowcount": (rows === null || rows === void 0 ? void 0 : rows.length) || 0,
558
+ "aria-colcount": (columns === null || columns === void 0 ? void 0 : columns.length) || 0,
559
+ onKeyDown: handleKeyPress,
560
+ onKeyUp: handleKeyUp,
561
+ onFocus: function onFocus() {
562
+ return setContainerHasFocus(true);
563
+ }
564
+ }), /*#__PURE__*/React.createElement(DataSpreadsheetHeader, {
565
+ activeCellCoordinates: activeCellCoordinates,
566
+ cellSizeValue: cellSizeValue,
567
+ defaultColumn: defaultColumn,
568
+ headerGroups: headerGroups,
569
+ selectionAreas: selectionAreas
570
+ }), /*#__PURE__*/React.createElement(DataSpreadsheetBody, {
571
+ activeCellCoordinates: activeCellCoordinates,
572
+ ref: currentMatcherRef,
573
+ clickAndHoldActive: clickAndHoldActive,
574
+ setClickAndHoldActive: setClickAndHoldActive,
575
+ currentMatcher: currentMatcher,
576
+ setCurrentMatcher: setCurrentMatcher,
577
+ setContainerHasFocus: setContainerHasFocus,
578
+ selectionAreas: selectionAreas,
579
+ setSelectionAreas: setSelectionAreas,
580
+ cellSize: cellSize,
581
+ defaultColumn: defaultColumn,
582
+ getTableBodyProps: getTableBodyProps,
583
+ onActiveCellChange: onActiveCellChange,
584
+ prepareRow: prepareRow,
585
+ rows: rows,
586
+ setActiveCellCoordinates: setActiveCellCoordinates,
587
+ scrollBarSize: scrollBarSize,
588
+ totalColumnsWidth: totalColumnsWidth,
589
+ id: id
590
+ }));
115
591
  }); // Return a placeholder if not released and not enabled by feature flag
116
592
 
117
593
  DataSpreadsheet = pkg.checkComponentEnabled(DataSpreadsheet, componentName); // The display name of the component, used by React. Note that displayName
@@ -122,6 +598,11 @@ DataSpreadsheet.displayName = componentName; // The types and DocGen commentary
122
598
  // See https://www.npmjs.com/package/prop-types#usage.
123
599
 
124
600
  DataSpreadsheet.propTypes = {
601
+ /**
602
+ * Specifies the cell height
603
+ */
604
+ cellSize: PropTypes.oneOf(['compact', 'standard', 'medium', 'large']),
605
+
125
606
  /**
126
607
  * Provide an optional class to be applied to the containing node.
127
608
  */
@@ -140,15 +621,17 @@ DataSpreadsheet.propTypes = {
140
621
  /**
141
622
  * The spreadsheet data that will be rendered in the body of the spreadsheet component
142
623
  */
143
- data: PropTypes.arrayOf(PropTypes.shape)
144
- /* TODO: add types and DocGen for all props. */
624
+ data: PropTypes.arrayOf(PropTypes.shape),
625
+
626
+ /**
627
+ * The spreadsheet id
628
+ */
629
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
145
630
 
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.
631
+ /**
632
+ * The event handler that is called when the active cell changes
633
+ */
634
+ onActiveCellChange: PropTypes.func
635
+ /* TODO: add types and DocGen for all props. */
150
636
 
151
- DataSpreadsheet.defaultProps = {
152
- data: [],
153
- columns: []
154
637
  };