@koine/react 2.0.0-beta.73 → 2.0.0-beta.75

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 (63) hide show
  1. package/FaviconTags.d.ts +9 -0
  2. package/FaviconTags.js +5 -0
  3. package/Meta.d.ts +5 -0
  4. package/Meta.js +5 -0
  5. package/NoJs.d.ts +3 -0
  6. package/NoJs.js +7 -0
  7. package/Polymorphic.d.ts +26 -0
  8. package/Polymorphic.js +1 -0
  9. package/classed.d.ts +8 -0
  10. package/classed.js +41 -0
  11. package/createUseMediaQueryWidth.d.ts +6 -0
  12. package/createUseMediaQueryWidth.js +38 -0
  13. package/extendComponent.d.ts +16 -0
  14. package/extendComponent.js +9 -0
  15. package/index.cjs.js +33 -23
  16. package/index.d.ts +28 -3
  17. package/index.esm.js +33 -26
  18. package/index.js +26 -3
  19. package/mergeRefs.d.ts +2 -0
  20. package/mergeRefs.js +13 -0
  21. package/package.json +245 -5
  22. package/useAsyncFn.d.ts +24 -0
  23. package/useAsyncFn.js +26 -0
  24. package/useFirstMountState.d.ts +2 -0
  25. package/useFirstMountState.js +10 -0
  26. package/useFixedOffset.d.ts +2 -0
  27. package/useFixedOffset.js +42 -0
  28. package/useFocus.d.ts +2 -0
  29. package/useFocus.js +9 -0
  30. package/useInterval.d.ts +2 -0
  31. package/useInterval.js +20 -0
  32. package/useIsomorphicLayoutEffect.d.ts +3 -0
  33. package/useIsomorphicLayoutEffect.js +4 -0
  34. package/useKeyUp.d.ts +2 -0
  35. package/useKeyUp.js +16 -0
  36. package/useMeasure.d.ts +22 -0
  37. package/useMeasure.js +119 -0
  38. package/useMountedState.d.ts +2 -0
  39. package/useMountedState.js +13 -0
  40. package/useNavigateAway.d.ts +3 -0
  41. package/useNavigateAway.js +25 -0
  42. package/usePrevious.d.ts +2 -0
  43. package/usePrevious.js +9 -0
  44. package/usePreviousRef.d.ts +2 -0
  45. package/usePreviousRef.js +9 -0
  46. package/useReveal.d.ts +13 -0
  47. package/useReveal.js +42 -0
  48. package/useScrollPosition.d.ts +7 -0
  49. package/useScrollPosition.js +58 -0
  50. package/useScrollThreshold.d.ts +2 -0
  51. package/useScrollThreshold.js +26 -0
  52. package/useScrollTo.d.ts +2 -0
  53. package/useScrollTo.js +18 -0
  54. package/useSmoothScroll.d.ts +2 -0
  55. package/useSmoothScroll.js +32 -0
  56. package/useSpinDelay.d.ts +2 -0
  57. package/useSpinDelay.js +36 -0
  58. package/useTraceUpdate.d.ts +2 -0
  59. package/useTraceUpdate.js +17 -0
  60. package/useUpdateEffect.d.ts +3 -0
  61. package/useUpdateEffect.js +11 -0
  62. package/useWindowSize.d.ts +3 -0
  63. package/useWindowSize.js +20 -0
package/package.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "name": "@koine/react",
3
3
  "sideEffects": false,
4
4
  "dependencies": {
5
- "@koine/dom": "2.0.0-beta.73",
6
- "@koine/utils": "2.0.0-beta.73"
5
+ "@koine/dom": "2.0.0-beta.75",
6
+ "@koine/utils": "2.0.0-beta.75"
7
7
  },
8
8
  "peerDependencies": {
9
9
  "@kuus/yup": "1.0.0-beta.7",
@@ -26,24 +26,264 @@
26
26
  }
27
27
  },
28
28
  "exports": {
29
- "./package.json": "./package.json",
30
29
  ".": {
31
30
  "module": "./index.esm.js",
32
31
  "import": "./index.cjs.mjs",
33
32
  "default": "./index.cjs.js"
34
33
  },
34
+ "./FaviconTags": {
35
+ "import": "./FaviconTags.js"
36
+ },
37
+ "./Meta": {
38
+ "import": "./Meta.js"
39
+ },
40
+ "./NoJs": {
41
+ "import": "./NoJs.js"
42
+ },
43
+ "./Polymorphic": {
44
+ "import": "./Polymorphic.js"
45
+ },
46
+ "./calendar.cjs.default": {
47
+ "import": "./calendar.cjs.default.js"
48
+ },
49
+ "./calendar.cjs": {
50
+ "import": "./calendar.cjs.js"
51
+ },
52
+ "./calendar.esm": {
53
+ "import": "./calendar.esm.js"
54
+ },
35
55
  "./calendar": {
36
56
  "module": "./calendar.esm.js",
37
57
  "import": "./calendar.cjs.mjs",
38
58
  "default": "./calendar.cjs.js"
39
59
  },
60
+ "./calendar/CalendarDaygridCell": {
61
+ "import": "./calendar/CalendarDaygridCell.js"
62
+ },
63
+ "./calendar/CalendarDaygridNav": {
64
+ "import": "./calendar/CalendarDaygridNav.js"
65
+ },
66
+ "./calendar/CalendarDaygridTable": {
67
+ "import": "./calendar/CalendarDaygridTable.js"
68
+ },
69
+ "./calendar/CalendarLegend": {
70
+ "import": "./calendar/CalendarLegend.js"
71
+ },
72
+ "./calendar/calendar-api-google": {
73
+ "import": "./calendar/calendar-api-google.js"
74
+ },
75
+ "./calendar/types": {
76
+ "import": "./calendar/types.js"
77
+ },
78
+ "./calendar/useCalendar": {
79
+ "import": "./calendar/useCalendar.js"
80
+ },
81
+ "./calendar/useDateLocale": {
82
+ "import": "./calendar/useDateLocale.js"
83
+ },
84
+ "./calendar/utils": {
85
+ "import": "./calendar/utils.js"
86
+ },
87
+ "./classed": {
88
+ "import": "./classed.js"
89
+ },
90
+ "./components/FaviconTags": {
91
+ "import": "./components/FaviconTags.js"
92
+ },
93
+ "./components/Meta": {
94
+ "import": "./components/Meta.js"
95
+ },
96
+ "./components/NoJs": {
97
+ "import": "./components/NoJs.js"
98
+ },
99
+ "./createUseMediaQueryWidth": {
100
+ "import": "./createUseMediaQueryWidth.js"
101
+ },
102
+ "./extendComponent": {
103
+ "import": "./extendComponent.js"
104
+ },
105
+ "./forms.cjs.default": {
106
+ "import": "./forms.cjs.default.js"
107
+ },
108
+ "./forms.cjs": {
109
+ "import": "./forms.cjs.js"
110
+ },
111
+ "./forms.esm": {
112
+ "import": "./forms.esm.js"
113
+ },
40
114
  "./forms": {
41
115
  "module": "./forms.esm.js",
42
116
  "import": "./forms.cjs.mjs",
43
117
  "default": "./forms.cjs.js"
44
- }
118
+ },
119
+ "./forms/antispam": {
120
+ "import": "./forms/antispam.js"
121
+ },
122
+ "./hooks": {
123
+ "import": "./hooks/index.js"
124
+ },
125
+ "./hooks/useAsyncFn": {
126
+ "import": "./hooks/useAsyncFn.js"
127
+ },
128
+ "./hooks/useFirstMountState": {
129
+ "import": "./hooks/useFirstMountState.js"
130
+ },
131
+ "./hooks/useFixedOffset": {
132
+ "import": "./hooks/useFixedOffset.js"
133
+ },
134
+ "./hooks/useFocus": {
135
+ "import": "./hooks/useFocus.js"
136
+ },
137
+ "./hooks/useInterval": {
138
+ "import": "./hooks/useInterval.js"
139
+ },
140
+ "./hooks/useIsomorphicLayoutEffect": {
141
+ "import": "./hooks/useIsomorphicLayoutEffect.js"
142
+ },
143
+ "./hooks/useKeyUp": {
144
+ "import": "./hooks/useKeyUp.js"
145
+ },
146
+ "./hooks/useMeasure": {
147
+ "import": "./hooks/useMeasure.js"
148
+ },
149
+ "./hooks/useMountedState": {
150
+ "import": "./hooks/useMountedState.js"
151
+ },
152
+ "./hooks/useNavigateAway": {
153
+ "import": "./hooks/useNavigateAway.js"
154
+ },
155
+ "./hooks/usePrevious": {
156
+ "import": "./hooks/usePrevious.js"
157
+ },
158
+ "./hooks/usePreviousRef": {
159
+ "import": "./hooks/usePreviousRef.js"
160
+ },
161
+ "./hooks/useReveal": {
162
+ "import": "./hooks/useReveal.js"
163
+ },
164
+ "./hooks/useScrollPosition": {
165
+ "import": "./hooks/useScrollPosition.js"
166
+ },
167
+ "./hooks/useScrollThreshold": {
168
+ "import": "./hooks/useScrollThreshold.js"
169
+ },
170
+ "./hooks/useScrollTo": {
171
+ "import": "./hooks/useScrollTo.js"
172
+ },
173
+ "./hooks/useSmoothScroll": {
174
+ "import": "./hooks/useSmoothScroll.js"
175
+ },
176
+ "./hooks/useSpinDelay": {
177
+ "import": "./hooks/useSpinDelay.js"
178
+ },
179
+ "./hooks/useTraceUpdate": {
180
+ "import": "./hooks/useTraceUpdate.js"
181
+ },
182
+ "./hooks/useUpdateEffect": {
183
+ "import": "./hooks/useUpdateEffect.js"
184
+ },
185
+ "./hooks/useWindowSize": {
186
+ "import": "./hooks/useWindowSize.js"
187
+ },
188
+ "./index.cjs.default": {
189
+ "import": "./index.cjs.default.js"
190
+ },
191
+ "./index.cjs": {
192
+ "import": "./index.cjs.js"
193
+ },
194
+ "./index.esm": {
195
+ "import": "./index.esm.js"
196
+ },
197
+ "./mergeRefs": {
198
+ "import": "./mergeRefs.js"
199
+ },
200
+ "./types": {
201
+ "import": "./types.js"
202
+ },
203
+ "./useAsyncFn": {
204
+ "import": "./useAsyncFn.js"
205
+ },
206
+ "./useFirstMountState": {
207
+ "import": "./useFirstMountState.js"
208
+ },
209
+ "./useFixedOffset": {
210
+ "import": "./useFixedOffset.js"
211
+ },
212
+ "./useFocus": {
213
+ "import": "./useFocus.js"
214
+ },
215
+ "./useInterval": {
216
+ "import": "./useInterval.js"
217
+ },
218
+ "./useIsomorphicLayoutEffect": {
219
+ "import": "./useIsomorphicLayoutEffect.js"
220
+ },
221
+ "./useKeyUp": {
222
+ "import": "./useKeyUp.js"
223
+ },
224
+ "./useMeasure": {
225
+ "import": "./useMeasure.js"
226
+ },
227
+ "./useMountedState": {
228
+ "import": "./useMountedState.js"
229
+ },
230
+ "./useNavigateAway": {
231
+ "import": "./useNavigateAway.js"
232
+ },
233
+ "./usePrevious": {
234
+ "import": "./usePrevious.js"
235
+ },
236
+ "./usePreviousRef": {
237
+ "import": "./usePreviousRef.js"
238
+ },
239
+ "./useReveal": {
240
+ "import": "./useReveal.js"
241
+ },
242
+ "./useScrollPosition": {
243
+ "import": "./useScrollPosition.js"
244
+ },
245
+ "./useScrollThreshold": {
246
+ "import": "./useScrollThreshold.js"
247
+ },
248
+ "./useScrollTo": {
249
+ "import": "./useScrollTo.js"
250
+ },
251
+ "./useSmoothScroll": {
252
+ "import": "./useSmoothScroll.js"
253
+ },
254
+ "./useSpinDelay": {
255
+ "import": "./useSpinDelay.js"
256
+ },
257
+ "./useTraceUpdate": {
258
+ "import": "./useTraceUpdate.js"
259
+ },
260
+ "./useUpdateEffect": {
261
+ "import": "./useUpdateEffect.js"
262
+ },
263
+ "./useWindowSize": {
264
+ "import": "./useWindowSize.js"
265
+ },
266
+ "./utils/Polymorphic": {
267
+ "import": "./utils/Polymorphic.js"
268
+ },
269
+ "./utils/classed": {
270
+ "import": "./utils/classed.js"
271
+ },
272
+ "./utils/createUseMediaQueryWidth": {
273
+ "import": "./utils/createUseMediaQueryWidth.js"
274
+ },
275
+ "./utils/extendComponent": {
276
+ "import": "./utils/extendComponent.js"
277
+ },
278
+ "./utils": {
279
+ "import": "./utils/index.js"
280
+ },
281
+ "./utils/mergeRefs": {
282
+ "import": "./utils/mergeRefs.js"
283
+ },
284
+ "./package.json": "./package.json"
45
285
  },
46
286
  "module": "./index.esm.js",
47
287
  "main": "./index.cjs.js",
48
- "version": "2.0.0-beta.73"
288
+ "version": "2.0.0-beta.75"
49
289
  }
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ type PromiseType<P extends Promise<any>> = P extends Promise<infer T> ? T : never;
3
+ type FunctionReturningPromise = (...args: any[]) => Promise<any>;
4
+ export type UseAsyncState<T> = {
5
+ loading: boolean;
6
+ error?: undefined;
7
+ value?: undefined;
8
+ } | {
9
+ loading: true;
10
+ error?: Error | undefined;
11
+ value?: T;
12
+ } | {
13
+ loading: false;
14
+ error: Error;
15
+ value?: undefined;
16
+ } | {
17
+ loading: false;
18
+ error?: undefined;
19
+ value: T;
20
+ };
21
+ type StateFromFunctionReturningPromise<T extends FunctionReturningPromise> = UseAsyncState<PromiseType<ReturnType<T>>>;
22
+ export type UseAsyncFnReturn<T extends FunctionReturningPromise = FunctionReturningPromise> = [StateFromFunctionReturningPromise<T>, T];
23
+ export declare let useAsyncFn: <T extends FunctionReturningPromise>(fn: T, deps?: React.DependencyList, initialState?: StateFromFunctionReturningPromise<T>) => UseAsyncFnReturn<T>;
24
+ export default useAsyncFn;
package/useAsyncFn.js ADDED
@@ -0,0 +1,26 @@
1
+ import React, { useCallback, useRef, useState } from "react";
2
+ import { useMountedState } from "./useMountedState";
3
+ export let useAsyncFn = (fn, deps = [], initialState = { loading: false }) => {
4
+ const lastCallId = useRef(0);
5
+ const isMounted = useMountedState();
6
+ const [state, set] = useState(initialState);
7
+ const callback = useCallback((...args) => {
8
+ const callId = ++lastCallId.current;
9
+ if (!state.loading) {
10
+ set((prevState) => ({ ...prevState, loading: true }));
11
+ }
12
+ return fn(...args).then((value) => {
13
+ isMounted() &&
14
+ callId === lastCallId.current &&
15
+ set({ value, loading: false });
16
+ return value;
17
+ }, (error) => {
18
+ isMounted() &&
19
+ callId === lastCallId.current &&
20
+ set({ error, loading: false });
21
+ return error;
22
+ });
23
+ }, deps);
24
+ return [state, callback];
25
+ };
26
+ export default useAsyncFn;
@@ -0,0 +1,2 @@
1
+ export declare let useFirstMountState: () => boolean;
2
+ export default useFirstMountState;
@@ -0,0 +1,10 @@
1
+ import { useRef } from "react";
2
+ export let useFirstMountState = () => {
3
+ const isFirst = useRef(true);
4
+ if (isFirst.current) {
5
+ isFirst.current = false;
6
+ return true;
7
+ }
8
+ return isFirst.current;
9
+ };
10
+ export default useFirstMountState;
@@ -0,0 +1,2 @@
1
+ export declare let useFixedOffset: (selector?: string) => import("react").MutableRefObject<number>;
2
+ export default useFixedOffset;
@@ -0,0 +1,42 @@
1
+ import { useRef } from "react";
2
+ import { debounce } from "@koine/utils";
3
+ import { $each, calculateFixedOffset, injectCss, listenResizeDebounced, } from "@koine/dom";
4
+ import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
5
+ const inject = (value) => {
6
+ injectCss("useFixedOffset", `html{scroll-padding-top: ${value}px}`);
7
+ };
8
+ export let useFixedOffset = (selector) => {
9
+ const fixedOffset = useRef(0);
10
+ useIsomorphicLayoutEffect(() => {
11
+ const update = () => {
12
+ const newFixedOffset = calculateFixedOffset();
13
+ fixedOffset.current = newFixedOffset;
14
+ inject(newFixedOffset);
15
+ };
16
+ update();
17
+ if (ResizeObserver) {
18
+ const observer = new ResizeObserver((entries) => {
19
+ let newFixedOffset = 0;
20
+ entries.forEach((entry) => {
21
+ newFixedOffset += entry.contentRect.height;
22
+ });
23
+ fixedOffset.current = newFixedOffset;
24
+ const updateOnResize = debounce(() => inject(newFixedOffset), 400, true);
25
+ updateOnResize();
26
+ });
27
+ $each(selector || "[data-fixed]", ($el) => {
28
+ if (observer)
29
+ observer.observe($el);
30
+ });
31
+ return () => {
32
+ observer?.disconnect();
33
+ };
34
+ }
35
+ else {
36
+ const listener = listenResizeDebounced(0, update);
37
+ return listener;
38
+ }
39
+ }, [selector]);
40
+ return fixedOffset;
41
+ };
42
+ export default useFixedOffset;
package/useFocus.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare let useFocus: () => (import("react").RefObject<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | (() => void))[];
2
+ export default useFocus;
package/useFocus.js ADDED
@@ -0,0 +1,9 @@
1
+ import { useRef } from "react";
2
+ export let useFocus = () => {
3
+ const elementRef = useRef(null);
4
+ const setFocus = () => {
5
+ elementRef.current && elementRef.current.focus();
6
+ };
7
+ return [elementRef, setFocus];
8
+ };
9
+ export default useFocus;
@@ -0,0 +1,2 @@
1
+ export declare let useInterval: <T extends () => unknown>(callback: T, delay: number, deps?: unknown[]) => void;
2
+ export default useInterval;
package/useInterval.js ADDED
@@ -0,0 +1,20 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { noop } from "@koine/utils";
3
+ export let useInterval = (callback, delay, deps = []) => {
4
+ const savedCallback = useRef();
5
+ useEffect(() => {
6
+ savedCallback.current = callback;
7
+ }, [callback, ...deps]);
8
+ useEffect(() => {
9
+ function tick() {
10
+ if (savedCallback.current)
11
+ savedCallback.current();
12
+ }
13
+ if (delay !== null) {
14
+ const id = setInterval(tick, delay);
15
+ return () => clearInterval(id);
16
+ }
17
+ return noop;
18
+ }, [delay]);
19
+ };
20
+ export default useInterval;
@@ -0,0 +1,3 @@
1
+ import { useLayoutEffect } from "react";
2
+ export declare let useIsomorphicLayoutEffect: typeof useLayoutEffect;
3
+ export default useIsomorphicLayoutEffect;
@@ -0,0 +1,4 @@
1
+ import { useEffect, useLayoutEffect } from "react";
2
+ import { isBrowser } from "@koine/utils";
3
+ export let useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect;
4
+ export default useIsomorphicLayoutEffect;
package/useKeyUp.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare let useKeyUp: (callback: (event: KeyboardEvent) => void, deps?: unknown[]) => void;
2
+ export default useKeyUp;
package/useKeyUp.js ADDED
@@ -0,0 +1,16 @@
1
+ import { useEffect } from "react";
2
+ import { on } from "@koine/dom";
3
+ export let useKeyUp = (callback, deps = []) => {
4
+ useEffect(() => {
5
+ const listener = on(window, "keyup", (event) => {
6
+ if (!event.ctrlKey &&
7
+ !event.altKey &&
8
+ !event.shiftKey &&
9
+ !event.metaKey) {
10
+ callback(event);
11
+ }
12
+ });
13
+ return listener;
14
+ }, [callback, ...deps]);
15
+ };
16
+ export default useKeyUp;
@@ -0,0 +1,22 @@
1
+ interface RectReadOnly {
2
+ readonly x: number;
3
+ readonly y: number;
4
+ readonly width: number;
5
+ readonly height: number;
6
+ readonly top: number;
7
+ readonly right: number;
8
+ readonly bottom: number;
9
+ readonly left: number;
10
+ [key: string]: number;
11
+ }
12
+ type HTMLOrSVGElement = HTMLElement | SVGElement;
13
+ export type UseMeasureOptions = {
14
+ scroll?: boolean;
15
+ };
16
+ export type UseMeasureReturn = [
17
+ (element: HTMLOrSVGElement | null) => void,
18
+ RectReadOnly,
19
+ () => void
20
+ ];
21
+ export declare let useMeasure: (options?: UseMeasureOptions) => UseMeasureReturn;
22
+ export default useMeasure;
package/useMeasure.js ADDED
@@ -0,0 +1,119 @@
1
+ import { useEffect, useMemo, useRef, useState } from "react";
2
+ import { debounce, noop } from "@koine/utils";
3
+ import { listenResizeDebounced, listenScrollDebounced, off, on, } from "@koine/dom";
4
+ let observer;
5
+ let findScrollContainers = (element) => {
6
+ const result = [];
7
+ if (!element || element === document.body)
8
+ return result;
9
+ const { overflow, overflowX, overflowY } = window.getComputedStyle(element);
10
+ if ([overflow, overflowX, overflowY].some((prop) => prop === "auto" || prop === "scroll"))
11
+ result.push(element);
12
+ return [...result, ...findScrollContainers(element.parentElement)];
13
+ };
14
+ const keys = [
15
+ "x",
16
+ "y",
17
+ "top",
18
+ "bottom",
19
+ "left",
20
+ "right",
21
+ "width",
22
+ "height",
23
+ ];
24
+ const areBoundsEqual = (a, b) => keys.every((key) => a[key] === b[key]);
25
+ export let useMeasure = (options) => {
26
+ const { scroll = false } = options || {};
27
+ const [bounds, setBounds] = useState({
28
+ left: 0,
29
+ top: 0,
30
+ width: 0,
31
+ height: 0,
32
+ bottom: 0,
33
+ right: 0,
34
+ x: 0,
35
+ y: 0,
36
+ });
37
+ const state = useRef([
38
+ null,
39
+ null,
40
+ null,
41
+ bounds,
42
+ ]);
43
+ const mounted = useRef(false);
44
+ useEffect(() => {
45
+ mounted.current = true;
46
+ return () => void (mounted.current = false);
47
+ }, []);
48
+ const [forceRefresh, , scrollChange] = useMemo(() => {
49
+ const callback = (..._args) => {
50
+ const [element, , , lastBounds] = state.current;
51
+ if (!element)
52
+ return;
53
+ const size = element.getBoundingClientRect();
54
+ Object.freeze(size);
55
+ if (mounted.current && !areBoundsEqual(lastBounds, size)) {
56
+ state.current[3] = size;
57
+ setBounds(size);
58
+ }
59
+ };
60
+ const debouncedCallback = debounce(callback);
61
+ return [callback, debouncedCallback, debouncedCallback];
62
+ }, [setBounds]);
63
+ function removeListeners() {
64
+ const [, scrollContainers, resizeObserver] = state.current;
65
+ if (scrollContainers) {
66
+ scrollContainers.forEach((element) => off(element, "scroll", scrollChange));
67
+ state.current[1] = null;
68
+ }
69
+ if (resizeObserver) {
70
+ resizeObserver.disconnect();
71
+ state.current[2] = null;
72
+ }
73
+ }
74
+ function addListeners() {
75
+ const [element, scrollContainers] = state.current;
76
+ if (!element)
77
+ return;
78
+ if (!observer && ResizeObserver) {
79
+ observer = new ResizeObserver(scrollChange);
80
+ state.current[2] = observer;
81
+ observer.observe(element);
82
+ if (scroll && scrollContainers) {
83
+ scrollContainers.forEach((scrollContainer) => on(scrollContainer, "scroll", scrollChange, {
84
+ capture: true,
85
+ passive: true,
86
+ }));
87
+ }
88
+ }
89
+ }
90
+ const ref = (node) => {
91
+ if (!node || node === state.current[0])
92
+ return;
93
+ removeListeners();
94
+ state.current[0] = node;
95
+ state.current[1] = findScrollContainers(node);
96
+ addListeners();
97
+ };
98
+ useEffect(() => {
99
+ if (scroll) {
100
+ const listener = listenScrollDebounced(0, forceRefresh, 100);
101
+ return listener;
102
+ }
103
+ return noop;
104
+ }, [scroll, forceRefresh]);
105
+ useEffect(() => {
106
+ const listener = listenResizeDebounced(0, forceRefresh, 100);
107
+ return listener;
108
+ }, [forceRefresh]);
109
+ useEffect(() => {
110
+ removeListeners();
111
+ addListeners();
112
+ }, [scroll]);
113
+ useEffect(() => {
114
+ forceRefresh();
115
+ return removeListeners;
116
+ }, []);
117
+ return [ref, bounds, forceRefresh];
118
+ };
119
+ export default useMeasure;
@@ -0,0 +1,2 @@
1
+ export declare let useMountedState: () => (() => boolean);
2
+ export default useMountedState;
@@ -0,0 +1,13 @@
1
+ import { useCallback, useEffect, useRef } from "react";
2
+ export let useMountedState = () => {
3
+ const mountedRef = useRef(false);
4
+ const get = useCallback(() => mountedRef.current, []);
5
+ useEffect(() => {
6
+ mountedRef.current = true;
7
+ return () => {
8
+ mountedRef.current = false;
9
+ };
10
+ }, []);
11
+ return get;
12
+ };
13
+ export default useMountedState;
@@ -0,0 +1,3 @@
1
+ export type UseNavigateAwayHandler = (event: BeforeUnloadEvent) => string | boolean;
2
+ export declare let useNavigateAway: (handler: UseNavigateAwayHandler) => void;
3
+ export default useNavigateAway;
@@ -0,0 +1,25 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { on } from "@koine/dom";
3
+ export let useNavigateAway = (handler) => {
4
+ const beforeUnloadHandlerRef = useRef();
5
+ useEffect(() => {
6
+ beforeUnloadHandlerRef.current = (event) => {
7
+ const customMessageOrCondition = handler(event);
8
+ if (customMessageOrCondition) {
9
+ event.preventDefault();
10
+ }
11
+ if (typeof customMessageOrCondition === "string") {
12
+ return (event.returnValue = customMessageOrCondition);
13
+ }
14
+ if (event.defaultPrevented) {
15
+ return (event.returnValue = "");
16
+ }
17
+ return;
18
+ };
19
+ }, [handler]);
20
+ useEffect(() => {
21
+ const listenerBeforeunload = on(window, "beforeunload", (event) => beforeUnloadHandlerRef.current?.(event));
22
+ return listenerBeforeunload;
23
+ }, []);
24
+ };
25
+ export default useNavigateAway;
@@ -0,0 +1,2 @@
1
+ export declare let usePrevious: <T extends unknown>(state: T, defaulValue: T) => T;
2
+ export default usePrevious;
package/usePrevious.js ADDED
@@ -0,0 +1,9 @@
1
+ import { useState } from "react";
2
+ export let usePrevious = (state, defaulValue) => {
3
+ const [tuple, setTuple] = useState([state, defaulValue]);
4
+ if (tuple[1] !== state) {
5
+ setTuple([tuple[1], state]);
6
+ }
7
+ return tuple[0];
8
+ };
9
+ export default usePrevious;
@@ -0,0 +1,2 @@
1
+ export declare let usePreviousRef: <T extends unknown>(value: T) => T | undefined;
2
+ export default usePreviousRef;