sheet-happens 0.0.35 → 0.0.37

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.
@@ -75,7 +75,7 @@ var MAX_SEARCHABLE_INDEX = 65536;
75
75
  var MAX_XY = [MAX_SEARCHABLE_INDEX, MAX_SEARCHABLE_INDEX];
76
76
  var COLORS = {
77
77
  selectionBorder: '#1a66ff',
78
- selectionBackground: '#e8f0ff',
78
+ selectionBackground: '#d8e6ff80',
79
79
  gridLine: '#0000001f',
80
80
  dragGhost: '#1a66ff30',
81
81
  dropTarget: '#1a66ff',
@@ -85,7 +85,8 @@ var COLORS = {
85
85
  headerActive: '#e8f0ff',
86
86
  headerActiveText: '#1a66ff',
87
87
  headerSelected: '#1a66ff',
88
- headerSelectedText: '#ffffff'
88
+ headerSelectedText: '#ffffff',
89
+ shadowColor: '#000000'
89
90
  };
90
91
  var SIZES = {
91
92
  knobArea: 6,
@@ -95,7 +96,9 @@ var SIZES = {
95
96
  minimumHeight: 22,
96
97
  resizeZone: 4,
97
98
  scrollZone: 50,
98
- scrollSpeed: 30
99
+ scrollSpeed: 30,
100
+ shadowBlur: 12,
101
+ shadowOpacity: 0.05
99
102
  };
100
103
  var DEFAULT_CELL_STYLE = {
101
104
  textAlign: 'left',
@@ -127,10 +130,10 @@ var HEADER_SELECTED_STYLE = {
127
130
  color: COLORS.headerSelectedText
128
131
  };
129
132
  var ARROW_KEYS = {
130
- 'ArrowRight': 'right',
131
- 'ArrowLeft': 'left',
132
- 'ArrowUp': 'up',
133
- 'ArrowDown': 'down'
133
+ ArrowRight: 'right',
134
+ ArrowLeft: 'left',
135
+ ArrowUp: 'up',
136
+ ArrowDown: 'down'
134
137
  };
135
138
 
136
139
  var clamp = function clamp(x, min, max) {
@@ -261,26 +264,88 @@ var isPointInsideSelection = function isPointInsideSelection(selection, point) {
261
264
  return x >= left && x <= right && y >= top && y <= bottom;
262
265
  };
263
266
  var normalizeSelection = function normalizeSelection(selection) {
264
- var _selection$13 = selection[0],
265
- left = _selection$13[0],
266
- top = _selection$13[1],
267
- _selection$14 = selection[1],
268
- right = _selection$14[0],
269
- bottom = _selection$14[1];
270
-
271
- if (left > right) {
272
- var _ref = [right, left];
273
- left = _ref[0];
274
- right = _ref[1];
275
- }
267
+ var anchor = selection[0],
268
+ head = selection[1];
269
+ var ax = anchor[0],
270
+ ay = anchor[1];
271
+ var hx = head[0],
272
+ hy = head[1];
273
+ var left = Math.min(ax, hx);
274
+ var right = Math.max(ax, hx);
275
+ var top = Math.min(ay, hy);
276
+ var bottom = Math.max(ay, hy);
277
+ return [[left, top], [right, bottom]];
278
+ };
279
+ var orientSelection = function orientSelection(normalized, to) {
280
+ var _normalized$ = normalized[0],
281
+ left = _normalized$[0],
282
+ top = _normalized$[1],
283
+ _normalized$2 = normalized[1],
284
+ right = _normalized$2[0],
285
+ bottom = _normalized$2[1];
286
+ var anchor = to[0],
287
+ head = to[1];
288
+ var ax = anchor[0],
289
+ ay = anchor[1];
290
+ var hx = head[0],
291
+ hy = head[1];
292
+ var swapX = (ax - hx || 1) * (left - right || 1) < 0;
293
+ var swapY = (ay - hy || 1) * (top - bottom || 1) < 0;
294
+ return [[swapX ? right : left, swapY ? bottom : top], [swapX ? left : right, swapY ? top : bottom]];
295
+ };
276
296
 
277
- if (top > bottom) {
278
- var _ref2 = [bottom, top];
279
- top = _ref2[0];
280
- bottom = _ref2[1];
297
+ var LIMIT = 1000;
298
+
299
+ var scanGroup = function scanGroup(keys, index, direction, match) {
300
+ if (match == null) return index;
301
+ var i = 0;
302
+ var limit = direction > 0 ? LIMIT : Math.min(LIMIT, index + 1);
303
+
304
+ for (; i < limit; i++) {
305
+ if (keys(index + i * direction) !== match) break;
281
306
  }
282
307
 
283
- return [[left, top], [right, bottom]];
308
+ return index + (i - 1) * direction;
309
+ };
310
+
311
+ var expandSelectionToColumnGroups = function expandSelectionToColumnGroups(selection, columnGroupKeys) {
312
+ var _normalizeSelection = normalizeSelection(selection),
313
+ _normalizeSelection$ = _normalizeSelection[0],
314
+ left = _normalizeSelection$[0],
315
+ top = _normalizeSelection$[1],
316
+ _normalizeSelection$2 = _normalizeSelection[1],
317
+ right = _normalizeSelection$2[0],
318
+ bottom = _normalizeSelection$2[1];
319
+
320
+ var leftKey = columnGroupKeys(left);
321
+ var rightKey = columnGroupKeys(right);
322
+ var startColumn = scanGroup(columnGroupKeys, left, -1, leftKey);
323
+ var endColumn = scanGroup(columnGroupKeys, right, 1, rightKey);
324
+ var expanded = [[startColumn, top], [endColumn, bottom]];
325
+ var oriented = orientSelection(expanded, selection);
326
+ return oriented;
327
+ };
328
+ var expandSelectionToRowGroups = function expandSelectionToRowGroups(selection, rowGroupKeys) {
329
+ var _normalizeSelection2 = normalizeSelection(selection),
330
+ _normalizeSelection2$ = _normalizeSelection2[0],
331
+ left = _normalizeSelection2$[0],
332
+ top = _normalizeSelection2$[1],
333
+ _normalizeSelection2$2 = _normalizeSelection2[1],
334
+ right = _normalizeSelection2$2[0],
335
+ bottom = _normalizeSelection2$2[1];
336
+
337
+ var topKey = rowGroupKeys(top);
338
+ var bottomKey = rowGroupKeys(bottom);
339
+ var startRow = scanGroup(rowGroupKeys, top, -1, topKey);
340
+ var endRow = scanGroup(rowGroupKeys, bottom, 1, bottomKey);
341
+ var expanded = [[left, startRow], [right, endRow]];
342
+ var oriented = orientSelection(expanded, selection);
343
+ return oriented;
344
+ };
345
+ var isBoundaryInsideGroup = function isBoundaryInsideGroup(index, rowOrColumnGroupKeys) {
346
+ var before = rowOrColumnGroupKeys(index - 1);
347
+ var after = rowOrColumnGroupKeys(index);
348
+ return before != null && after != null && before === after;
284
349
  };
285
350
 
286
351
  var createRowOrColumnProp = function createRowOrColumnProp(rowColProp, defaultValue) {
@@ -426,7 +491,7 @@ var findInDisplayData = function findInDisplayData(displayData, start, direction
426
491
  return maxXY(cell, [0, 0]);
427
492
  };
428
493
 
429
- var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editData, sourceData, cellReadOnly, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow, cellLayout, visibleCells, sheetStyle, onEdit, onCommit, onKnobAreaChange, onDragOffsetChange, onDropTargetChange, onSelectionChange, onInvalidateColumn, onInvalidateRow, onChange, onColumnOrderChange, onRowOrderChange, onCellWidthChange, onCellHeightChange, onRightClick, dontCommitEditOnSelectionChange) {
494
+ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editData, sourceData, cellReadOnly, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow, cellLayout, visibleCells, sheetStyle, columnGroupKeys, rowGroupKeys, onEdit, onCommit, onKnobAreaChange, onDragOffsetChange, onDropTargetChange, onSelectionChange, onInvalidateColumn, onInvalidateRow, onChange, onColumnOrderChange, onRowOrderChange, onCellWidthChange, onCellHeightChange, onRightClick, dontCommitEditOnSelectionChange) {
430
495
  var _useState = useState(null),
431
496
  hitTarget = _useState[0],
432
497
  setHitTarget = _useState[1];
@@ -762,7 +827,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
762
827
 
763
828
  setDraggingSelection(true);
764
829
  onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([anchor, head], scrollTo, true);
765
- }, [getMousePosition, getScrollPosition, getMouseHit, onColumnOrderChange, onRowOrderChange, onCellWidthChange, onCellHeightChange, onKnobAreaChange, onSelectionChange, onCommit, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow]);
830
+ }, [getMousePosition, getScrollPosition, getMouseHit, onColumnOrderChange, onRowOrderChange, onCellWidthChange, onCellHeightChange, onKnobAreaChange, onSelectionChange, onCommit, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow, dontCommitEditOnSelectionChange]);
766
831
  var onPointerUp = useCallback(function (e) {
767
832
  var _getMouseHit;
768
833
 
@@ -814,7 +879,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
814
879
 
815
880
  if (!insideSelection) {
816
881
  var order = cellX > minX ? cellX - indices.length : cellX;
817
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[order, minY], [order + maxX - minX, maxY]]);
882
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[order, minY], [order + maxX - minX, maxY]], false, false, true);
818
883
  onColumnOrderChange === null || onColumnOrderChange === void 0 ? void 0 : onColumnOrderChange(indices, order);
819
884
  onInvalidateColumn === null || onInvalidateColumn === void 0 ? void 0 : onInvalidateColumn(Math.min(minX, order));
820
885
  }
@@ -828,7 +893,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
828
893
  if (!_insideSelection) {
829
894
  var _order = cellY > minY ? cellY - _indices4.length : cellY;
830
895
 
831
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[minX, _order], [maxX, _order + maxY - minY]]);
896
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[minX, _order], [maxX, _order + maxY - minY]], false, false, true);
832
897
  onRowOrderChange === null || onRowOrderChange === void 0 ? void 0 : onRowOrderChange(_indices4, _order);
833
898
  onInvalidateRow === null || onInvalidateRow === void 0 ? void 0 : onInvalidateRow(Math.min(minY, _order));
834
899
  }
@@ -1088,6 +1153,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1088
1153
  var _cellX = pixelToColumn(Math.max(_x, getIndentX()), 0.5);
1089
1154
 
1090
1155
  var insideSelection = _cellX >= minX && _cellX <= maxX + 1;
1156
+ var insideGroup = isBoundaryInsideGroup(_cellX, columnGroupKeys);
1091
1157
  var _anchor3 = columnDrag.anchor,
1092
1158
  _scroll5 = columnDrag.scroll;
1093
1159
  var shift = _x - _anchor3;
@@ -1096,7 +1162,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1096
1162
  _currentScroll2 = _getScrollPosition7[0];
1097
1163
 
1098
1164
  onDragOffsetChange === null || onDragOffsetChange === void 0 ? void 0 : onDragOffsetChange([shift + _currentScroll2 - _scroll5, 0]);
1099
- onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(insideSelection ? null : [[_cellX, -1], [_cellX, -1]]);
1165
+ onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(insideSelection || insideGroup ? null : [[_cellX, -1], [_cellX, -1]]);
1100
1166
  }
1101
1167
 
1102
1168
  if (rowDrag) {
@@ -1104,6 +1170,8 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1104
1170
 
1105
1171
  var _insideSelection2 = _cellY >= minY && _cellY <= maxY + 1;
1106
1172
 
1173
+ var _insideGroup = isBoundaryInsideGroup(_cellY, rowGroupKeys);
1174
+
1107
1175
  var _anchor4 = rowDrag.anchor,
1108
1176
  _scroll6 = rowDrag.scroll;
1109
1177
 
@@ -1113,10 +1181,10 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1113
1181
  _currentScroll3 = _getScrollPosition8[1];
1114
1182
 
1115
1183
  onDragOffsetChange === null || onDragOffsetChange === void 0 ? void 0 : onDragOffsetChange([0, _shift + _currentScroll3 - _scroll6]);
1116
- onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(_insideSelection2 ? null : [[-1, _cellY], [-1, _cellY]]);
1184
+ onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(_insideSelection2 || _insideGroup ? null : [[-1, _cellY], [-1, _cellY]]);
1117
1185
  }
1118
1186
  }
1119
- }, [getMousePosition, getScrollPosition, getMouseHit, onCellWidthChange, onCellHeightChange]);
1187
+ }, [getMousePosition, getScrollPosition, getMouseHit, onCellWidthChange, onCellHeightChange, onDragOffsetChange, onDropTargetChange, onSelectionChange, onKnobAreaChange, onInvalidateRow, onInvalidateColumn]);
1120
1188
  var onDoubleClick = useCallback(function (e) {
1121
1189
  var pixelToCell = ref.current.cellLayout.pixelToCell;
1122
1190
  e.preventDefault();
@@ -1419,7 +1487,7 @@ var useClipboardCopy = function useClipboardCopy(textAreaRef, selection, editMod
1419
1487
  }
1420
1488
  });
1421
1489
  };
1422
- var useClipboardPaste = function useClipboardPaste(textAreaRef, selection, onSelectionChange, onChange) {
1490
+ var useClipboardPaste = function useClipboardPaste(textAreaRef, selection, onSelectionChange, onChange, isReadOnly) {
1423
1491
  useEffect(function () {
1424
1492
  var onPaste = function onPaste(e) {
1425
1493
  var textArea = textAreaRef.current;
@@ -1432,10 +1500,10 @@ var useClipboardPaste = function useClipboardPaste(textAreaRef, selection, onSel
1432
1500
 
1433
1501
  if (types.includes('text/html')) {
1434
1502
  var pastedHtml = clipboardData.getData('text/html');
1435
- parsed = parsePastedHtml(selection, pastedHtml);
1503
+ parsed = parsePastedHtml(selection, pastedHtml, isReadOnly);
1436
1504
  } else if (types.includes('text/plain')) {
1437
1505
  var text = clipboardData.getData('text/plain');
1438
- parsed = parsePastedText(selection, text);
1506
+ parsed = parsePastedText(selection, text, isReadOnly);
1439
1507
  }
1440
1508
 
1441
1509
  if (!parsed) return;
@@ -1521,7 +1589,7 @@ var findTable = function findTable(element) {
1521
1589
  }
1522
1590
  };
1523
1591
 
1524
- var parsePastedHtml = function parsePastedHtml(selection, html) {
1592
+ var parsePastedHtml = function parsePastedHtml(selection, html, isReadOnly) {
1525
1593
  var div = document.createElement('div');
1526
1594
  div.innerHTML = html.trim();
1527
1595
 
@@ -1572,7 +1640,7 @@ var parsePastedHtml = function parsePastedHtml(selection, html) {
1572
1640
 
1573
1641
  str = str.replaceAll('\n', '');
1574
1642
  str = str.replaceAll(/\s\s+/g, ' ');
1575
- changes.push({
1643
+ if (!(isReadOnly !== null && isReadOnly !== void 0 && isReadOnly(x, y))) changes.push({
1576
1644
  x: x,
1577
1645
  y: y,
1578
1646
  value: str
@@ -1596,7 +1664,7 @@ var parsePastedHtml = function parsePastedHtml(selection, html) {
1596
1664
  };
1597
1665
  };
1598
1666
 
1599
- var parsePastedText = function parsePastedText(selection, text) {
1667
+ var parsePastedText = function parsePastedText(selection, text, isReadOnly) {
1600
1668
  var _normalizeSelection3 = normalizeSelection(selection),
1601
1669
  _normalizeSelection3$ = _normalizeSelection3[0],
1602
1670
  minX = _normalizeSelection3$[0],
@@ -1614,9 +1682,11 @@ var parsePastedText = function parsePastedText(selection, text) {
1614
1682
  right = Math.max(right, left + cols.length - 1);
1615
1683
 
1616
1684
  for (var x = 0; x < cols.length; x++) {
1617
- changes.push({
1618
- x: left + x,
1619
- y: top + y,
1685
+ var X = left + x;
1686
+ var Y = top + y;
1687
+ if (!(isReadOnly !== null && isReadOnly !== void 0 && isReadOnly(X, Y))) changes.push({
1688
+ x: X,
1689
+ y: Y,
1620
1690
  value: cols[x]
1621
1691
  });
1622
1692
  }
@@ -2006,6 +2076,8 @@ var makeIntMap = function makeIntMap(initialSize) {
2006
2076
  };
2007
2077
 
2008
2078
  var resolveSheetStyle = function resolveSheetStyle(sheetStyle) {
2079
+ var _sheetStyle$shadowBlu, _sheetStyle$shadowOpa, _sheetStyle$shadowCol;
2080
+
2009
2081
  return {
2010
2082
  freezeColumns: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.freezeColumns) || 0,
2011
2083
  freezeRows: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.freezeRows) || 0,
@@ -2014,7 +2086,10 @@ var resolveSheetStyle = function resolveSheetStyle(sheetStyle) {
2014
2086
  hideGridlines: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.hideGridlines) || false,
2015
2087
  hideScrollBars: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.hideScrollBars) || false,
2016
2088
  columnHeaderHeight: sheetStyle !== null && sheetStyle !== void 0 && sheetStyle.hideColumnHeaders ? 1 : SIZES.headerHeight,
2017
- rowHeaderWidth: sheetStyle !== null && sheetStyle !== void 0 && sheetStyle.hideRowHeaders ? 1 : SIZES.headerWidth
2089
+ rowHeaderWidth: sheetStyle !== null && sheetStyle !== void 0 && sheetStyle.hideRowHeaders ? 1 : SIZES.headerWidth,
2090
+ shadowBlur: (_sheetStyle$shadowBlu = sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.shadowBlur) != null ? _sheetStyle$shadowBlu : SIZES.shadowBlur,
2091
+ shadowOpacity: (_sheetStyle$shadowOpa = sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.shadowOpacity) != null ? _sheetStyle$shadowOpa : SIZES.shadowOpacity,
2092
+ shadowColor: (_sheetStyle$shadowCol = sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.shadowColor) != null ? _sheetStyle$shadowCol : COLORS.shadowColor
2018
2093
  };
2019
2094
  };
2020
2095
  var resolveCellStyle = function resolveCellStyle(optionalStyle, defaultStyle) {
@@ -2046,11 +2121,16 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2046
2121
  rowHeaderWidth = sheetStyle.rowHeaderWidth,
2047
2122
  columnHeaderHeight = sheetStyle.columnHeaderHeight,
2048
2123
  freezeColumns = sheetStyle.freezeColumns,
2049
- freezeRows = sheetStyle.freezeRows;
2124
+ freezeRows = sheetStyle.freezeRows,
2125
+ shadowBlur = sheetStyle.shadowBlur,
2126
+ shadowColor = sheetStyle.shadowColor,
2127
+ shadowOpacity = sheetStyle.shadowOpacity;
2050
2128
  var columns = visibleCells.columns,
2051
2129
  rows = visibleCells.rows;
2052
2130
  var columnToPixel = cellLayout.columnToPixel,
2053
- rowToPixel = cellLayout.rowToPixel;
2131
+ rowToPixel = cellLayout.rowToPixel,
2132
+ columnToAbsolute = cellLayout.columnToAbsolute,
2133
+ rowToAbsolute = cellLayout.rowToAbsolute;
2054
2134
  var clickables = [];
2055
2135
  var freeze = [freezeColumns, freezeRows];
2056
2136
  var indent = [rowHeaderWidth, columnHeaderHeight];
@@ -2058,6 +2138,7 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2058
2138
  context.clearRect(0, 0, width, height);
2059
2139
  context.fillStyle = 'white';
2060
2140
  context.fillRect(0, 0, width, height);
2141
+ context.shadowColor = '#00000080';
2061
2142
 
2062
2143
  for (var _iterator = _createForOfIteratorHelperLoose(rows), _step; !(_step = _iterator()).done;) {
2063
2144
  var y = _step.value;
@@ -2137,15 +2218,15 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2137
2218
 
2138
2219
  var drawGridLineX = function drawGridLineX(x, height) {
2139
2220
  context.beginPath();
2140
- context.moveTo(x - .5, 0);
2141
- context.lineTo(x - .5, height);
2221
+ context.moveTo(x - 0.5, 0);
2222
+ context.lineTo(x - 0.5, height);
2142
2223
  context.stroke();
2143
2224
  };
2144
2225
 
2145
2226
  var drawGridLineY = function drawGridLineY(y, width) {
2146
2227
  context.beginPath();
2147
- context.moveTo(0, y - .5);
2148
- context.lineTo(width, y - .5);
2228
+ context.moveTo(0, y - 0.5);
2229
+ context.lineTo(width, y - 0.5);
2149
2230
  context.stroke();
2150
2231
  };
2151
2232
 
@@ -2325,6 +2406,31 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2325
2406
  context.strokeRect(_left6 - 1, _top6 - 1, _right6 - _left6, _bottom6 - _top6);
2326
2407
  }
2327
2408
 
2409
+ var scrollX = dataOffset[0],
2410
+ scrollY = dataOffset[1];
2411
+ var hasRowShadow = freezeRows > 0 && scrollY > 0;
2412
+ var hasColumnShadow = freezeColumns > 0 && scrollX > 0;
2413
+
2414
+ if (hasRowShadow || hasColumnShadow) {
2415
+ if (hasRowShadow) {
2416
+ var h = columnHeaderHeight + rowToAbsolute(freezeRows);
2417
+ var gradient = context.createLinearGradient(0, h, 0, h + shadowBlur);
2418
+ halfShadowGradient(gradient, shadowColor, shadowOpacity);
2419
+ context.fillStyle = gradient;
2420
+ context.fillRect(0, h, width, shadowBlur);
2421
+ }
2422
+
2423
+ if (hasColumnShadow) {
2424
+ var w = rowHeaderWidth + columnToAbsolute(freezeColumns);
2425
+
2426
+ var _gradient = context.createLinearGradient(w, 0, w + shadowBlur, 0);
2427
+
2428
+ halfShadowGradient(_gradient, shadowColor, shadowOpacity);
2429
+ context.fillStyle = _gradient;
2430
+ context.fillRect(w, 0, shadowBlur, height);
2431
+ }
2432
+ }
2433
+
2328
2434
  context.textBaseline = 'middle';
2329
2435
 
2330
2436
  for (var _iterator7 = _createForOfIteratorHelperLoose(rows), _step7; !(_step7 = _iterator7()).done;) {
@@ -2590,8 +2696,27 @@ var excelHeaderString = function excelHeaderString(num) {
2590
2696
  return s || '';
2591
2697
  };
2592
2698
 
2699
+ var halfShadowGradient = function halfShadowGradient(gradient, rgb, opacity) {
2700
+ var hex = function hex(x) {
2701
+ return ('0' + Math.round(x).toString(16)).slice(-2);
2702
+ };
2703
+
2704
+ var ease = function ease(x) {
2705
+ return 1.0 - Math.sin(x * Math.PI / 2);
2706
+ };
2707
+
2708
+ var adjust = function adjust(x) {
2709
+ return 1.0 - Math.pow(1.0 - x, 2.2);
2710
+ };
2711
+
2712
+ for (var i = 0; i <= 16; ++i) {
2713
+ var f = i / 16;
2714
+ gradient.addColorStop(f, rgb + hex(adjust(opacity * ease(f) * 0.5) * 255));
2715
+ }
2716
+ };
2717
+
2593
2718
  var Sheet = forwardRef(function (props, ref) {
2594
- var _props$selection, _props$secondarySelec, _props$inputComponent;
2719
+ var _props$selection, _props$secondarySelec, _props$cacheLayout, _props$inputComponent;
2595
2720
 
2596
2721
  var canvasRef = useRef(null);
2597
2722
  var overlayRef = useRef(null);
@@ -2675,6 +2800,12 @@ var Sheet = forwardRef(function (props, ref) {
2675
2800
  var canOrderRow = useMemo(function () {
2676
2801
  return createRowOrColumnProp(props.canOrderRow, true);
2677
2802
  }, [props.canOrderRow]);
2803
+ var rowGroupKeys = useMemo(function () {
2804
+ return createRowOrColumnProp(props.rowGroupKeys, null);
2805
+ }, [props.rowGroupKeys]);
2806
+ var columnGroupKeys = useMemo(function () {
2807
+ return createRowOrColumnProp(props.columnGroupKeys, null);
2808
+ }, [props.columnGroupKeys]);
2678
2809
  var cellReadOnly = useMemo(function () {
2679
2810
  return createCellProp(props.readOnly, false);
2680
2811
  }, [props.readOnly]);
@@ -2702,17 +2833,19 @@ var Sheet = forwardRef(function (props, ref) {
2702
2833
  var editCellX = editCell[0],
2703
2834
  editCellY = editCell[1];
2704
2835
  var editMode = editCellX !== -1 && editCellY !== -1;
2836
+ var shouldCacheLayout = ((_props$cacheLayout = props.cacheLayout) != null ? _props$cacheLayout : false) !== false;
2837
+ var layoutVersion = typeof props.cacheLayout === 'number' ? props.cacheLayout : 0;
2705
2838
  var columnLayout = useMemo(function () {
2706
2839
  return makeLayoutCache(cellWidth);
2707
- }, [props.cacheLayout ? null : cellWidth]);
2840
+ }, [shouldCacheLayout ? layoutVersion : cellWidth]);
2708
2841
  var rowLayout = useMemo(function () {
2709
2842
  return makeLayoutCache(cellHeight);
2710
- }, [props.cacheLayout ? null : cellHeight]);
2843
+ }, [shouldCacheLayout ? layoutVersion : cellHeight]);
2711
2844
  useMemo(function () {
2712
- if (!props.cacheLayout) return;
2845
+ if (!shouldCacheLayout) return;
2713
2846
  columnLayout.setSizer(cellWidth);
2714
2847
  rowLayout.setSizer(cellHeight);
2715
- }, [props.cacheLayout, cellWidth, cellHeight]);
2848
+ }, [shouldCacheLayout, layoutVersion, cellWidth, cellHeight]);
2716
2849
  var freezeColumns = sheetStyle.freezeColumns,
2717
2850
  freezeRows = sheetStyle.freezeRows,
2718
2851
  rowHeaderWidth = sheetStyle.rowHeaderWidth,
@@ -2732,7 +2865,7 @@ var Sheet = forwardRef(function (props, ref) {
2732
2865
  }
2733
2866
  }, [visibleCells, props.onScrollChange]);
2734
2867
 
2735
- var changeSelection = function changeSelection(newSelection, scrollTo, toHead) {
2868
+ var changeSelection = function changeSelection(newSelection, scrollTo, toHead, dragOperation) {
2736
2869
  if (scrollTo === void 0) {
2737
2870
  scrollTo = true;
2738
2871
  }
@@ -2741,6 +2874,20 @@ var Sheet = forwardRef(function (props, ref) {
2741
2874
  toHead = false;
2742
2875
  }
2743
2876
 
2877
+ if (dragOperation === void 0) {
2878
+ dragOperation = false;
2879
+ }
2880
+
2881
+ if (!dragOperation) {
2882
+ if (isColumnSelection(newSelection) && columnGroupKeys) {
2883
+ newSelection = expandSelectionToColumnGroups(newSelection, columnGroupKeys);
2884
+ }
2885
+
2886
+ if (isRowSelection(newSelection) && rowGroupKeys) {
2887
+ newSelection = expandSelectionToRowGroups(newSelection, rowGroupKeys);
2888
+ }
2889
+ }
2890
+
2744
2891
  if (!isSameSelection(selection, newSelection)) {
2745
2892
  setSelection(newSelection);
2746
2893
  }
@@ -2749,8 +2896,9 @@ var Sheet = forwardRef(function (props, ref) {
2749
2896
  if (!overlay) return;
2750
2897
 
2751
2898
  if (scrollTo) {
2752
- var anchor = newSelection[0],
2753
- head = newSelection[1];
2899
+ var _newSelection = newSelection,
2900
+ anchor = _newSelection[0],
2901
+ head = _newSelection[1];
2754
2902
  scrollToCell(overlay, toHead ? head : anchor, [canvasWidth, canvasHeight], [freezeColumns, freezeRows], dataOffset, maxScroll, cellLayout, function (dataOffset, maxScroll) {
2755
2903
  setDataOffset(dataOffset);
2756
2904
  setMaxScroll(maxScroll);
@@ -2812,10 +2960,10 @@ var Sheet = forwardRef(function (props, ref) {
2812
2960
  var hitmapRef = useRef(NO_CLICKABLES);
2813
2961
  var textAreaRef = useRef(null);
2814
2962
  useClipboardCopy(textAreaRef, selection, editMode, editData);
2815
- useClipboardPaste(textAreaRef, selection, changeSelection, props.onChange);
2963
+ useClipboardPaste(textAreaRef, selection, changeSelection, props.onChange, cellReadOnly);
2816
2964
  var onScroll = useScroll(dataOffset, maxScroll, cellLayout, setDataOffset, setMaxScroll);
2817
2965
 
2818
- var _useMouse = useMouse(hitmapRef, selection, knobArea, editMode, editData, sourceData, cellReadOnly, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow, cellLayout, visibleCells, sheetStyle, startEditingCell, commitEditingCell, setKnobArea, setDragOffset, setDropTarget, changeSelection, props.cacheLayout ? columnLayout.clearAfter : undefined, props.cacheLayout ? rowLayout.clearAfter : undefined, props.onChange, props.onColumnOrderChange, props.onRowOrderChange, props.onCellWidthChange, props.onCellHeightChange, props.onRightClick, props.dontCommitEditOnSelectionChange),
2966
+ var _useMouse = useMouse(hitmapRef, selection, knobArea, editMode, editData, sourceData, cellReadOnly, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow, cellLayout, visibleCells, sheetStyle, columnGroupKeys, rowGroupKeys, startEditingCell, commitEditingCell, setKnobArea, setDragOffset, setDropTarget, changeSelection, props.cacheLayout ? columnLayout.clearAfter : undefined, props.cacheLayout ? rowLayout.clearAfter : undefined, props.onChange, props.onColumnOrderChange, props.onRowOrderChange, props.onCellWidthChange, props.onCellHeightChange, props.onRightClick, props.dontCommitEditOnSelectionChange),
2819
2967
  mouseHandlers = _useMouse.mouseHandlers,
2820
2968
  knobPosition = _useMouse.knobPosition;
2821
2969
 
@@ -3014,8 +3162,8 @@ var Sheet = forwardRef(function (props, ref) {
3014
3162
  borderBottom: '1px solid #ddd'
3015
3163
  };
3016
3164
  var canvasStyles = {
3017
- width: 'calc(100% - 14px)',
3018
- height: 'calc(100% - 15px)',
3165
+ width: canvasWidth,
3166
+ height: canvasHeight,
3019
3167
  outline: '1px solid #ddd'
3020
3168
  };
3021
3169
 
@@ -3023,7 +3171,6 @@ var Sheet = forwardRef(function (props, ref) {
3023
3171
  delete canvasStyles['outline'];
3024
3172
  delete overlayDivStyles['borderBottom'];
3025
3173
  overlayDivClassName = '';
3026
- canvasStyles.width = 'calc(100%)';
3027
3174
  }
3028
3175
 
3029
3176
  var renderedInside = useMemo(function () {