sheet-happens 0.0.36 → 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.
@@ -22,6 +22,7 @@ export declare const COLORS: {
22
22
  headerActiveText: string;
23
23
  headerSelected: string;
24
24
  headerSelectedText: string;
25
+ shadowColor: string;
25
26
  };
26
27
  export declare const SIZES: {
27
28
  knobArea: number;
@@ -32,6 +33,8 @@ export declare const SIZES: {
32
33
  resizeZone: number;
33
34
  scrollZone: number;
34
35
  scrollSpeed: number;
36
+ shadowBlur: number;
37
+ shadowOpacity: number;
35
38
  };
36
39
  export declare const DEFAULT_CELL_STYLE: Required<Style>;
37
40
  export declare const DEFAULT_COLUMN_HEADER_STYLE: Required<Style>;
@@ -16,3 +16,4 @@ export declare const isCellSelection: (selection: Rectangle) => boolean;
16
16
  export declare const isEmptySelection: (selection: Rectangle) => boolean;
17
17
  export declare const isPointInsideSelection: (selection: Rectangle, point: XY) => boolean;
18
18
  export declare const normalizeSelection: (selection: Rectangle) => Rectangle;
19
+ export declare const orientSelection: (normalized: Rectangle, to: Rectangle) => Rectangle;
@@ -0,0 +1,4 @@
1
+ import { Rectangle, RowOrColumnPropertyFunction } from './types';
2
+ export declare const expandSelectionToColumnGroups: (selection: Rectangle, columnGroupKeys: RowOrColumnPropertyFunction<string | number | null>) => Rectangle;
3
+ export declare const expandSelectionToRowGroups: (selection: Rectangle, rowGroupKeys: RowOrColumnPropertyFunction<string | number | null>) => Rectangle;
4
+ export declare const isBoundaryInsideGroup: (index: number, rowOrColumnGroupKeys: RowOrColumnPropertyFunction<string | number | null>) => boolean;
package/dist/index.css CHANGED
@@ -1,18 +1,21 @@
1
1
  ._PxIi8::-webkit-scrollbar {
2
- -webkit-appearance: none;
2
+ -webkit-appearance: none;
3
3
  }
4
4
  ._PxIi8::-webkit-scrollbar:vertical {
5
- width: 13px;
5
+ width: 13px;
6
6
  }
7
7
  ._PxIi8::-webkit-scrollbar:horizontal {
8
- height: 13px;
8
+ height: 13px;
9
+ }
10
+ ._PxIi8::-webkit-scrollbar-corner {
11
+ background: #fff;
9
12
  }
10
13
  ._PxIi8::-webkit-scrollbar-thumb {
11
- border-radius: 8px;
12
- background-color: #c1c1c1;
13
- border: 2px solid #fff;
14
+ border-radius: 8px;
15
+ background-color: #c1c1c1;
16
+ border: 2px solid #fff;
14
17
  }
15
18
  ._PxIi8::-webkit-scrollbar-track {
16
- background-color: #fff;
17
- border-radius: 0px;
18
- }
19
+ background-color: #fff;
20
+ border-radius: 0px;
21
+ }
package/dist/index.js CHANGED
@@ -78,7 +78,7 @@ var MAX_SEARCHABLE_INDEX = 65536;
78
78
  var MAX_XY = [MAX_SEARCHABLE_INDEX, MAX_SEARCHABLE_INDEX];
79
79
  var COLORS = {
80
80
  selectionBorder: '#1a66ff',
81
- selectionBackground: '#e8f0ff',
81
+ selectionBackground: '#d8e6ff80',
82
82
  gridLine: '#0000001f',
83
83
  dragGhost: '#1a66ff30',
84
84
  dropTarget: '#1a66ff',
@@ -88,7 +88,8 @@ var COLORS = {
88
88
  headerActive: '#e8f0ff',
89
89
  headerActiveText: '#1a66ff',
90
90
  headerSelected: '#1a66ff',
91
- headerSelectedText: '#ffffff'
91
+ headerSelectedText: '#ffffff',
92
+ shadowColor: '#000000'
92
93
  };
93
94
  var SIZES = {
94
95
  knobArea: 6,
@@ -98,7 +99,9 @@ var SIZES = {
98
99
  minimumHeight: 22,
99
100
  resizeZone: 4,
100
101
  scrollZone: 50,
101
- scrollSpeed: 30
102
+ scrollSpeed: 30,
103
+ shadowBlur: 12,
104
+ shadowOpacity: 0.05
102
105
  };
103
106
  var DEFAULT_CELL_STYLE = {
104
107
  textAlign: 'left',
@@ -130,10 +133,10 @@ var HEADER_SELECTED_STYLE = {
130
133
  color: COLORS.headerSelectedText
131
134
  };
132
135
  var ARROW_KEYS = {
133
- 'ArrowRight': 'right',
134
- 'ArrowLeft': 'left',
135
- 'ArrowUp': 'up',
136
- 'ArrowDown': 'down'
136
+ ArrowRight: 'right',
137
+ ArrowLeft: 'left',
138
+ ArrowUp: 'up',
139
+ ArrowDown: 'down'
137
140
  };
138
141
 
139
142
  var clamp = function clamp(x, min, max) {
@@ -264,26 +267,88 @@ var isPointInsideSelection = function isPointInsideSelection(selection, point) {
264
267
  return x >= left && x <= right && y >= top && y <= bottom;
265
268
  };
266
269
  var normalizeSelection = function normalizeSelection(selection) {
267
- var _selection$13 = selection[0],
268
- left = _selection$13[0],
269
- top = _selection$13[1],
270
- _selection$14 = selection[1],
271
- right = _selection$14[0],
272
- bottom = _selection$14[1];
273
-
274
- if (left > right) {
275
- var _ref = [right, left];
276
- left = _ref[0];
277
- right = _ref[1];
278
- }
270
+ var anchor = selection[0],
271
+ head = selection[1];
272
+ var ax = anchor[0],
273
+ ay = anchor[1];
274
+ var hx = head[0],
275
+ hy = head[1];
276
+ var left = Math.min(ax, hx);
277
+ var right = Math.max(ax, hx);
278
+ var top = Math.min(ay, hy);
279
+ var bottom = Math.max(ay, hy);
280
+ return [[left, top], [right, bottom]];
281
+ };
282
+ var orientSelection = function orientSelection(normalized, to) {
283
+ var _normalized$ = normalized[0],
284
+ left = _normalized$[0],
285
+ top = _normalized$[1],
286
+ _normalized$2 = normalized[1],
287
+ right = _normalized$2[0],
288
+ bottom = _normalized$2[1];
289
+ var anchor = to[0],
290
+ head = to[1];
291
+ var ax = anchor[0],
292
+ ay = anchor[1];
293
+ var hx = head[0],
294
+ hy = head[1];
295
+ var swapX = (ax - hx || 1) * (left - right || 1) < 0;
296
+ var swapY = (ay - hy || 1) * (top - bottom || 1) < 0;
297
+ return [[swapX ? right : left, swapY ? bottom : top], [swapX ? left : right, swapY ? top : bottom]];
298
+ };
279
299
 
280
- if (top > bottom) {
281
- var _ref2 = [bottom, top];
282
- top = _ref2[0];
283
- bottom = _ref2[1];
300
+ var LIMIT = 1000;
301
+
302
+ var scanGroup = function scanGroup(keys, index, direction, match) {
303
+ if (match == null) return index;
304
+ var i = 0;
305
+ var limit = direction > 0 ? LIMIT : Math.min(LIMIT, index + 1);
306
+
307
+ for (; i < limit; i++) {
308
+ if (keys(index + i * direction) !== match) break;
284
309
  }
285
310
 
286
- return [[left, top], [right, bottom]];
311
+ return index + (i - 1) * direction;
312
+ };
313
+
314
+ var expandSelectionToColumnGroups = function expandSelectionToColumnGroups(selection, columnGroupKeys) {
315
+ var _normalizeSelection = normalizeSelection(selection),
316
+ _normalizeSelection$ = _normalizeSelection[0],
317
+ left = _normalizeSelection$[0],
318
+ top = _normalizeSelection$[1],
319
+ _normalizeSelection$2 = _normalizeSelection[1],
320
+ right = _normalizeSelection$2[0],
321
+ bottom = _normalizeSelection$2[1];
322
+
323
+ var leftKey = columnGroupKeys(left);
324
+ var rightKey = columnGroupKeys(right);
325
+ var startColumn = scanGroup(columnGroupKeys, left, -1, leftKey);
326
+ var endColumn = scanGroup(columnGroupKeys, right, 1, rightKey);
327
+ var expanded = [[startColumn, top], [endColumn, bottom]];
328
+ var oriented = orientSelection(expanded, selection);
329
+ return oriented;
330
+ };
331
+ var expandSelectionToRowGroups = function expandSelectionToRowGroups(selection, rowGroupKeys) {
332
+ var _normalizeSelection2 = normalizeSelection(selection),
333
+ _normalizeSelection2$ = _normalizeSelection2[0],
334
+ left = _normalizeSelection2$[0],
335
+ top = _normalizeSelection2$[1],
336
+ _normalizeSelection2$2 = _normalizeSelection2[1],
337
+ right = _normalizeSelection2$2[0],
338
+ bottom = _normalizeSelection2$2[1];
339
+
340
+ var topKey = rowGroupKeys(top);
341
+ var bottomKey = rowGroupKeys(bottom);
342
+ var startRow = scanGroup(rowGroupKeys, top, -1, topKey);
343
+ var endRow = scanGroup(rowGroupKeys, bottom, 1, bottomKey);
344
+ var expanded = [[left, startRow], [right, endRow]];
345
+ var oriented = orientSelection(expanded, selection);
346
+ return oriented;
347
+ };
348
+ var isBoundaryInsideGroup = function isBoundaryInsideGroup(index, rowOrColumnGroupKeys) {
349
+ var before = rowOrColumnGroupKeys(index - 1);
350
+ var after = rowOrColumnGroupKeys(index);
351
+ return before != null && after != null && before === after;
287
352
  };
288
353
 
289
354
  var createRowOrColumnProp = function createRowOrColumnProp(rowColProp, defaultValue) {
@@ -429,7 +494,7 @@ var findInDisplayData = function findInDisplayData(displayData, start, direction
429
494
  return maxXY(cell, [0, 0]);
430
495
  };
431
496
 
432
- 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) {
497
+ 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) {
433
498
  var _useState = React.useState(null),
434
499
  hitTarget = _useState[0],
435
500
  setHitTarget = _useState[1];
@@ -765,7 +830,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
765
830
 
766
831
  setDraggingSelection(true);
767
832
  onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([anchor, head], scrollTo, true);
768
- }, [getMousePosition, getScrollPosition, getMouseHit, onColumnOrderChange, onRowOrderChange, onCellWidthChange, onCellHeightChange, onKnobAreaChange, onSelectionChange, onCommit, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow]);
833
+ }, [getMousePosition, getScrollPosition, getMouseHit, onColumnOrderChange, onRowOrderChange, onCellWidthChange, onCellHeightChange, onKnobAreaChange, onSelectionChange, onCommit, canSizeColumn, canSizeRow, canOrderColumn, canOrderRow, dontCommitEditOnSelectionChange]);
769
834
  var onPointerUp = React.useCallback(function (e) {
770
835
  var _getMouseHit;
771
836
 
@@ -817,7 +882,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
817
882
 
818
883
  if (!insideSelection) {
819
884
  var order = cellX > minX ? cellX - indices.length : cellX;
820
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[order, minY], [order + maxX - minX, maxY]]);
885
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[order, minY], [order + maxX - minX, maxY]], false, false, true);
821
886
  onColumnOrderChange === null || onColumnOrderChange === void 0 ? void 0 : onColumnOrderChange(indices, order);
822
887
  onInvalidateColumn === null || onInvalidateColumn === void 0 ? void 0 : onInvalidateColumn(Math.min(minX, order));
823
888
  }
@@ -831,7 +896,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
831
896
  if (!_insideSelection) {
832
897
  var _order = cellY > minY ? cellY - _indices4.length : cellY;
833
898
 
834
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[minX, _order], [maxX, _order + maxY - minY]]);
899
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([[minX, _order], [maxX, _order + maxY - minY]], false, false, true);
835
900
  onRowOrderChange === null || onRowOrderChange === void 0 ? void 0 : onRowOrderChange(_indices4, _order);
836
901
  onInvalidateRow === null || onInvalidateRow === void 0 ? void 0 : onInvalidateRow(Math.min(minY, _order));
837
902
  }
@@ -1091,6 +1156,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1091
1156
  var _cellX = pixelToColumn(Math.max(_x, getIndentX()), 0.5);
1092
1157
 
1093
1158
  var insideSelection = _cellX >= minX && _cellX <= maxX + 1;
1159
+ var insideGroup = isBoundaryInsideGroup(_cellX, columnGroupKeys);
1094
1160
  var _anchor3 = columnDrag.anchor,
1095
1161
  _scroll5 = columnDrag.scroll;
1096
1162
  var shift = _x - _anchor3;
@@ -1099,7 +1165,7 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1099
1165
  _currentScroll2 = _getScrollPosition7[0];
1100
1166
 
1101
1167
  onDragOffsetChange === null || onDragOffsetChange === void 0 ? void 0 : onDragOffsetChange([shift + _currentScroll2 - _scroll5, 0]);
1102
- onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(insideSelection ? null : [[_cellX, -1], [_cellX, -1]]);
1168
+ onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(insideSelection || insideGroup ? null : [[_cellX, -1], [_cellX, -1]]);
1103
1169
  }
1104
1170
 
1105
1171
  if (rowDrag) {
@@ -1107,6 +1173,8 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1107
1173
 
1108
1174
  var _insideSelection2 = _cellY >= minY && _cellY <= maxY + 1;
1109
1175
 
1176
+ var _insideGroup = isBoundaryInsideGroup(_cellY, rowGroupKeys);
1177
+
1110
1178
  var _anchor4 = rowDrag.anchor,
1111
1179
  _scroll6 = rowDrag.scroll;
1112
1180
 
@@ -1116,10 +1184,10 @@ var useMouse = function useMouse(hitmapRef, selection, knobArea, editMode, editD
1116
1184
  _currentScroll3 = _getScrollPosition8[1];
1117
1185
 
1118
1186
  onDragOffsetChange === null || onDragOffsetChange === void 0 ? void 0 : onDragOffsetChange([0, _shift + _currentScroll3 - _scroll6]);
1119
- onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(_insideSelection2 ? null : [[-1, _cellY], [-1, _cellY]]);
1187
+ onDropTargetChange === null || onDropTargetChange === void 0 ? void 0 : onDropTargetChange(_insideSelection2 || _insideGroup ? null : [[-1, _cellY], [-1, _cellY]]);
1120
1188
  }
1121
1189
  }
1122
- }, [getMousePosition, getScrollPosition, getMouseHit, onCellWidthChange, onCellHeightChange]);
1190
+ }, [getMousePosition, getScrollPosition, getMouseHit, onCellWidthChange, onCellHeightChange, onDragOffsetChange, onDropTargetChange, onSelectionChange, onKnobAreaChange, onInvalidateRow, onInvalidateColumn]);
1123
1191
  var onDoubleClick = React.useCallback(function (e) {
1124
1192
  var pixelToCell = ref.current.cellLayout.pixelToCell;
1125
1193
  e.preventDefault();
@@ -2011,6 +2079,8 @@ var makeIntMap = function makeIntMap(initialSize) {
2011
2079
  };
2012
2080
 
2013
2081
  var resolveSheetStyle = function resolveSheetStyle(sheetStyle) {
2082
+ var _sheetStyle$shadowBlu, _sheetStyle$shadowOpa, _sheetStyle$shadowCol;
2083
+
2014
2084
  return {
2015
2085
  freezeColumns: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.freezeColumns) || 0,
2016
2086
  freezeRows: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.freezeRows) || 0,
@@ -2019,7 +2089,10 @@ var resolveSheetStyle = function resolveSheetStyle(sheetStyle) {
2019
2089
  hideGridlines: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.hideGridlines) || false,
2020
2090
  hideScrollBars: (sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.hideScrollBars) || false,
2021
2091
  columnHeaderHeight: sheetStyle !== null && sheetStyle !== void 0 && sheetStyle.hideColumnHeaders ? 1 : SIZES.headerHeight,
2022
- rowHeaderWidth: sheetStyle !== null && sheetStyle !== void 0 && sheetStyle.hideRowHeaders ? 1 : SIZES.headerWidth
2092
+ rowHeaderWidth: sheetStyle !== null && sheetStyle !== void 0 && sheetStyle.hideRowHeaders ? 1 : SIZES.headerWidth,
2093
+ shadowBlur: (_sheetStyle$shadowBlu = sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.shadowBlur) != null ? _sheetStyle$shadowBlu : SIZES.shadowBlur,
2094
+ shadowOpacity: (_sheetStyle$shadowOpa = sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.shadowOpacity) != null ? _sheetStyle$shadowOpa : SIZES.shadowOpacity,
2095
+ shadowColor: (_sheetStyle$shadowCol = sheetStyle === null || sheetStyle === void 0 ? void 0 : sheetStyle.shadowColor) != null ? _sheetStyle$shadowCol : COLORS.shadowColor
2023
2096
  };
2024
2097
  };
2025
2098
  var resolveCellStyle = function resolveCellStyle(optionalStyle, defaultStyle) {
@@ -2051,11 +2124,16 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2051
2124
  rowHeaderWidth = sheetStyle.rowHeaderWidth,
2052
2125
  columnHeaderHeight = sheetStyle.columnHeaderHeight,
2053
2126
  freezeColumns = sheetStyle.freezeColumns,
2054
- freezeRows = sheetStyle.freezeRows;
2127
+ freezeRows = sheetStyle.freezeRows,
2128
+ shadowBlur = sheetStyle.shadowBlur,
2129
+ shadowColor = sheetStyle.shadowColor,
2130
+ shadowOpacity = sheetStyle.shadowOpacity;
2055
2131
  var columns = visibleCells.columns,
2056
2132
  rows = visibleCells.rows;
2057
2133
  var columnToPixel = cellLayout.columnToPixel,
2058
- rowToPixel = cellLayout.rowToPixel;
2134
+ rowToPixel = cellLayout.rowToPixel,
2135
+ columnToAbsolute = cellLayout.columnToAbsolute,
2136
+ rowToAbsolute = cellLayout.rowToAbsolute;
2059
2137
  var clickables = [];
2060
2138
  var freeze = [freezeColumns, freezeRows];
2061
2139
  var indent = [rowHeaderWidth, columnHeaderHeight];
@@ -2063,6 +2141,7 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2063
2141
  context.clearRect(0, 0, width, height);
2064
2142
  context.fillStyle = 'white';
2065
2143
  context.fillRect(0, 0, width, height);
2144
+ context.shadowColor = '#00000080';
2066
2145
 
2067
2146
  for (var _iterator = _createForOfIteratorHelperLoose(rows), _step; !(_step = _iterator()).done;) {
2068
2147
  var y = _step.value;
@@ -2142,15 +2221,15 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2142
2221
 
2143
2222
  var drawGridLineX = function drawGridLineX(x, height) {
2144
2223
  context.beginPath();
2145
- context.moveTo(x - .5, 0);
2146
- context.lineTo(x - .5, height);
2224
+ context.moveTo(x - 0.5, 0);
2225
+ context.lineTo(x - 0.5, height);
2147
2226
  context.stroke();
2148
2227
  };
2149
2228
 
2150
2229
  var drawGridLineY = function drawGridLineY(y, width) {
2151
2230
  context.beginPath();
2152
- context.moveTo(0, y - .5);
2153
- context.lineTo(width, y - .5);
2231
+ context.moveTo(0, y - 0.5);
2232
+ context.lineTo(width, y - 0.5);
2154
2233
  context.stroke();
2155
2234
  };
2156
2235
 
@@ -2330,6 +2409,31 @@ var renderSheet = function renderSheet(context, cellLayout, visibleCells, sheetS
2330
2409
  context.strokeRect(_left6 - 1, _top6 - 1, _right6 - _left6, _bottom6 - _top6);
2331
2410
  }
2332
2411
 
2412
+ var scrollX = dataOffset[0],
2413
+ scrollY = dataOffset[1];
2414
+ var hasRowShadow = freezeRows > 0 && scrollY > 0;
2415
+ var hasColumnShadow = freezeColumns > 0 && scrollX > 0;
2416
+
2417
+ if (hasRowShadow || hasColumnShadow) {
2418
+ if (hasRowShadow) {
2419
+ var h = columnHeaderHeight + rowToAbsolute(freezeRows);
2420
+ var gradient = context.createLinearGradient(0, h, 0, h + shadowBlur);
2421
+ halfShadowGradient(gradient, shadowColor, shadowOpacity);
2422
+ context.fillStyle = gradient;
2423
+ context.fillRect(0, h, width, shadowBlur);
2424
+ }
2425
+
2426
+ if (hasColumnShadow) {
2427
+ var w = rowHeaderWidth + columnToAbsolute(freezeColumns);
2428
+
2429
+ var _gradient = context.createLinearGradient(w, 0, w + shadowBlur, 0);
2430
+
2431
+ halfShadowGradient(_gradient, shadowColor, shadowOpacity);
2432
+ context.fillStyle = _gradient;
2433
+ context.fillRect(w, 0, shadowBlur, height);
2434
+ }
2435
+ }
2436
+
2333
2437
  context.textBaseline = 'middle';
2334
2438
 
2335
2439
  for (var _iterator7 = _createForOfIteratorHelperLoose(rows), _step7; !(_step7 = _iterator7()).done;) {
@@ -2595,8 +2699,27 @@ var excelHeaderString = function excelHeaderString(num) {
2595
2699
  return s || '';
2596
2700
  };
2597
2701
 
2702
+ var halfShadowGradient = function halfShadowGradient(gradient, rgb, opacity) {
2703
+ var hex = function hex(x) {
2704
+ return ('0' + Math.round(x).toString(16)).slice(-2);
2705
+ };
2706
+
2707
+ var ease = function ease(x) {
2708
+ return 1.0 - Math.sin(x * Math.PI / 2);
2709
+ };
2710
+
2711
+ var adjust = function adjust(x) {
2712
+ return 1.0 - Math.pow(1.0 - x, 2.2);
2713
+ };
2714
+
2715
+ for (var i = 0; i <= 16; ++i) {
2716
+ var f = i / 16;
2717
+ gradient.addColorStop(f, rgb + hex(adjust(opacity * ease(f) * 0.5) * 255));
2718
+ }
2719
+ };
2720
+
2598
2721
  var Sheet = React.forwardRef(function (props, ref) {
2599
- var _props$selection, _props$secondarySelec, _props$inputComponent;
2722
+ var _props$selection, _props$secondarySelec, _props$cacheLayout, _props$inputComponent;
2600
2723
 
2601
2724
  var canvasRef = React.useRef(null);
2602
2725
  var overlayRef = React.useRef(null);
@@ -2680,6 +2803,12 @@ var Sheet = React.forwardRef(function (props, ref) {
2680
2803
  var canOrderRow = React.useMemo(function () {
2681
2804
  return createRowOrColumnProp(props.canOrderRow, true);
2682
2805
  }, [props.canOrderRow]);
2806
+ var rowGroupKeys = React.useMemo(function () {
2807
+ return createRowOrColumnProp(props.rowGroupKeys, null);
2808
+ }, [props.rowGroupKeys]);
2809
+ var columnGroupKeys = React.useMemo(function () {
2810
+ return createRowOrColumnProp(props.columnGroupKeys, null);
2811
+ }, [props.columnGroupKeys]);
2683
2812
  var cellReadOnly = React.useMemo(function () {
2684
2813
  return createCellProp(props.readOnly, false);
2685
2814
  }, [props.readOnly]);
@@ -2707,17 +2836,19 @@ var Sheet = React.forwardRef(function (props, ref) {
2707
2836
  var editCellX = editCell[0],
2708
2837
  editCellY = editCell[1];
2709
2838
  var editMode = editCellX !== -1 && editCellY !== -1;
2839
+ var shouldCacheLayout = ((_props$cacheLayout = props.cacheLayout) != null ? _props$cacheLayout : false) !== false;
2840
+ var layoutVersion = typeof props.cacheLayout === 'number' ? props.cacheLayout : 0;
2710
2841
  var columnLayout = React.useMemo(function () {
2711
2842
  return makeLayoutCache(cellWidth);
2712
- }, [props.cacheLayout ? null : cellWidth]);
2843
+ }, [shouldCacheLayout ? layoutVersion : cellWidth]);
2713
2844
  var rowLayout = React.useMemo(function () {
2714
2845
  return makeLayoutCache(cellHeight);
2715
- }, [props.cacheLayout ? null : cellHeight]);
2846
+ }, [shouldCacheLayout ? layoutVersion : cellHeight]);
2716
2847
  React.useMemo(function () {
2717
- if (!props.cacheLayout) return;
2848
+ if (!shouldCacheLayout) return;
2718
2849
  columnLayout.setSizer(cellWidth);
2719
2850
  rowLayout.setSizer(cellHeight);
2720
- }, [props.cacheLayout, cellWidth, cellHeight]);
2851
+ }, [shouldCacheLayout, layoutVersion, cellWidth, cellHeight]);
2721
2852
  var freezeColumns = sheetStyle.freezeColumns,
2722
2853
  freezeRows = sheetStyle.freezeRows,
2723
2854
  rowHeaderWidth = sheetStyle.rowHeaderWidth,
@@ -2737,7 +2868,7 @@ var Sheet = React.forwardRef(function (props, ref) {
2737
2868
  }
2738
2869
  }, [visibleCells, props.onScrollChange]);
2739
2870
 
2740
- var changeSelection = function changeSelection(newSelection, scrollTo, toHead) {
2871
+ var changeSelection = function changeSelection(newSelection, scrollTo, toHead, dragOperation) {
2741
2872
  if (scrollTo === void 0) {
2742
2873
  scrollTo = true;
2743
2874
  }
@@ -2746,6 +2877,20 @@ var Sheet = React.forwardRef(function (props, ref) {
2746
2877
  toHead = false;
2747
2878
  }
2748
2879
 
2880
+ if (dragOperation === void 0) {
2881
+ dragOperation = false;
2882
+ }
2883
+
2884
+ if (!dragOperation) {
2885
+ if (isColumnSelection(newSelection) && columnGroupKeys) {
2886
+ newSelection = expandSelectionToColumnGroups(newSelection, columnGroupKeys);
2887
+ }
2888
+
2889
+ if (isRowSelection(newSelection) && rowGroupKeys) {
2890
+ newSelection = expandSelectionToRowGroups(newSelection, rowGroupKeys);
2891
+ }
2892
+ }
2893
+
2749
2894
  if (!isSameSelection(selection, newSelection)) {
2750
2895
  setSelection(newSelection);
2751
2896
  }
@@ -2754,8 +2899,9 @@ var Sheet = React.forwardRef(function (props, ref) {
2754
2899
  if (!overlay) return;
2755
2900
 
2756
2901
  if (scrollTo) {
2757
- var anchor = newSelection[0],
2758
- head = newSelection[1];
2902
+ var _newSelection = newSelection,
2903
+ anchor = _newSelection[0],
2904
+ head = _newSelection[1];
2759
2905
  scrollToCell(overlay, toHead ? head : anchor, [canvasWidth, canvasHeight], [freezeColumns, freezeRows], dataOffset, maxScroll, cellLayout, function (dataOffset, maxScroll) {
2760
2906
  setDataOffset(dataOffset);
2761
2907
  setMaxScroll(maxScroll);
@@ -2820,7 +2966,7 @@ var Sheet = React.forwardRef(function (props, ref) {
2820
2966
  useClipboardPaste(textAreaRef, selection, changeSelection, props.onChange, cellReadOnly);
2821
2967
  var onScroll = useScroll(dataOffset, maxScroll, cellLayout, setDataOffset, setMaxScroll);
2822
2968
 
2823
- 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),
2969
+ 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),
2824
2970
  mouseHandlers = _useMouse.mouseHandlers,
2825
2971
  knobPosition = _useMouse.knobPosition;
2826
2972
 
@@ -3019,8 +3165,8 @@ var Sheet = React.forwardRef(function (props, ref) {
3019
3165
  borderBottom: '1px solid #ddd'
3020
3166
  };
3021
3167
  var canvasStyles = {
3022
- width: 'calc(100% - 14px)',
3023
- height: 'calc(100% - 15px)',
3168
+ width: canvasWidth,
3169
+ height: canvasHeight,
3024
3170
  outline: '1px solid #ddd'
3025
3171
  };
3026
3172
 
@@ -3028,7 +3174,6 @@ var Sheet = React.forwardRef(function (props, ref) {
3028
3174
  delete canvasStyles['outline'];
3029
3175
  delete overlayDivStyles['borderBottom'];
3030
3176
  overlayDivClassName = '';
3031
- canvasStyles.width = 'calc(100%)';
3032
3177
  }
3033
3178
 
3034
3179
  var renderedInside = React.useMemo(function () {