@carbon/ibm-products 1.15.0 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. package/README.md +30 -27
  2. package/css/components/Datagrid/styles/datagrid.css +4 -0
  3. package/css/components/Datagrid/styles/datagrid.css.map +1 -1
  4. package/css/components/Datagrid/styles/index.css +5 -1
  5. package/css/components/Datagrid/styles/index.css.map +1 -1
  6. package/css/components/Datagrid/styles/useNestedRows.css +1 -1
  7. package/css/index-full-carbon.css +195 -88
  8. package/css/index-full-carbon.css.map +1 -1
  9. package/css/index-full-carbon.min.css +7 -4
  10. package/css/index-full-carbon.min.css.map +1 -1
  11. package/css/index-without-carbon-released-only.css +9 -3
  12. package/css/index-without-carbon-released-only.css.map +1 -1
  13. package/css/index-without-carbon-released-only.min.css +4 -1
  14. package/css/index-without-carbon-released-only.min.css.map +1 -1
  15. package/css/index-without-carbon.css +78 -22
  16. package/css/index-without-carbon.css.map +1 -1
  17. package/css/index-without-carbon.min.css +6 -3
  18. package/css/index-without-carbon.min.css.map +1 -1
  19. package/css/index.css +104 -53
  20. package/css/index.css.map +1 -1
  21. package/css/index.min.css +7 -4
  22. package/css/index.min.css.map +1 -1
  23. package/es/components/AddSelect/AddSelect.js +39 -10
  24. package/es/components/AddSelect/AddSelectColumn.js +31 -73
  25. package/es/components/AddSelect/AddSelectFilter.js +48 -5
  26. package/es/components/AddSelect/AddSelectSort.js +61 -0
  27. package/es/components/AddSelect/add-select-utils.js +21 -0
  28. package/es/components/AddSelect/hooks/useItemSort.js +20 -0
  29. package/es/components/DataSpreadsheet/DataSpreadsheet.js +38 -15
  30. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +93 -46
  31. package/es/components/DataSpreadsheet/DataSpreadsheetHeader.js +82 -6
  32. package/es/components/DataSpreadsheet/hooks/index.js +3 -1
  33. package/es/components/DataSpreadsheet/hooks/useSpreadsheetEdit.js +65 -19
  34. package/es/components/DataSpreadsheet/hooks/useSpreadsheetMouseMove.js +60 -0
  35. package/es/components/DataSpreadsheet/hooks/useSpreadsheetMouseUp.js +153 -0
  36. package/es/components/DataSpreadsheet/utils/checkSelectedHeaderCell.js +16 -0
  37. package/es/components/DataSpreadsheet/utils/createCellSelectionArea.js +11 -6
  38. package/es/components/DataSpreadsheet/utils/generateData.js +17 -9
  39. package/es/components/DataSpreadsheet/utils/getSpreadsheetWidth.js +30 -0
  40. package/es/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +6 -2
  41. package/es/components/DataSpreadsheet/utils/moveColumnIndicatorLine.js +34 -0
  42. package/es/components/Datagrid/Datagrid/Datagrid.js +24 -12
  43. package/es/components/Datagrid/Datagrid/DatagridHead.js +8 -16
  44. package/es/components/Datagrid/Datagrid/DatagridHeaderRow.js +10 -10
  45. package/es/components/Datagrid/Datagrid/DatagridRow.js +12 -2
  46. package/es/components/Datagrid/Datagrid/index.js +6 -7
  47. package/es/components/Datagrid/index.js +1 -1
  48. package/es/components/Datagrid/useNestedRows.js +3 -3
  49. package/es/components/Datagrid/useRowExpander.js +1 -1
  50. package/es/components/ExportModal/ExportModal.js +10 -5
  51. package/es/components/SidePanel/SidePanel.js +5 -1
  52. package/es/components/WebTerminal/WebTerminal.js +36 -11
  53. package/es/components/WebTerminal/WebTerminalContentWrapper.js +49 -0
  54. package/es/components/WebTerminal/index.js +2 -1
  55. package/es/components/index.js +1 -1
  56. package/es/global/js/package-settings.js +1 -0
  57. package/lib/components/AddSelect/AddSelect.js +40 -10
  58. package/lib/components/AddSelect/AddSelectColumn.js +32 -71
  59. package/lib/components/AddSelect/AddSelectFilter.js +47 -4
  60. package/lib/components/AddSelect/AddSelectSort.js +79 -0
  61. package/lib/components/AddSelect/add-select-utils.js +29 -2
  62. package/lib/components/AddSelect/hooks/useItemSort.js +33 -0
  63. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +37 -14
  64. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +96 -45
  65. package/lib/components/DataSpreadsheet/DataSpreadsheetHeader.js +85 -6
  66. package/lib/components/DataSpreadsheet/hooks/index.js +17 -1
  67. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetEdit.js +68 -18
  68. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetMouseMove.js +74 -0
  69. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetMouseUp.js +161 -0
  70. package/lib/components/DataSpreadsheet/utils/checkSelectedHeaderCell.js +26 -0
  71. package/lib/components/DataSpreadsheet/utils/createCellSelectionArea.js +11 -6
  72. package/lib/components/DataSpreadsheet/utils/generateData.js +17 -9
  73. package/lib/components/DataSpreadsheet/utils/getSpreadsheetWidth.js +40 -0
  74. package/lib/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +6 -2
  75. package/lib/components/DataSpreadsheet/utils/moveColumnIndicatorLine.js +45 -0
  76. package/lib/components/Datagrid/Datagrid/Datagrid.js +25 -8
  77. package/lib/components/Datagrid/Datagrid/DatagridHead.js +8 -16
  78. package/lib/components/Datagrid/Datagrid/DatagridHeaderRow.js +10 -10
  79. package/lib/components/Datagrid/Datagrid/DatagridRow.js +14 -2
  80. package/lib/components/Datagrid/Datagrid/index.js +3 -5
  81. package/lib/components/Datagrid/index.js +2 -2
  82. package/lib/components/Datagrid/useNestedRows.js +3 -3
  83. package/lib/components/Datagrid/useRowExpander.js +1 -1
  84. package/lib/components/ExportModal/ExportModal.js +9 -4
  85. package/lib/components/SidePanel/SidePanel.js +5 -1
  86. package/lib/components/WebTerminal/WebTerminal.js +36 -10
  87. package/lib/components/WebTerminal/WebTerminalContentWrapper.js +58 -0
  88. package/lib/components/WebTerminal/index.js +9 -1
  89. package/lib/components/index.js +6 -0
  90. package/lib/global/js/package-settings.js +1 -0
  91. package/package.json +14 -13
  92. package/scss/components/AddSelect/_add-select.scss +15 -2
  93. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +38 -14
  94. package/scss/components/Datagrid/styles/datagrid.scss +8 -0
  95. package/scss/components/Datagrid/styles/useNestedRows.scss +1 -1
  96. package/scss/components/SidePanel/_side-panel.scss +22 -3
  97. package/scss/components/WebTerminal/_storybook-styles.scss +5 -0
  98. package/scss/components/WebTerminal/_web-terminal.scss +14 -4
@@ -1,6 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
5
 
5
6
  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; }
6
7
 
@@ -12,7 +13,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
12
13
  * This source code is licensed under the Apache-2.0 license found in the
13
14
  * LICENSE file in the root directory of this source tree.
14
15
  */
15
- import React, { useRef, useCallback, useEffect, forwardRef } from 'react';
16
+ import React, { useRef, useCallback, useEffect, forwardRef, useState } from 'react';
16
17
  import PropTypes from 'prop-types';
17
18
  import { FixedSizeList } from 'react-window';
18
19
  import cx from 'classnames';
@@ -24,7 +25,10 @@ import { usePreviousValue } from '../../global/js/hooks';
24
25
  import { removeCellSelections } from './utils/removeCellSelections';
25
26
  import { createCellSelectionArea } from './utils/createCellSelectionArea';
26
27
  import { checkActiveHeaderCell } from './utils/checkActiveHeaderCell';
28
+ import { checkSelectedHeaderCell } from './utils/checkSelectedHeaderCell';
27
29
  import { handleHeaderCellSelection } from './utils/handleHeaderCellSelection';
30
+ import { getSpreadsheetWidth } from './utils/getSpreadsheetWidth';
31
+ import { useSpreadsheetMouseUp } from './hooks';
28
32
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
29
33
  export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
30
34
  var columns = _ref.columns,
@@ -50,7 +54,18 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
50
54
  currentMatcher = _ref.currentMatcher,
51
55
  setCurrentMatcher = _ref.setCurrentMatcher,
52
56
  onSelectionAreaChange = _ref.onSelectionAreaChange,
53
- setActiveCellInsideSelectionArea = _ref.setActiveCellInsideSelectionArea;
57
+ setActiveCellInsideSelectionArea = _ref.setActiveCellInsideSelectionArea,
58
+ totalVisibleColumns = _ref.totalVisibleColumns,
59
+ setHeaderCellHoldActive = _ref.setHeaderCellHoldActive,
60
+ setColumnOrder = _ref.setColumnOrder,
61
+ visibleColumns = _ref.visibleColumns;
62
+
63
+ var _useState = useState(false),
64
+ _useState2 = _slicedToArray(_useState, 2),
65
+ validStartingPoint = _useState2[0],
66
+ setValidStartingPoint = _useState2[1];
67
+
68
+ var contentScrollRef = useRef();
54
69
  var previousState = usePreviousValue({
55
70
  selectionAreaData: selectionAreaData,
56
71
  clickAndHoldActive: clickAndHoldActive
@@ -114,14 +129,15 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
114
129
  defaultColumn: defaultColumn,
115
130
  selectionAreas: selectionAreas,
116
131
  setSelectionAreas: setSelectionAreas,
117
- setActiveCellInsideSelectionArea: setActiveCellInsideSelectionArea
132
+ setActiveCellInsideSelectionArea: setActiveCellInsideSelectionArea,
133
+ visibleColumns: visibleColumns
118
134
  });
119
135
  }
120
136
 
121
137
  return;
122
138
  });
123
139
  }
124
- }, [selectionAreas, setSelectionAreas, defaultColumn, onSelectionAreaChange, setSelectionAreaData, ref, activeCellCoordinates, setActiveCellInsideSelectionArea]);
140
+ }, [selectionAreas, setSelectionAreas, defaultColumn, onSelectionAreaChange, setSelectionAreaData, ref, activeCellCoordinates, setActiveCellInsideSelectionArea, visibleColumns]);
125
141
 
126
142
  var populateSelectionAreaCellData = function populateSelectionAreaCellData(_ref2) {
127
143
  var rowStart = _ref2.rowStart,
@@ -137,41 +153,23 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
137
153
  }
138
154
 
139
155
  return cellContainer;
140
- }; // Mouse up
141
-
142
-
143
- useEffect(function () {
144
- var handleMouseUp = function handleMouseUp(event) {
145
- setClickAndHoldActive(false);
146
- var cellButton = event.target.closest(".".concat(blockClass, "__body--td"));
147
-
148
- if (cellButton) {
149
- var endCellCoordinates = {
150
- row: Number(cellButton.getAttribute('data-row-index')),
151
- column: Number(cellButton.getAttribute('data-column-index'))
152
- };
153
- setSelectionAreas(function (prev) {
154
- var selectionAreaClone = deepCloneObject(prev);
155
- var indexOfItemToUpdate = selectionAreaClone.findIndex(function (item) {
156
- return item.matcher === currentMatcher;
157
- }); // No items in the array have an object that matches the value of currentMatcher
158
-
159
- if (indexOfItemToUpdate === -1) {
160
- return prev;
161
- }
162
-
163
- selectionAreaClone[indexOfItemToUpdate].point2 = endCellCoordinates;
164
- selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
165
- return selectionAreaClone;
166
- });
167
- }
168
- };
169
-
170
- document.addEventListener('mouseup', handleMouseUp);
171
- return function () {
172
- document.removeEventListener('mouseup', handleMouseUp);
173
- };
174
- }, [selectionAreas, currentMatcher, setSelectionAreas, setClickAndHoldActive, setCurrentMatcher, ref]); // Make sure that if the cellSize prop changes, the active
156
+ };
157
+
158
+ useSpreadsheetMouseUp({
159
+ currentMatcher: currentMatcher,
160
+ setClickAndHoldActive: setClickAndHoldActive,
161
+ setSelectionAreas: setSelectionAreas,
162
+ setValidStartingPoint: setValidStartingPoint,
163
+ validStartingPoint: validStartingPoint,
164
+ ref: ref,
165
+ setHeaderCellHoldActive: setHeaderCellHoldActive,
166
+ setColumnOrder: setColumnOrder,
167
+ visibleColumns: visibleColumns,
168
+ setActiveCellCoordinates: setActiveCellCoordinates,
169
+ rows: rows,
170
+ activeCellCoordinates: activeCellCoordinates,
171
+ defaultColumn: defaultColumn
172
+ }); // Make sure that if the cellSize prop changes, the active
175
173
  // cell also gets updated with the new size
176
174
 
177
175
  useEffect(function () {
@@ -187,6 +185,9 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
187
185
  var handleBodyCellClick = useCallback(function (cell, columnIndex) {
188
186
  return function (event) {
189
187
  event.preventDefault();
188
+ var closestBodyCell = event.target.closest(".".concat(blockClass, "__body--td"));
189
+ var isValidSelectionAreaStart = closestBodyCell.classList.contains("".concat(blockClass, "__body--td"));
190
+ setValidStartingPoint(isValidSelectionAreaStart);
190
191
  var isHoldingCommandKey = event.metaKey || event.ctrlKey;
191
192
  var isHoldingShiftKey = event.shiftKey;
192
193
  setContainerHasFocus(true);
@@ -247,6 +248,21 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
247
248
  }
248
249
  };
249
250
  }, [currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData, setActiveCellInsideSelectionArea]);
251
+
252
+ var handleBodyScroll = function handleBodyScroll() {
253
+ var headerRowElement = ref.current.querySelector("\n .".concat(blockClass, "__header--container .").concat(blockClass, "__tr"));
254
+ headerRowElement.scrollLeft = contentScrollRef.current.scrollLeft;
255
+ };
256
+
257
+ useEffect(function () {
258
+ contentScrollRef.current.addEventListener('scroll', function (event) {
259
+ return handleBodyScroll(event);
260
+ });
261
+ var contentScrollElementRef = contentScrollRef.current;
262
+ return function () {
263
+ contentScrollElementRef.removeEventListener('scroll', handleBodyScroll);
264
+ };
265
+ });
250
266
  var handleBodyCellHover = useCallback(function (cell, columnIndex) {
251
267
  return function () {
252
268
  if (clickAndHoldActive) {
@@ -331,6 +347,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
331
347
  var row = rows[index];
332
348
 
333
349
  if (rows && rows.length) {
350
+ var _cx;
351
+
334
352
  prepareRow(row);
335
353
  return /*#__PURE__*/React.createElement("div", _extends({}, row.getRowProps({
336
354
  style: style
@@ -339,7 +357,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
339
357
  "data-row-index": index,
340
358
  "aria-rowindex": index + 1
341
359
  }), /*#__PURE__*/React.createElement("div", {
342
- role: "rowheader"
360
+ role: "rowheader",
361
+ className: "".concat(blockClass, "__td-th--cell-container")
343
362
  }, /*#__PURE__*/React.createElement("button", {
344
363
  id: "".concat(blockClass, "__cell--").concat(index, "--header"),
345
364
  tabIndex: -1,
@@ -347,9 +366,9 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
347
366
  "data-column-index": "header",
348
367
  type: "button",
349
368
  onClick: handleRowHeaderClick(index),
350
- className: cx("".concat(blockClass, "__td"), "".concat(blockClass, "__td-th"), "".concat(blockClass, "--interactive-cell-element"), _defineProperty({}, "".concat(blockClass, "__td-th--active-header"), (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === index || checkActiveHeaderCell(index, selectionAreas, 'row'))),
369
+ className: cx("".concat(blockClass, "__td"), "".concat(blockClass, "__td-th"), "".concat(blockClass, "--interactive-cell-element"), (_cx = {}, _defineProperty(_cx, "".concat(blockClass, "__td-th--active-header"), (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === index || checkActiveHeaderCell(index, selectionAreas, 'row')), _defineProperty(_cx, "".concat(blockClass, "__td-th--selected-header"), checkSelectedHeaderCell(index, selectionAreas, 'row')), _cx)),
351
370
  style: {
352
- width: (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth) - 4
371
+ width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth
353
372
  }
354
373
  }, index + 1)), row.cells.map(function (cell, index) {
355
374
  return /*#__PURE__*/React.createElement("div", _extends({
@@ -358,7 +377,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
358
377
  }, cell.getCellProps(), {
359
378
  role: "gridcell",
360
379
  style: _objectSpread(_objectSpread({}, cell.getCellProps().style), {}, {
361
- display: 'grid'
380
+ display: 'grid',
381
+ minWidth: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width
362
382
  })
363
383
  }), /*#__PURE__*/React.createElement("button", {
364
384
  id: "".concat(blockClass, "__cell--").concat(cell.row.index, "--").concat(index),
@@ -373,7 +393,7 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
373
393
  }, cell.render('Cell')));
374
394
  }));
375
395
  }
376
- }, [prepareRow, rows, defaultColumn.rowHeaderWidth, activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, selectionAreas, handleRowHeaderClick, handleBodyCellClick, handleBodyCellHover]);
396
+ }, [prepareRow, rows, activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, selectionAreas, handleRowHeaderClick, handleBodyCellClick, handleBodyCellHover, defaultColumn]);
377
397
  var spreadsheetBodyRef = useRef();
378
398
  return /*#__PURE__*/React.createElement("div", _extends({
379
399
  ref: spreadsheetBodyRef,
@@ -383,7 +403,13 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
383
403
  height: 400,
384
404
  itemCount: rows.length || defaultEmptyRowCount,
385
405
  itemSize: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight,
386
- width: totalColumnsWidth + scrollBarSize
406
+ width: getSpreadsheetWidth({
407
+ scrollBarSizeValue: scrollBarSize,
408
+ totalVisibleColumns: totalVisibleColumns,
409
+ defaultColumn: defaultColumn,
410
+ totalColumnsWidth: totalColumnsWidth
411
+ }),
412
+ outerRef: contentScrollRef
387
413
  }, rows !== null && rows !== void 0 && rows.length ? RenderRow : RenderEmptyRows));
388
414
  });
389
415
  DataSpreadsheetBody.propTypes = {
@@ -494,6 +520,11 @@ DataSpreadsheetBody.propTypes = {
494
520
  */
495
521
  setClickAndHoldActive: PropTypes.func,
496
522
 
523
+ /**
524
+ * Setter fn for column ordering, provided from react-table
525
+ */
526
+ setColumnOrder: PropTypes.func,
527
+
497
528
  /**
498
529
  * Setter fn for containerHasFocus state value
499
530
  */
@@ -504,6 +535,11 @@ DataSpreadsheetBody.propTypes = {
504
535
  */
505
536
  setCurrentMatcher: PropTypes.func,
506
537
 
538
+ /**
539
+ * Setter fn for header cell hold active value
540
+ */
541
+ setHeaderCellHoldActive: PropTypes.func,
542
+
507
543
  /**
508
544
  * Setter fn for selectionAreaData state value
509
545
  */
@@ -517,5 +553,16 @@ DataSpreadsheetBody.propTypes = {
517
553
  /**
518
554
  * The total columns width
519
555
  */
520
- totalColumnsWidth: PropTypes.number
556
+ totalColumnsWidth: PropTypes.number,
557
+
558
+ /**
559
+ * The total number of columns to be initially visible, additional columns will be rendered and
560
+ * visible via horizontal scrollbar
561
+ */
562
+ totalVisibleColumns: PropTypes.number,
563
+
564
+ /**
565
+ * Prop from react-table used to reorder columns
566
+ */
567
+ visibleColumns: PropTypes.array
521
568
  };
@@ -19,8 +19,11 @@ import { px } from '@carbon/layout';
19
19
  import { pkg } from '../../settings';
20
20
  import { usePreviousValue } from '../../global/js/hooks';
21
21
  import { checkActiveHeaderCell } from './utils/checkActiveHeaderCell';
22
+ import { checkSelectedHeaderCell } from './utils/checkSelectedHeaderCell';
22
23
  import { handleHeaderCellSelection } from './utils/handleHeaderCellSelection';
23
24
  import { selectAllCells } from './utils/selectAllCells';
25
+ import { getSpreadsheetWidth } from './utils/getSpreadsheetWidth';
26
+ import { useSpreadsheetMouseMove } from './hooks';
24
27
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
25
28
  export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref) {
26
29
  var activeCellCoordinates = _ref.activeCellCoordinates,
@@ -35,13 +38,21 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
35
38
  setSelectionAreas = _ref.setSelectionAreas,
36
39
  setSelectionAreaData = _ref.setSelectionAreaData,
37
40
  rows = _ref.rows,
38
- updateActiveCellCoordinates = _ref.updateActiveCellCoordinates;
41
+ totalVisibleColumns = _ref.totalVisibleColumns,
42
+ updateActiveCellCoordinates = _ref.updateActiveCellCoordinates,
43
+ setHeaderCellHoldActive = _ref.setHeaderCellHoldActive,
44
+ headerCellHoldActive = _ref.headerCellHoldActive;
39
45
 
40
46
  var _useState = useState(0),
41
47
  _useState2 = _slicedToArray(_useState, 2),
42
48
  scrollBarSizeValue = _useState2[0],
43
49
  setScrollBarSizeValue = _useState2[1];
44
50
 
51
+ var _useState3 = useState(false),
52
+ _useState4 = _slicedToArray(_useState3, 2),
53
+ selectedHeaderReorderActive = _useState4[0],
54
+ setSelectedHeaderReorderActive = _useState4[1];
55
+
45
56
  var previousState = usePreviousValue({
46
57
  cellSize: cellSize
47
58
  });
@@ -87,6 +98,39 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
87
98
  });
88
99
  };
89
100
 
101
+ var handleHeaderMouseDown = function handleHeaderMouseDown(index) {
102
+ return function (event) {
103
+ var _selectionAreaToClone;
104
+
105
+ setSelectedHeaderReorderActive(true);
106
+ var clickXPosition = event.clientX;
107
+ var headerButtonCoords = event.target.getBoundingClientRect();
108
+ var offsetXValue = clickXPosition - headerButtonCoords.left;
109
+ var bodyContainer = document.querySelector(".".concat(blockClass, "__list--container")).firstElementChild;
110
+ var selectionAreaToClone = selectionAreas.filter(function (item) {
111
+ var _item$header;
112
+
113
+ return (item === null || item === void 0 ? void 0 : (_item$header = item.header) === null || _item$header === void 0 ? void 0 : _item$header.index) === index;
114
+ });
115
+ var selectionAreaElement = ref.current.querySelector("[data-matcher-id=\"".concat((_selectionAreaToClone = selectionAreaToClone[0]) === null || _selectionAreaToClone === void 0 ? void 0 : _selectionAreaToClone.matcher, "\"]"));
116
+ var selectionAreaClonedElement = selectionAreaElement.cloneNode();
117
+ var reorderIndicatorLine = selectionAreaElement.cloneNode();
118
+ reorderIndicatorLine.className = "".concat(blockClass, "__reorder-indicator-line");
119
+ reorderIndicatorLine.style.width = px(2);
120
+ selectionAreaClonedElement.classList.add("".concat(blockClass, "__selection-area--element-cloned"));
121
+ selectionAreaClonedElement.setAttribute('data-clone-offset-x', offsetXValue);
122
+ selectionAreaClonedElement.setAttribute('data-column-index-original', index);
123
+ bodyContainer.appendChild(selectionAreaClonedElement);
124
+ bodyContainer.appendChild(reorderIndicatorLine);
125
+ setHeaderCellHoldActive(true);
126
+ };
127
+ };
128
+
129
+ useSpreadsheetMouseMove({
130
+ ref: ref,
131
+ headerCellHoldActive: headerCellHoldActive,
132
+ defaultColumn: defaultColumn
133
+ });
90
134
  return /*#__PURE__*/React.createElement("div", {
91
135
  className: cx("".concat(blockClass, "__header--container")),
92
136
  role: "rowgroup"
@@ -95,13 +139,21 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
95
139
  key: "header_".concat(index)
96
140
  }, headerGroup.getHeaderGroupProps(), {
97
141
  style: _objectSpread(_objectSpread({}, headerGroup.getHeaderGroupProps().style), {}, {
98
- width: px(parseInt(headerGroup.getHeaderGroupProps().style.width) + scrollBarSizeValue)
142
+ width: getSpreadsheetWidth({
143
+ type: 'header',
144
+ headerGroup: headerGroup,
145
+ scrollBarSizeValue: scrollBarSizeValue,
146
+ totalVisibleColumns: totalVisibleColumns,
147
+ defaultColumn: defaultColumn
148
+ }),
149
+ overflow: 'hidden'
99
150
  }),
100
151
  className: "".concat(blockClass, "__tr")
101
152
  }), /*#__PURE__*/React.createElement("div", {
102
153
  role: "columnheader",
154
+ className: "".concat(blockClass, "__select-all-cell-container"),
103
155
  style: {
104
- width: (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth) - 4,
156
+ width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth,
105
157
  height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight
106
158
  }
107
159
  }, /*#__PURE__*/React.createElement("button", {
@@ -113,6 +165,9 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
113
165
  onClick: handleSelectAllClick,
114
166
  className: cx("".concat(blockClass, "__th"), "".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__th--select-all"), _defineProperty({}, "".concat(blockClass, "__th--active-header"), (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header'))
115
167
  }, "\xA0")), headerGroup.headers.map(function (column, index) {
168
+ var _cx2;
169
+
170
+ var selectedHeader = checkSelectedHeaderCell(index, selectionAreas, 'column');
116
171
  return /*#__PURE__*/React.createElement("div", _extends({
117
172
  key: "column_".concat(index),
118
173
  role: "columnheader",
@@ -122,11 +177,16 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
122
177
  "data-row-index": "header",
123
178
  "data-column-index": index,
124
179
  tabIndex: -1,
125
- onClick: handleColumnHeaderClick(index),
180
+ onMouseDown: selectedHeader ? handleHeaderMouseDown(index) : null,
181
+ onMouseUp: selectedHeader ? function () {
182
+ return setSelectedHeaderReorderActive(false);
183
+ } : null,
184
+ onClick: !selectedHeader ? handleColumnHeaderClick(index) : null,
126
185
  style: {
127
- height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight
186
+ height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight,
187
+ width: (column === null || column === void 0 ? void 0 : column.width) || (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width)
128
188
  },
129
- className: cx("".concat(blockClass, "__th"), "".concat(blockClass, "--interactive-cell-element"), _defineProperty({}, "".concat(blockClass, "__th--active-header"), (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === index || checkActiveHeaderCell(index, selectionAreas, 'column'))),
189
+ className: cx("".concat(blockClass, "__th"), "".concat(blockClass, "--interactive-cell-element"), (_cx2 = {}, _defineProperty(_cx2, "".concat(blockClass, "__th--active-header"), (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === index || checkActiveHeaderCell(index, selectionAreas, 'column')), _defineProperty(_cx2, "".concat(blockClass, "__th--selected-header"), selectedHeader), _defineProperty(_cx2, "".concat(blockClass, "__th--selected-header-reorder-active"), selectedHeaderReorderActive), _cx2)),
130
190
  type: "button"
131
191
  }, column.render('Header')));
132
192
  }));
@@ -160,6 +220,11 @@ DataSpreadsheetHeader.propTypes = {
160
220
  width: PropTypes.number
161
221
  }),
162
222
 
223
+ /**
224
+ * Whether or not a click/hold is active on a header cell
225
+ */
226
+ headerCellHoldActive: PropTypes.bool,
227
+
163
228
  /**
164
229
  * Headers provided from useTable hook
165
230
  */
@@ -190,6 +255,11 @@ DataSpreadsheetHeader.propTypes = {
190
255
  */
191
256
  setCurrentMatcher: PropTypes.func,
192
257
 
258
+ /**
259
+ * Setter fn for header cell hold active value
260
+ */
261
+ setHeaderCellHoldActive: PropTypes.func,
262
+
193
263
  /**
194
264
  * Setter fn for selectionAreaData state value
195
265
  */
@@ -200,6 +270,12 @@ DataSpreadsheetHeader.propTypes = {
200
270
  */
201
271
  setSelectionAreas: PropTypes.func,
202
272
 
273
+ /**
274
+ * The total number of columns to be initially visible, additional columns will be rendered and
275
+ * visible via horizontal scrollbar
276
+ */
277
+ totalVisibleColumns: PropTypes.number,
278
+
203
279
  /**
204
280
  * Function used to update the active cell coordinates
205
281
  */
@@ -8,4 +8,6 @@ export { useMoveActiveCell } from './useMoveActiveCell';
8
8
  export { useMultipleKeyTracking } from './useMultipleKeyTracking';
9
9
  export { useResetSpreadsheetFocus } from './useResetSpreadsheetFocus';
10
10
  export { useSpreadsheetOutsideClick } from './useSpreadsheetOutsideClick';
11
- export { useSpreadsheetEdit } from './useSpreadsheetEdit';
11
+ export { useSpreadsheetEdit } from './useSpreadsheetEdit';
12
+ export { useSpreadsheetMouseUp } from './useSpreadsheetMouseUp';
13
+ export { useSpreadsheetMouseMove } from './useSpreadsheetMouseMove';
@@ -1,11 +1,15 @@
1
- // /**
2
- // * Copyright IBM Corp. 2022, 2022
3
- // *
4
- // * This source code is licensed under the Apache-2.0 license found in the
5
- // * LICENSE file in the root directory of this source tree.
6
- // */
7
- import { useEffect } from 'react';
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+
3
+ /**
4
+ * Copyright IBM Corp. 2022, 2022
5
+ *
6
+ * This source code is licensed under the Apache-2.0 license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ import { useEffect, useState } from 'react';
8
10
  import { px } from '@carbon/layout';
11
+ import { pkg } from '../../../settings';
12
+ import { usePreviousValue } from '../../../global/js/hooks';
9
13
  export var useSpreadsheetEdit = function useSpreadsheetEdit(_ref) {
10
14
  var isEditing = _ref.isEditing,
11
15
  rows = _ref.rows,
@@ -13,10 +17,29 @@ export var useSpreadsheetEdit = function useSpreadsheetEdit(_ref) {
13
17
  activeCellRef = _ref.activeCellRef,
14
18
  cellEditorRef = _ref.cellEditorRef,
15
19
  cellEditorRulerRef = _ref.cellEditorRulerRef,
16
- columns = _ref.columns,
20
+ visibleColumns = _ref.visibleColumns,
17
21
  defaultColumn = _ref.defaultColumn,
18
- cellEditorValue = _ref.cellEditorValue;
22
+ cellEditorValue = _ref.cellEditorValue,
23
+ _ref$blockClass = _ref.blockClass,
24
+ blockClass = _ref$blockClass === void 0 ? "".concat(pkg.prefix, "--data-spreadsheet") : _ref$blockClass;
25
+
26
+ var _useState = useState(null),
27
+ _useState2 = _slicedToArray(_useState, 2),
28
+ nextIndex = _useState2[0],
29
+ setNextIndex = _useState2[1];
30
+
31
+ var previousState = usePreviousValue({
32
+ nextIndex: nextIndex
33
+ });
19
34
  useEffect(function () {
35
+ if (!(previousState !== null && previousState !== void 0 && previousState.nextIndex)) {
36
+ setNextIndex(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column);
37
+ }
38
+ }, [previousState === null || previousState === void 0 ? void 0 : previousState.nextIndex, activeCellCoordinates]);
39
+ useEffect(function () {
40
+ var rulerWidth = cellEditorRulerRef.current.offsetWidth;
41
+ var cellEditorCurrentWidth = parseInt(cellEditorRef.current.style.width);
42
+
20
43
  if (isEditing) {
21
44
  var _rows$activeCellCoord, _cellProps$column, _cellEditorRef$curren;
22
45
 
@@ -26,25 +49,47 @@ export var useSpreadsheetEdit = function useSpreadsheetEdit(_ref) {
26
49
  cellEditorRef.current.style.left = activeCellLeftPosition;
27
50
  cellEditorRef.current.style.top = activeCellTopPosition;
28
51
  cellEditorRef.current.style.display = 'block';
29
- cellEditorRef.current.style.width = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.width;
30
52
  cellEditorRef.current.style.height = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.height;
31
53
  cellEditorRef.current.style.paddingTop = "".concat((parseInt(activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.height) - 16) / 2 - 1, "px"); // calculate paddingTop based on cellHeight which could be variable depending on the cellSize prop
32
54
 
33
55
  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';
34
56
  (_cellEditorRef$curren = cellEditorRef.current) === null || _cellEditorRef$curren === void 0 ? void 0 : _cellEditorRef$curren.focus();
35
- var rulerWidth = cellEditorRulerRef.current.offsetWidth;
36
- var cellWidth = activeCellRef.current.offsetWidth;
37
57
 
38
- if (rulerWidth >= cellWidth) {
39
- var widthMultiplier = Math.floor(rulerWidth / cellWidth) + 1;
40
- var startingColumnPosition = activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column;
58
+ if (rulerWidth < cellEditorCurrentWidth) {
59
+ var _visibleColumns$nextI;
60
+
61
+ var currentColumnWidth = ((_visibleColumns$nextI = visibleColumns[nextIndex]) === null || _visibleColumns$nextI === void 0 ? void 0 : _visibleColumns$nextI.width) || (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width); // If the contents of the cell editor is deleted past the point of the next column
62
+
63
+ if (rulerWidth < cellEditorCurrentWidth - currentColumnWidth) {
64
+ cellEditorRef.current.style.width = px(parseInt(cellEditorRef.current.style.width) - currentColumnWidth);
65
+ setNextIndex(function (prev) {
66
+ if (prev === 0) {
67
+ return prev;
68
+ }
69
+
70
+ return prev - 1;
71
+ });
72
+ } // Decrease cell editor width by increment of current column width
73
+
74
+ }
75
+
76
+ if (rulerWidth >= cellEditorCurrentWidth) {
77
+ var _visibleColumns;
78
+
79
+ setNextIndex(function (prev) {
80
+ if (prev === visibleColumns.length - 1) {
81
+ return prev;
82
+ }
83
+
84
+ return prev + 1;
85
+ });
86
+ var onLastColumnIndex = nextIndex + 1 === visibleColumns.length;
87
+ var nextColumnWidth = onLastColumnIndex ? 0 : ((_visibleColumns = visibleColumns[nextIndex + 1]) === null || _visibleColumns === void 0 ? void 0 : _visibleColumns.width) || (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width);
41
88
  var startingRowPosition = activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row;
42
- var totalColumns = columns.length;
43
89
  var totalRows = rows.length;
44
- var totalMultiplierPossible = totalColumns - startingColumnPosition;
45
90
  var totalCellEditorMaxHeight = (totalRows - startingRowPosition) * defaultColumn.rowHeight;
46
91
  cellEditorRef.current.style.maxHeight = px(totalCellEditorMaxHeight);
47
- cellEditorRef.current.style.width = px(cellWidth * (widthMultiplier <= totalMultiplierPossible ? widthMultiplier : totalMultiplierPossible));
92
+ cellEditorRef.current.style.width = px(nextColumnWidth + cellEditorCurrentWidth);
48
93
  cellEditorRef.current.style.height = px(cellEditorRef.current.scrollHeight); // adds dynamic height to cell editor
49
94
  // Cell editor has reached max height, we need to add the scrolling back.
50
95
  // We also need to subtract 1 to account for the fact that the cell editor
@@ -63,6 +108,7 @@ export var useSpreadsheetEdit = function useSpreadsheetEdit(_ref) {
63
108
  cellEditorRef.current.style.display = 'none';
64
109
  cellEditorRef.current.blur();
65
110
  activeCellRef.current.focus();
111
+ setNextIndex(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column);
66
112
  }
67
- }, [isEditing, activeCellCoordinates, rows, cellEditorValue, columns.length, defaultColumn, cellEditorValue, activeCellRef, cellEditorRef, cellEditorRulerRef]);
113
+ }, [isEditing, activeCellCoordinates, rows, cellEditorValue, defaultColumn, activeCellRef, cellEditorRef, cellEditorRulerRef, visibleColumns, blockClass, previousState === null || previousState === void 0 ? void 0 : previousState.cellEditorValue, nextIndex]);
68
114
  };
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Copyright IBM Corp. 2022, 2022
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { useEffect } from 'react';
8
+ import { px } from '@carbon/layout';
9
+ import { pkg } from '../../../settings';
10
+ import { getScrollbarWidth } from '../../../global/js/utils/getScrollbarWidth';
11
+ import { moveColumnIndicatorLine } from '../utils/moveColumnIndicatorLine'; // Used specifically for reordering columns, will move the position of the
12
+ // cloned selection area to follow the position of the cursor
13
+
14
+ export var useSpreadsheetMouseMove = function useSpreadsheetMouseMove(_ref) {
15
+ var ref = _ref.ref,
16
+ _ref$blockClass = _ref.blockClass,
17
+ blockClass = _ref$blockClass === void 0 ? "".concat(pkg.prefix, "--data-spreadsheet") : _ref$blockClass,
18
+ headerCellHoldActive = _ref.headerCellHoldActive,
19
+ defaultColumn = _ref.defaultColumn;
20
+ useEffect(function () {
21
+ var handleMouseMove = function handleMouseMove(event) {
22
+ var clonedSelectionElement = ref.current.querySelector(".".concat(blockClass, "__selection-area--element-cloned"));
23
+
24
+ if (clonedSelectionElement) {
25
+ ref.current.addEventListener('mousemove', handleMouseMove);
26
+ }
27
+
28
+ var spreadsheetCoords = ref.current.getBoundingClientRect();
29
+ moveColumnIndicatorLine({
30
+ clonedSelectionElement: clonedSelectionElement,
31
+ ref: ref,
32
+ spreadsheetCoords: spreadsheetCoords
33
+ });
34
+ var scrollbarWidth = getScrollbarWidth();
35
+ var spreadsheetWrapperElement = ref.current;
36
+ spreadsheetWrapperElement.getBoundingClientRect();
37
+ var xPositionRelativeToSpreadsheet = event.clientX - spreadsheetCoords.left;
38
+ var offsetXValue = clonedSelectionElement === null || clonedSelectionElement === void 0 ? void 0 : clonedSelectionElement.getAttribute('data-clone-offset-x');
39
+ var totalSpreadsheetWidth = ref.current.offsetWidth;
40
+ var clonedSelectionWidth = clonedSelectionElement.offsetWidth;
41
+ var clonePlacement = Math.max(xPositionRelativeToSpreadsheet - offsetXValue, defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth); // Moves the position of the cloned selection area to follow mouse
42
+
43
+ clonedSelectionElement.style.left = px(totalSpreadsheetWidth - clonedSelectionWidth - scrollbarWidth >= clonePlacement ? clonePlacement : totalSpreadsheetWidth - clonedSelectionWidth - scrollbarWidth);
44
+ };
45
+
46
+ if (headerCellHoldActive) {
47
+ ref.current.addEventListener('mousemove', handleMouseMove);
48
+ }
49
+
50
+ var spreadsheetRef = ref.current;
51
+
52
+ if (!headerCellHoldActive) {
53
+ spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.removeEventListener('mousemove', handleMouseMove);
54
+ }
55
+
56
+ return function () {
57
+ spreadsheetRef === null || spreadsheetRef === void 0 ? void 0 : spreadsheetRef.removeEventListener('mousemove', handleMouseMove);
58
+ };
59
+ });
60
+ };