@rowsncolumns/grid 9.0.3 → 13.2.32

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 (208) hide show
  1. package/LICENSE.md +100 -0
  2. package/Readme.md +53 -59
  3. package/dist/cjs/Cell.d.ts +35 -0
  4. package/dist/cjs/Cell.d.ts.map +1 -0
  5. package/dist/cjs/Cell.js +29 -0
  6. package/dist/{CellOverlay.d.ts → cjs/CellOverlay.d.ts} +5 -5
  7. package/dist/cjs/CellOverlay.d.ts.map +1 -0
  8. package/dist/cjs/CellOverlay.js +126 -0
  9. package/dist/cjs/Context.d.ts +8 -0
  10. package/dist/cjs/Context.d.ts.map +1 -0
  11. package/dist/cjs/Context.js +13 -0
  12. package/dist/{FillHandle.d.ts → cjs/FillHandle.d.ts} +2 -1
  13. package/dist/cjs/FillHandle.d.ts.map +1 -0
  14. package/dist/cjs/FillHandle.js +26 -0
  15. package/dist/cjs/Grid.d.ts +558 -0
  16. package/dist/cjs/Grid.d.ts.map +1 -0
  17. package/dist/cjs/Grid.js +2446 -0
  18. package/dist/{GridLine.d.ts → cjs/GridLine.d.ts} +2 -1
  19. package/dist/cjs/GridLine.d.ts.map +1 -0
  20. package/dist/cjs/GridLine.js +10 -0
  21. package/dist/cjs/Image.d.ts +11 -0
  22. package/dist/cjs/Image.d.ts.map +1 -0
  23. package/dist/cjs/Image.js +57 -0
  24. package/dist/cjs/MemoizedGrid.d.ts +49 -0
  25. package/dist/cjs/MemoizedGrid.d.ts.map +1 -0
  26. package/dist/cjs/MemoizedGrid.js +105 -0
  27. package/dist/cjs/Selection.d.ts +5 -0
  28. package/dist/cjs/Selection.d.ts.map +1 -0
  29. package/dist/cjs/Selection.js +10 -0
  30. package/dist/{helpers.d.ts → cjs/helpers.d.ts} +59 -39
  31. package/dist/cjs/helpers.d.ts.map +1 -0
  32. package/dist/cjs/helpers.js +1409 -0
  33. package/dist/{hooks → cjs/hooks}/useCopyPaste.d.ts +3 -2
  34. package/dist/cjs/hooks/useCopyPaste.d.ts.map +1 -0
  35. package/dist/cjs/hooks/useCopyPaste.js +230 -0
  36. package/dist/{hooks → cjs/hooks}/useEditable.d.ts +21 -8
  37. package/dist/cjs/hooks/useEditable.d.ts.map +1 -0
  38. package/dist/cjs/hooks/useEditable.js +491 -0
  39. package/dist/{hooks → cjs/hooks}/useFilter.d.ts +3 -2
  40. package/dist/cjs/hooks/useFilter.d.ts.map +1 -0
  41. package/dist/cjs/hooks/useFilter.js +97 -0
  42. package/dist/{hooks → cjs/hooks}/useImage.d.ts +1 -0
  43. package/dist/cjs/hooks/useImage.d.ts.map +1 -0
  44. package/dist/cjs/hooks/useImage.js +80 -0
  45. package/dist/{hooks → cjs/hooks}/usePagination.d.ts +3 -2
  46. package/dist/cjs/hooks/usePagination.d.ts.map +1 -0
  47. package/dist/cjs/hooks/usePagination.js +53 -0
  48. package/dist/{hooks → cjs/hooks}/useSizer.d.ts +28 -29
  49. package/dist/cjs/hooks/useSizer.d.ts.map +1 -0
  50. package/dist/cjs/hooks/useSizer.js +176 -0
  51. package/dist/{hooks → cjs/hooks}/useTooltip.d.ts +2 -1
  52. package/dist/cjs/hooks/useTooltip.d.ts.map +1 -0
  53. package/dist/cjs/hooks/useTooltip.js +82 -0
  54. package/dist/{hooks → cjs/hooks}/useUndo.d.ts +2 -1
  55. package/dist/cjs/hooks/useUndo.d.ts.map +1 -0
  56. package/dist/cjs/hooks/useUndo.js +87 -0
  57. package/dist/cjs/index.d.ts +19 -0
  58. package/dist/cjs/index.d.ts.map +1 -0
  59. package/dist/cjs/index.js +29 -0
  60. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  61. package/dist/{types.d.ts → cjs/types.d.ts} +8 -3
  62. package/dist/cjs/types.d.ts.map +1 -0
  63. package/dist/{types.js → cjs/types.js} +7 -8
  64. package/dist/cjs/utils.d.ts +9 -0
  65. package/dist/cjs/utils.d.ts.map +1 -0
  66. package/dist/cjs/utils.js +58 -0
  67. package/dist/cjs/vitest.config.d.ts +3 -0
  68. package/dist/cjs/vitest.config.d.ts.map +1 -0
  69. package/dist/cjs/vitest.config.js +24 -0
  70. package/dist/esm/Cell.d.ts +35 -0
  71. package/dist/esm/Cell.d.ts.map +1 -0
  72. package/dist/esm/Cell.js +24 -0
  73. package/dist/esm/CellOverlay.d.ts +21 -0
  74. package/dist/esm/CellOverlay.d.ts.map +1 -0
  75. package/dist/esm/CellOverlay.js +120 -0
  76. package/dist/esm/Context.d.ts +8 -0
  77. package/dist/esm/Context.d.ts.map +1 -0
  78. package/dist/esm/Context.js +9 -0
  79. package/dist/esm/FillHandle.d.ts +8 -0
  80. package/dist/esm/FillHandle.d.ts.map +1 -0
  81. package/dist/{FillHandle.js → esm/FillHandle.js} +5 -11
  82. package/dist/esm/Grid.d.ts +558 -0
  83. package/dist/esm/Grid.d.ts.map +1 -0
  84. package/dist/esm/Grid.js +2451 -0
  85. package/dist/esm/GridLine.d.ts +5 -0
  86. package/dist/esm/GridLine.d.ts.map +1 -0
  87. package/dist/esm/GridLine.js +7 -0
  88. package/dist/esm/Image.d.ts +11 -0
  89. package/dist/esm/Image.d.ts.map +1 -0
  90. package/dist/esm/Image.js +53 -0
  91. package/dist/esm/MemoizedGrid.d.ts +49 -0
  92. package/dist/esm/MemoizedGrid.d.ts.map +1 -0
  93. package/dist/esm/MemoizedGrid.js +98 -0
  94. package/dist/esm/Selection.d.ts +5 -0
  95. package/dist/esm/Selection.d.ts.map +1 -0
  96. package/dist/esm/Selection.js +7 -0
  97. package/dist/esm/helpers.d.ts +281 -0
  98. package/dist/esm/helpers.d.ts.map +1 -0
  99. package/dist/esm/helpers.js +1260 -0
  100. package/dist/esm/hooks/useCopyPaste.d.ts +53 -0
  101. package/dist/esm/hooks/useCopyPaste.d.ts.map +1 -0
  102. package/dist/{hooks → esm/hooks}/useCopyPaste.js +40 -46
  103. package/dist/esm/hooks/useEditable.d.ts +253 -0
  104. package/dist/esm/hooks/useEditable.d.ts.map +1 -0
  105. package/dist/esm/hooks/useEditable.js +482 -0
  106. package/dist/esm/hooks/useFilter.d.ts +69 -0
  107. package/dist/esm/hooks/useFilter.d.ts.map +1 -0
  108. package/dist/{hooks → esm/hooks}/useFilter.js +22 -42
  109. package/dist/esm/hooks/useImage.d.ts +13 -0
  110. package/dist/esm/hooks/useImage.d.ts.map +1 -0
  111. package/dist/esm/hooks/useImage.js +76 -0
  112. package/dist/esm/hooks/usePagination.d.ts +69 -0
  113. package/dist/esm/hooks/usePagination.d.ts.map +1 -0
  114. package/dist/esm/hooks/usePagination.js +47 -0
  115. package/dist/esm/hooks/useSizer.d.ts +114 -0
  116. package/dist/esm/hooks/useSizer.d.ts.map +1 -0
  117. package/dist/esm/hooks/useSizer.js +176 -0
  118. package/dist/esm/hooks/useTooltip.d.ts +43 -0
  119. package/dist/esm/hooks/useTooltip.d.ts.map +1 -0
  120. package/dist/esm/hooks/useTooltip.js +80 -0
  121. package/dist/esm/hooks/useUndo.d.ts +36 -0
  122. package/dist/esm/hooks/useUndo.d.ts.map +1 -0
  123. package/dist/{hooks → esm/hooks}/useUndo.js +16 -25
  124. package/dist/esm/index.d.ts +19 -0
  125. package/dist/esm/index.d.ts.map +1 -0
  126. package/dist/esm/index.js +17 -0
  127. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  128. package/dist/esm/types.d.ts +70 -0
  129. package/dist/esm/types.d.ts.map +1 -0
  130. package/dist/esm/types.js +68 -0
  131. package/dist/esm/utils.d.ts +9 -0
  132. package/dist/esm/utils.d.ts.map +1 -0
  133. package/dist/esm/utils.js +104 -0
  134. package/dist/esm/vitest.config.d.ts +3 -0
  135. package/dist/esm/vitest.config.d.ts.map +1 -0
  136. package/dist/esm/vitest.config.js +22 -0
  137. package/package.json +28 -29
  138. package/dist/Cell.d.ts +0 -23
  139. package/dist/Cell.js +0 -55
  140. package/dist/Cell.js.map +0 -1
  141. package/dist/CellOverlay.js +0 -116
  142. package/dist/CellOverlay.js.map +0 -1
  143. package/dist/FillHandle.js.map +0 -1
  144. package/dist/Grid.d.ts +0 -385
  145. package/dist/Grid.js +0 -1684
  146. package/dist/Grid.js.map +0 -1
  147. package/dist/GridLine.js +0 -13
  148. package/dist/GridLine.js.map +0 -1
  149. package/dist/Image.d.ts +0 -8
  150. package/dist/Image.js +0 -50
  151. package/dist/Image.js.map +0 -1
  152. package/dist/Selection.d.ts +0 -4
  153. package/dist/Selection.js +0 -9
  154. package/dist/Selection.js.map +0 -1
  155. package/dist/helpers.js +0 -1033
  156. package/dist/helpers.js.map +0 -1
  157. package/dist/hooks/useCopyPaste.js.map +0 -1
  158. package/dist/hooks/useEditable.js +0 -477
  159. package/dist/hooks/useEditable.js.map +0 -1
  160. package/dist/hooks/useFilter.js.map +0 -1
  161. package/dist/hooks/useImage.js +0 -42
  162. package/dist/hooks/useImage.js.map +0 -1
  163. package/dist/hooks/usePagination.js +0 -73
  164. package/dist/hooks/usePagination.js.map +0 -1
  165. package/dist/hooks/useSelection.d.ts +0 -175
  166. package/dist/hooks/useSelection.js +0 -980
  167. package/dist/hooks/useSelection.js.map +0 -1
  168. package/dist/hooks/useSizer.js +0 -150
  169. package/dist/hooks/useSizer.js.map +0 -1
  170. package/dist/hooks/useTooltip.js +0 -106
  171. package/dist/hooks/useTooltip.js.map +0 -1
  172. package/dist/hooks/useTouch.d.ts +0 -21
  173. package/dist/hooks/useTouch.js +0 -73
  174. package/dist/hooks/useTouch.js.map +0 -1
  175. package/dist/hooks/useUndo.js.map +0 -1
  176. package/dist/index.d.ts +0 -25
  177. package/dist/index.js +0 -61
  178. package/dist/index.js.map +0 -1
  179. package/dist/types.js.map +0 -1
  180. package/dist/utils.d.ts +0 -8
  181. package/dist/utils.js +0 -153
  182. package/dist/utils.js.map +0 -1
  183. package/src/Cell.tsx +0 -100
  184. package/src/CellOverlay.tsx +0 -191
  185. package/src/FillHandle.tsx +0 -37
  186. package/src/Grid.tsx +0 -2677
  187. package/src/GridLine.tsx +0 -23
  188. package/src/Image.tsx +0 -43
  189. package/src/Selection.tsx +0 -9
  190. package/src/helpers.ts +0 -1455
  191. package/src/hooks/useCopyPaste.ts +0 -265
  192. package/src/hooks/useEditable.tsx +0 -945
  193. package/src/hooks/useFilter.tsx +0 -233
  194. package/src/hooks/useImage.ts +0 -57
  195. package/src/hooks/usePagination.tsx +0 -153
  196. package/src/hooks/useSelection.ts +0 -1437
  197. package/src/hooks/useSizer.ts +0 -312
  198. package/src/hooks/useTooltip.tsx +0 -172
  199. package/src/hooks/useTouch.ts +0 -116
  200. package/src/hooks/useUndo.ts +0 -134
  201. package/src/index.tsx +0 -46
  202. package/src/tests/Grid.spec.tsx +0 -47
  203. package/src/tests/helpers.test.ts +0 -292
  204. package/src/tests/usePagination.test.ts +0 -28
  205. package/src/tests/useSelection.test.ts +0 -27
  206. package/src/tests/useUndo.test.ts +0 -73
  207. package/src/types.ts +0 -69
  208. package/src/utils.tsx +0 -287
@@ -1,980 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const react_1 = require("react");
4
- const helpers_1 = require("./../helpers");
5
- const types_1 = require("./../types");
6
- const EMPTY_SELECTION = [];
7
- const defaultIsHidden = (i) => false;
8
- const defaultSelectionSpan = () => true;
9
- /**
10
- * Hook to enable selection in datagrid
11
- * @param initialSelection
12
- */
13
- const useSelection = ({ gridRef, initialActiveCell = null, initialSelections = EMPTY_SELECTION, columnCount = 0, rowCount = 0, selectionPolicy = "multiple", newSelectionMode = "clear", allowDeselectSelection = true, onFill, isHiddenRow = defaultIsHidden, isHiddenColumn = defaultIsHidden, alwaysScrollToActiveCell = true, selectionTopBound = 0, selectionBottomBound = rowCount - 1, selectionLeftBound = 0, selectionRightBound = columnCount - 1, mouseDownInterceptor, mouseMoveInterceptor, mergedCells = [], canSelectionSpanMergedCells = defaultSelectionSpan, getValue, onSelectionMove, }) => {
14
- const [activeCell, setActiveCell] = (0, react_1.useState)(initialActiveCell);
15
- const [selections, setSelections] = (0, react_1.useState)(initialSelections);
16
- const [fillSelection, setFillSelection] = (0, react_1.useState)(null);
17
- const selectionStart = (0, react_1.useRef)(null);
18
- const selectionEnd = (0, react_1.useRef)(null);
19
- const isSelecting = (0, react_1.useRef)(false);
20
- const isFilling = (0, react_1.useRef)(false);
21
- const firstActiveCell = (0, react_1.useRef)(null);
22
- /* Drag drop selection */
23
- const [_, forceRender] = (0, react_1.useReducer)((s) => s + 1, 0);
24
- const isDragging = (0, react_1.useRef)(false);
25
- const hasUserMovedSelection = (0, react_1.useRef)(false);
26
- const initialDraggedSelection = (0, react_1.useRef)();
27
- const initialDraggedCell = (0, react_1.useRef)();
28
- const draggedSelection = (0, react_1.useRef)();
29
- const draggedSelectionIndex = (0, react_1.useRef)();
30
- /**
31
- * Need to store in ref because on mousemove and mouseup event that are
32
- * registered in document
33
- */
34
- const activeCellRef = (0, react_1.useRef)(activeCell);
35
- const activeSelectionsRef = (0, react_1.useRef)(selections);
36
- const mergedCellsRef = (0, react_1.useRef)(mergedCells);
37
- (0, react_1.useEffect)(() => {
38
- activeCellRef.current = activeCell;
39
- }, [activeCell]);
40
- (0, react_1.useEffect)(() => {
41
- activeSelectionsRef.current = selections;
42
- }, [selections]);
43
- (0, react_1.useEffect)(() => {
44
- mergedCellsRef.current = mergedCells;
45
- }, [mergedCells]);
46
- /* Check if cell is out of bounds */
47
- const isCellOutOfBounds = (0, react_1.useCallback)((cell) => {
48
- return (cell.rowIndex < selectionTopBound ||
49
- cell.columnIndex < selectionLeftBound);
50
- }, [selectionTopBound, selectionLeftBound]);
51
- /* New selection */
52
- const newSelection = (start, end = start) => {
53
- /* Validate bounds */
54
- if (isCellOutOfBounds(start)) {
55
- return;
56
- }
57
- selectionStart.current = start;
58
- selectionEnd.current = end;
59
- const bounds = selectionFromStartEnd(start, end);
60
- if (!bounds)
61
- return;
62
- const coords = { rowIndex: bounds.top, columnIndex: bounds.left };
63
- /* Keep track of first cell that was selected by user */
64
- setActiveCell(coords);
65
- if (newSelectionMode === "clear") {
66
- firstActiveCell.current = coords;
67
- clearSelections();
68
- }
69
- else if (newSelectionMode === "modify") {
70
- modifySelection(coords);
71
- }
72
- else {
73
- appendSelection(coords);
74
- }
75
- };
76
- /**
77
- * selection object from start, end
78
- * @param start
79
- * @param end
80
- */
81
- const selectionFromStartEnd = (start, end) => {
82
- if (!(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
83
- return null;
84
- const spanMerges = canSelectionSpanMergedCells === null || canSelectionSpanMergedCells === void 0 ? void 0 : canSelectionSpanMergedCells(start, end);
85
- return (0, helpers_1.cellRangeToBounds)(start, end, spanMerges, gridRef.current.getCellBounds);
86
- };
87
- /* Modify current selection */
88
- const modifySelection = (coords, setInProgress) => {
89
- if (selectionPolicy === "single") {
90
- return;
91
- }
92
- if (!selectionStart.current)
93
- return;
94
- if (isCellOutOfBounds(coords)) {
95
- return;
96
- }
97
- selectionEnd.current = coords;
98
- const bounds = selectionFromStartEnd(selectionStart.current, coords);
99
- if (!bounds)
100
- return;
101
- /**
102
- * 1. Multiple selections on mousedown/mousemove
103
- * 2. Move the activeCell to newly selection. Done by appendSelection
104
- */
105
- setSelections((prevSelection) => {
106
- const len = prevSelection.length;
107
- if (!len) {
108
- return [{ bounds, inProgress: setInProgress ? true : false }];
109
- }
110
- return prevSelection.map((sel, i) => {
111
- if (len - 1 === i) {
112
- return {
113
- ...sel,
114
- bounds,
115
- inProgress: setInProgress ? true : false,
116
- };
117
- }
118
- return sel;
119
- });
120
- });
121
- };
122
- /* Adds a new selection, CMD key */
123
- const appendSelection = (start, end = start) => {
124
- if (selectionPolicy !== "multiple") {
125
- return;
126
- }
127
- if (!start)
128
- return;
129
- /* Validate bounds */
130
- if (isCellOutOfBounds(start)) {
131
- return;
132
- }
133
- selectionStart.current = start;
134
- selectionEnd.current = end;
135
- const bounds = selectionFromStartEnd(start, end);
136
- if (!bounds)
137
- return;
138
- setActiveCell({ rowIndex: bounds.top, columnIndex: bounds.left });
139
- setSelections((prev) => [...prev, { bounds }]);
140
- };
141
- const removeSelectionByIndex = (0, react_1.useCallback)((index) => {
142
- const newSelection = selections.filter((_, idx) => idx !== index);
143
- setSelections(newSelection);
144
- return newSelection;
145
- }, [selections]);
146
- const clearSelections = () => {
147
- setSelections(EMPTY_SELECTION);
148
- };
149
- const getPossibleActiveCellFromSelections = (selections) => {
150
- if (!selections.length)
151
- return null;
152
- const { bounds } = selections[selections.length - 1];
153
- return {
154
- rowIndex: bounds.top,
155
- columnIndex: bounds.left,
156
- };
157
- };
158
- const cellIndexInSelection = (cell, selections) => {
159
- const id = (0, helpers_1.cellIdentifier)(Math.max(selectionTopBound, cell.rowIndex), Math.max(selectionLeftBound, cell.columnIndex));
160
- return selections.findIndex((sel) => {
161
- const boundedCells = (0, helpers_1.getBoundedCells)(sel.bounds);
162
- return boundedCells.has(id);
163
- });
164
- };
165
- const cellEqualsSelection = (cell, selections) => {
166
- if (cell === null)
167
- return false;
168
- return selections.some((sel) => {
169
- return (sel.bounds.left === cell.columnIndex &&
170
- sel.bounds.top === cell.rowIndex &&
171
- sel.bounds.right === cell.columnIndex &&
172
- sel.bounds.bottom === cell.rowIndex);
173
- });
174
- };
175
- const boundsSubsetOfSelection = (bounds, selection) => {
176
- return (bounds.top >= selection.top &&
177
- bounds.bottom <= selection.bottom &&
178
- bounds.left >= selection.left &&
179
- bounds.right <= selection.right);
180
- };
181
- /**
182
- * Triggers a new selection start
183
- */
184
- const handleMouseDown = (0, react_1.useCallback)((e) => {
185
- var _a;
186
- /* Exit early if grid is not initialized */
187
- if (!gridRef || !gridRef.current)
188
- return;
189
- const coords = gridRef.current.getCellCoordsFromOffset(e.nativeEvent.clientX, e.nativeEvent.clientY);
190
- if (!coords)
191
- return;
192
- /* Check if its context menu click */
193
- const isContextMenuClick = e.nativeEvent.which === types_1.MouseButtonCodes.right;
194
- if (isContextMenuClick) {
195
- const cellIndex = cellIndexInSelection(coords, selections);
196
- if (cellIndex !== -1)
197
- return;
198
- }
199
- const isShiftKey = e.nativeEvent.shiftKey;
200
- const isMetaKey = e.nativeEvent.ctrlKey || e.nativeEvent.metaKey;
201
- const allowMultiple = isMetaKey;
202
- const allowDeselect = allowDeselectSelection;
203
- const hasSelections = selections.length > 0;
204
- const isDeselecting = isMetaKey && allowDeselect;
205
- if (!isContextMenuClick && selectionPolicy !== "single") {
206
- document.addEventListener("mouseup", handleMouseUp);
207
- document.addEventListener("mousemove", handleMouseMove);
208
- }
209
- /* Activate selection mode */
210
- isSelecting.current = true;
211
- if ((mouseDownInterceptor === null || mouseDownInterceptor === void 0 ? void 0 : mouseDownInterceptor(e, coords, selectionStart, selectionEnd)) ===
212
- false) {
213
- return;
214
- }
215
- /* Shift key */
216
- if (isShiftKey) {
217
- modifySelection(coords);
218
- return;
219
- }
220
- /* Is the current cell same as active cell */
221
- const isSameAsActiveCell = (0, helpers_1.isEqualCells)(coords, activeCell);
222
- /* Command or Control key */
223
- if (activeCell && allowMultiple) {
224
- /**
225
- * User is adding activeCell to selection
226
- *
227
- * 1. User is selecting and not de-selecting
228
- * 2. User has not made any selection
229
- * 3. Trying to add active cell to selection
230
- */
231
- if (isSameAsActiveCell && (!isDeselecting || !hasSelections)) {
232
- return;
233
- }
234
- /**
235
- * User is manually trying to select multiple selections,
236
- * So add the current active cell to the list
237
- */
238
- if (isMetaKey && !hasSelections) {
239
- appendSelection(activeCell);
240
- }
241
- /**
242
- * Check if this cell has already been selected (only for manual deselect)
243
- * Remove it from selection
244
- *
245
- * Future enhancements -> Split selection, so that 1 cell can be removed from range
246
- */
247
- if (isMetaKey && allowDeselect) {
248
- const cellIndex = cellIndexInSelection(coords, selections);
249
- if (cellIndex !== -1) {
250
- const newSelection = removeSelectionByIndex(cellIndex);
251
- const nextActiveCell = getPossibleActiveCellFromSelections(newSelection);
252
- if (nextActiveCell !== null) {
253
- setActiveCell(nextActiveCell);
254
- }
255
- if (newSelection.length === 1 &&
256
- cellEqualsSelection(nextActiveCell, newSelection)) {
257
- /* Since we only have 1 cell, lets clear the selections and only keep activeCell */
258
- clearSelections();
259
- }
260
- return;
261
- }
262
- }
263
- /**
264
- * TODO
265
- * 1. Ability to remove selection
266
- * 2. Ability to remove from selection area
267
- * 3. Ability to switch activeCell if its part of removed selection
268
- */
269
- appendSelection(coords);
270
- return;
271
- }
272
- /**
273
- * Scroll to the selected cell
274
- */
275
- if (alwaysScrollToActiveCell) {
276
- (_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.scrollToItem(coords);
277
- }
278
- /**
279
- * If user is selecting the same same,
280
- * let not trigger another state change
281
- */
282
- if (isSameAsActiveCell)
283
- return;
284
- /* Trigger new selection */
285
- newSelection(coords);
286
- }, [
287
- activeCell,
288
- selections,
289
- selectionPolicy,
290
- allowDeselectSelection,
291
- alwaysScrollToActiveCell,
292
- rowCount,
293
- columnCount,
294
- newSelectionMode,
295
- ]);
296
- /**
297
- * Mousemove handler
298
- */
299
- const handleMouseMove = (0, react_1.useCallback)((e) => {
300
- var _a;
301
- /* Exit if user is not in selection mode */
302
- if (!isSelecting.current || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
303
- return;
304
- const coords = gridRef.current.getCellCoordsFromOffset(e.clientX, e.clientY);
305
- if (!coords)
306
- return;
307
- if ((mouseMoveInterceptor === null || mouseMoveInterceptor === void 0 ? void 0 : mouseMoveInterceptor(e, coords, selectionStart, selectionEnd)) === false) {
308
- return;
309
- }
310
- if ((0, helpers_1.isEqualCells)(firstActiveCell.current, coords)) {
311
- return clearSelections();
312
- }
313
- modifySelection(coords, true);
314
- (_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.scrollToItem(coords);
315
- }, []);
316
- /**
317
- * Mouse up handler
318
- */
319
- const handleMouseUp = (0, react_1.useCallback)(() => {
320
- /* Reset selection mode */
321
- isSelecting.current = false;
322
- /* Remove listener */
323
- document.removeEventListener("mousemove", handleMouseMove);
324
- document.removeEventListener("mouseup", handleMouseUp);
325
- /* Update last selection */
326
- setSelections((prevSelection) => {
327
- const len = prevSelection.length;
328
- if (!len)
329
- return EMPTY_SELECTION;
330
- return prevSelection.map((sel, i) => {
331
- if (len - 1 === i) {
332
- return {
333
- ...sel,
334
- inProgress: false,
335
- };
336
- }
337
- return sel;
338
- });
339
- });
340
- }, []);
341
- /**
342
- * Navigate selection using keyboard
343
- * @param direction
344
- * @param modify
345
- */
346
- const keyNavigate = (0, react_1.useCallback)((direction, modify, metaKeyPressed) => {
347
- if (!selectionStart.current ||
348
- !selectionEnd.current ||
349
- !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current) ||
350
- !activeCell)
351
- return;
352
- const currentCell = modify ? selectionEnd.current : activeCell;
353
- var { rowIndex, columnIndex } = currentCell;
354
- const isMergedCell = gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.isMergedCell({
355
- rowIndex,
356
- columnIndex,
357
- });
358
- const currentBounds = gridRef.current.getCellBounds({
359
- rowIndex,
360
- columnIndex,
361
- });
362
- switch (direction) {
363
- case types_1.Direction.Up:
364
- if (isMergedCell)
365
- rowIndex = currentBounds.top;
366
- rowIndex = (0, helpers_1.clampIndex)(Math.max(rowIndex - 1, selectionTopBound), isHiddenRow, direction);
367
- // Shift + Ctrl/Commmand
368
- // TODO: Scroll to last contentful cell
369
- if (metaKeyPressed) {
370
- const startCell = {
371
- ...currentCell,
372
- // Expand from the starting cell
373
- columnIndex: selectionStart.current.columnIndex,
374
- };
375
- rowIndex = (0, helpers_1.findNextCellInDataRegion)(startCell, getValue, isHiddenRow, direction, selectionTopBound);
376
- }
377
- break;
378
- case types_1.Direction.Down:
379
- if (isMergedCell)
380
- rowIndex = currentBounds.bottom;
381
- rowIndex = (0, helpers_1.clampIndex)(Math.min(rowIndex + 1, selectionBottomBound), isHiddenRow, direction);
382
- // Shift + Ctrl/Commmand
383
- if (metaKeyPressed) {
384
- const startCell = {
385
- ...currentCell,
386
- // Expand from the starting cell
387
- columnIndex: selectionStart.current.columnIndex,
388
- };
389
- rowIndex = (0, helpers_1.findNextCellInDataRegion)(startCell, getValue, isHiddenRow, direction, selectionBottomBound);
390
- }
391
- break;
392
- case types_1.Direction.Left:
393
- if (isMergedCell)
394
- columnIndex = currentBounds.left;
395
- columnIndex = (0, helpers_1.clampIndex)(Math.max(columnIndex - 1, selectionLeftBound), isHiddenColumn, direction);
396
- // Shift + Ctrl/Commmand
397
- if (metaKeyPressed) {
398
- const startCell = {
399
- ...currentCell,
400
- // Expand from the starting cell
401
- rowIndex: selectionStart.current.rowIndex,
402
- };
403
- columnIndex = (0, helpers_1.findNextCellInDataRegion)(startCell, getValue, isHiddenColumn, direction, selectionLeftBound);
404
- }
405
- break;
406
- case types_1.Direction.Right:
407
- if (isMergedCell)
408
- columnIndex = currentBounds.right;
409
- columnIndex = (0, helpers_1.clampIndex)(Math.min(columnIndex + 1, selectionRightBound), isHiddenColumn, direction);
410
- // Shift + Ctrl/Commmand
411
- if (metaKeyPressed) {
412
- const startCell = {
413
- ...currentCell,
414
- // Expand from the starting cell
415
- rowIndex: selectionStart.current.rowIndex,
416
- };
417
- columnIndex = (0, helpers_1.findNextCellInDataRegion)(startCell, getValue, isHiddenColumn, direction, selectionRightBound);
418
- }
419
- break;
420
- }
421
- const newBounds = gridRef.current.getCellBounds({
422
- rowIndex,
423
- columnIndex,
424
- });
425
- const coords = { rowIndex: newBounds.top, columnIndex: newBounds.left };
426
- const scrollToCell = modify
427
- ? selectionEnd.current.rowIndex === coords.rowIndex
428
- ? // Scroll to a column
429
- { columnIndex: coords.columnIndex }
430
- : // Scroll to row
431
- { rowIndex: coords.rowIndex }
432
- : // Scroll to cell
433
- { rowIndex, columnIndex };
434
- const isUserNavigatingToActiveCell = (0, helpers_1.isEqualCells)(firstActiveCell.current, coords);
435
- if (modify && !isUserNavigatingToActiveCell) {
436
- modifySelection(coords);
437
- }
438
- else {
439
- newSelection(coords);
440
- }
441
- /* Keep the item in view */
442
- gridRef.current.scrollToItem(scrollToCell);
443
- }, [
444
- activeCell,
445
- isHiddenRow,
446
- isHiddenColumn,
447
- selectionLeftBound,
448
- selectionTopBound,
449
- selectionPolicy,
450
- newSelectionMode,
451
- ]);
452
- // ⌘A or ⌘+Shift+Space
453
- const selectAll = () => {
454
- selectionStart.current = {
455
- rowIndex: selectionTopBound,
456
- columnIndex: selectionLeftBound,
457
- };
458
- modifySelection({
459
- rowIndex: selectionBottomBound,
460
- columnIndex: selectionRightBound,
461
- });
462
- };
463
- // Ctrl+Space
464
- const selectColumn = (0, react_1.useCallback)(() => {
465
- if (!selectionEnd.current || !selectionStart.current)
466
- return;
467
- selectionStart.current = {
468
- rowIndex: selectionTopBound,
469
- columnIndex: selectionStart.current.columnIndex,
470
- };
471
- modifySelection({
472
- rowIndex: rowCount - 1,
473
- columnIndex: selectionEnd.current.columnIndex,
474
- });
475
- }, [selectionTopBound]);
476
- // Shift+Space
477
- const selectRow = (0, react_1.useCallback)(() => {
478
- if (!selectionEnd.current || !selectionStart.current)
479
- return;
480
- selectionStart.current = {
481
- rowIndex: selectionStart.current.rowIndex,
482
- columnIndex: selectionLeftBound,
483
- };
484
- modifySelection({
485
- rowIndex: selectionEnd.current.rowIndex,
486
- columnIndex: selectionRightBound,
487
- });
488
- }, [selectionLeftBound]);
489
- // Home
490
- const selectFirstCellInRow = () => {
491
- if (!selectionStart.current || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
492
- return;
493
- const cell = {
494
- rowIndex: selectionStart.current.rowIndex,
495
- columnIndex: selectionLeftBound,
496
- };
497
- newSelection(cell);
498
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem(cell);
499
- };
500
- // End
501
- const selectLastCellInRow = () => {
502
- if (!selectionStart.current || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
503
- return;
504
- const cell = {
505
- rowIndex: selectionStart.current.rowIndex,
506
- columnIndex: selectionRightBound,
507
- };
508
- newSelection(cell);
509
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem(cell);
510
- };
511
- // ⌘+Home
512
- const selectFirstCellInColumn = () => {
513
- if (!selectionStart.current || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
514
- return;
515
- const cell = {
516
- rowIndex: selectionTopBound,
517
- columnIndex: selectionStart.current.columnIndex,
518
- };
519
- newSelection(cell);
520
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem(cell);
521
- };
522
- // ⌘+End
523
- const selectLastCellInColumn = () => {
524
- if (!selectionStart.current || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
525
- return;
526
- const cell = {
527
- rowIndex: rowCount - 1,
528
- columnIndex: selectionStart.current.columnIndex,
529
- };
530
- newSelection(cell);
531
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem(cell);
532
- };
533
- // ⌘+Backspace
534
- const scrollToActiveCell = () => {
535
- if (!activeCell || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
536
- return;
537
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem(activeCell, helpers_1.Align.smart);
538
- };
539
- // Page down
540
- const pageDown = () => {
541
- if (!activeCell || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
542
- return;
543
- const { visibleRowStartIndex, visibleRowStopIndex } = gridRef.current.getViewPort();
544
- const pageSize = visibleRowStopIndex - visibleRowStartIndex;
545
- const rowIndex = Math.min(activeCell.rowIndex + pageSize, rowCount - 1);
546
- const newActiveCell = {
547
- rowIndex,
548
- columnIndex: activeCell.columnIndex,
549
- };
550
- handleSetActiveCell(newActiveCell, false);
551
- /* Scroll to the new row */
552
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem({ rowIndex }, helpers_1.Align.end);
553
- };
554
- // Page up
555
- const pageUp = () => {
556
- if (!activeCell || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
557
- return;
558
- const { visibleRowStartIndex, visibleRowStopIndex } = gridRef.current.getViewPort();
559
- const pageSize = visibleRowStopIndex - visibleRowStartIndex;
560
- const rowIndex = Math.max(activeCell.rowIndex - pageSize, selectionTopBound);
561
- const newActiveCell = {
562
- rowIndex,
563
- columnIndex: activeCell.columnIndex,
564
- };
565
- handleSetActiveCell(newActiveCell, false);
566
- /* Scroll to the new row */
567
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem({ rowIndex }, helpers_1.Align.end);
568
- };
569
- // Page right
570
- const pageRight = () => {
571
- if (!activeCell || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
572
- return;
573
- const { visibleColumnStartIndex, visibleColumnStopIndex } = gridRef.current.getViewPort();
574
- const pageSize = visibleColumnStopIndex - visibleColumnStartIndex;
575
- const columnIndex = Math.min(activeCell.columnIndex + pageSize, selectionRightBound);
576
- const newActiveCell = {
577
- columnIndex,
578
- rowIndex: activeCell.rowIndex,
579
- };
580
- handleSetActiveCell(newActiveCell, false);
581
- /* Scroll to the new row */
582
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem({ columnIndex }, helpers_1.Align.end);
583
- };
584
- // Page left
585
- const pageLeft = () => {
586
- if (!activeCell || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
587
- return;
588
- const { visibleColumnStartIndex, visibleColumnStopIndex } = gridRef.current.getViewPort();
589
- const pageSize = visibleColumnStopIndex - visibleColumnStartIndex;
590
- const columnIndex = Math.max(activeCell.columnIndex - pageSize, selectionLeftBound);
591
- const newActiveCell = {
592
- columnIndex,
593
- rowIndex: activeCell.rowIndex,
594
- };
595
- handleSetActiveCell(newActiveCell, false);
596
- /* Scroll to the new row */
597
- gridRef === null || gridRef === void 0 ? void 0 : gridRef.current.scrollToItem({ columnIndex }, helpers_1.Align.end);
598
- };
599
- const handleKeyDown = (0, react_1.useCallback)((e) => {
600
- if (!(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
601
- return;
602
- const isShiftKey = e.nativeEvent.shiftKey;
603
- const isAltKey = e.nativeEvent.altKey;
604
- const isMetaKey = e.nativeEvent.ctrlKey || e.nativeEvent.metaKey;
605
- switch (e.nativeEvent.which) {
606
- case types_1.KeyCodes.Right:
607
- keyNavigate(types_1.Direction.Right, isShiftKey, isMetaKey);
608
- e.preventDefault();
609
- break;
610
- case types_1.KeyCodes.Left:
611
- keyNavigate(types_1.Direction.Left, isShiftKey, isMetaKey);
612
- e.preventDefault();
613
- break;
614
- // Up
615
- case types_1.KeyCodes.Up:
616
- keyNavigate(types_1.Direction.Up, isShiftKey, isMetaKey);
617
- e.preventDefault();
618
- break;
619
- case types_1.KeyCodes.Down:
620
- keyNavigate(types_1.Direction.Down, isShiftKey, isMetaKey);
621
- e.preventDefault();
622
- break;
623
- case types_1.KeyCodes.A:
624
- if (isMetaKey) {
625
- selectAll();
626
- }
627
- e.preventDefault();
628
- break;
629
- case types_1.KeyCodes.Home:
630
- if (isMetaKey) {
631
- selectFirstCellInColumn();
632
- }
633
- else {
634
- selectFirstCellInRow();
635
- }
636
- break;
637
- case types_1.KeyCodes.End:
638
- if (isMetaKey) {
639
- selectLastCellInColumn();
640
- }
641
- else {
642
- selectLastCellInRow();
643
- }
644
- break;
645
- case types_1.KeyCodes.BackSpace:
646
- if (isMetaKey)
647
- scrollToActiveCell();
648
- break;
649
- case types_1.KeyCodes.SPACE:
650
- if (isMetaKey && isShiftKey) {
651
- selectAll();
652
- }
653
- else if (isMetaKey) {
654
- selectColumn();
655
- }
656
- else if (isShiftKey) {
657
- selectRow();
658
- }
659
- break;
660
- case types_1.KeyCodes.Tab:
661
- /* Cycle through the selections if selections.length > 0 */
662
- if (selections.length && activeCell && gridRef) {
663
- const { bounds } = selections[selections.length - 1];
664
- const activeCellBounds = gridRef.current.getCellBounds(activeCell);
665
- const direction = isShiftKey ? types_1.Direction.Left : types_1.Direction.Right;
666
- const nextCell = (0, helpers_1.findNextCellWithinBounds)(activeCellBounds, bounds, direction);
667
- if (nextCell) {
668
- setActiveCell(nextCell);
669
- if (gridRef.current)
670
- gridRef.current.scrollToItem(nextCell);
671
- }
672
- }
673
- else {
674
- if (isShiftKey) {
675
- keyNavigate(types_1.Direction.Left);
676
- }
677
- else {
678
- keyNavigate(types_1.Direction.Right);
679
- }
680
- }
681
- e.preventDefault();
682
- break;
683
- case types_1.KeyCodes.PageDown:
684
- if (isAltKey) {
685
- pageRight();
686
- }
687
- else
688
- pageDown();
689
- break;
690
- case types_1.KeyCodes.PageUp:
691
- if (isAltKey) {
692
- pageLeft();
693
- }
694
- else
695
- pageUp();
696
- break;
697
- }
698
- }, [
699
- rowCount,
700
- columnCount,
701
- activeCell,
702
- selections,
703
- selectionPolicy,
704
- newSelectionMode,
705
- ]);
706
- /**
707
- * User modified active cell deliberately
708
- */
709
- const handleSetActiveCell = (0, react_1.useCallback)((coords, shouldScroll = true) => {
710
- selectionStart.current = coords;
711
- firstActiveCell.current = coords;
712
- selectionEnd.current = coords;
713
- setActiveCell(coords);
714
- /* Scroll to the cell */
715
- if (shouldScroll && coords && (gridRef === null || gridRef === void 0 ? void 0 : gridRef.current)) {
716
- gridRef.current.scrollToItem(coords);
717
- }
718
- }, []);
719
- const handleFillHandleMouseDown = (0, react_1.useCallback)((e) => {
720
- e.stopPropagation();
721
- isFilling.current = true;
722
- document.addEventListener("mousemove", handleFillHandleMouseMove);
723
- document.addEventListener("mouseup", handleFillHandleMouseUp);
724
- }, [selections]);
725
- /**
726
- * TODO
727
- * 1. Fill does not extend to merged cells
728
- */
729
- const handleFillHandleMouseMove = (0, react_1.useCallback)((e) => {
730
- /* Exit if user is not in selection mode */
731
- if (!isFilling.current || !(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current) || !activeCellRef.current)
732
- return;
733
- const coords = gridRef.current.getCellCoordsFromOffset(e.clientX, e.clientY, false);
734
- if (!coords)
735
- return;
736
- const selections = activeSelectionsRef.current;
737
- let bounds = selectionFromStartEnd(activeCellRef.current, coords);
738
- const hasSelections = selections.length > 0;
739
- const activeCellBounds = hasSelections
740
- ? selections[selections.length - 1].bounds
741
- : gridRef.current.getCellBounds(activeCellRef.current);
742
- if (!bounds)
743
- return;
744
- const direction = bounds.top < activeCellBounds.top
745
- ? types_1.Direction.Up
746
- : bounds.bottom > activeCellBounds.bottom
747
- ? types_1.Direction.Down
748
- : bounds.right > activeCellBounds.right
749
- ? types_1.Direction.Right
750
- : types_1.Direction.Left;
751
- if (direction === types_1.Direction.Right) {
752
- bounds = {
753
- ...activeCellBounds,
754
- right: Math.min(selectionRightBound, bounds.right),
755
- };
756
- }
757
- if (direction === types_1.Direction.Up) {
758
- bounds = {
759
- ...activeCellBounds,
760
- top: Math.max(selectionTopBound, bounds.top),
761
- };
762
- }
763
- if (direction === types_1.Direction.Left) {
764
- bounds = {
765
- ...activeCellBounds,
766
- left: Math.max(selectionLeftBound, bounds.left),
767
- };
768
- }
769
- if (direction === types_1.Direction.Down) {
770
- bounds = {
771
- ...activeCellBounds,
772
- bottom: Math.min(selectionBottomBound, bounds.bottom),
773
- };
774
- }
775
- /**
776
- * If user moves back to the same selection, clear
777
- */
778
- if (hasSelections &&
779
- boundsSubsetOfSelection(bounds, selections[0].bounds)) {
780
- setFillSelection(null);
781
- return;
782
- }
783
- setFillSelection({ bounds });
784
- gridRef.current.scrollToItem(coords);
785
- }, []);
786
- /**
787
- * When user releases mouse on the fill handle
788
- */
789
- const handleFillHandleMouseUp = (0, react_1.useCallback)((e) => {
790
- var _a;
791
- isFilling.current = false;
792
- /* Remove listener */
793
- document.removeEventListener("mousemove", handleFillHandleMouseMove);
794
- document.removeEventListener("mouseup", handleFillHandleMouseUp);
795
- /* Exit early */
796
- if (!gridRef || !activeCellRef.current)
797
- return;
798
- /* Update last selection */
799
- let fillSelection = null;
800
- setFillSelection((prev) => {
801
- fillSelection = prev;
802
- return null;
803
- });
804
- /* Use ref, as we are binding to document */
805
- const selections = activeSelectionsRef.current;
806
- const activeCell = activeCellRef.current;
807
- if (!activeCell || !fillSelection)
808
- return;
809
- const newBounds = fillSelection === null || fillSelection === void 0 ? void 0 : fillSelection.bounds;
810
- if (!newBounds)
811
- return;
812
- /* Focus on the grid */
813
- (_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.focus();
814
- /* Callback */
815
- onFill && onFill(activeCell, fillSelection, selections);
816
- /* Modify last selection */
817
- setSelections((prevSelection) => {
818
- const len = prevSelection.length;
819
- if (!len) {
820
- return [{ bounds: newBounds }];
821
- }
822
- return prevSelection.map((sel, i) => {
823
- if (len - 1 === i) {
824
- return {
825
- ...sel,
826
- bounds: newBounds,
827
- };
828
- }
829
- return sel;
830
- });
831
- });
832
- }, []);
833
- /**
834
- * Remove the last selection from state
835
- */
836
- const handleClearLastSelection = (0, react_1.useCallback)(() => {
837
- setSelections((prev) => prev.slice(0, -1));
838
- }, []);
839
- const fillHandleProps = (0, react_1.useMemo)(() => {
840
- return {
841
- onMouseDown: handleFillHandleMouseDown,
842
- };
843
- }, [handleFillHandleMouseDown]);
844
- /**
845
- * When user mouse downs on selection
846
- */
847
- const handleSelectionMouseDown = (0, react_1.useCallback)((e, activeCell, selection, index, shouldClamp = true) => {
848
- if (!gridRef.current) {
849
- return;
850
- }
851
- let coords = gridRef.current.getCellCoordsFromOffset(e.nativeEvent.clientX, e.nativeEvent.clientY, false // Todo
852
- );
853
- if (!coords) {
854
- return;
855
- }
856
- /* Initial cell that is selected by user */
857
- initialDraggedCell.current = coords;
858
- /* Make sure the coords do not extend selection bounds */
859
- if (shouldClamp) {
860
- coords = (0, helpers_1.clampCellCoords)(coords, activeCell, selection);
861
- }
862
- /* Set selection */
863
- if (activeCell) {
864
- initialDraggedSelection.current = draggedSelection.current = {
865
- bounds: gridRef.current.getCellBounds(activeCell),
866
- };
867
- }
868
- if (selection) {
869
- initialDraggedSelection.current = draggedSelection.current = selection;
870
- draggedSelectionIndex.current = index;
871
- }
872
- /* Set dragging flag */
873
- isDragging.current = true;
874
- /* Listen to mousemove and mousedown events */
875
- document.addEventListener("mouseup", handleSelectionMouseUp);
876
- document.addEventListener("mousemove", handleSelectionMouseMove);
877
- /* Force a re-render */
878
- forceRender();
879
- }, [selectionTopBound, selectionLeftBound, rowCount, columnCount, selections]);
880
- /**
881
- * Ond drag move
882
- */
883
- const handleSelectionMouseMove = (0, react_1.useCallback)((e) => {
884
- var _a;
885
- if (!(gridRef === null || gridRef === void 0 ? void 0 : gridRef.current))
886
- return;
887
- const coords = gridRef.current.getCellCoordsFromOffset(e.clientX, e.clientY);
888
- if (!coords) {
889
- return;
890
- }
891
- if (!initialDraggedSelection.current || !initialDraggedCell.current) {
892
- return;
893
- }
894
- /**
895
- * Skip if user is moving the selection
896
- * to the same starting position
897
- */
898
- if (!hasUserMovedSelection.current &&
899
- (0, helpers_1.isEqualCells)(initialDraggedCell.current, coords)) {
900
- return;
901
- }
902
- let sel = (0, helpers_1.newSelectionFromDrag)(initialDraggedSelection.current, initialDraggedCell.current, coords, selectionTopBound, selectionLeftBound, rowCount, columnCount);
903
- // Not required
904
- // sel = { bounds : extendAreaToMergedCells(sel.bounds, mergedCellsRef.current) }
905
- draggedSelection.current = sel;
906
- // User has now moved the selection,
907
- hasUserMovedSelection.current = true;
908
- /* Scroll to the cell */
909
- (_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.scrollToItem(coords);
910
- /* Re-render */
911
- forceRender();
912
- }, []);
913
- /**
914
- * When drag/drop is complete
915
- */
916
- const handleSelectionMouseUp = (0, react_1.useCallback)(() => {
917
- var _a;
918
- const sel = draggedSelection.current;
919
- if (sel) {
920
- /* Select the first cell in the selection area */
921
- const coords = { rowIndex: sel.bounds.top, columnIndex: sel.bounds.left };
922
- setActiveCell(coords);
923
- /* Update selection start */
924
- selectionStart.current = coords;
925
- if ((0, helpers_1.selectionSpansCells)(sel === null || sel === void 0 ? void 0 : sel.bounds)) {
926
- setSelections((prev) => {
927
- return prev.map((cur, index) => {
928
- if (index === draggedSelectionIndex.current) {
929
- return sel;
930
- }
931
- return cur;
932
- });
933
- });
934
- /* Update selection end */
935
- selectionEnd.current = {
936
- rowIndex: sel.bounds.bottom,
937
- columnIndex: sel.bounds.right,
938
- };
939
- }
940
- }
941
- if (initialDraggedSelection.current && sel) {
942
- onSelectionMove === null || onSelectionMove === void 0 ? void 0 : onSelectionMove(initialDraggedSelection.current, sel);
943
- }
944
- /* Focus on the grid */
945
- (_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.focus();
946
- /* Reset all references */
947
- isDragging.current = false;
948
- draggedSelection.current = void 0;
949
- draggedSelectionIndex.current = void 0;
950
- hasUserMovedSelection.current = false;
951
- /* Remove event handlers */
952
- document.removeEventListener("mouseup", handleSelectionMouseUp);
953
- document.removeEventListener("mousemove", handleSelectionMouseMove);
954
- /* Force render */
955
- forceRender();
956
- }, []);
957
- return {
958
- activeCell,
959
- selections,
960
- isDragging: isDragging.current,
961
- draggedSelection: draggedSelection.current,
962
- initialDraggedSelection: initialDraggedSelection.current,
963
- onSelectionMouseDown: handleSelectionMouseDown,
964
- onMouseDown: handleMouseDown,
965
- onKeyDown: handleKeyDown,
966
- newSelection,
967
- setSelections,
968
- setActiveCell: handleSetActiveCell,
969
- setActiveCellState: setActiveCell,
970
- fillHandleProps,
971
- fillSelection,
972
- clearLastSelection: handleClearLastSelection,
973
- modifySelection,
974
- selectAll,
975
- appendSelection,
976
- clearSelections,
977
- };
978
- };
979
- exports.default = useSelection;
980
- //# sourceMappingURL=useSelection.js.map