@carbon/ibm-products 1.14.0 → 1.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. package/css/components/Datagrid/styles/datagrid.css +4 -0
  2. package/css/components/Datagrid/styles/datagrid.css.map +1 -1
  3. package/css/components/Datagrid/styles/index.css +5 -1
  4. package/css/components/Datagrid/styles/index.css.map +1 -1
  5. package/css/components/Datagrid/styles/useNestedRows.css +1 -1
  6. package/css/index-full-carbon.css +75 -16
  7. package/css/index-full-carbon.css.map +1 -1
  8. package/css/index-full-carbon.min.css +6 -3
  9. package/css/index-full-carbon.min.css.map +1 -1
  10. package/css/index-without-carbon-released-only.css +13 -7
  11. package/css/index-without-carbon-released-only.css.map +1 -1
  12. package/css/index-without-carbon-released-only.min.css +5 -2
  13. package/css/index-without-carbon-released-only.min.css.map +1 -1
  14. package/css/index-without-carbon.css +75 -16
  15. package/css/index-without-carbon.css.map +1 -1
  16. package/css/index-without-carbon.min.css +6 -3
  17. package/css/index-without-carbon.min.css.map +1 -1
  18. package/css/index.css +75 -16
  19. package/css/index.css.map +1 -1
  20. package/css/index.min.css +6 -3
  21. package/css/index.min.css.map +1 -1
  22. package/es/components/AddSelect/AddSelect.js +34 -23
  23. package/es/components/AddSelect/AddSelectFilter.js +52 -9
  24. package/es/components/DataSpreadsheet/DataSpreadsheet.js +186 -129
  25. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +67 -15
  26. package/es/components/DataSpreadsheet/DataSpreadsheetHeader.js +55 -11
  27. package/es/components/DataSpreadsheet/hooks/index.js +2 -1
  28. package/es/components/DataSpreadsheet/hooks/useMultipleKeyTracking.js +36 -8
  29. package/es/components/DataSpreadsheet/hooks/useSpreadsheetEdit.js +113 -0
  30. package/es/components/DataSpreadsheet/utils/checkSelectedHeaderCell.js +16 -0
  31. package/es/components/DataSpreadsheet/utils/createCellSelectionArea.js +29 -12
  32. package/es/components/DataSpreadsheet/utils/generateData.js +17 -9
  33. package/es/components/DataSpreadsheet/utils/getSelectionAreaPoints.js +18 -0
  34. package/es/components/DataSpreadsheet/utils/getSpreadsheetWidth.js +30 -0
  35. package/es/components/DataSpreadsheet/utils/handleActiveCellInSelectionEnter.js +121 -0
  36. package/es/components/DataSpreadsheet/utils/handleActiveCellInSelectionTab.js +108 -0
  37. package/es/components/DataSpreadsheet/utils/handleEditSubmit.js +87 -0
  38. package/es/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +46 -8
  39. package/es/components/DataSpreadsheet/utils/handleMultipleKeys.js +153 -15
  40. package/es/components/DataSpreadsheet/utils/selectAllCells.js +53 -0
  41. package/es/components/Datagrid/Datagrid/Datagrid.js +24 -12
  42. package/es/components/Datagrid/Datagrid/DatagridHead.js +8 -16
  43. package/es/components/Datagrid/Datagrid/DatagridHeaderRow.js +10 -10
  44. package/es/components/Datagrid/Datagrid/DatagridRow.js +12 -2
  45. package/es/components/Datagrid/Datagrid/index.js +6 -7
  46. package/es/components/Datagrid/index.js +1 -1
  47. package/es/components/Datagrid/useNestedRows.js +3 -3
  48. package/es/components/Datagrid/useRowExpander.js +1 -1
  49. package/es/components/ExportModal/ExportModal.js +10 -5
  50. package/es/components/MultiAddSelect/MultiAddSelect.js +150 -3
  51. package/es/components/PageHeader/PageHeader.js +3 -1
  52. package/es/components/SidePanel/SidePanel.js +5 -1
  53. package/es/components/SingleAddSelect/SingleAddSelect.js +90 -4
  54. package/es/components/TagSet/TagSet.js +13 -6
  55. package/es/components/Tearsheet/TearsheetShell.js +34 -10
  56. package/es/components/WebTerminal/WebTerminal.js +36 -11
  57. package/es/components/WebTerminal/WebTerminalContentWrapper.js +49 -0
  58. package/es/components/WebTerminal/index.js +2 -1
  59. package/es/components/index.js +1 -1
  60. package/es/global/js/package-settings.js +3 -1
  61. package/lib/components/AddSelect/AddSelect.js +34 -23
  62. package/lib/components/AddSelect/AddSelectFilter.js +51 -8
  63. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +190 -128
  64. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +69 -15
  65. package/lib/components/DataSpreadsheet/DataSpreadsheetHeader.js +58 -12
  66. package/lib/components/DataSpreadsheet/hooks/index.js +9 -1
  67. package/lib/components/DataSpreadsheet/hooks/useMultipleKeyTracking.js +36 -8
  68. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetEdit.js +129 -0
  69. package/lib/components/DataSpreadsheet/utils/checkSelectedHeaderCell.js +26 -0
  70. package/lib/components/DataSpreadsheet/utils/createCellSelectionArea.js +31 -13
  71. package/lib/components/DataSpreadsheet/utils/generateData.js +17 -9
  72. package/lib/components/DataSpreadsheet/utils/getSelectionAreaPoints.js +27 -0
  73. package/lib/components/DataSpreadsheet/utils/getSpreadsheetWidth.js +40 -0
  74. package/lib/components/DataSpreadsheet/utils/handleActiveCellInSelectionEnter.js +127 -0
  75. package/lib/components/DataSpreadsheet/utils/handleActiveCellInSelectionTab.js +118 -0
  76. package/lib/components/DataSpreadsheet/utils/handleEditSubmit.js +94 -0
  77. package/lib/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +48 -8
  78. package/lib/components/DataSpreadsheet/utils/handleMultipleKeys.js +161 -22
  79. package/lib/components/DataSpreadsheet/utils/selectAllCells.js +60 -0
  80. package/lib/components/Datagrid/Datagrid/Datagrid.js +25 -8
  81. package/lib/components/Datagrid/Datagrid/DatagridHead.js +8 -16
  82. package/lib/components/Datagrid/Datagrid/DatagridHeaderRow.js +10 -10
  83. package/lib/components/Datagrid/Datagrid/DatagridRow.js +14 -2
  84. package/lib/components/Datagrid/Datagrid/index.js +3 -5
  85. package/lib/components/Datagrid/index.js +2 -2
  86. package/lib/components/Datagrid/useNestedRows.js +3 -3
  87. package/lib/components/Datagrid/useRowExpander.js +1 -1
  88. package/lib/components/ExportModal/ExportModal.js +9 -4
  89. package/lib/components/MultiAddSelect/MultiAddSelect.js +150 -2
  90. package/lib/components/PageHeader/PageHeader.js +3 -1
  91. package/lib/components/SidePanel/SidePanel.js +5 -1
  92. package/lib/components/SingleAddSelect/SingleAddSelect.js +91 -3
  93. package/lib/components/TagSet/TagSet.js +13 -6
  94. package/lib/components/Tearsheet/TearsheetShell.js +36 -10
  95. package/lib/components/WebTerminal/WebTerminal.js +36 -10
  96. package/lib/components/WebTerminal/WebTerminalContentWrapper.js +58 -0
  97. package/lib/components/WebTerminal/index.js +9 -1
  98. package/lib/components/index.js +6 -0
  99. package/lib/global/js/package-settings.js +3 -1
  100. package/package.json +13 -13
  101. package/scss/components/AboutModal/_about-modal.scss +4 -0
  102. package/scss/components/AddSelect/_add-select.scss +9 -2
  103. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +39 -2
  104. package/scss/components/Datagrid/styles/datagrid.scss +8 -0
  105. package/scss/components/Datagrid/styles/useNestedRows.scss +1 -1
  106. package/scss/components/ExportModal/_export-modal.scss +0 -4
  107. package/scss/components/SidePanel/_side-panel.scss +22 -3
  108. package/scss/components/WebTerminal/_storybook-styles.scss +5 -0
  109. package/scss/components/WebTerminal/_web-terminal.scss +14 -4
@@ -24,7 +24,9 @@ import { usePreviousValue } from '../../global/js/hooks';
24
24
  import { removeCellSelections } from './utils/removeCellSelections';
25
25
  import { createCellSelectionArea } from './utils/createCellSelectionArea';
26
26
  import { checkActiveHeaderCell } from './utils/checkActiveHeaderCell';
27
+ import { checkSelectedHeaderCell } from './utils/checkSelectedHeaderCell';
27
28
  import { handleHeaderCellSelection } from './utils/handleHeaderCellSelection';
29
+ import { getSpreadsheetWidth } from './utils/getSpreadsheetWidth';
28
30
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
29
31
  export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
30
32
  var columns = _ref.columns,
@@ -49,7 +51,10 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
49
51
  setClickAndHoldActive = _ref.setClickAndHoldActive,
50
52
  currentMatcher = _ref.currentMatcher,
51
53
  setCurrentMatcher = _ref.setCurrentMatcher,
52
- onSelectionAreaChange = _ref.onSelectionAreaChange;
54
+ onSelectionAreaChange = _ref.onSelectionAreaChange,
55
+ setActiveCellInsideSelectionArea = _ref.setActiveCellInsideSelectionArea,
56
+ totalVisibleColumns = _ref.totalVisibleColumns;
57
+ var contentScrollRef = useRef();
53
58
  var previousState = usePreviousValue({
54
59
  selectionAreaData: selectionAreaData,
55
60
  clickAndHoldActive: clickAndHoldActive
@@ -107,18 +112,21 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
107
112
 
108
113
  if (!area.areaCreated && area.point1 && area.point2 && area.matcher) {
109
114
  createCellSelectionArea({
115
+ ref: ref,
110
116
  area: area,
111
117
  blockClass: blockClass,
118
+ columns: columns,
112
119
  defaultColumn: defaultColumn,
113
120
  selectionAreas: selectionAreas,
114
- setSelectionAreas: setSelectionAreas
121
+ setSelectionAreas: setSelectionAreas,
122
+ setActiveCellInsideSelectionArea: setActiveCellInsideSelectionArea
115
123
  });
116
124
  }
117
125
 
118
126
  return;
119
127
  });
120
128
  }
121
- }, [selectionAreas, setSelectionAreas, defaultColumn, onSelectionAreaChange, setSelectionAreaData]);
129
+ }, [selectionAreas, setSelectionAreas, defaultColumn, onSelectionAreaChange, setSelectionAreaData, ref, activeCellCoordinates, setActiveCellInsideSelectionArea, columns]);
122
130
 
123
131
  var populateSelectionAreaCellData = function populateSelectionAreaCellData(_ref2) {
124
132
  var rowStart = _ref2.rowStart,
@@ -196,6 +204,9 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
196
204
  // meaning that selectionAreas should only have one item by default
197
205
 
198
206
  if (isHoldingCommandKey) {
207
+ var activeCellElement = ref.current.querySelector(".".concat(blockClass, "__active-cell--highlight"));
208
+ activeCellElement.setAttribute('data-selection-id', tempMatcher);
209
+ setActiveCellInsideSelectionArea(true);
199
210
  setActiveCellCoordinates(activeCoordinates);
200
211
  setCurrentMatcher(tempMatcher);
201
212
  setSelectionAreas(function (prev) {
@@ -226,6 +237,7 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
226
237
  setSelectionAreas(selectionAreaClone);
227
238
  }
228
239
  } else {
240
+ setActiveCellInsideSelectionArea(false);
229
241
  setActiveCellCoordinates(activeCoordinates); // remove all previous cell selections
230
242
 
231
243
  removeCellSelections({
@@ -239,7 +251,22 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
239
251
  setSelectionAreaData([]);
240
252
  }
241
253
  };
242
- }, [currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData]);
254
+ }, [currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData, setActiveCellInsideSelectionArea]);
255
+
256
+ var handleBodyScroll = function handleBodyScroll() {
257
+ var headerRowElement = ref.current.querySelector("\n .".concat(blockClass, "__header--container .").concat(blockClass, "__tr"));
258
+ headerRowElement.scrollLeft = contentScrollRef.current.scrollLeft;
259
+ };
260
+
261
+ useEffect(function () {
262
+ contentScrollRef.current.addEventListener('scroll', function (event) {
263
+ return handleBodyScroll(event);
264
+ });
265
+ var contentScrollElementRef = contentScrollRef.current;
266
+ return function () {
267
+ contentScrollElementRef.removeEventListener('scroll', handleBodyScroll);
268
+ };
269
+ });
243
270
  var handleBodyCellHover = useCallback(function (cell, columnIndex) {
244
271
  return function () {
245
272
  if (clickAndHoldActive) {
@@ -272,7 +299,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
272
299
  };
273
300
  }, [clickAndHoldActive, currentMatcher, setSelectionAreas]);
274
301
  var handleRowHeaderClick = useCallback(function (index) {
275
- return function () {
302
+ return function (event) {
303
+ var isHoldingCommandKey = event.metaKey || event.ctrlKey;
276
304
  handleHeaderCellSelection({
277
305
  type: 'row',
278
306
  activeCellCoordinates: activeCellCoordinates,
@@ -283,7 +311,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
283
311
  setSelectionAreas: setSelectionAreas,
284
312
  spreadsheetRef: ref,
285
313
  index: index,
286
- setSelectionAreaData: setSelectionAreaData
314
+ setSelectionAreaData: setSelectionAreaData,
315
+ isHoldingCommandKey: isHoldingCommandKey
287
316
  });
288
317
  };
289
318
  }, [columns, ref, setSelectionAreas, setCurrentMatcher, setActiveCellCoordinates, activeCellCoordinates, rows, setSelectionAreaData]); // Builds the empty rows and calls `onDataUpdate` to set the new empty rows
@@ -322,35 +351,41 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
322
351
  var row = rows[index];
323
352
 
324
353
  if (rows && rows.length) {
354
+ var _cx;
355
+
325
356
  prepareRow(row);
326
357
  return /*#__PURE__*/React.createElement("div", _extends({}, row.getRowProps({
327
358
  style: style
328
359
  }), {
329
360
  className: cx("".concat(blockClass, "__tr")),
330
361
  "data-row-index": index,
331
- "aria-rowindex": index
362
+ "aria-rowindex": index + 1
332
363
  }), /*#__PURE__*/React.createElement("div", {
333
- role: "rowheader"
364
+ role: "rowheader",
365
+ className: "".concat(blockClass, "__td-th--cell-container")
334
366
  }, /*#__PURE__*/React.createElement("button", {
367
+ id: "".concat(blockClass, "__cell--").concat(index, "--header"),
335
368
  tabIndex: -1,
336
369
  "data-row-index": index,
337
370
  "data-column-index": "header",
338
371
  type: "button",
339
372
  onClick: handleRowHeaderClick(index),
340
- 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'))),
373
+ 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)),
341
374
  style: {
342
- width: (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth) - 4
375
+ width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth
343
376
  }
344
377
  }, index + 1)), row.cells.map(function (cell, index) {
345
378
  return /*#__PURE__*/React.createElement("div", _extends({
346
379
  key: "cell_".concat(index),
347
- "aria-colindex": index
380
+ "aria-colindex": index + 1
348
381
  }, cell.getCellProps(), {
349
382
  role: "gridcell",
350
383
  style: _objectSpread(_objectSpread({}, cell.getCellProps().style), {}, {
351
- display: 'grid'
384
+ display: 'grid',
385
+ minWidth: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width
352
386
  })
353
387
  }), /*#__PURE__*/React.createElement("button", {
388
+ id: "".concat(blockClass, "__cell--").concat(cell.row.index, "--").concat(index),
354
389
  tabIndex: -1,
355
390
  "data-row-index": cell.row.index,
356
391
  "data-column-index": index,
@@ -362,7 +397,7 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
362
397
  }, cell.render('Cell')));
363
398
  }));
364
399
  }
365
- }, [prepareRow, rows, defaultColumn.rowHeaderWidth, activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, selectionAreas, handleRowHeaderClick, handleBodyCellClick, handleBodyCellHover]);
400
+ }, [prepareRow, rows, activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, selectionAreas, handleRowHeaderClick, handleBodyCellClick, handleBodyCellHover, defaultColumn]);
366
401
  var spreadsheetBodyRef = useRef();
367
402
  return /*#__PURE__*/React.createElement("div", _extends({
368
403
  ref: spreadsheetBodyRef,
@@ -372,7 +407,13 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
372
407
  height: 400,
373
408
  itemCount: rows.length || defaultEmptyRowCount,
374
409
  itemSize: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight,
375
- width: totalColumnsWidth + scrollBarSize
410
+ width: getSpreadsheetWidth({
411
+ scrollBarSizeValue: scrollBarSize,
412
+ totalVisibleColumns: totalVisibleColumns,
413
+ defaultColumn: defaultColumn,
414
+ totalColumnsWidth: totalColumnsWidth
415
+ }),
416
+ outerRef: contentScrollRef
376
417
  }, rows !== null && rows !== void 0 && rows.length ? RenderRow : RenderEmptyRows));
377
418
  });
378
419
  DataSpreadsheetBody.propTypes = {
@@ -473,6 +514,11 @@ DataSpreadsheetBody.propTypes = {
473
514
  */
474
515
  setActiveCellCoordinates: PropTypes.func,
475
516
 
517
+ /**
518
+ * Setter fn for active cell inside of selection area
519
+ */
520
+ setActiveCellInsideSelectionArea: PropTypes.func,
521
+
476
522
  /**
477
523
  * Setter fn for clickAndHold state value
478
524
  */
@@ -501,5 +547,11 @@ DataSpreadsheetBody.propTypes = {
501
547
  /**
502
548
  * The total columns width
503
549
  */
504
- totalColumnsWidth: PropTypes.number
550
+ totalColumnsWidth: PropTypes.number,
551
+
552
+ /**
553
+ * The total number of columns to be initially visible, additional columns will be rendered and
554
+ * visible via horizontal scrollbar
555
+ */
556
+ totalVisibleColumns: PropTypes.number
505
557
  };
@@ -15,11 +15,13 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
15
15
  import React, { forwardRef, useEffect, useState } from 'react';
16
16
  import PropTypes from 'prop-types';
17
17
  import cx from 'classnames';
18
- import { px } from '@carbon/layout';
19
18
  import { pkg } from '../../settings';
19
+ import { usePreviousValue } from '../../global/js/hooks';
20
20
  import { checkActiveHeaderCell } from './utils/checkActiveHeaderCell';
21
+ import { checkSelectedHeaderCell } from './utils/checkSelectedHeaderCell';
21
22
  import { handleHeaderCellSelection } from './utils/handleHeaderCellSelection';
22
- import { usePreviousValue } from '../../global/js/hooks';
23
+ import { selectAllCells } from './utils/selectAllCells';
24
+ import { getSpreadsheetWidth } from './utils/getSpreadsheetWidth';
23
25
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
24
26
  export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref) {
25
27
  var activeCellCoordinates = _ref.activeCellCoordinates,
@@ -33,7 +35,9 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
33
35
  setCurrentMatcher = _ref.setCurrentMatcher,
34
36
  setSelectionAreas = _ref.setSelectionAreas,
35
37
  setSelectionAreaData = _ref.setSelectionAreaData,
36
- rows = _ref.rows;
38
+ rows = _ref.rows,
39
+ totalVisibleColumns = _ref.totalVisibleColumns,
40
+ updateActiveCellCoordinates = _ref.updateActiveCellCoordinates;
37
41
 
38
42
  var _useState = useState(0),
39
43
  _useState2 = _slicedToArray(_useState, 2),
@@ -55,7 +59,8 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
55
59
  }, [cellSize, ref, scrollBarSize, previousState === null || previousState === void 0 ? void 0 : previousState.cellSize]);
56
60
 
57
61
  var handleColumnHeaderClick = function handleColumnHeaderClick(index) {
58
- return function () {
62
+ return function (event) {
63
+ var isHoldingCommandKey = event.metaKey || event.ctrlKey;
59
64
  handleHeaderCellSelection({
60
65
  type: 'column',
61
66
  activeCellCoordinates: activeCellCoordinates,
@@ -66,47 +71,75 @@ export var DataSpreadsheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref)
66
71
  setSelectionAreas: setSelectionAreas,
67
72
  spreadsheetRef: ref,
68
73
  index: index,
69
- setSelectionAreaData: setSelectionAreaData
74
+ setSelectionAreaData: setSelectionAreaData,
75
+ isHoldingCommandKey: isHoldingCommandKey
70
76
  });
71
77
  };
72
78
  };
73
79
 
80
+ var handleSelectAllClick = function handleSelectAllClick() {
81
+ selectAllCells({
82
+ ref: ref,
83
+ setCurrentMatcher: setCurrentMatcher,
84
+ setSelectionAreas: setSelectionAreas,
85
+ rows: rows,
86
+ columns: columns,
87
+ activeCellCoordinates: activeCellCoordinates,
88
+ updateActiveCellCoordinates: updateActiveCellCoordinates
89
+ });
90
+ };
91
+
74
92
  return /*#__PURE__*/React.createElement("div", {
75
- className: cx("".concat(blockClass, "__header--container"))
93
+ className: cx("".concat(blockClass, "__header--container")),
94
+ role: "rowgroup"
76
95
  }, headerGroups.map(function (headerGroup, index) {
77
96
  return /*#__PURE__*/React.createElement("div", _extends({
78
97
  key: "header_".concat(index)
79
98
  }, headerGroup.getHeaderGroupProps(), {
80
99
  style: _objectSpread(_objectSpread({}, headerGroup.getHeaderGroupProps().style), {}, {
81
- width: px(parseInt(headerGroup.getHeaderGroupProps().style.width) + scrollBarSizeValue)
100
+ width: getSpreadsheetWidth({
101
+ type: 'header',
102
+ headerGroup: headerGroup,
103
+ scrollBarSizeValue: scrollBarSizeValue,
104
+ totalVisibleColumns: totalVisibleColumns,
105
+ defaultColumn: defaultColumn
106
+ }),
107
+ overflow: 'hidden'
82
108
  }),
83
109
  className: "".concat(blockClass, "__tr")
84
110
  }), /*#__PURE__*/React.createElement("div", {
85
111
  role: "columnheader",
112
+ className: "".concat(blockClass, "__select-all-cell-container"),
86
113
  style: {
87
- width: (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth) - 4,
114
+ width: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeaderWidth,
88
115
  height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight
89
116
  }
90
117
  }, /*#__PURE__*/React.createElement("button", {
118
+ id: "".concat(blockClass, "__cell--header--header"),
91
119
  "data-row-index": "header",
92
120
  "data-column-index": "header",
93
121
  type: "button",
94
122
  tabIndex: -1,
123
+ onClick: handleSelectAllClick,
95
124
  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'))
96
125
  }, "\xA0")), headerGroup.headers.map(function (column, index) {
126
+ var _cx2;
127
+
97
128
  return /*#__PURE__*/React.createElement("div", _extends({
98
129
  key: "column_".concat(index),
99
130
  role: "columnheader",
100
131
  className: "".concat(blockClass, "__columnheader")
101
132
  }, column.getHeaderProps()), /*#__PURE__*/React.createElement("button", {
133
+ id: "".concat(blockClass, "__cell--header--").concat(index),
102
134
  "data-row-index": "header",
103
135
  "data-column-index": index,
104
136
  tabIndex: -1,
105
137
  onClick: handleColumnHeaderClick(index),
106
138
  style: {
107
- height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight
139
+ height: defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.rowHeight,
140
+ width: (column === null || column === void 0 ? void 0 : column.width) || (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width)
108
141
  },
109
- 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'))),
142
+ 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"), checkSelectedHeaderCell(index, selectionAreas, 'column')), _cx2)),
110
143
  type: "button"
111
144
  }, column.render('Header')));
112
145
  }));
@@ -178,5 +211,16 @@ DataSpreadsheetHeader.propTypes = {
178
211
  /**
179
212
  * Setter fn for selectionAreas value
180
213
  */
181
- setSelectionAreas: PropTypes.func
214
+ setSelectionAreas: PropTypes.func,
215
+
216
+ /**
217
+ * The total number of columns to be initially visible, additional columns will be rendered and
218
+ * visible via horizontal scrollbar
219
+ */
220
+ totalVisibleColumns: PropTypes.number,
221
+
222
+ /**
223
+ * Function used to update the active cell coordinates
224
+ */
225
+ updateActiveCellCoordinates: PropTypes.func
182
226
  };
@@ -7,4 +7,5 @@
7
7
  export { useMoveActiveCell } from './useMoveActiveCell';
8
8
  export { useMultipleKeyTracking } from './useMultipleKeyTracking';
9
9
  export { useResetSpreadsheetFocus } from './useResetSpreadsheetFocus';
10
- export { useSpreadsheetOutsideClick } from './useSpreadsheetOutsideClick';
10
+ export { useSpreadsheetOutsideClick } from './useSpreadsheetOutsideClick';
11
+ export { useSpreadsheetEdit } from './useSpreadsheetEdit';
@@ -9,6 +9,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
9
9
  */
10
10
  import { useEffect, useState } from 'react';
11
11
  import { usePreviousValue } from '../../../global/js/hooks';
12
+ import { includesResourceKey } from '../utils/handleMultipleKeys';
12
13
 
13
14
  var hasFocus = function hasFocus() {
14
15
  return typeof document !== 'undefined' && document.hasFocus();
@@ -19,15 +20,20 @@ export var useMultipleKeyTracking = function useMultipleKeyTracking(_ref) {
19
20
  containerHasFocus = _ref.containerHasFocus,
20
21
  isEditing = _ref.isEditing;
21
22
 
22
- var _useState = useState(hasFocus),
23
+ var _useState = useState(''),
23
24
  _useState2 = _slicedToArray(_useState, 2),
24
- windowFocused = _useState2[0],
25
- setWindowFocused = _useState2[1];
25
+ usingMac = _useState2[0],
26
+ setUsingMac = _useState2[1];
26
27
 
27
- var _useState3 = useState([]),
28
+ var _useState3 = useState(hasFocus),
28
29
  _useState4 = _slicedToArray(_useState3, 2),
29
- keysPressedList = _useState4[0],
30
- setKeysPressedList = _useState4[1];
30
+ windowFocused = _useState4[0],
31
+ setWindowFocused = _useState4[1];
32
+
33
+ var _useState5 = useState([]),
34
+ _useState6 = _slicedToArray(_useState5, 2),
35
+ keysPressedList = _useState6[0],
36
+ setKeysPressedList = _useState6[1];
31
37
 
32
38
  var previousState = usePreviousValue({
33
39
  isEditing: isEditing,
@@ -36,6 +42,14 @@ export var useMultipleKeyTracking = function useMultipleKeyTracking(_ref) {
36
42
  // we need to clear out the keysPressedList
37
43
 
38
44
  useEffect(function () {
45
+ var userAgentString = window.navigator.userAgent;
46
+
47
+ if (userAgentString.includes('Macintosh')) {
48
+ setUsingMac(true);
49
+ } else {
50
+ setUsingMac(false);
51
+ }
52
+
39
53
  setWindowFocused(hasFocus());
40
54
 
41
55
  var onWindowFocus = function onWindowFocus() {
@@ -61,6 +75,19 @@ export var useMultipleKeyTracking = function useMultipleKeyTracking(_ref) {
61
75
  // Prevent multiple keys of the same type being added to our keysPressedList array
62
76
  if (keysPressedList.includes(event.code)) {
63
77
  return;
78
+ } // Because keyup events are lost when using the Command key
79
+ // we need to remove the previously pressed keys so that we
80
+ // do not have keys in the pressed list that should not be
81
+
82
+
83
+ if (includesResourceKey(keysPressedList, usingMac) && keysPressedList.length > 1) {
84
+ var clonedKeys = _toConsumableArray(keysPressedList);
85
+
86
+ var filteredClonedKeys = clonedKeys.filter(function (item) {
87
+ return item === 'MetaLeft' || item === 'MetaRight';
88
+ });
89
+ filteredClonedKeys.push(event.code);
90
+ return setKeysPressedList(_toConsumableArray(new Set(filteredClonedKeys)));
64
91
  }
65
92
 
66
93
  var tempKeys = _toConsumableArray(keysPressedList);
@@ -103,9 +130,10 @@ export var useMultipleKeyTracking = function useMultipleKeyTracking(_ref) {
103
130
  setKeysPressedList([]);
104
131
  }
105
132
  }
106
- }, [keysPressedList, containerHasFocus, ref, isEditing, previousState === null || previousState === void 0 ? void 0 : previousState.isEditing, windowFocused, previousState === null || previousState === void 0 ? void 0 : previousState.windowFocused]);
133
+ }, [keysPressedList, containerHasFocus, ref, isEditing, previousState === null || previousState === void 0 ? void 0 : previousState.isEditing, windowFocused, previousState === null || previousState === void 0 ? void 0 : previousState.windowFocused, usingMac]);
107
134
  return {
108
135
  keysPressedList: keysPressedList,
109
- windowFocused: windowFocused
136
+ windowFocused: windowFocused,
137
+ usingMac: usingMac
110
138
  };
111
139
  };
@@ -0,0 +1,113 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ // /**
3
+ // * Copyright IBM Corp. 2022, 2022
4
+ // *
5
+ // * This source code is licensed under the Apache-2.0 license found in the
6
+ // * LICENSE file in the root directory of this source tree.
7
+ // */
8
+ import { useEffect, useState } from 'react';
9
+ import { px } from '@carbon/layout';
10
+ import { pkg } from '../../../settings';
11
+ import { usePreviousValue } from '../../../global/js/hooks';
12
+ export var useSpreadsheetEdit = function useSpreadsheetEdit(_ref) {
13
+ var isEditing = _ref.isEditing,
14
+ rows = _ref.rows,
15
+ activeCellCoordinates = _ref.activeCellCoordinates,
16
+ activeCellRef = _ref.activeCellRef,
17
+ cellEditorRef = _ref.cellEditorRef,
18
+ cellEditorRulerRef = _ref.cellEditorRulerRef,
19
+ columns = _ref.columns,
20
+ defaultColumn = _ref.defaultColumn,
21
+ cellEditorValue = _ref.cellEditorValue,
22
+ _ref$blockClass = _ref.blockClass,
23
+ blockClass = _ref$blockClass === void 0 ? "".concat(pkg.prefix, "--data-spreadsheet") : _ref$blockClass;
24
+
25
+ var _useState = useState(null),
26
+ _useState2 = _slicedToArray(_useState, 2),
27
+ nextIndex = _useState2[0],
28
+ setNextIndex = _useState2[1];
29
+
30
+ var previousState = usePreviousValue({
31
+ nextIndex: nextIndex
32
+ });
33
+ useEffect(function () {
34
+ if (!(previousState !== null && previousState !== void 0 && previousState.nextIndex)) {
35
+ setNextIndex(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column);
36
+ }
37
+ }, [previousState === null || previousState === void 0 ? void 0 : previousState.nextIndex, activeCellCoordinates]);
38
+ useEffect(function () {
39
+ var rulerWidth = cellEditorRulerRef.current.offsetWidth;
40
+ var cellEditorCurrentWidth = parseInt(cellEditorRef.current.style.width);
41
+
42
+ if (isEditing) {
43
+ var _rows$activeCellCoord, _cellProps$column, _cellEditorRef$curren;
44
+
45
+ var cellProps = (_rows$activeCellCoord = rows[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row]) === null || _rows$activeCellCoord === void 0 ? void 0 : _rows$activeCellCoord.cells[activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column];
46
+ var activeCellLeftPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.left;
47
+ var activeCellTopPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.top;
48
+ cellEditorRef.current.style.left = activeCellLeftPosition;
49
+ cellEditorRef.current.style.top = activeCellTopPosition;
50
+ cellEditorRef.current.style.display = 'block';
51
+ cellEditorRef.current.style.height = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.height;
52
+ 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
53
+
54
+ 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';
55
+ (_cellEditorRef$curren = cellEditorRef.current) === null || _cellEditorRef$curren === void 0 ? void 0 : _cellEditorRef$curren.focus();
56
+
57
+ if (rulerWidth < cellEditorCurrentWidth) {
58
+ var _columns$nextIndex;
59
+
60
+ var currentColumnWidth = ((_columns$nextIndex = columns[nextIndex]) === null || _columns$nextIndex === void 0 ? void 0 : _columns$nextIndex.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
61
+
62
+ if (rulerWidth < cellEditorCurrentWidth - currentColumnWidth) {
63
+ cellEditorRef.current.style.width = px(parseInt(cellEditorRef.current.style.width) - currentColumnWidth);
64
+ setNextIndex(function (prev) {
65
+ if (prev === 0) {
66
+ return prev;
67
+ }
68
+
69
+ return prev - 1;
70
+ });
71
+ } // Decrease cell editor width by increment of current column width
72
+
73
+ }
74
+
75
+ if (rulerWidth >= cellEditorCurrentWidth) {
76
+ var _columns;
77
+
78
+ setNextIndex(function (prev) {
79
+ if (prev === columns.length - 1) {
80
+ return prev;
81
+ }
82
+
83
+ return prev + 1;
84
+ });
85
+ var onLastColumnIndex = nextIndex + 1 === columns.length;
86
+ var nextColumnWidth = onLastColumnIndex ? 0 : ((_columns = columns[nextIndex + 1]) === null || _columns === void 0 ? void 0 : _columns.width) || (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width);
87
+ var startingRowPosition = activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row;
88
+ var totalRows = rows.length;
89
+ var totalCellEditorMaxHeight = (totalRows - startingRowPosition) * defaultColumn.rowHeight;
90
+ cellEditorRef.current.style.maxHeight = px(totalCellEditorMaxHeight);
91
+ cellEditorRef.current.style.width = px(nextColumnWidth + cellEditorCurrentWidth);
92
+ cellEditorRef.current.style.height = px(cellEditorRef.current.scrollHeight); // adds dynamic height to cell editor
93
+ // Cell editor has reached max height, we need to add the scrolling back.
94
+ // We also need to subtract 1 to account for the fact that the cell editor
95
+ // is placed one pixel below the cell being edited to account for the border
96
+
97
+ if (cellEditorRef.current.clientHeight === totalCellEditorMaxHeight - 1) {
98
+ cellEditorRef.current.style.overflow = 'auto';
99
+ } else {
100
+ cellEditorRef.current.style.overflow = 'hidden';
101
+ }
102
+ }
103
+ }
104
+
105
+ if (!isEditing) {
106
+ cellEditorRef.current.style.overflow = 'hidden';
107
+ cellEditorRef.current.style.display = 'none';
108
+ cellEditorRef.current.blur();
109
+ activeCellRef.current.focus();
110
+ setNextIndex(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column);
111
+ }
112
+ }, [isEditing, activeCellCoordinates, rows, cellEditorValue, columns.length, defaultColumn, activeCellRef, cellEditorRef, cellEditorRulerRef, columns, blockClass, previousState === null || previousState === void 0 ? void 0 : previousState.cellEditorValue, nextIndex]);
113
+ };
@@ -0,0 +1,16 @@
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 { deepCloneObject } from '../../../global/js/utils/deepCloneObject';
8
+ export var checkSelectedHeaderCell = function checkSelectedHeaderCell(headerIndex, selectionAreas, headerType) {
9
+ var areasCloned = deepCloneObject(selectionAreas);
10
+ var isSelectedHeader = areasCloned.some(function (area) {
11
+ var _area$header, _area$header2;
12
+
13
+ return (area === null || area === void 0 ? void 0 : (_area$header = area.header) === null || _area$header === void 0 ? void 0 : _area$header.type) === headerType && headerIndex === (area === null || area === void 0 ? void 0 : (_area$header2 = area.header) === null || _area$header2 === void 0 ? void 0 : _area$header2.index);
14
+ });
15
+ return isSelectedHeader;
16
+ };
@@ -6,34 +6,51 @@
6
6
  */
7
7
  import { px } from '@carbon/layout';
8
8
  import { deepCloneObject } from '../../../global/js/utils/deepCloneObject';
9
+ import { getSelectionAreaPoints } from './getSelectionAreaPoints';
9
10
  export var createCellSelectionArea = function createCellSelectionArea(_ref) {
10
- var area = _ref.area,
11
+ var ref = _ref.ref,
12
+ area = _ref.area,
11
13
  blockClass = _ref.blockClass,
14
+ columns = _ref.columns,
12
15
  defaultColumn = _ref.defaultColumn,
13
16
  selectionAreas = _ref.selectionAreas,
14
- setSelectionAreas = _ref.setSelectionAreas;
15
- var greatestRow = Math.max(area.point1.row, area.point2.row);
16
- var greatestColumn = Math.max(area.point1.column, area.point2.column);
17
- var lowestRowIndex = Math.min(area.point1.row, area.point2.row);
18
- var lowestColumnIndex = Math.min(area.point1.column, area.point2.column);
19
- var point1Element = document.querySelector("[data-row-index=\"".concat(area.point1.row, "\"][data-column-index=\"").concat(area.point1.column, "\"]")) || document.querySelector(".".concat(blockClass, "__body--td")); // if we can't find the point1 element (this can happen in the case where a virtualized row is not present anymore in the DOM), we get the default height/width of the first body cell we find
17
+ setSelectionAreas = _ref.setSelectionAreas,
18
+ setActiveCellInsideSelectionArea = _ref.setActiveCellInsideSelectionArea;
19
+
20
+ var _getSelectionAreaPoin = getSelectionAreaPoints(area),
21
+ lowestColumnIndex = _getSelectionAreaPoin.lowestColumnIndex,
22
+ lowestRowIndex = _getSelectionAreaPoin.lowestRowIndex,
23
+ greatestColumnIndex = _getSelectionAreaPoin.greatestColumnIndex,
24
+ greatestRowIndex = _getSelectionAreaPoin.greatestRowIndex;
25
+
26
+ if (greatestRowIndex - lowestRowIndex > 0 || greatestColumnIndex - lowestColumnIndex > 0) {
27
+ setActiveCellInsideSelectionArea(true);
28
+ var activeCellElement = ref.current.querySelector(".".concat(blockClass, "__active-cell--highlight"));
29
+ activeCellElement.setAttribute('data-selection-id', area.matcher);
30
+ }
31
+
32
+ var selectionAreaVariableWidth = 0;
33
+ columns.forEach(function (item, index) {
34
+ if (index >= lowestColumnIndex && index <= greatestColumnIndex) {
35
+ selectionAreaVariableWidth += (item === null || item === void 0 ? void 0 : item.width) || (defaultColumn === null || defaultColumn === void 0 ? void 0 : defaultColumn.width);
36
+ }
37
+ });
38
+ var point1Element = document.querySelector("[data-row-index=\"".concat(area.point1.row, "\"][data-column-index=\"").concat(area.point1.column, "\"]")) || document.querySelector(".".concat(blockClass, "__body--td")); // if we can't find the point1 element (this can happen in the case where a virtualized row is not present anymore in the DOM), we get the default height of the first body cell we find
20
39
 
21
- var selectionAreaCellWidth = point1Element.offsetWidth;
22
40
  var selectionAreaCellHeight = point1Element.offsetHeight;
23
- var selectionAreaTotalWidth = selectionAreaCellWidth * (greatestColumn - lowestColumnIndex + 1);
24
- var selectionAreaTotalHeight = selectionAreaCellHeight * (greatestRow - lowestRowIndex + 1);
41
+ var selectionAreaTotalHeight = selectionAreaCellHeight * (greatestRowIndex - lowestRowIndex + 1);
25
42
  var bodyContainer = document.querySelector(".".concat(blockClass, "__list--container")).firstElementChild;
26
43
  var placementElement = bodyContainer.querySelector("[data-row-index=\"".concat(lowestRowIndex, "\"][data-column-index=\"").concat(lowestColumnIndex, "\"]"));
27
44
  var relativePosition = {
28
45
  top: placementElement ? placementElement.getBoundingClientRect().top - bodyContainer.getBoundingClientRect().top : lowestRowIndex === 0 ? 0 : selectionAreaCellHeight * lowestRowIndex,
29
46
  // calculate top value here if virtualized row is not in DOM
30
- left: placementElement ? placementElement.getBoundingClientRect().left - bodyContainer.getBoundingClientRect().left : lowestColumnIndex === 0 ? 0 + (defaultColumn.rowHeaderWidth - 4) : selectionAreaCellWidth * lowestColumnIndex + (defaultColumn.rowHeaderWidth - 4) // calculate left value here if virtualized row is not in DOM, accounting for row header cell width (including borders)
47
+ left: placementElement ? placementElement.getBoundingClientRect().left - bodyContainer.getBoundingClientRect().left : lowestColumnIndex === 0 ? 0 + (defaultColumn.rowHeaderWidth - 4) : defaultColumn.width * lowestColumnIndex + (defaultColumn.rowHeaderWidth - 4) // calculate left value here if virtualized row is not in DOM, accounting for row header cell width (including borders)
31
48
 
32
49
  };
33
50
  var selectionAreaElement = document.querySelector("[data-matcher-id=\"".concat(area.matcher, "\"]")) || document.createElement('div');
34
51
  selectionAreaElement.classList.add("".concat(blockClass, "__selection-area--element"));
35
52
  selectionAreaElement.setAttribute('data-matcher-id', area.matcher);
36
- selectionAreaElement.style.width = px(selectionAreaTotalWidth);
53
+ selectionAreaElement.style.width = px(selectionAreaVariableWidth);
37
54
  selectionAreaElement.style.height = px(selectionAreaTotalHeight);
38
55
  selectionAreaElement.style.left = px(relativePosition.left);
39
56
  selectionAreaElement.style.top = px(relativePosition.top);