@rowsncolumns/grid 9.0.4 → 13.2.33

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 -982
  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 -1440
  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,312 +0,0 @@
1
- import React, { useCallback, useState, useRef, useEffect } from "react";
2
- import { ViewPortProps, GridRef, CellInterface, ItemSizer } from "./../Grid";
3
- import {
4
- debounce,
5
- HiddenType,
6
- isNull,
7
- autoSizerCanvas,
8
- castToString,
9
- cellIdentifier,
10
- } from "./../helpers";
11
- import invariant from "tiny-invariant";
12
-
13
- export interface IProps {
14
- /**
15
- * Used to access grid functions
16
- */
17
- gridRef: React.MutableRefObject<GridRef | null>;
18
- /**
19
- * Value getter for a cell
20
- */
21
- getValue: (cell: CellInterface) => any;
22
- /**
23
- * Visible rows when the grid is first visible, Since we do not know how many rows can fit
24
- */
25
- initialVisibleRows?: number;
26
- /**
27
- * Restrict column width by this number
28
- */
29
- minColumnWidth?: number;
30
- /**
31
- * Cell padding, used for width calculation
32
- */
33
- cellSpacing?: number;
34
- /**
35
- * Scroll timeout
36
- */
37
- timeout?: number;
38
- /**
39
- * Calculate width and resize the grid on scroll
40
- */
41
- resizeOnScroll?: boolean;
42
- /**
43
- * Font used to calculate width
44
- */
45
- fontFamily?: string;
46
- fontSize?: number;
47
- fontWeight?: string;
48
- fontStyle?: string;
49
- /**
50
- * Strategy used to calculate column width
51
- * lazy = visible rows
52
- * full = all rows
53
- *
54
- * columns are always lazy
55
- */
56
- resizeStrategy?: ResizeStrategy;
57
- /**
58
- * No of rows in teh grid
59
- */
60
- rowCount?: number;
61
- /**
62
- * Enable autoresize
63
- */
64
- autoResize?: boolean;
65
- /**
66
- * Map of index to size
67
- */
68
- columnSizes?: SizeType;
69
- /**
70
- * Hidden rows
71
- */
72
- isHiddenRow: HiddenType;
73
- /**
74
- * Hidden columns
75
- */
76
- isHiddenColumn: HiddenType;
77
- /**
78
- * Number of frozen rows
79
- */
80
- frozenRows?: number;
81
- /**
82
- * Current scaling factor
83
- */
84
- scale?: number;
85
- /**
86
- * Get text value
87
- */
88
- getText: (config: any) => string | undefined;
89
- }
90
-
91
- export type ResizeStrategy = "lazy" | "full";
92
-
93
- export interface AutoResizerResults {
94
- /**
95
- * Column width function consumed by the grid
96
- */
97
- columnWidth?: ItemSizer;
98
- /**
99
- * Callback when viewport is changed
100
- */
101
- onViewChange: (cells: ViewPortProps) => void;
102
- /**
103
- * Get column width based on resize strategy
104
- */
105
- getColumnWidth: (columnIndex: number, scale?: number) => number;
106
- /**
107
- * Text size getter
108
- */
109
- getTextMetrics: (text: string | number) => TextDimensions;
110
- }
111
-
112
- export interface TextDimensions {
113
- width: number;
114
- height: number;
115
- }
116
-
117
- export type SizeType = {
118
- [key: number]: number;
119
- };
120
-
121
- const defaultGetText = (text: any) => text;
122
-
123
- /**
124
- * Auto sizer hook
125
- * @param param
126
- *
127
- * TODO
128
- * Dynamically resize columns after user has scrolled down/view port changed ?
129
- */
130
- const useAutoSizer = ({
131
- gridRef,
132
- getValue,
133
- initialVisibleRows = 20,
134
- cellSpacing = 10,
135
- minColumnWidth = 60,
136
- timeout = 300,
137
- resizeStrategy = "lazy",
138
- rowCount,
139
- resizeOnScroll = true,
140
- fontFamily = "Arial",
141
- fontSize = 12,
142
- fontWeight = "",
143
- fontStyle = "",
144
- autoResize = true,
145
- columnSizes = {},
146
- frozenRows = 0,
147
- scale = 1,
148
- isHiddenRow,
149
- isHiddenColumn,
150
- getText = defaultGetText,
151
- }: IProps): AutoResizerResults => {
152
- invariant(
153
- !(resizeStrategy === "full" && rowCount === void 0),
154
- "Row count should be specified if resize stragtegy is full"
155
- );
156
-
157
- const autoSizer = useRef(autoSizerCanvas);
158
- const [viewport, setViewport] = useState<ViewPortProps>({
159
- rowStartIndex: 0,
160
- rowStopIndex: 0,
161
- columnStartIndex: 0,
162
- columnStopIndex: 0,
163
- visibleRowStartIndex: 0,
164
- visibleRowStopIndex: 0,
165
- visibleColumnStartIndex: 0,
166
- visibleColumnStopIndex: 0,
167
- });
168
- const isMounted = useRef(false);
169
- const getValueRef = useRef<typeof getValue>();
170
- const viewPortRef = useRef<typeof viewport>();
171
- const hiddenRowRef = useRef<typeof isHiddenRow>(isHiddenRow);
172
- const handleResize = useCallback(
173
- ({ rowIndex, columnIndex }: CellInterface) => {
174
- gridRef.current &&
175
- gridRef.current.resetAfterIndices({ rowIndex, columnIndex });
176
- },
177
- []
178
- );
179
- const debounceResizer = useRef<any>(null);
180
-
181
- useEffect(() => {
182
- getValueRef.current = getValue;
183
- viewPortRef.current = viewport;
184
- hiddenRowRef.current = isHiddenRow;
185
- });
186
-
187
- useEffect(() => {
188
- isMounted.current = true;
189
- debounceResizer.current = debounce(handleResize, timeout);
190
- }, []);
191
-
192
- /* Update any styles, fonts if necessary */
193
- useEffect(() => {
194
- autoSizer.current.setFont({ fontFamily, fontSize, fontWeight, fontStyle });
195
- }, [fontFamily, fontSize, fontWeight, fontStyle]);
196
-
197
- const getTextMetrics = useCallback((text: string | number) => {
198
- return autoSizer.current.measureText(castToString(text) as string);
199
- }, []);
200
-
201
- /**
202
- * Get width of a single cell
203
- */
204
- const getCellWidth = useCallback(
205
- (rowIndex: number, columnIndex: number) => {
206
- const cellValue =
207
- getValueRef.current?.({
208
- rowIndex,
209
- columnIndex,
210
- }) ?? null;
211
- let width = cellValue?.spacing ?? 0;
212
- /* Check if its null */
213
- if (cellValue !== null) {
214
- const isCellConfig = typeof cellValue === "object";
215
- const text = getText(cellValue);
216
- if (cellIdentifier !== void 0 && !isNull(text) && text !== void 0) {
217
- /* Reset fonts */
218
- autoSizer.current.reset();
219
-
220
- if (isCellConfig) {
221
- const isBold = cellValue.bold;
222
- autoSizer.current.setFont({
223
- fontWeight: isBold ? "bold" : "",
224
- fontSize: (cellValue.fontSize || fontSize) * scale,
225
- fontFamily: cellValue.fontFamily,
226
- fontStyle: cellValue.italic ? "italic" : "",
227
- });
228
- }
229
- const metrics = autoSizer.current.measureText(text);
230
- if (metrics) {
231
- width += Math.ceil(metrics.width) + cellSpacing;
232
- }
233
- }
234
- }
235
- return width;
236
- },
237
- [scale]
238
- );
239
-
240
- /**
241
- * Calculate column width
242
- */
243
- const getColumnWidth = useCallback(
244
- (columnIndex: number) => {
245
- const { rowStartIndex = 0, rowStopIndex = 0 } = viewPortRef.current ?? {};
246
- const visibleRows =
247
- resizeStrategy === "full"
248
- ? (rowCount as number)
249
- : rowStopIndex || initialVisibleRows;
250
- let start = resizeStrategy === "full" ? 0 : rowStartIndex;
251
- let maxWidth = minColumnWidth;
252
-
253
- /* Calculate for frozen rows */
254
- for (let i = 0; i < frozenRows; i++) {
255
- if (hiddenRowRef.current?.(i)) {
256
- continue;
257
- }
258
- const width = getCellWidth(i, columnIndex);
259
- if (width > maxWidth) maxWidth = width;
260
- }
261
-
262
- /* Loop through all visible rows */
263
- while (start < visibleRows) {
264
- if (hiddenRowRef.current?.(start)) {
265
- start++;
266
- continue;
267
- }
268
- const width = getCellWidth(start, columnIndex);
269
- if (width > maxWidth) maxWidth = width;
270
- start++;
271
- }
272
-
273
- return maxWidth / scale;
274
- },
275
- [viewport, initialVisibleRows, frozenRows, scale]
276
- );
277
-
278
- const handleViewChange = useCallback(
279
- (cells: ViewPortProps) => {
280
- /* Update viewport cells */
281
- setViewport(cells);
282
-
283
- /* Check if viewport has changed */
284
- if (
285
- resizeStrategy === "full" ||
286
- !resizeOnScroll ||
287
- (cells.rowStartIndex === viewport.rowStartIndex &&
288
- cells.columnStartIndex === viewport.columnStartIndex)
289
- )
290
- return;
291
- if (gridRef.current) {
292
- /* During first mount, column width is calculated. Do not re-calculate */
293
- if (!isMounted.current) return;
294
- debounceResizer.current({
295
- rowIndex: cells.rowStartIndex,
296
- columnIndex: cells.columnStartIndex,
297
- });
298
- }
299
- },
300
- [resizeOnScroll, viewport, resizeStrategy]
301
- );
302
-
303
- return {
304
- ...(autoResize ? { columnWidth: getColumnWidth } : undefined),
305
- getColumnWidth,
306
- // getRowHeight,
307
- onViewChange: handleViewChange,
308
- getTextMetrics,
309
- };
310
- };
311
-
312
- export default useAutoSizer;
@@ -1,172 +0,0 @@
1
- import React, {
2
- useCallback,
3
- useState,
4
- useMemo,
5
- useRef,
6
- useEffect,
7
- } from "react";
8
- import { CellInterface, GridRef } from "../Grid";
9
- import { debounce, throttle } from "../helpers";
10
-
11
- export interface TooltipOptions {
12
- /**
13
- * Tooltip component
14
- */
15
- getTooltip?: (cell: CellInterface | null) => React.ElementType | null;
16
- /**
17
- * Grid references
18
- */
19
- gridRef: React.MutableRefObject<GridRef | null>;
20
- }
21
-
22
- export interface TooltipResults {
23
- /**
24
- * Tooltip component to inject into the page
25
- */
26
- tooltipComponent: React.ReactElement | null;
27
- /**
28
- * Mousemove listener to align tooltip
29
- */
30
- onMouseMove: ((e: React.MouseEvent<HTMLElement>) => void) | undefined;
31
- /**
32
- * Mouse leave listener to hide tooltip
33
- */
34
- onMouseLeave: ((e: React.MouseEvent<HTMLElement>) => void) | undefined;
35
- }
36
-
37
- export interface DefaultTooltipProps {
38
- /**
39
- * Tooltip x position
40
- */
41
- x?: number;
42
- /**
43
- * Tooltip y position
44
- */
45
- y?: number;
46
- width?: number;
47
- height?: number;
48
- scrollLeft?: number;
49
- scrollTop?: number;
50
- }
51
-
52
- const DefaultTooltipComponent: React.FC<DefaultTooltipProps> = ({
53
- x = 0,
54
- y = 0,
55
- scrollLeft = 0,
56
- scrollTop = 0,
57
- width = 0,
58
- height = 0,
59
- }) => {
60
- const posX = x + width - scrollLeft;
61
- const posY = y - scrollTop;
62
- return (
63
- <div
64
- style={{
65
- position: "absolute",
66
- left: 0,
67
- top: 0,
68
- transform: `translate(${posX}px, ${posY}px)`,
69
- maxWidth: 200,
70
- minWidth: 160,
71
- background: "white",
72
- boxShadow: "0 4px 8px 3px rgba(60,64,67,.15)",
73
- padding: 12,
74
- borderRadius: 4,
75
- fontSize: 13,
76
- }}
77
- >
78
- {x}
79
- </div>
80
- );
81
- };
82
-
83
- const getDefaultTooltip = () => DefaultTooltipComponent;
84
-
85
- const useTooltip = ({
86
- gridRef,
87
- getTooltip = getDefaultTooltip,
88
- }: TooltipOptions): TooltipResults => {
89
- const [activeCell, setActiveCell] = useState<CellInterface | null>(null);
90
- const isTooltipActive = useRef(false);
91
- const activeCellRef = useRef(activeCell);
92
- const [tooltipPosition, setTooltipPosition] = useState<
93
- Pick<
94
- DefaultTooltipProps,
95
- "x" | "y" | "width" | "height" | "scrollLeft" | "scrollTop"
96
- >
97
- >({});
98
- const showTooltip = !!activeCell;
99
- const TooltipComponent = useMemo(() => {
100
- return getTooltip(activeCell);
101
- }, [activeCell, getTooltip]);
102
-
103
- const handleTooltipMouseEnter = useCallback(() => {
104
- isTooltipActive.current = true;
105
- }, []);
106
- const handleTooltipMouseLeave = useCallback(() => {
107
- isTooltipActive.current = false;
108
- setActiveCell(null);
109
- }, []);
110
-
111
- const tooltipComponent =
112
- showTooltip && TooltipComponent ? (
113
- <TooltipComponent
114
- {...tooltipPosition}
115
- onMouseEnter={handleTooltipMouseEnter}
116
- onMouseLeave={handleTooltipMouseLeave}
117
- />
118
- ) : null;
119
-
120
- const handleMouseMove = useCallback((e: React.MouseEvent<HTMLElement>) => {
121
- if (!gridRef.current) return;
122
- const coords = gridRef.current.getCellCoordsFromOffset(
123
- e.clientX,
124
- e.clientY
125
- );
126
-
127
- if (!coords) return;
128
- const { rowIndex, columnIndex } = coords;
129
- /* Exit if its the same cell */
130
- if (
131
- activeCellRef.current &&
132
- activeCellRef.current.rowIndex === rowIndex &&
133
- activeCellRef.current.columnIndex === columnIndex
134
- )
135
- return;
136
-
137
- const pos = gridRef.current.getCellOffsetFromCoords(coords);
138
- const scrollPosition = gridRef.current.getScrollPosition();
139
- setTooltipPosition({
140
- ...pos,
141
- ...scrollPosition,
142
- });
143
- setActiveCell({ rowIndex, columnIndex });
144
- }, []);
145
-
146
- const handleMouseLeave = useCallback(() => {
147
- if (isTooltipActive.current) return;
148
- setActiveCell(null);
149
- }, []);
150
-
151
- /* Raf throttler */
152
- const mouseMoveThrottler =
153
- useRef<(e: React.MouseEvent<HTMLElement>) => void>();
154
- const mouseLeaveThrottler = useRef<() => void>();
155
- useEffect(() => {
156
- mouseMoveThrottler.current = throttle(handleMouseMove, 100);
157
- mouseLeaveThrottler.current = debounce(handleMouseLeave, 2000);
158
- }, []);
159
-
160
- /* Update activecell ref */
161
- useEffect(() => {
162
- activeCellRef.current = activeCell;
163
- }, [activeCell]);
164
-
165
- return {
166
- tooltipComponent,
167
- onMouseMove: mouseMoveThrottler.current,
168
- onMouseLeave: mouseLeaveThrottler.current,
169
- };
170
- };
171
-
172
- export default useTooltip;
@@ -1,116 +0,0 @@
1
- import React, { useCallback, useEffect, useRef } from "react";
2
- import { GridRef, ScrollCoords } from "../Grid";
3
- // @ts-ignore
4
- import { Scroller } from "scroller";
5
- import { canUseDOM } from "../helpers";
6
-
7
- export interface TouchProps {
8
- /**
9
- * Grid reference to access grid methods
10
- */
11
- gridRef: React.MutableRefObject<GridRef | null>;
12
- }
13
-
14
- export interface TouchResults {
15
- isTouchDevice: boolean;
16
- scrollTo: (scrollState: ScrollCoords) => void;
17
- scrollToTop: () => void;
18
- }
19
-
20
- /**
21
- * Enable touch interactions
22
- * Supports
23
- * 1. Scrolling
24
- * 2. Cell selection
25
- */
26
- const useTouch = ({ gridRef }: TouchProps): TouchResults => {
27
- const scrollerRef = useRef<typeof Scroller | null>(null);
28
- const isTouchDevice = useRef<boolean>(false);
29
- useEffect(() => {
30
- isTouchDevice.current = canUseDOM && "ontouchstart" in window;
31
- /* Update dimension */
32
- if (isTouchDevice.current) {
33
- const options = {
34
- scrollingX: true,
35
- scrollingY: true,
36
- decelerationRate: 0.95,
37
- penetrationAcceleration: 0.08,
38
- };
39
-
40
- /* Add listeners */
41
- gridRef.current?.container?.addEventListener(
42
- "touchstart",
43
- handleTouchStart
44
- );
45
- gridRef.current?.container?.addEventListener("touchend", handleTouchEnd);
46
- gridRef.current?.container?.addEventListener(
47
- "touchmove",
48
- handleTouchMove
49
- );
50
-
51
- /* Add scroller */
52
- scrollerRef.current = new Scroller(handleTouchScroll, options);
53
-
54
- const dims = gridRef.current?.getDimensions();
55
- /* Update dimensions */
56
- if (dims) updateScrollDimensions(dims);
57
- }
58
- }, []);
59
-
60
- /* Scroll to x, y coordinate */
61
- const scrollTo = useCallback(({ scrollLeft, scrollTop }: ScrollCoords) => {
62
- if (scrollerRef.current)
63
- scrollerRef.current.scrollTo(scrollLeft, scrollTop);
64
- }, []);
65
- /* Scrolls to top if mobile */
66
- const scrollToTop = useCallback(() => {
67
- if (scrollerRef.current) scrollerRef.current.scrollTo(0, 0);
68
- }, []);
69
-
70
- const updateScrollDimensions = useCallback(
71
- ({
72
- containerWidth,
73
- containerHeight,
74
- estimatedTotalWidth,
75
- estimatedTotalHeight,
76
- }: {
77
- containerWidth: number;
78
- containerHeight: number;
79
- estimatedTotalWidth: number;
80
- estimatedTotalHeight: number;
81
- }) => {
82
- scrollerRef.current.setDimensions(
83
- containerWidth,
84
- containerHeight,
85
- estimatedTotalWidth,
86
- estimatedTotalHeight
87
- );
88
- },
89
- []
90
- );
91
-
92
- const handleTouchScroll = useCallback(
93
- (scrollLeft: number, scrollTop: number) => {
94
- gridRef.current?.scrollTo({ scrollTop, scrollLeft });
95
- },
96
- []
97
- );
98
- const handleTouchStart = useCallback((e: globalThis.TouchEvent) => {
99
- scrollerRef.current.doTouchStart(e.touches, e.timeStamp);
100
- }, []);
101
- const handleTouchMove = useCallback((e: globalThis.TouchEvent) => {
102
- e.preventDefault();
103
- scrollerRef.current.doTouchMove(e.touches, e.timeStamp);
104
- }, []);
105
- const handleTouchEnd = useCallback((e: globalThis.TouchEvent) => {
106
- scrollerRef.current.doTouchEnd(e.timeStamp);
107
- }, []);
108
-
109
- return {
110
- isTouchDevice: isTouchDevice.current,
111
- scrollTo,
112
- scrollToTop,
113
- };
114
- };
115
-
116
- export default useTouch;