@carbon/ibm-products 1.14.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/css/index-full-carbon.css +23 -5
  2. package/css/index-full-carbon.css.map +1 -1
  3. package/css/index-full-carbon.min.css +3 -3
  4. package/css/index-full-carbon.min.css.map +1 -1
  5. package/css/index-without-carbon-released-only.css +4 -4
  6. package/css/index-without-carbon-released-only.css.map +1 -1
  7. package/css/index-without-carbon-released-only.min.css +2 -2
  8. package/css/index-without-carbon-released-only.min.css.map +1 -1
  9. package/css/index-without-carbon.css +23 -5
  10. package/css/index-without-carbon.css.map +1 -1
  11. package/css/index-without-carbon.min.css +3 -3
  12. package/css/index-without-carbon.min.css.map +1 -1
  13. package/css/index.css +23 -5
  14. package/css/index.css.map +1 -1
  15. package/css/index.min.css +3 -3
  16. package/css/index.min.css.map +1 -1
  17. package/es/components/AddSelect/AddSelect.js +25 -19
  18. package/es/components/AddSelect/AddSelectFilter.js +5 -5
  19. package/es/components/DataSpreadsheet/DataSpreadsheet.js +174 -127
  20. package/es/components/DataSpreadsheet/DataSpreadsheetBody.js +24 -8
  21. package/es/components/DataSpreadsheet/DataSpreadsheetHeader.js +31 -6
  22. package/es/components/DataSpreadsheet/hooks/index.js +2 -1
  23. package/es/components/DataSpreadsheet/hooks/useMultipleKeyTracking.js +36 -8
  24. package/es/components/DataSpreadsheet/hooks/useSpreadsheetEdit.js +68 -0
  25. package/es/components/DataSpreadsheet/utils/createCellSelectionArea.js +20 -8
  26. package/es/components/DataSpreadsheet/utils/getSelectionAreaPoints.js +18 -0
  27. package/es/components/DataSpreadsheet/utils/handleActiveCellInSelectionEnter.js +121 -0
  28. package/es/components/DataSpreadsheet/utils/handleActiveCellInSelectionTab.js +108 -0
  29. package/es/components/DataSpreadsheet/utils/handleEditSubmit.js +87 -0
  30. package/es/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +42 -8
  31. package/es/components/DataSpreadsheet/utils/handleMultipleKeys.js +153 -15
  32. package/es/components/DataSpreadsheet/utils/selectAllCells.js +53 -0
  33. package/es/components/MultiAddSelect/MultiAddSelect.js +150 -3
  34. package/es/components/PageHeader/PageHeader.js +3 -1
  35. package/es/components/SingleAddSelect/SingleAddSelect.js +90 -4
  36. package/es/components/TagSet/TagSet.js +13 -6
  37. package/es/components/Tearsheet/TearsheetShell.js +34 -10
  38. package/es/global/js/package-settings.js +2 -1
  39. package/lib/components/AddSelect/AddSelect.js +25 -19
  40. package/lib/components/AddSelect/AddSelectFilter.js +5 -5
  41. package/lib/components/DataSpreadsheet/DataSpreadsheet.js +178 -126
  42. package/lib/components/DataSpreadsheet/DataSpreadsheetBody.js +24 -8
  43. package/lib/components/DataSpreadsheet/DataSpreadsheetHeader.js +32 -6
  44. package/lib/components/DataSpreadsheet/hooks/index.js +9 -1
  45. package/lib/components/DataSpreadsheet/hooks/useMultipleKeyTracking.js +36 -8
  46. package/lib/components/DataSpreadsheet/hooks/useSpreadsheetEdit.js +79 -0
  47. package/lib/components/DataSpreadsheet/utils/createCellSelectionArea.js +21 -8
  48. package/lib/components/DataSpreadsheet/utils/getSelectionAreaPoints.js +27 -0
  49. package/lib/components/DataSpreadsheet/utils/handleActiveCellInSelectionEnter.js +127 -0
  50. package/lib/components/DataSpreadsheet/utils/handleActiveCellInSelectionTab.js +118 -0
  51. package/lib/components/DataSpreadsheet/utils/handleEditSubmit.js +94 -0
  52. package/lib/components/DataSpreadsheet/utils/handleHeaderCellSelection.js +44 -8
  53. package/lib/components/DataSpreadsheet/utils/handleMultipleKeys.js +161 -22
  54. package/lib/components/DataSpreadsheet/utils/selectAllCells.js +60 -0
  55. package/lib/components/MultiAddSelect/MultiAddSelect.js +150 -2
  56. package/lib/components/PageHeader/PageHeader.js +3 -1
  57. package/lib/components/SingleAddSelect/SingleAddSelect.js +91 -3
  58. package/lib/components/TagSet/TagSet.js +13 -6
  59. package/lib/components/Tearsheet/TearsheetShell.js +36 -10
  60. package/lib/global/js/package-settings.js +2 -1
  61. package/package.json +11 -11
  62. package/scss/components/AboutModal/_about-modal.scss +4 -0
  63. package/scss/components/DataSpreadsheet/_data-spreadsheet.scss +22 -1
  64. package/scss/components/ExportModal/_export-modal.scss +0 -4
@@ -1,4 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _typeof from "@babel/runtime/helpers/typeof";
2
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
4
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
5
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
@@ -16,8 +17,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
16
17
  */
17
18
  // Import portions of React that are needed.
18
19
  import React, { useMemo, useRef, useState, useCallback, useEffect } from 'react';
19
- import { useBlockLayout, useTable } from 'react-table';
20
- import { px } from '@carbon/layout'; // Other standard imports.
20
+ import { useBlockLayout, useTable } from 'react-table'; // Other standard imports.
21
21
 
22
22
  import PropTypes from 'prop-types';
23
23
  import cx from 'classnames';
@@ -29,12 +29,17 @@ import { getDevtoolsProps } from '../../global/js/utils/devtools';
29
29
  import { getScrollbarWidth } from '../../global/js/utils/getScrollbarWidth';
30
30
  import { useActiveElement, usePreviousValue } from '../../global/js/hooks';
31
31
  import uuidv4 from '../../global/js/utils/uuidv4';
32
- import { useResetSpreadsheetFocus, useSpreadsheetOutsideClick, useMoveActiveCell, useMultipleKeyTracking } from './hooks';
32
+ import { deepCloneObject } from '../../global/js/utils/deepCloneObject';
33
+ import { useResetSpreadsheetFocus, useSpreadsheetOutsideClick, useMoveActiveCell, useMultipleKeyTracking, useSpreadsheetEdit } from './hooks';
33
34
  import { createActiveCellFn } from './utils/createActiveCellFn';
34
35
  import { getCellSize } from './utils/getCellSize';
35
- import { handleMultipleKeys, includesShift } from './utils/handleMultipleKeys';
36
+ import { handleMultipleKeys, includesResourceKey, includesShift } from './utils/handleMultipleKeys';
36
37
  import { handleHeaderCellSelection } from './utils/handleHeaderCellSelection';
37
- import { removeCellSelections } from './utils/removeCellSelections'; // cspell:words rowcount colcount
38
+ import { removeCellSelections } from './utils/removeCellSelections';
39
+ import { selectAllCells } from './utils/selectAllCells';
40
+ import { handleEditSubmit } from './utils/handleEditSubmit';
41
+ import { handleActiveCellInSelectionEnter } from './utils/handleActiveCellInSelectionEnter';
42
+ import { handleActiveCellInSelectionTab } from './utils/handleActiveCellInSelectionTab'; // cspell:words rowcount colcount
38
43
  // The block part of our conventional BEM class names (blockClass__E--M).
39
44
 
40
45
  var blockClass = "".concat(pkg.prefix, "--data-spreadsheet");
@@ -117,6 +122,11 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
117
122
  cellEditorValue = _useState16[0],
118
123
  setCellEditorValue = _useState16[1];
119
124
 
125
+ var _useState17 = useState(false),
126
+ _useState18 = _slicedToArray(_useState17, 2),
127
+ activeCellInsideSelectionArea = _useState18[0],
128
+ setActiveCellInsideSelectionArea = _useState18[1];
129
+
120
130
  var previousState = usePreviousValue({
121
131
  activeCellCoordinates: activeCellCoordinates,
122
132
  isEditing: isEditing
@@ -124,10 +134,10 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
124
134
  var cellSizeValue = getCellSize(cellSize);
125
135
  var cellEditorRef = useRef();
126
136
 
127
- var _useState17 = useState(),
128
- _useState18 = _slicedToArray(_useState17, 2),
129
- activeCellContent = _useState18[0],
130
- setActiveCellContent = _useState18[1];
137
+ var _useState19 = useState(),
138
+ _useState20 = _slicedToArray(_useState19, 2),
139
+ activeCellContent = _useState20[0],
140
+ setActiveCellContent = _useState20[1];
131
141
 
132
142
  var activeCellRef = useRef();
133
143
  var cellEditorRulerRef = useRef();
@@ -144,7 +154,8 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
144
154
  containerHasFocus: containerHasFocus,
145
155
  isEditing: isEditing
146
156
  }),
147
- keysPressedList = _useMultipleKeyTracki.keysPressedList;
157
+ keysPressedList = _useMultipleKeyTracki.keysPressedList,
158
+ usingMac = _useMultipleKeyTracki.usingMac;
148
159
 
149
160
  var scrollBarSize = useMemo(function () {
150
161
  return getScrollbarWidth();
@@ -257,6 +268,8 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
257
268
  var handleInitialArrowPress = useCallback(function () {
258
269
  // If activeCellCoordinates is null then we need to set an initial value
259
270
  // which will place the activeCell on the select all cell/button
271
+ setActiveCellInsideSelectionArea(false);
272
+
260
273
  if (!activeCellCoordinates) {
261
274
  setActiveCellCoordinates({
262
275
  column: 'header',
@@ -267,16 +280,20 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
267
280
  return;
268
281
  }, [activeCellCoordinates]);
269
282
  var updateActiveCellCoordinates = useCallback(function (_ref3) {
270
- var coords = _ref3.coords,
271
- updatedValue = _ref3.updatedValue;
283
+ var _ref3$coords = _ref3.coords,
284
+ coords = _ref3$coords === void 0 ? _objectSpread({}, activeCellCoordinates) : _ref3$coords,
285
+ updatedValue = _ref3.updatedValue,
286
+ _ref3$optOutOfSelecti = _ref3.optOutOfSelectionAreaUpdate,
287
+ optOutOfSelectionAreaUpdate = _ref3$optOutOfSelecti === void 0 ? false : _ref3$optOutOfSelecti;
272
288
 
273
289
  var newActiveCell = _objectSpread(_objectSpread({}, coords), updatedValue);
274
290
 
275
291
  setActiveCellCoordinates(newActiveCell); // Only run if the active cell is _not_ a header cell. This will add a point1 object
276
292
  // to selectionAreas every time the active cell changes, allowing us to create cell
277
- // selections using keyboard
293
+ // selections using keyboard. Opting out of the selection area updates here means
294
+ // that the active cell is being moved within a selection area
278
295
 
279
- if (newActiveCell.row !== 'header' && newActiveCell.column !== 'header') {
296
+ if (newActiveCell.row !== 'header' && newActiveCell.column !== 'header' && !optOutOfSelectionAreaUpdate) {
280
297
  var tempMatcher = uuidv4();
281
298
  setSelectionAreas([{
282
299
  point1: newActiveCell,
@@ -284,7 +301,7 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
284
301
  }]);
285
302
  setCurrentMatcher(tempMatcher);
286
303
  }
287
- }, []);
304
+ }, [activeCellCoordinates]);
288
305
  var handleHomeEndKey = useCallback(function (_ref4) {
289
306
  var type = _ref4.type;
290
307
 
@@ -341,7 +358,13 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
341
358
  currentMatcher: currentMatcher,
342
359
  rows: rows,
343
360
  setSelectionAreas: setSelectionAreas,
344
- columns: columns
361
+ columns: columns,
362
+ updateActiveCellCoordinates: updateActiveCellCoordinates,
363
+ spreadsheetRef: spreadsheetRef,
364
+ removeCellSelections: removeCellSelections,
365
+ blockClass: blockClass,
366
+ setCurrentMatcher: setCurrentMatcher,
367
+ usingMac: usingMac
345
368
  });
346
369
  } // Allow arrow key navigation if there are less than two activeKeys OR
347
370
  // if one of the activeCellCoordinates is in a header position
@@ -349,9 +372,26 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
349
372
 
350
373
  if (keysPressedList.length < 2 && !includesShift(keysPressedList) || activeCellCoordinates.row === 'header' || activeCellCoordinates.column === 'header') {
351
374
  switch (key) {
375
+ // Enter
376
+ case 'Enter':
377
+ {
378
+ handleActiveCellInSelectionEnter({
379
+ activeCellInsideSelectionArea: activeCellInsideSelectionArea,
380
+ activeCellCoordinates: activeCellCoordinates,
381
+ activeCellRef: activeCellRef,
382
+ selectionAreas: selectionAreas,
383
+ updateActiveCellCoordinates: updateActiveCellCoordinates
384
+ });
385
+ break;
386
+ }
352
387
  // HOME
388
+
353
389
  case 'Home':
354
390
  {
391
+ if (includesResourceKey(keysPressedList, usingMac)) {
392
+ return;
393
+ }
394
+
355
395
  handleHomeEndKey({
356
396
  type: 'home'
357
397
  });
@@ -360,6 +400,10 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
360
400
 
361
401
  case 'End':
362
402
  {
403
+ if (includesResourceKey(keysPressedList, usingMac)) {
404
+ return;
405
+ }
406
+
363
407
  handleHomeEndKey({
364
408
  type: 'end'
365
409
  });
@@ -369,6 +413,17 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
369
413
 
370
414
  case 'Tab':
371
415
  {
416
+ if (activeCellInsideSelectionArea) {
417
+ event.preventDefault();
418
+ return handleActiveCellInSelectionTab({
419
+ activeCellInsideSelectionArea: activeCellInsideSelectionArea,
420
+ activeCellCoordinates: activeCellCoordinates,
421
+ activeCellRef: activeCellRef,
422
+ selectionAreas: selectionAreas,
423
+ updateActiveCellCoordinates: updateActiveCellCoordinates
424
+ });
425
+ }
426
+
372
427
  setSelectionAreas([]);
373
428
  removeActiveCell();
374
429
  removeCellEditor();
@@ -515,7 +570,7 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
515
570
  }
516
571
  }
517
572
  }
518
- }, [updateActiveCellCoordinates, handleInitialArrowPress, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, isEditing, removeCellEditor, selectionAreas, handleHomeEndKey, keysPressedList]);
573
+ }, [activeCellInsideSelectionArea, updateActiveCellCoordinates, handleInitialArrowPress, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, isEditing, removeCellEditor, selectionAreas, handleHomeEndKey, keysPressedList, usingMac]);
519
574
 
520
575
  var startEditMode = function startEditMode() {
521
576
  setIsEditing(true);
@@ -537,12 +592,37 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
537
592
  var handleActiveCellClick = function handleActiveCellClick() {
538
593
  if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' || (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header') {
539
594
  var indexValue = (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' ? activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column : activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row;
595
+
596
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header') {
597
+ return;
598
+ }
599
+
540
600
  handleRowColumnHeaderClick({
541
601
  isKeyboard: false,
542
602
  index: indexValue
543
603
  });
544
604
  }
545
605
 
606
+ return;
607
+ }; // Mouse down on active cell
608
+
609
+
610
+ var handleActiveCellMouseDown = function handleActiveCellMouseDown() {
611
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) !== 'header' || (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) !== 'header') {
612
+ var tempMatcher = uuidv4();
613
+ setClickAndHoldActive(true);
614
+ removeCellSelections({
615
+ spreadsheetRef: spreadsheetRef
616
+ });
617
+ setSelectionAreas([{
618
+ point1: activeCellCoordinates,
619
+ matcher: tempMatcher
620
+ }]);
621
+ setCurrentMatcher(tempMatcher);
622
+ setSelectionAreaData([]);
623
+ setActiveCellInsideSelectionArea(false);
624
+ }
625
+
546
626
  return;
547
627
  }; // Go into edit mode if 'Enter' key is pressed on activeCellRef
548
628
 
@@ -550,7 +630,7 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
550
630
  var handleActiveCellKeyDown = function handleActiveCellKeyDown(event) {
551
631
  var key = event.key;
552
632
 
553
- if (key === 'Enter') {
633
+ if (key === 'Enter' && !activeCellInsideSelectionArea) {
554
634
  if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) !== 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) !== 'header') {
555
635
  startEditMode();
556
636
  }
@@ -580,18 +660,30 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
580
660
  index: index
581
661
  }; // Select an entire column
582
662
 
583
- if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header') {
663
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) !== 'header') {
584
664
  handleHeaderCellSelection(_objectSpread({
585
665
  type: 'column'
586
666
  }, handleHeaderCellProps));
587
667
  } // Select an entire row
588
668
 
589
669
 
590
- if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header') {
670
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) !== 'header') {
591
671
  handleHeaderCellSelection(_objectSpread({
592
672
  type: 'row'
593
673
  }, handleHeaderCellProps));
594
674
  }
675
+
676
+ if ((activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) === 'header' && (activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row) === 'header') {
677
+ selectAllCells({
678
+ ref: spreadsheetRef,
679
+ setCurrentMatcher: setCurrentMatcher,
680
+ setSelectionAreas: setSelectionAreas,
681
+ rows: rows,
682
+ columns: columns,
683
+ activeCellCoordinates: activeCellCoordinates,
684
+ updateActiveCellCoordinates: updateActiveCellCoordinates
685
+ });
686
+ }
595
687
  }; // Go into edit mode if double click is detected on activeCellRef
596
688
 
597
689
 
@@ -599,116 +691,55 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
599
691
  startEditMode();
600
692
  };
601
693
 
602
- var updateSelectionAreaOnCellEditSubmit = function updateSelectionAreaOnCellEditSubmit(_ref6) {
603
- var type = _ref6.type;
604
-
605
- var submitEditChanges = function submitEditChanges() {
606
- var prevCoords = previousState === null || previousState === void 0 ? void 0 : previousState.activeCellCoordinates;
607
- var cellProps = rows[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row].cells[prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.column];
608
- removeCellEditor();
609
- updateData(prevCoords === null || prevCoords === void 0 ? void 0 : prevCoords.row, cellProps.column.id);
610
- };
611
-
612
- removeCellSelections({
613
- spreadsheetRef: spreadsheetRef
614
- });
615
- submitEditChanges();
616
- var tempMatcher = uuidv4();
617
- var newSelectionArea = {
618
- row: type === 'Enter' ? activeCellCoordinates.row === rows.length - 1 ? activeCellCoordinates.row : activeCellCoordinates.row + 1 : activeCellCoordinates.row,
619
- column: type === 'Tab' ? activeCellCoordinates.column === columns.length - 1 ? activeCellCoordinates.column : activeCellCoordinates.column + 1 : activeCellCoordinates.column
620
- };
621
- setSelectionAreas([{
622
- point1: newSelectionArea,
623
- point2: newSelectionArea,
624
- matcher: tempMatcher,
625
- areaCreated: false
626
- }]);
627
- setCurrentMatcher(tempMatcher);
628
- cellEditorRulerRef.current.textContent = '';
629
- }; // Update the data
630
-
631
-
632
- var handleEditSubmit = function handleEditSubmit(event) {
633
- var key = event.key;
634
-
635
- if (key === 'Enter') {
636
- updateSelectionAreaOnCellEditSubmit({
637
- type: 'Enter'
638
- });
639
- setActiveCellCoordinates(function (prev) {
640
- return _objectSpread(_objectSpread({}, prev), {}, {
641
- row: prev.row === rows.length - 1 ? prev.row : prev.row + 1 // do not move to next cell below if we're already in the last row
642
-
643
- });
644
- });
694
+ useSpreadsheetEdit({
695
+ isEditing: isEditing,
696
+ rows: rows,
697
+ activeCellCoordinates: activeCellCoordinates,
698
+ activeCellRef: activeCellRef,
699
+ cellEditorRef: cellEditorRef,
700
+ cellEditorRulerRef: cellEditorRulerRef,
701
+ columns: columns,
702
+ defaultColumn: defaultColumn,
703
+ cellEditorValue: cellEditorValue
704
+ });
705
+ var handleActiveCellMouseEnter = useCallback(function () {
706
+ handleActiveCellMouseEnterCallback(selectionAreas, clickAndHoldActive);
707
+ }, [clickAndHoldActive, selectionAreas, handleActiveCellMouseEnterCallback]); // Only update if there are cell selection areas
708
+ // Find point object that matches currentMatcher and remove the second point
709
+ // because hovering over the active cell while clicking and holding should
710
+ // remove the previously existing selection area
711
+
712
+ var handleActiveCellMouseEnterCallback = useCallback(function (areas, clickHold) {
713
+ if (!currentMatcher) {
714
+ return;
645
715
  }
646
716
 
647
- if (key === 'Tab') {
648
- event.preventDefault();
649
- updateSelectionAreaOnCellEditSubmit({
650
- type: 'Tab'
651
- });
652
- setActiveCellCoordinates(function (prev) {
653
- return _objectSpread(_objectSpread({}, prev), {}, {
654
- column: prev.column === columns.length - 1 ? prev.column : prev.column + 1 // do not move to next cell below if we're already in the last column
655
-
717
+ if (areas && areas.length && clickHold && currentMatcher) {
718
+ setSelectionAreas(function (prev) {
719
+ var selectionAreaClone = deepCloneObject(prev);
720
+ var indexOfItemToUpdate = selectionAreaClone.findIndex(function (item) {
721
+ return item.matcher === currentMatcher;
656
722
  });
657
- });
658
- }
659
723
 
660
- return;
661
- };
724
+ if (indexOfItemToUpdate === -1) {
725
+ return prev;
726
+ }
662
727
 
663
- useEffect(function () {
664
- if (isEditing) {
665
- var _rows$activeCellCoord, _cellProps$column, _cellEditorRef$curren;
666
-
667
- 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];
668
- var activeCellLeftPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.left;
669
- var activeCellTopPosition = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.top;
670
- cellEditorRef.current.style.left = activeCellLeftPosition;
671
- cellEditorRef.current.style.top = activeCellTopPosition;
672
- cellEditorRef.current.style.display = 'block';
673
- cellEditorRef.current.style.width = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.width;
674
- cellEditorRef.current.style.height = activeCellRef === null || activeCellRef === void 0 ? void 0 : activeCellRef.current.style.height;
675
- 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
676
-
677
- 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';
678
- (_cellEditorRef$curren = cellEditorRef.current) === null || _cellEditorRef$curren === void 0 ? void 0 : _cellEditorRef$curren.focus();
679
- var rulerWidth = cellEditorRulerRef.current.offsetWidth;
680
- var cellWidth = activeCellRef.current.offsetWidth;
681
-
682
- if (rulerWidth >= cellWidth) {
683
- var widthMultiplier = Math.floor(rulerWidth / cellWidth) + 1;
684
- var startingColumnPosition = activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column;
685
- var startingRowPosition = activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row;
686
- var totalColumns = columns.length;
687
- var totalRows = rows.length;
688
- var totalMultiplierPossible = totalColumns - startingColumnPosition;
689
- var totalCellEditorMaxHeight = (totalRows - startingRowPosition) * defaultColumn.rowHeight;
690
- cellEditorRef.current.style.maxHeight = px(totalCellEditorMaxHeight);
691
- cellEditorRef.current.style.width = px(cellWidth * (widthMultiplier <= totalMultiplierPossible ? widthMultiplier : totalMultiplierPossible));
692
- cellEditorRef.current.style.height = px(cellEditorRef.current.scrollHeight); // adds dynamic height to cell editor
693
- // Cell editor has reached max height, we need to add the scrolling back.
694
- // We also need to subtract 1 to account for the fact that the cell editor
695
- // is placed one pixel below the cell being edited to account for the border
696
-
697
- if (cellEditorRef.current.clientHeight === totalCellEditorMaxHeight - 1) {
698
- cellEditorRef.current.style.overflow = 'auto';
699
- } else {
700
- cellEditorRef.current.style.overflow = 'hidden';
728
+ if (_typeof(selectionAreaClone[indexOfItemToUpdate].point2) === 'object' && selectionAreaClone[indexOfItemToUpdate].areaCreated) {
729
+ selectionAreaClone[indexOfItemToUpdate].point2 = selectionAreaClone[indexOfItemToUpdate].point1;
730
+ selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
731
+ setActiveCellInsideSelectionArea(false);
732
+ removeCellSelections({
733
+ matcher: currentMatcher,
734
+ spreadsheetRef: spreadsheetRef
735
+ });
736
+ return selectionAreaClone;
701
737
  }
702
- }
703
- }
704
738
 
705
- if (!isEditing) {
706
- cellEditorRef.current.style.overflow = 'hidden';
707
- cellEditorRef.current.style.display = 'none';
708
- cellEditorRef.current.blur();
709
- activeCellRef.current.focus();
739
+ return prev;
740
+ });
710
741
  }
711
- }, [isEditing, activeCellCoordinates, rows, cellEditorValue, columns.length, defaultColumn]);
742
+ }, [spreadsheetRef, currentMatcher]);
712
743
  return /*#__PURE__*/React.createElement("div", _extends({}, rest, getTableProps(), getDevtoolsProps(componentName), {
713
744
  className: cx(blockClass, className, "".concat(blockClass, "--interactive-cell-element"), _defineProperty({}, "".concat(blockClass, "__container-has-focus"), containerHasFocus)),
714
745
  ref: spreadsheetRef,
@@ -735,7 +766,8 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
735
766
  setActiveCellCoordinates: setActiveCellCoordinates,
736
767
  setSelectionAreas: setSelectionAreas,
737
768
  setCurrentMatcher: setCurrentMatcher,
738
- setSelectionAreaData: setSelectionAreaData
769
+ setSelectionAreaData: setSelectionAreaData,
770
+ updateActiveCellCoordinates: updateActiveCellCoordinates
739
771
  }), /*#__PURE__*/React.createElement(DataSpreadsheetBody, {
740
772
  activeCellCoordinates: activeCellCoordinates,
741
773
  ref: spreadsheetRef,
@@ -762,24 +794,39 @@ export var DataSpreadsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref)
762
794
  totalColumnsWidth: totalColumnsWidth,
763
795
  id: id,
764
796
  columns: columns,
765
- defaultEmptyRowCount: defaultEmptyRowCount
797
+ defaultEmptyRowCount: defaultEmptyRowCount,
798
+ setActiveCellInsideSelectionArea: setActiveCellInsideSelectionArea
766
799
  }), /*#__PURE__*/React.createElement("button", {
800
+ onMouseDown: handleActiveCellMouseDown,
767
801
  onClick: handleActiveCellClick,
768
802
  onKeyDown: handleActiveCellKeyDown,
769
803
  onDoubleClick: handleActiveCellDoubleClick,
804
+ onMouseEnter: handleActiveCellMouseEnter,
770
805
  ref: activeCellRef,
771
- className: cx("".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__active-cell--highlight")),
806
+ className: cx("".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__active-cell--highlight"), _defineProperty({}, "".concat(blockClass, "__active-cell--with-selection"), activeCellInsideSelectionArea)),
772
807
  type: "button"
773
808
  }, activeCellContent), /*#__PURE__*/React.createElement(TextArea, {
774
809
  value: cellEditorValue,
775
- onKeyDown: handleEditSubmit,
810
+ onKeyDown: handleEditSubmit({
811
+ activeCellCoordinates: activeCellCoordinates,
812
+ cellEditorRulerRef: cellEditorRulerRef,
813
+ columns: columns,
814
+ previousState: previousState,
815
+ removeCellEditor: removeCellEditor,
816
+ rows: rows,
817
+ setActiveCellCoordinates: setActiveCellCoordinates,
818
+ setCurrentMatcher: setCurrentMatcher,
819
+ setSelectionAreas: setSelectionAreas,
820
+ spreadsheetRef: spreadsheetRef,
821
+ updateData: updateData
822
+ }),
776
823
  onChange: function onChange(event) {
777
824
  setCellEditorValue(event.target.value);
778
825
  cellEditorRulerRef.current.textContent = event.target.value;
779
826
  },
780
827
  ref: cellEditorRef,
781
828
  labelText: "",
782
- "aria-labelledby": activeCellCoordinates ? "[data-row-index=\"".concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, "\"][data-column-index=\"").concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column, "\"]") : null,
829
+ "aria-labelledby": activeCellCoordinates ? "#".concat(blockClass, "__cell--").concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.row, "--").concat(activeCellCoordinates === null || activeCellCoordinates === void 0 ? void 0 : activeCellCoordinates.column) : null,
783
830
  className: cx("".concat(blockClass, "__cell-editor"), "".concat(blockClass, "--interactive-cell-element"), "".concat(blockClass, "__cell-editor--").concat(cellSize), _defineProperty({}, "".concat(blockClass, "__cell-editor--active"), isEditing))
784
831
  }), /*#__PURE__*/React.createElement("pre", {
785
832
  "aria-hidden": true,
@@ -49,7 +49,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
49
49
  setClickAndHoldActive = _ref.setClickAndHoldActive,
50
50
  currentMatcher = _ref.currentMatcher,
51
51
  setCurrentMatcher = _ref.setCurrentMatcher,
52
- onSelectionAreaChange = _ref.onSelectionAreaChange;
52
+ onSelectionAreaChange = _ref.onSelectionAreaChange,
53
+ setActiveCellInsideSelectionArea = _ref.setActiveCellInsideSelectionArea;
53
54
  var previousState = usePreviousValue({
54
55
  selectionAreaData: selectionAreaData,
55
56
  clickAndHoldActive: clickAndHoldActive
@@ -107,18 +108,20 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
107
108
 
108
109
  if (!area.areaCreated && area.point1 && area.point2 && area.matcher) {
109
110
  createCellSelectionArea({
111
+ ref: ref,
110
112
  area: area,
111
113
  blockClass: blockClass,
112
114
  defaultColumn: defaultColumn,
113
115
  selectionAreas: selectionAreas,
114
- setSelectionAreas: setSelectionAreas
116
+ setSelectionAreas: setSelectionAreas,
117
+ setActiveCellInsideSelectionArea: setActiveCellInsideSelectionArea
115
118
  });
116
119
  }
117
120
 
118
121
  return;
119
122
  });
120
123
  }
121
- }, [selectionAreas, setSelectionAreas, defaultColumn, onSelectionAreaChange, setSelectionAreaData]);
124
+ }, [selectionAreas, setSelectionAreas, defaultColumn, onSelectionAreaChange, setSelectionAreaData, ref, activeCellCoordinates, setActiveCellInsideSelectionArea]);
122
125
 
123
126
  var populateSelectionAreaCellData = function populateSelectionAreaCellData(_ref2) {
124
127
  var rowStart = _ref2.rowStart,
@@ -196,6 +199,9 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
196
199
  // meaning that selectionAreas should only have one item by default
197
200
 
198
201
  if (isHoldingCommandKey) {
202
+ var activeCellElement = ref.current.querySelector(".".concat(blockClass, "__active-cell--highlight"));
203
+ activeCellElement.setAttribute('data-selection-id', tempMatcher);
204
+ setActiveCellInsideSelectionArea(true);
199
205
  setActiveCellCoordinates(activeCoordinates);
200
206
  setCurrentMatcher(tempMatcher);
201
207
  setSelectionAreas(function (prev) {
@@ -226,6 +232,7 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
226
232
  setSelectionAreas(selectionAreaClone);
227
233
  }
228
234
  } else {
235
+ setActiveCellInsideSelectionArea(false);
229
236
  setActiveCellCoordinates(activeCoordinates); // remove all previous cell selections
230
237
 
231
238
  removeCellSelections({
@@ -239,7 +246,7 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
239
246
  setSelectionAreaData([]);
240
247
  }
241
248
  };
242
- }, [currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData]);
249
+ }, [currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData, setActiveCellInsideSelectionArea]);
243
250
  var handleBodyCellHover = useCallback(function (cell, columnIndex) {
244
251
  return function () {
245
252
  if (clickAndHoldActive) {
@@ -272,7 +279,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
272
279
  };
273
280
  }, [clickAndHoldActive, currentMatcher, setSelectionAreas]);
274
281
  var handleRowHeaderClick = useCallback(function (index) {
275
- return function () {
282
+ return function (event) {
283
+ var isHoldingCommandKey = event.metaKey || event.ctrlKey;
276
284
  handleHeaderCellSelection({
277
285
  type: 'row',
278
286
  activeCellCoordinates: activeCellCoordinates,
@@ -283,7 +291,8 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
283
291
  setSelectionAreas: setSelectionAreas,
284
292
  spreadsheetRef: ref,
285
293
  index: index,
286
- setSelectionAreaData: setSelectionAreaData
294
+ setSelectionAreaData: setSelectionAreaData,
295
+ isHoldingCommandKey: isHoldingCommandKey
287
296
  });
288
297
  };
289
298
  }, [columns, ref, setSelectionAreas, setCurrentMatcher, setActiveCellCoordinates, activeCellCoordinates, rows, setSelectionAreaData]); // Builds the empty rows and calls `onDataUpdate` to set the new empty rows
@@ -328,10 +337,11 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
328
337
  }), {
329
338
  className: cx("".concat(blockClass, "__tr")),
330
339
  "data-row-index": index,
331
- "aria-rowindex": index
340
+ "aria-rowindex": index + 1
332
341
  }), /*#__PURE__*/React.createElement("div", {
333
342
  role: "rowheader"
334
343
  }, /*#__PURE__*/React.createElement("button", {
344
+ id: "".concat(blockClass, "__cell--").concat(index, "--header"),
335
345
  tabIndex: -1,
336
346
  "data-row-index": index,
337
347
  "data-column-index": "header",
@@ -344,13 +354,14 @@ export var DataSpreadsheetBody = /*#__PURE__*/forwardRef(function (_ref, ref) {
344
354
  }, index + 1)), row.cells.map(function (cell, index) {
345
355
  return /*#__PURE__*/React.createElement("div", _extends({
346
356
  key: "cell_".concat(index),
347
- "aria-colindex": index
357
+ "aria-colindex": index + 1
348
358
  }, cell.getCellProps(), {
349
359
  role: "gridcell",
350
360
  style: _objectSpread(_objectSpread({}, cell.getCellProps().style), {}, {
351
361
  display: 'grid'
352
362
  })
353
363
  }), /*#__PURE__*/React.createElement("button", {
364
+ id: "".concat(blockClass, "__cell--").concat(cell.row.index, "--").concat(index),
354
365
  tabIndex: -1,
355
366
  "data-row-index": cell.row.index,
356
367
  "data-column-index": index,
@@ -473,6 +484,11 @@ DataSpreadsheetBody.propTypes = {
473
484
  */
474
485
  setActiveCellCoordinates: PropTypes.func,
475
486
 
487
+ /**
488
+ * Setter fn for active cell inside of selection area
489
+ */
490
+ setActiveCellInsideSelectionArea: PropTypes.func,
491
+
476
492
  /**
477
493
  * Setter fn for clickAndHold state value
478
494
  */