@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
@@ -0,0 +1,482 @@
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react";
2
+ import { autoSizerCanvas, castToString, clampIndex, findNextCellWithinBounds, isEqualCells, isNull, } from "../helpers";
3
+ import { Direction, KeyCodes } from "./../types";
4
+ /**
5
+ * Default cell editor
6
+ * @param props
7
+ */
8
+ const DefaultEditor = (props) => {
9
+ const { onChange, onSubmit, onCancel, position, cell, getNextFocusableCell, value = "", activeCell, autoFocus = true, onKeyDown, selections, scrollPosition, maxWidth, maxHeight, isFrozenRow, isFrozenColumn, frozenRowOffset, frozenColumnOffset, isNewValue, ...rest } = props;
10
+ const borderWidth = 2;
11
+ const padding = 10; /* 2 + 1 + 1 + 2 + 2 */
12
+ const inputRef = useRef(null);
13
+ const { x = 0, y = 0, width = 0, height = 0 } = position;
14
+ const getWidth = useCallback((text) => {
15
+ const textWidth = autoSizerCanvas.measureText(text)?.width || 0;
16
+ return Math.max(textWidth + padding, width + borderWidth / 2);
17
+ }, [width]);
18
+ useEffect(() => {
19
+ setInputWidth(getWidth(value));
20
+ }, [value]);
21
+ const [inputWidth, setInputWidth] = useState(() => getWidth(value));
22
+ useEffect(() => {
23
+ if (!inputRef.current)
24
+ return;
25
+ if (autoFocus)
26
+ inputRef.current.focus();
27
+ /* Focus cursor at the end */
28
+ inputRef.current.selectionStart = castToString(value)?.length ?? 0;
29
+ }, []);
30
+ const inputHeight = height;
31
+ return (React.createElement("div", { style: {
32
+ top: y - borderWidth / 2,
33
+ left: x,
34
+ position: "absolute",
35
+ width: inputWidth,
36
+ height: inputHeight + borderWidth,
37
+ padding: borderWidth,
38
+ boxShadow: "0 2px 6px 2px rgba(60,64,67,.15)",
39
+ border: "2px #1a73e8 solid",
40
+ background: "white",
41
+ } },
42
+ React.createElement("textarea", { rows: 1, cols: 1, ref: inputRef, value: value, style: {
43
+ font: "12px Arial",
44
+ lineHeight: 1.2,
45
+ width: "100%",
46
+ height: "100%",
47
+ padding: "0 1px",
48
+ margin: 0,
49
+ boxSizing: "border-box",
50
+ borderWidth: 0,
51
+ outline: "none",
52
+ resize: "none",
53
+ overflow: "hidden",
54
+ verticalAlign: "top",
55
+ background: "transparent",
56
+ }, onChange: (e) => {
57
+ onChange?.(e.target.value, cell);
58
+ }, onKeyDown: (e) => {
59
+ if (!inputRef.current)
60
+ return;
61
+ const isShiftKey = e.nativeEvent.shiftKey;
62
+ const isMetaKey = e.nativeEvent.metaKey;
63
+ const value = inputRef.current.value;
64
+ const isCursorAtEnd = value.length === inputRef.current.selectionEnd;
65
+ const isNewCondition = isNewValue && !isShiftKey && !isMetaKey && isCursorAtEnd;
66
+ // Enter key
67
+ if (e.which === KeyCodes.Enter) {
68
+ onSubmit &&
69
+ onSubmit(value, cell, getNextFocusableCell?.(cell, isShiftKey ? Direction.Up : Direction.Down));
70
+ }
71
+ if (isNewCondition && e.which === KeyCodes.Right) {
72
+ onSubmit &&
73
+ onSubmit(value, cell, getNextFocusableCell?.(cell, Direction.Right));
74
+ }
75
+ if (isNewCondition && e.which === KeyCodes.Left) {
76
+ onSubmit &&
77
+ onSubmit(value, cell, getNextFocusableCell?.(cell, Direction.Left));
78
+ }
79
+ if (isNewCondition && e.which === KeyCodes.Up) {
80
+ onSubmit &&
81
+ onSubmit(value, cell, getNextFocusableCell?.(cell, Direction.Up));
82
+ }
83
+ if (isNewCondition && e.which === KeyCodes.Down) {
84
+ onSubmit &&
85
+ onSubmit(value, cell, getNextFocusableCell?.(cell, Direction.Down));
86
+ }
87
+ if (e.which === KeyCodes.Escape) {
88
+ onCancel && onCancel(e);
89
+ }
90
+ if (e.which === KeyCodes.Tab) {
91
+ e.preventDefault();
92
+ onSubmit &&
93
+ onSubmit(value, cell, getNextFocusableCell?.(cell, isShiftKey ? Direction.Left : Direction.Right));
94
+ }
95
+ onKeyDown?.(e);
96
+ }, ...rest })));
97
+ };
98
+ export const getDefaultEditor = (cell) => DefaultEditor;
99
+ const defaultCanEdit = (cell) => true;
100
+ const defaultIsHidden = (i) => false;
101
+ /**
102
+ * Hook to make grid editable
103
+ * @param param
104
+ *
105
+ * TODO:
106
+ * 1. Edit a cell
107
+ * 2. Tab to next cell
108
+ * 3. Enter a value
109
+ * 4. Press down key
110
+ *
111
+ * Moves to incorrect cell
112
+ */
113
+ const useEditable = ({ getEditor = getDefaultEditor, gridRef, getValue, onChange, onSubmit, onCancel, onDelete, selections = [], activeCell, canEdit = defaultCanEdit, frozenRows = 0, frozenColumns = 0, hideOnBlur = true, isHiddenRow = defaultIsHidden, isHiddenColumn = defaultIsHidden, rowCount, columnCount, selectionTopBound = 0, selectionBottomBound = rowCount - 1, selectionLeftBound = 0, selectionRightBound = columnCount - 1, editorProps, onBeforeEdit, onKeyDown, sticky = false, }) => {
114
+ const [isEditorShown, setShowEditor] = useState(false);
115
+ const [value, setValue] = useState("");
116
+ const [position, setPosition] = useState({
117
+ x: 0,
118
+ y: 0,
119
+ width: 0,
120
+ height: 0,
121
+ });
122
+ const currentActiveCellRef = useRef(null);
123
+ const initialActiveCell = useRef(undefined);
124
+ const [scrollPosition, setScrollPosition] = useState({
125
+ scrollLeft: 0,
126
+ scrollTop: 0,
127
+ });
128
+ const [autoFocus, setAutoFocus] = useState(true);
129
+ const isDirtyRef = useRef(false);
130
+ const isEnteringNewValue = useRef(false);
131
+ const currentValueRef = useRef(value);
132
+ const initialValueRef = useRef(undefined);
133
+ const maxEditorDimensionsRef = useRef(undefined);
134
+ const showEditor = useCallback(() => setShowEditor(true), []);
135
+ const hideEditor = useCallback(() => {
136
+ setShowEditor(false);
137
+ currentActiveCellRef.current = null;
138
+ }, []);
139
+ const focusGrid = useCallback(() => {
140
+ requestAnimationFrame(() => gridRef.current && gridRef.current.focus());
141
+ }, []);
142
+ /* Keep ref in sync */
143
+ useEffect(() => {
144
+ currentValueRef.current = value;
145
+ });
146
+ /**
147
+ * Make a cell editable
148
+ * @param coords
149
+ * @param initialValue
150
+ */
151
+ const makeEditable = useCallback((coords, initialValue, autoFocus = true) => {
152
+ if (!gridRef.current)
153
+ return;
154
+ /* Get actual coords for merged cells */
155
+ coords = gridRef.current.getActualCellCoords(coords);
156
+ /* Check if its the same cell */
157
+ if (isEqualCells(coords, currentActiveCellRef.current)) {
158
+ return;
159
+ }
160
+ /* Call on before edit */
161
+ if (canEdit(coords)) {
162
+ /* Let user modify coords before edit */
163
+ onBeforeEdit?.(coords);
164
+ /* Focus */
165
+ gridRef.current?.scrollToCell(coords);
166
+ currentActiveCellRef.current = coords;
167
+ /* Get offsets */
168
+ const pos = gridRef.current.getCellOffsetFromCoords(coords);
169
+ if (isNull(pos)) {
170
+ return;
171
+ }
172
+ const scrollPosition = gridRef.current.getScrollPosition();
173
+ const cellValue = getValue?.(coords.rowIndex, coords.columnIndex);
174
+ const value = initialValue ?? cellValue ?? "";
175
+ const cellPosition = sticky
176
+ ? // Editor is rendered outside the <Grid /> component
177
+ // If the user has scrolled down, and then activate the editor, we will need to adjust the position
178
+ // of the sticky editor accordingly
179
+ // Subsequent scroll events has no effect, cos of sticky option
180
+ getCellPosition(pos, scrollPosition)
181
+ : pos;
182
+ /**
183
+ * Set max editor ref based on grid container
184
+ */
185
+ const { containerWidth, containerHeight } = gridRef.current.getDimensions();
186
+ maxEditorDimensionsRef.current = {
187
+ height: containerHeight - (cellPosition.y ?? 0),
188
+ width: containerWidth - (cellPosition.x ?? 0),
189
+ };
190
+ /**
191
+ * If the user has entered a value in the cell, mark it as dirty
192
+ * So that during mousedown, onSubmit gets called
193
+ */
194
+ isEnteringNewValue.current =
195
+ initialValue !== void 0 || cellValue === void 0;
196
+ isDirtyRef.current = !!initialValue;
197
+ initialValueRef.current = initialValue ?? value;
198
+ /* Trigger onChange handlers */
199
+ setValue(value);
200
+ onChange?.(value, coords);
201
+ setAutoFocus(autoFocus);
202
+ setScrollPosition(scrollPosition);
203
+ setPosition(cellPosition);
204
+ showEditor();
205
+ }
206
+ }, [frozenRows, frozenColumns, onBeforeEdit, canEdit, sticky, getValue]);
207
+ /* Frozen flags */
208
+ const isFrozenRow = currentActiveCellRef.current &&
209
+ currentActiveCellRef.current?.rowIndex < frozenRows;
210
+ const isFrozenColumn = currentActiveCellRef.current &&
211
+ currentActiveCellRef.current?.columnIndex < frozenColumns;
212
+ /**
213
+ * Get current cell position based on scroll position
214
+ * @param position
215
+ * @param scrollPosition
216
+ */
217
+ const getCellPosition = (position, scrollPosition) => {
218
+ if (!currentActiveCellRef.current)
219
+ return { x: 0, y: 0, width: 0, height: 0 };
220
+ return {
221
+ ...position,
222
+ x: position.x -
223
+ (isFrozenColumn ? 0 : scrollPosition.scrollLeft),
224
+ y: position.y - (isFrozenRow ? 0 : scrollPosition.scrollTop),
225
+ };
226
+ };
227
+ /* Activate edit mode */
228
+ const handleDoubleClick = useCallback((e) => {
229
+ if (!gridRef.current)
230
+ return;
231
+ const coords = gridRef.current.getCellCoordsFromOffset(e.nativeEvent.clientX, e.nativeEvent.clientY);
232
+ if (!coords)
233
+ return;
234
+ const { rowIndex, columnIndex } = coords;
235
+ makeEditable({ rowIndex, columnIndex });
236
+ }, [makeEditable, frozenRows, frozenColumns]);
237
+ const isSelectionKey = useCallback((keyCode) => {
238
+ return ([
239
+ KeyCodes.Right,
240
+ KeyCodes.Left,
241
+ KeyCodes.Up,
242
+ KeyCodes.Down,
243
+ KeyCodes.Meta,
244
+ KeyCodes.Escape,
245
+ KeyCodes.Tab,
246
+ KeyCodes.Home,
247
+ KeyCodes.End,
248
+ KeyCodes.CapsLock,
249
+ KeyCodes.PageDown,
250
+ KeyCodes.PageUp,
251
+ KeyCodes.ScrollLock,
252
+ KeyCodes.NumLock,
253
+ KeyCodes.Insert,
254
+ KeyCodes.Pause,
255
+ ].indexOf(keyCode) !== -1 ||
256
+ // Exclude Function keys
257
+ (keyCode >= KeyCodes.F1 && keyCode <= KeyCodes.F12));
258
+ }, []);
259
+ /**
260
+ * Helper function to keep track of
261
+ * the first cell that the user started editing
262
+ * @param cell
263
+ */
264
+ const setInitialActiveCell = (cell) => {
265
+ initialActiveCell.current = cell;
266
+ };
267
+ const handleKeyDown = useCallback((e) => {
268
+ const keyCode = e.nativeEvent.keyCode;
269
+ const isEnter = keyCode === KeyCodes.Enter;
270
+ if (keyCode === KeyCodes.Tab && !initialActiveCell.current) {
271
+ setInitialActiveCell(activeCell);
272
+ }
273
+ // if (isArrowKey(keyCode)) {
274
+ // setInitialActiveCell(null);
275
+ // }
276
+ if (isSelectionKey(keyCode) ||
277
+ e.nativeEvent.ctrlKey ||
278
+ (e.nativeEvent.shiftKey &&
279
+ (e.nativeEvent.key === "Shift" ||
280
+ e.nativeEvent.which === KeyCodes.SPACE)) ||
281
+ e.nativeEvent.metaKey ||
282
+ e.nativeEvent.which === KeyCodes.ALT)
283
+ return;
284
+ /* If user has not made any selection yet */
285
+ if (!activeCell)
286
+ return;
287
+ const { rowIndex, columnIndex } = activeCell;
288
+ if (keyCode === KeyCodes.Delete || keyCode === KeyCodes.BackSpace) {
289
+ // TODO: onbefore delete
290
+ onDelete && onDelete(activeCell, selections);
291
+ e.preventDefault();
292
+ return;
293
+ }
294
+ const initialValue = isEnter // Enter key
295
+ ? undefined
296
+ : e.nativeEvent.key;
297
+ /* Open the editor */
298
+ makeEditable({ rowIndex, columnIndex }, initialValue);
299
+ /* Prevent the first keystroke */
300
+ e.preventDefault();
301
+ }, [getValue, selections, activeCell, onDelete]);
302
+ /**
303
+ * Get next focusable cell
304
+ * Respects selection bounds
305
+ */
306
+ const getNextFocusableCell = useCallback((currentCell, direction = Direction.Right) => {
307
+ /* Next immediate cell */
308
+ const range = gridRef.current?.getCellBounds(currentCell);
309
+ if (!range)
310
+ return null;
311
+ let nextActiveCell;
312
+ switch (direction) {
313
+ case Direction.Right: {
314
+ const columnIndex = clampIndex(Math.min(range.endColumnIndex + 1, selectionRightBound), isHiddenColumn, direction);
315
+ nextActiveCell = {
316
+ rowIndex: range.startRowIndex,
317
+ columnIndex,
318
+ };
319
+ break;
320
+ }
321
+ case Direction.Up: {
322
+ const rowIndex = clampIndex(Math.max(range.startRowIndex - 1, selectionTopBound), isHiddenRow, direction);
323
+ nextActiveCell = {
324
+ rowIndex,
325
+ columnIndex: range.startColumnIndex,
326
+ };
327
+ break;
328
+ }
329
+ case Direction.Left: {
330
+ const columnIndex = clampIndex(Math.max(range.startColumnIndex - 1, selectionLeftBound), isHiddenColumn, direction);
331
+ nextActiveCell = {
332
+ rowIndex: range.startRowIndex,
333
+ columnIndex,
334
+ };
335
+ break;
336
+ }
337
+ case Direction.Down: {
338
+ // Down
339
+ const rowIndex = clampIndex(Math.min((initialActiveCell.current?.rowIndex ?? range.endRowIndex) + 1, selectionBottomBound), isHiddenRow, direction);
340
+ nextActiveCell = {
341
+ rowIndex,
342
+ columnIndex: initialActiveCell.current?.columnIndex ?? range.startColumnIndex,
343
+ };
344
+ break;
345
+ }
346
+ }
347
+ if (direction === Direction.Right && !initialActiveCell.current) {
348
+ setInitialActiveCell(currentCell);
349
+ }
350
+ if (direction === Direction.Down) {
351
+ /* Move to the next row + cell */
352
+ setInitialActiveCell(null);
353
+ }
354
+ /* If user has selected some cells and active cell is within this selection */
355
+ if (selections.length && currentCell && gridRef.current) {
356
+ const { range } = selections[selections.length - 1];
357
+ const activeCellBounds = gridRef.current.getCellBounds(currentCell);
358
+ const nextCell = findNextCellWithinBounds(activeCellBounds, range, direction);
359
+ if (nextCell)
360
+ nextActiveCell = nextCell;
361
+ }
362
+ return nextActiveCell;
363
+ }, [
364
+ selections,
365
+ isHiddenRow,
366
+ isHiddenColumn,
367
+ selectionBottomBound,
368
+ selectionTopBound,
369
+ ]);
370
+ /* Save the value */
371
+ const handleSubmit = useCallback((value, activeCell, nextActiveCell) => {
372
+ /**
373
+ * Hide the editor first, so that we can handle onBlur events
374
+ * 1. Editor hides -> Submit
375
+ * 2. If user clicks outside the grid, onBlur is called, if there is a activeCell, we do another submit
376
+ */
377
+ hideEditor();
378
+ /* Save the new value */
379
+ onSubmit && onSubmit(value, activeCell, nextActiveCell);
380
+ /* Keep the focus */
381
+ focusGrid();
382
+ }, [onSubmit]);
383
+ /* When the input is blurred out */
384
+ const handleCancel = useCallback((e) => {
385
+ hideEditor();
386
+ onCancel && onCancel(e);
387
+ /* Keep the focus back in the grid */
388
+ focusGrid();
389
+ }, [onCancel]);
390
+ const handleMouseDown = useCallback((e) => {
391
+ /* Persistent input, hides only during Enter key or during submit or cancel calls */
392
+ if (!hideOnBlur) {
393
+ return;
394
+ }
395
+ if (currentActiveCellRef.current) {
396
+ if (isDirtyRef.current) {
397
+ handleSubmit(currentValueRef.current, currentActiveCellRef.current);
398
+ }
399
+ else {
400
+ handleCancel();
401
+ }
402
+ }
403
+ setInitialActiveCell(null);
404
+ }, [hideOnBlur, handleSubmit, handleCancel]);
405
+ const handleChange = useCallback((newValue, activeCell) => {
406
+ /**
407
+ * Make sure we dont call onChange if initialValue is set
408
+ * This is to accomodate for editor that fire onChange during initialvalue
409
+ * Eg: Slate <Editor value='' onChange />
410
+ */
411
+ if (initialValueRef.current !== void 0 &&
412
+ initialValueRef.current === newValue) {
413
+ initialValueRef.current = void 0;
414
+ return;
415
+ }
416
+ if (!currentActiveCellRef.current)
417
+ return;
418
+ /* Check if the value has changed. Used to conditionally submit if editor is not in focus */
419
+ isDirtyRef.current = newValue !== value;
420
+ setValue(newValue);
421
+ onChange?.(newValue, activeCell);
422
+ }, [value]);
423
+ const handleScroll = useCallback((scrollPos) => {
424
+ if (!currentActiveCellRef.current)
425
+ return;
426
+ setScrollPosition(scrollPos);
427
+ }, []);
428
+ /* Editor */
429
+ const editingCell = currentActiveCellRef.current;
430
+ const Editor = useMemo(() => {
431
+ return editingCell
432
+ ? getEditor(editingCell) || getDefaultEditor(editingCell)
433
+ : null;
434
+ }, [editingCell]);
435
+ const handleBlur = useCallback((e) => {
436
+ if (currentActiveCellRef.current) {
437
+ /* Keep the focus */
438
+ focusGrid();
439
+ }
440
+ }, []);
441
+ const finalCellPosition = useMemo(() => {
442
+ /**
443
+ * Since the editor is sticky,
444
+ * we dont need to adjust the position,
445
+ * as scrollposition wont move the editor
446
+ *
447
+ * When the editor is first active, in makeEditable,
448
+ * we accomodate for the initial scrollPosition
449
+ */
450
+ if (sticky) {
451
+ return position;
452
+ }
453
+ /**
454
+ * If editor is not sticky, keep adjusting
455
+ * its position to accomodate for scroll
456
+ */
457
+ return getCellPosition(position, scrollPosition);
458
+ }, [sticky, position, scrollPosition, frozenColumns, frozenRows]);
459
+ /* Get offset of frozen rows and columns */
460
+ const frozenRowOffset = useMemo(() => gridRef.current?.getRowOffset(frozenRows), [frozenRows]);
461
+ const frozenColumnOffset = useMemo(() => gridRef.current?.getColumnOffset(frozenColumns), [frozenColumns]);
462
+ const editorComponent = isEditorShown && Editor ? (React.createElement(Editor, { ...editorProps?.(),
463
+ /* This is the cell that is currently being edited */
464
+ cell: editingCell, activeCell: activeCell, autoFocus: autoFocus, value: value, isNewValue: isEnteringNewValue.current, selections: selections, onChange: handleChange, onSubmit: handleSubmit, onCancel: handleCancel, position: finalCellPosition, scrollPosition: scrollPosition, getNextFocusableCell: getNextFocusableCell, onBlur: handleBlur, onKeyDown: onKeyDown, maxWidth: maxEditorDimensionsRef.current?.width, maxHeight: maxEditorDimensionsRef.current?.height, isFrozenRow: isFrozenRow, isFrozenColumn: isFrozenColumn, frozenRowOffset: frozenRowOffset, frozenColumnOffset: frozenColumnOffset })) : null;
465
+ return {
466
+ editorComponent,
467
+ onDoubleClick: handleDoubleClick,
468
+ onKeyDown: handleKeyDown,
469
+ getNextFocusableCell,
470
+ isEditInProgress: !!editingCell,
471
+ editingCell,
472
+ makeEditable,
473
+ setValue: handleChange,
474
+ hideEditor,
475
+ showEditor,
476
+ submitEditor: handleSubmit,
477
+ cancelEditor: handleCancel,
478
+ onMouseDown: handleMouseDown,
479
+ onScroll: handleScroll,
480
+ };
481
+ };
482
+ export default useEditable;
@@ -0,0 +1,69 @@
1
+ import React from "react";
2
+ import type { AreaStyle, CellInterface, GridRange, GridRef } from "./../Grid";
3
+ export interface FilterView {
4
+ bounds: GridRange;
5
+ filters?: Filter;
6
+ style?: AreaStyle;
7
+ title?: string;
8
+ }
9
+ export type Filter = Record<string, FilterDefinition>;
10
+ export type FilterDefinition<T = string | number> = {
11
+ condition?: FilterConditionDefinition<T>;
12
+ equals?: T[];
13
+ sort?: SortDirection;
14
+ };
15
+ export type FilterOperators = ContainsTextOperators | DataValidationOperator;
16
+ export type FilterConditionDefinition<T = string | number> = {
17
+ operator?: FilterOperators;
18
+ values?: T[];
19
+ };
20
+ export type SortDirection = "asc" | "desc";
21
+ export type DataValidationOperator = "isEmpty" | "notIsEmpty" | "between" | "notBetween" | "equal" | "notEqual" | "greaterThan" | "lessThan" | "greaterThanOrEqual" | "lessThanOrEqual";
22
+ export type ContainsTextOperators = "containsText" | "notContainsText" | "containsBlanks" | "notContainsBlanks" | "containsErrors" | "notContainsErrors" | "startsWithText" | "endsWithText" | "equalText";
23
+ export interface FilterProps {
24
+ /**
25
+ * Returns filter component
26
+ */
27
+ getFilterComponent?: (cell: CellInterface | null) => React.ElementType | null;
28
+ /**
29
+ * Access grid methods
30
+ */
31
+ gridRef: React.MutableRefObject<GridRef | null>;
32
+ /**
33
+ * Get value of a cell
34
+ */
35
+ getValue: (cell: CellInterface) => any;
36
+ /**
37
+ * Width of the filter panel
38
+ */
39
+ width?: number;
40
+ offset?: number;
41
+ frozenRows?: number;
42
+ frozenColumns?: number;
43
+ }
44
+ export interface FilterResults {
45
+ /**
46
+ * Component to render filter
47
+ */
48
+ filterComponent: React.ReactNode;
49
+ /**
50
+ * Enable filter
51
+ */
52
+ showFilter: (cell: CellInterface, index: number, filterView: FilterView, filter?: FilterDefinition) => void;
53
+ /**
54
+ * Hide filter component
55
+ */
56
+ hideFilter: () => void;
57
+ }
58
+ export interface FilterState {
59
+ filterView: FilterView;
60
+ filter?: FilterDefinition;
61
+ index: number;
62
+ }
63
+ /**
64
+ * Use filter hook
65
+ * @param param0
66
+ */
67
+ declare const useFilter: ({ getFilterComponent, gridRef, width, offset, getValue, frozenRows, frozenColumns, }: FilterProps) => FilterResults;
68
+ export default useFilter;
69
+ //# sourceMappingURL=useFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFilter.d.ts","sourceRoot":"","sources":["../../../hooks/useFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAG9D,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EACT,OAAO,EACR,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AACtD,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,IAAI;IAClD,SAAS,CAAC,EAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IACb,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,qBAAqB,GAAG,sBAAsB,CAAC;AAC7E,MAAM,MAAM,yBAAyB,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,IAAI;IAC3D,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;CACd,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAC3C,MAAM,MAAM,sBAAsB,GAC9B,SAAS,GACT,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,OAAO,GACP,UAAU,GACV,aAAa,GACb,UAAU,GACV,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,MAAM,qBAAqB,GAC7B,cAAc,GACd,iBAAiB,GACjB,gBAAgB,GAChB,mBAAmB,GACnB,gBAAgB,GAChB,mBAAmB,GACnB,gBAAgB,GAChB,cAAc,GACd,WAAW,CAAC;AAEhB,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,KAAK,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;IAC9E;;OAEG;IACH,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAChD;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,GAAG,CAAC;IACvC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC;;OAEG;IACH,UAAU,EAAE,CACV,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,UAAU,EACtB,MAAM,CAAC,EAAE,gBAAgB,KACtB,IAAI,CAAC;IACV;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAKD,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,QAAA,MAAM,SAAS,GAAI,sFAQhB,WAAW,KAAG,aA0HhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -1,30 +1,5 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- const react_1 = __importStar(require("react"));
27
- const helpers_1 = require("../helpers");
1
+ import React, { useCallback, useMemo, useState } from "react";
2
+ import { isNull } from "../helpers";
28
3
  /* Default filter component */
29
4
  const getDefaultFilerComponent = (cell) => null;
30
5
  /**
@@ -32,20 +7,22 @@ const getDefaultFilerComponent = (cell) => null;
32
7
  * @param param0
33
8
  */
34
9
  const useFilter = ({ getFilterComponent = getDefaultFilerComponent, gridRef, width = 220, offset = 20, getValue, frozenRows = 0, frozenColumns = 0, }) => {
35
- const [filterCell, setFilterCell] = (0, react_1.useState)(null);
36
- const [isFilterVisible, setIsFilterVisible] = (0, react_1.useState)(false);
37
- const [currentFilter, setCurrentFilter] = (0, react_1.useState)(null);
38
- const [position, setPosition] = (0, react_1.useState)({
10
+ const [filterCell, setFilterCell] = useState(null);
11
+ const [isFilterVisible, setIsFilterVisible] = useState(false);
12
+ const [currentFilter, setCurrentFilter] = useState(null);
13
+ const [position, setPosition] = useState({
39
14
  x: 0,
40
15
  y: 0,
16
+ width: 0,
17
+ height: 0,
41
18
  });
42
- const FilterComponent = (0, react_1.useMemo)(() => {
19
+ const FilterComponent = useMemo(() => {
43
20
  return getFilterComponent(filterCell);
44
21
  }, [filterCell]);
45
22
  /**
46
23
  * Show filter panel
47
24
  */
48
- const handleShowFilter = (0, react_1.useCallback)((coords, index, filterView, filter) => {
25
+ const handleShowFilter = useCallback((coords, index, filterView, filter) => {
49
26
  if (!gridRef.current)
50
27
  return;
51
28
  /* Get actual coords for merged cells */
@@ -57,12 +34,16 @@ const useFilter = ({ getFilterComponent = getDefaultFilerComponent, gridRef, wid
57
34
  /* Check if its frozen */
58
35
  const isFrozenColumn = coords.columnIndex < frozenColumns;
59
36
  const isFrozenRow = coords.rowIndex < frozenRows;
37
+ if (isNull(pos)) {
38
+ return;
39
+ }
60
40
  /* Set cell position */
61
- setPosition(() => {
41
+ setPosition((prev) => {
62
42
  const left = pos.x;
63
43
  const top = pos.y;
64
44
  const cellWidth = pos.width;
65
45
  return {
46
+ ...prev,
66
47
  x: left +
67
48
  cellWidth -
68
49
  (isFrozenColumn ? 0 : scrollPosition.scrollLeft) <
@@ -85,33 +66,32 @@ const useFilter = ({ getFilterComponent = getDefaultFilerComponent, gridRef, wid
85
66
  /* Show filter */
86
67
  showFilter();
87
68
  }, [frozenRows, frozenColumns]);
88
- const hideFilter = (0, react_1.useCallback)(() => {
69
+ const hideFilter = useCallback(() => {
89
70
  setIsFilterVisible(false);
90
71
  }, []);
91
- const showFilter = (0, react_1.useCallback)(() => {
72
+ const showFilter = useCallback(() => {
92
73
  setIsFilterVisible(true);
93
74
  }, []);
94
- const values = (0, react_1.useMemo)(() => {
75
+ const values = useMemo(() => {
95
76
  if (!filterCell || !currentFilter)
96
77
  return [];
97
78
  const { filterView } = currentFilter;
98
79
  const { columnIndex } = filterCell;
99
80
  const { bounds } = filterView;
100
81
  const filterValues = new Set();
101
- for (let i = bounds.top + 1; i <= bounds.bottom; i++) {
82
+ for (let i = bounds.startRowIndex + 1; i <= bounds.endRowIndex; i++) {
102
83
  const cell = { rowIndex: i, columnIndex };
103
84
  const text = getValue(cell);
104
- const value = (0, helpers_1.isNull)(text) ? "" : text;
85
+ const value = isNull(text) ? "" : text;
105
86
  filterValues.add(value);
106
87
  }
107
88
  return Array.from(filterValues);
108
89
  }, [filterCell, currentFilter]);
109
- const filterComponent = isFilterVisible && FilterComponent ? (react_1.default.createElement(FilterComponent, { position: position, width: width, values: values, index: currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.index, filterView: currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filterView, filter: currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filter, columnIndex: filterCell === null || filterCell === void 0 ? void 0 : filterCell.columnIndex, rowIndex: filterCell === null || filterCell === void 0 ? void 0 : filterCell.rowIndex, onRequestClose: hideFilter, onRequestShow: handleShowFilter })) : null;
90
+ const filterComponent = isFilterVisible && FilterComponent ? (React.createElement(FilterComponent, { position: position, width: width, values: values, index: currentFilter?.index, filterView: currentFilter?.filterView, filter: currentFilter?.filter, columnIndex: filterCell?.columnIndex, rowIndex: filterCell?.rowIndex, onRequestClose: hideFilter, onRequestShow: handleShowFilter })) : null;
110
91
  return {
111
92
  filterComponent,
112
93
  showFilter: handleShowFilter,
113
94
  hideFilter,
114
95
  };
115
96
  };
116
- exports.default = useFilter;
117
- //# sourceMappingURL=useFilter.js.map
97
+ export default useFilter;