tona-hooks 1.0.1 → 1.0.18
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.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +26 -65
- package/package.json +8 -7
- package/dist/index.d.mts +0 -71
- package/dist/index.mjs +0 -274
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dispatch, EffectCallback,
|
|
1
|
+
import { Dispatch, EffectCallback, useEffect } from "preact/hooks";
|
|
2
2
|
import { SetStateAction } from "preact/compat";
|
|
3
3
|
import { RefObject } from "preact";
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ declare function useEventCallback<Args extends unknown[], R>(fn: (...args: Args)
|
|
|
25
25
|
declare function useEventCallback<Args extends unknown[], R>(fn: ((...args: Args) => R) | undefined): ((...args: Args) => R) | undefined;
|
|
26
26
|
//#endregion
|
|
27
27
|
//#region src/use-isomorphic-layout-effect.d.ts
|
|
28
|
-
declare const useIsomorphicLayoutEffect: typeof
|
|
28
|
+
declare const useIsomorphicLayoutEffect: typeof useEffect;
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/use-query-dom.d.ts
|
|
31
31
|
interface UseQueryDomOptions<T> {
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
|
|
2
|
+
import { useCallback as useCallback$1, useRef as useRef$1 } from "preact/compat";
|
|
3
3
|
|
|
4
4
|
//#region src/use-ajax-complete.ts
|
|
5
5
|
/**
|
|
@@ -10,7 +10,7 @@ let preact_compat = require("preact/compat");
|
|
|
10
10
|
* @param config.onError 错误时的回调函数
|
|
11
11
|
*/
|
|
12
12
|
function useAjaxComplete(config) {
|
|
13
|
-
|
|
13
|
+
useEffect(() => {
|
|
14
14
|
const { urlPattern, onSuccess, onError } = config;
|
|
15
15
|
const handleAjaxComplete = (_, jqXHR, option) => {
|
|
16
16
|
const url = option?.url;
|
|
@@ -31,77 +31,49 @@ function useAjaxComplete(config) {
|
|
|
31
31
|
//#endregion
|
|
32
32
|
//#region src/use-effect-once.ts
|
|
33
33
|
const useEffectOnce = (effect) => {
|
|
34
|
-
|
|
34
|
+
useEffect(effect, []);
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
//#endregion
|
|
38
38
|
//#region src/use-isomorphic-layout-effect.ts
|
|
39
|
-
const useIsomorphicLayoutEffect = typeof window !== "undefined" ?
|
|
39
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
40
40
|
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region src/use-event-callback.ts
|
|
43
43
|
function useEventCallback(fn) {
|
|
44
|
-
const ref =
|
|
44
|
+
const ref = useRef$1(() => {
|
|
45
45
|
throw new Error("Cannot call an event handler while rendering.");
|
|
46
46
|
});
|
|
47
47
|
useIsomorphicLayoutEffect(() => {
|
|
48
48
|
ref.current = fn;
|
|
49
49
|
}, [fn]);
|
|
50
|
-
return
|
|
50
|
+
return useCallback$1((...args) => ref.current?.(...args), [ref]);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
//#endregion
|
|
54
54
|
//#region src/use-query-dom.ts
|
|
55
55
|
function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
|
|
56
|
-
const [data, setData] =
|
|
57
|
-
const [isPending, setIsPending] =
|
|
58
|
-
const queryFnRef =
|
|
59
|
-
const observerRef =
|
|
60
|
-
const ajaxStartRef =
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
return globalThis.localStorage.getItem("tona-debug-avatar") === "1";
|
|
64
|
-
} catch {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
})();
|
|
68
|
-
(0, preact_hooks.useEffect)(() => {
|
|
56
|
+
const [data, setData] = useState(null);
|
|
57
|
+
const [isPending, setIsPending] = useState(false);
|
|
58
|
+
const queryFnRef = useRef(queryFn);
|
|
59
|
+
const observerRef = useRef(null);
|
|
60
|
+
const ajaxStartRef = useRef(0);
|
|
61
|
+
useEffect(() => {
|
|
69
62
|
queryFnRef.current = queryFn;
|
|
70
63
|
}, [queryFn]);
|
|
71
|
-
const queryElement =
|
|
64
|
+
const queryElement = useCallback(() => {
|
|
72
65
|
const element = document.querySelector(selector);
|
|
73
66
|
const nextData = queryFnRef.current(element);
|
|
74
67
|
setData((prev) => {
|
|
75
68
|
if (Object.is(prev, nextData)) return prev;
|
|
76
69
|
return nextData;
|
|
77
70
|
});
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
elementFound: Boolean(element),
|
|
81
|
-
nextData,
|
|
82
|
-
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
83
|
-
});
|
|
84
|
-
}, [debug, selector]);
|
|
85
|
-
(0, preact_hooks.useEffect)(() => {
|
|
71
|
+
}, [selector]);
|
|
72
|
+
useEffect(() => {
|
|
86
73
|
queryElement();
|
|
87
74
|
if (!observe) return;
|
|
88
75
|
const targetNode = document.querySelector(selector)?.parentElement || document.body;
|
|
89
|
-
const observer = new MutationObserver(
|
|
90
|
-
if (debug) {
|
|
91
|
-
const summary = records.map((r) => ({
|
|
92
|
-
type: r.type,
|
|
93
|
-
target: r.target instanceof Element ? r.target.tagName : "unknown",
|
|
94
|
-
attributeName: r.attributeName || null,
|
|
95
|
-
addedNodes: r.addedNodes.length,
|
|
96
|
-
removedNodes: r.removedNodes.length
|
|
97
|
-
}));
|
|
98
|
-
console.log("[useQueryDOM:mutation]", {
|
|
99
|
-
selector,
|
|
100
|
-
summary
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
queryElement();
|
|
104
|
-
});
|
|
76
|
+
const observer = new MutationObserver(queryElement);
|
|
105
77
|
observerRef.current = observer;
|
|
106
78
|
observer.observe(targetNode, {
|
|
107
79
|
childList: true,
|
|
@@ -114,12 +86,11 @@ function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
|
|
|
114
86
|
observerRef.current = null;
|
|
115
87
|
};
|
|
116
88
|
}, [
|
|
117
|
-
debug,
|
|
118
89
|
observe,
|
|
119
90
|
queryElement,
|
|
120
91
|
selector
|
|
121
92
|
]);
|
|
122
|
-
|
|
93
|
+
useEffect(() => {
|
|
123
94
|
if (!ajaxUrl) return;
|
|
124
95
|
const urls = Array.isArray(ajaxUrl) ? ajaxUrl : [ajaxUrl];
|
|
125
96
|
let timeoutId = null;
|
|
@@ -183,7 +154,7 @@ function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
|
|
|
183
154
|
//#endregion
|
|
184
155
|
//#region src/use-unmount.ts
|
|
185
156
|
const useUnmount = (fn) => {
|
|
186
|
-
const fnRef =
|
|
157
|
+
const fnRef = useRef(fn);
|
|
187
158
|
fnRef.current = fn;
|
|
188
159
|
useEffectOnce(() => () => fnRef.current());
|
|
189
160
|
};
|
|
@@ -191,9 +162,9 @@ const useUnmount = (fn) => {
|
|
|
191
162
|
//#endregion
|
|
192
163
|
//#region src/use-raf-state.ts
|
|
193
164
|
const useRafState = (initialState) => {
|
|
194
|
-
const frame =
|
|
195
|
-
const [state, setState] =
|
|
196
|
-
const setRafState =
|
|
165
|
+
const frame = useRef(0);
|
|
166
|
+
const [state, setState] = useState(initialState);
|
|
167
|
+
const setRafState = useCallback((value) => {
|
|
197
168
|
cancelAnimationFrame(frame.current);
|
|
198
169
|
frame.current = requestAnimationFrame(() => {
|
|
199
170
|
setState(value);
|
|
@@ -218,14 +189,12 @@ const isBrowser = typeof window !== "undefined";
|
|
|
218
189
|
//#endregion
|
|
219
190
|
//#region src/use-scroll.ts
|
|
220
191
|
const useScroll = (ref) => {
|
|
221
|
-
if (
|
|
222
|
-
if (typeof ref !== "object" || typeof ref.current === "undefined") console.error("`useScroll` expects a single ref argument.");
|
|
223
|
-
}
|
|
192
|
+
if (typeof ref !== "object" || typeof ref.current === "undefined") console.error("`useScroll` expects a single ref argument.");
|
|
224
193
|
const [state, setState] = useRafState({
|
|
225
194
|
x: 0,
|
|
226
195
|
y: 0
|
|
227
196
|
});
|
|
228
|
-
|
|
197
|
+
useEffect(() => {
|
|
229
198
|
const handler = () => {
|
|
230
199
|
if (ref.current) setState({
|
|
231
200
|
x: ref.current.scrollLeft,
|
|
@@ -250,7 +219,7 @@ const useWindowScroll = () => {
|
|
|
250
219
|
x: isBrowser ? window.pageXOffset : 0,
|
|
251
220
|
y: isBrowser ? window.pageYOffset : 0
|
|
252
221
|
}));
|
|
253
|
-
|
|
222
|
+
useEffect(() => {
|
|
254
223
|
const handler = () => {
|
|
255
224
|
setState((state$1) => {
|
|
256
225
|
const { pageXOffset, pageYOffset } = window;
|
|
@@ -273,12 +242,4 @@ const useWindowScroll = () => {
|
|
|
273
242
|
};
|
|
274
243
|
|
|
275
244
|
//#endregion
|
|
276
|
-
|
|
277
|
-
exports.useEffectOnce = useEffectOnce;
|
|
278
|
-
exports.useEventCallback = useEventCallback;
|
|
279
|
-
exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
|
|
280
|
-
exports.useQueryDOM = useQueryDOM;
|
|
281
|
-
exports.useRafState = useRafState;
|
|
282
|
-
exports.useScroll = useScroll;
|
|
283
|
-
exports.useUnmount = useUnmount;
|
|
284
|
-
exports.useWindowScroll = useWindowScroll;
|
|
245
|
+
export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tona-hooks",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "guangzan",
|
|
@@ -8,25 +8,26 @@
|
|
|
8
8
|
"email": "guangzan1999@outlook.com"
|
|
9
9
|
},
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"homepage": "https://github.com/
|
|
11
|
+
"homepage": "https://github.com/guangzan/tona/tree/main/packages/hooks#readme",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "git+https://github.com/
|
|
14
|
+
"url": "git+https://github.com/guangzan/tona.git",
|
|
15
|
+
"directory": "packages/hooks"
|
|
15
16
|
},
|
|
16
17
|
"bugs": {
|
|
17
|
-
"url": "https://github.com/
|
|
18
|
+
"url": "https://github.com/guangzan/tona/issues"
|
|
18
19
|
},
|
|
19
20
|
"keywords": [
|
|
20
21
|
"博客园"
|
|
21
22
|
],
|
|
23
|
+
"type": "module",
|
|
22
24
|
"exports": {
|
|
23
25
|
".": {
|
|
24
26
|
"types": "./dist/index.d.ts",
|
|
25
|
-
"import": "./dist/index.
|
|
26
|
-
"require": "./dist/index.js"
|
|
27
|
+
"import": "./dist/index.js"
|
|
27
28
|
}
|
|
28
29
|
},
|
|
29
|
-
"main": "./dist/index.
|
|
30
|
+
"main": "./dist/index.js",
|
|
30
31
|
"module": "./dist/index.js",
|
|
31
32
|
"types": "./dist/index.d.ts",
|
|
32
33
|
"files": [
|
package/dist/index.d.mts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Dispatch, EffectCallback, useLayoutEffect } from "preact/hooks";
|
|
2
|
-
import { SetStateAction } from "preact/compat";
|
|
3
|
-
import { RefObject } from "preact";
|
|
4
|
-
|
|
5
|
-
//#region src/use-ajax-complete.d.ts
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 通用的 Ajax 完成监听 Hook
|
|
9
|
-
* @param config 配置对象
|
|
10
|
-
* @param config.urlPattern 要监听的 URL 模式(支持字符串包含匹配)
|
|
11
|
-
* @param config.onSuccess 成功时的回调函数
|
|
12
|
-
* @param config.onError 错误时的回调函数
|
|
13
|
-
*/
|
|
14
|
-
declare function useAjaxComplete(config: {
|
|
15
|
-
urlPattern: string | string[];
|
|
16
|
-
onSuccess?: (response: any, jqXHR: JQuery.jqXHR, option: JQuery.AjaxSettings) => void;
|
|
17
|
-
onError?: (response: any, jqXHR: JQuery.jqXHR, option: JQuery.AjaxSettings) => void;
|
|
18
|
-
}): void;
|
|
19
|
-
//#endregion
|
|
20
|
-
//#region src/use-effect-once.d.ts
|
|
21
|
-
declare const useEffectOnce: (effect: EffectCallback) => void;
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region src/use-event-callback.d.ts
|
|
24
|
-
declare function useEventCallback<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => R;
|
|
25
|
-
declare function useEventCallback<Args extends unknown[], R>(fn: ((...args: Args) => R) | undefined): ((...args: Args) => R) | undefined;
|
|
26
|
-
//#endregion
|
|
27
|
-
//#region src/use-isomorphic-layout-effect.d.ts
|
|
28
|
-
declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
|
|
29
|
-
//#endregion
|
|
30
|
-
//#region src/use-query-dom.d.ts
|
|
31
|
-
interface UseQueryDomOptions<T> {
|
|
32
|
-
selector: string;
|
|
33
|
-
observe?: boolean;
|
|
34
|
-
queryFn: (el: Element | null) => T | null;
|
|
35
|
-
/**
|
|
36
|
-
* 监听的 selector 的 DOM 相关的 AJAX 请求 URL
|
|
37
|
-
*/
|
|
38
|
-
ajaxUrl?: string | string[];
|
|
39
|
-
}
|
|
40
|
-
interface UseQueryDomResult<T> {
|
|
41
|
-
data: T | null;
|
|
42
|
-
isPending: boolean;
|
|
43
|
-
}
|
|
44
|
-
declare function useQueryDOM<T>({
|
|
45
|
-
selector,
|
|
46
|
-
observe,
|
|
47
|
-
queryFn,
|
|
48
|
-
ajaxUrl
|
|
49
|
-
}: UseQueryDomOptions<T>): UseQueryDomResult<T>;
|
|
50
|
-
//#endregion
|
|
51
|
-
//#region src/use-raf-state.d.ts
|
|
52
|
-
declare const useRafState: <S>(initialState: S | (() => S)) => [S, Dispatch<SetStateAction<S>>];
|
|
53
|
-
//#endregion
|
|
54
|
-
//#region src/use-scroll.d.ts
|
|
55
|
-
interface State$1 {
|
|
56
|
-
x: number;
|
|
57
|
-
y: number;
|
|
58
|
-
}
|
|
59
|
-
declare const useScroll: (ref: RefObject<HTMLElement>) => State$1;
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/use-unmount.d.ts
|
|
62
|
-
declare const useUnmount: (fn: () => any) => void;
|
|
63
|
-
//#endregion
|
|
64
|
-
//#region src/use-window-scroll.d.ts
|
|
65
|
-
interface State {
|
|
66
|
-
x: number;
|
|
67
|
-
y: number;
|
|
68
|
-
}
|
|
69
|
-
declare const useWindowScroll: () => State;
|
|
70
|
-
//#endregion
|
|
71
|
-
export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
|
package/dist/index.mjs
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
|
|
2
|
-
import { useCallback as useCallback$1, useRef as useRef$1 } from "preact/compat";
|
|
3
|
-
|
|
4
|
-
//#region src/use-ajax-complete.ts
|
|
5
|
-
/**
|
|
6
|
-
* 通用的 Ajax 完成监听 Hook
|
|
7
|
-
* @param config 配置对象
|
|
8
|
-
* @param config.urlPattern 要监听的 URL 模式(支持字符串包含匹配)
|
|
9
|
-
* @param config.onSuccess 成功时的回调函数
|
|
10
|
-
* @param config.onError 错误时的回调函数
|
|
11
|
-
*/
|
|
12
|
-
function useAjaxComplete(config) {
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
const { urlPattern, onSuccess, onError } = config;
|
|
15
|
-
const handleAjaxComplete = (_, jqXHR, option) => {
|
|
16
|
-
const url = option?.url;
|
|
17
|
-
if (!url) return;
|
|
18
|
-
if (!(Array.isArray(urlPattern) ? urlPattern : [urlPattern]).some((pattern) => url.includes(pattern))) return;
|
|
19
|
-
const response = jqXHR.responseJSON || jqXHR.responseText;
|
|
20
|
-
const hasError = jqXHR.status >= 400;
|
|
21
|
-
if (hasError && onError) onError(response, jqXHR, option);
|
|
22
|
-
else if (!hasError && onSuccess) onSuccess(response, jqXHR, option);
|
|
23
|
-
};
|
|
24
|
-
$(document).on("ajaxComplete", handleAjaxComplete);
|
|
25
|
-
return () => {
|
|
26
|
-
$(document).off("ajaxComplete", handleAjaxComplete);
|
|
27
|
-
};
|
|
28
|
-
}, [config]);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region src/use-effect-once.ts
|
|
33
|
-
const useEffectOnce = (effect) => {
|
|
34
|
-
useEffect(effect, []);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region src/use-isomorphic-layout-effect.ts
|
|
39
|
-
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
40
|
-
|
|
41
|
-
//#endregion
|
|
42
|
-
//#region src/use-event-callback.ts
|
|
43
|
-
function useEventCallback(fn) {
|
|
44
|
-
const ref = useRef$1(() => {
|
|
45
|
-
throw new Error("Cannot call an event handler while rendering.");
|
|
46
|
-
});
|
|
47
|
-
useIsomorphicLayoutEffect(() => {
|
|
48
|
-
ref.current = fn;
|
|
49
|
-
}, [fn]);
|
|
50
|
-
return useCallback$1((...args) => ref.current?.(...args), [ref]);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
//#endregion
|
|
54
|
-
//#region src/use-query-dom.ts
|
|
55
|
-
function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
|
|
56
|
-
const [data, setData] = useState(null);
|
|
57
|
-
const [isPending, setIsPending] = useState(false);
|
|
58
|
-
const queryFnRef = useRef(queryFn);
|
|
59
|
-
const observerRef = useRef(null);
|
|
60
|
-
const ajaxStartRef = useRef(0);
|
|
61
|
-
const debug = selector === "#user_icon.navbar-avatar" && (() => {
|
|
62
|
-
try {
|
|
63
|
-
return globalThis.localStorage.getItem("tona-debug-avatar") === "1";
|
|
64
|
-
} catch {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
})();
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
queryFnRef.current = queryFn;
|
|
70
|
-
}, [queryFn]);
|
|
71
|
-
const queryElement = useCallback(() => {
|
|
72
|
-
const element = document.querySelector(selector);
|
|
73
|
-
const nextData = queryFnRef.current(element);
|
|
74
|
-
setData((prev) => {
|
|
75
|
-
if (Object.is(prev, nextData)) return prev;
|
|
76
|
-
return nextData;
|
|
77
|
-
});
|
|
78
|
-
if (debug) console.log("[useQueryDOM]", {
|
|
79
|
-
selector,
|
|
80
|
-
elementFound: Boolean(element),
|
|
81
|
-
nextData,
|
|
82
|
-
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
83
|
-
});
|
|
84
|
-
}, [debug, selector]);
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
queryElement();
|
|
87
|
-
if (!observe) return;
|
|
88
|
-
const targetNode = document.querySelector(selector)?.parentElement || document.body;
|
|
89
|
-
const observer = new MutationObserver((records) => {
|
|
90
|
-
if (debug) {
|
|
91
|
-
const summary = records.map((r) => ({
|
|
92
|
-
type: r.type,
|
|
93
|
-
target: r.target instanceof Element ? r.target.tagName : "unknown",
|
|
94
|
-
attributeName: r.attributeName || null,
|
|
95
|
-
addedNodes: r.addedNodes.length,
|
|
96
|
-
removedNodes: r.removedNodes.length
|
|
97
|
-
}));
|
|
98
|
-
console.log("[useQueryDOM:mutation]", {
|
|
99
|
-
selector,
|
|
100
|
-
summary
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
queryElement();
|
|
104
|
-
});
|
|
105
|
-
observerRef.current = observer;
|
|
106
|
-
observer.observe(targetNode, {
|
|
107
|
-
childList: true,
|
|
108
|
-
subtree: true,
|
|
109
|
-
attributes: true,
|
|
110
|
-
characterData: false
|
|
111
|
-
});
|
|
112
|
-
return () => {
|
|
113
|
-
observer.disconnect();
|
|
114
|
-
observerRef.current = null;
|
|
115
|
-
};
|
|
116
|
-
}, [
|
|
117
|
-
debug,
|
|
118
|
-
observe,
|
|
119
|
-
queryElement,
|
|
120
|
-
selector
|
|
121
|
-
]);
|
|
122
|
-
useEffect(() => {
|
|
123
|
-
if (!ajaxUrl) return;
|
|
124
|
-
const urls = Array.isArray(ajaxUrl) ? ajaxUrl : [ajaxUrl];
|
|
125
|
-
let timeoutId = null;
|
|
126
|
-
const pendingRequests = /* @__PURE__ */ new Set();
|
|
127
|
-
const clearPending = () => {
|
|
128
|
-
setIsPending(false);
|
|
129
|
-
if (timeoutId) {
|
|
130
|
-
clearTimeout(timeoutId);
|
|
131
|
-
timeoutId = null;
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
const checkAllRequestsComplete = () => {
|
|
135
|
-
if (pendingRequests.size === 0) clearPending();
|
|
136
|
-
};
|
|
137
|
-
const handleAjaxSend = (_, __, ajaxOptions) => {
|
|
138
|
-
const url = ajaxOptions?.url || "";
|
|
139
|
-
if (urls.some((targetUrl) => url.includes(targetUrl))) {
|
|
140
|
-
pendingRequests.add(url);
|
|
141
|
-
setIsPending(true);
|
|
142
|
-
ajaxStartRef.current = Date.now();
|
|
143
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
144
|
-
timeoutId = window.setTimeout(() => {
|
|
145
|
-
pendingRequests.delete(url);
|
|
146
|
-
checkAllRequestsComplete();
|
|
147
|
-
}, 1e4);
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
const handleAjaxComplete = (_, __, ajaxOptions) => {
|
|
151
|
-
const url = ajaxOptions?.url || "";
|
|
152
|
-
if (urls.some((targetUrl) => url.includes(targetUrl))) {
|
|
153
|
-
pendingRequests.delete(url);
|
|
154
|
-
setTimeout(() => {
|
|
155
|
-
checkAllRequestsComplete();
|
|
156
|
-
}, 50);
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
const handleAjaxError = (_, __, ajaxOptions) => {
|
|
160
|
-
const url = ajaxOptions?.url || "";
|
|
161
|
-
if (urls.some((targetUrl) => url.includes(targetUrl))) {
|
|
162
|
-
pendingRequests.delete(url);
|
|
163
|
-
checkAllRequestsComplete();
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
$(document).ajaxSend(handleAjaxSend);
|
|
167
|
-
$(document).ajaxComplete(handleAjaxComplete);
|
|
168
|
-
$(document).ajaxError(handleAjaxError);
|
|
169
|
-
return () => {
|
|
170
|
-
$(document).off("ajaxSend", handleAjaxSend);
|
|
171
|
-
$(document).off("ajaxComplete", handleAjaxComplete);
|
|
172
|
-
$(document).off("ajaxError", handleAjaxError);
|
|
173
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
174
|
-
pendingRequests.clear();
|
|
175
|
-
};
|
|
176
|
-
}, [ajaxUrl]);
|
|
177
|
-
return {
|
|
178
|
-
data,
|
|
179
|
-
isPending
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
//#endregion
|
|
184
|
-
//#region src/use-unmount.ts
|
|
185
|
-
const useUnmount = (fn) => {
|
|
186
|
-
const fnRef = useRef(fn);
|
|
187
|
-
fnRef.current = fn;
|
|
188
|
-
useEffectOnce(() => () => fnRef.current());
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
//#endregion
|
|
192
|
-
//#region src/use-raf-state.ts
|
|
193
|
-
const useRafState = (initialState) => {
|
|
194
|
-
const frame = useRef(0);
|
|
195
|
-
const [state, setState] = useState(initialState);
|
|
196
|
-
const setRafState = useCallback((value) => {
|
|
197
|
-
cancelAnimationFrame(frame.current);
|
|
198
|
-
frame.current = requestAnimationFrame(() => {
|
|
199
|
-
setState(value);
|
|
200
|
-
});
|
|
201
|
-
}, []);
|
|
202
|
-
useUnmount(() => {
|
|
203
|
-
cancelAnimationFrame(frame.current);
|
|
204
|
-
});
|
|
205
|
-
return [state, setRafState];
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
//#endregion
|
|
209
|
-
//#region src/misc/util.ts
|
|
210
|
-
function on(obj, ...args) {
|
|
211
|
-
if (obj?.addEventListener) obj.addEventListener(...args);
|
|
212
|
-
}
|
|
213
|
-
function off(obj, ...args) {
|
|
214
|
-
if (obj?.removeEventListener) obj.removeEventListener(...args);
|
|
215
|
-
}
|
|
216
|
-
const isBrowser = typeof window !== "undefined";
|
|
217
|
-
|
|
218
|
-
//#endregion
|
|
219
|
-
//#region src/use-scroll.ts
|
|
220
|
-
const useScroll = (ref) => {
|
|
221
|
-
if (typeof ref !== "object" || typeof ref.current === "undefined") console.error("`useScroll` expects a single ref argument.");
|
|
222
|
-
const [state, setState] = useRafState({
|
|
223
|
-
x: 0,
|
|
224
|
-
y: 0
|
|
225
|
-
});
|
|
226
|
-
useEffect(() => {
|
|
227
|
-
const handler = () => {
|
|
228
|
-
if (ref.current) setState({
|
|
229
|
-
x: ref.current.scrollLeft,
|
|
230
|
-
y: ref.current.scrollTop
|
|
231
|
-
});
|
|
232
|
-
};
|
|
233
|
-
if (ref.current) on(ref.current, "scroll", handler, {
|
|
234
|
-
capture: false,
|
|
235
|
-
passive: true
|
|
236
|
-
});
|
|
237
|
-
return () => {
|
|
238
|
-
if (ref.current) off(ref.current, "scroll", handler);
|
|
239
|
-
};
|
|
240
|
-
}, [ref, setState]);
|
|
241
|
-
return state;
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
//#endregion
|
|
245
|
-
//#region src/use-window-scroll.ts
|
|
246
|
-
const useWindowScroll = () => {
|
|
247
|
-
const [state, setState] = useRafState(() => ({
|
|
248
|
-
x: isBrowser ? window.pageXOffset : 0,
|
|
249
|
-
y: isBrowser ? window.pageYOffset : 0
|
|
250
|
-
}));
|
|
251
|
-
useEffect(() => {
|
|
252
|
-
const handler = () => {
|
|
253
|
-
setState((state$1) => {
|
|
254
|
-
const { pageXOffset, pageYOffset } = window;
|
|
255
|
-
return state$1.x !== pageXOffset || state$1.y !== pageYOffset ? {
|
|
256
|
-
x: pageXOffset,
|
|
257
|
-
y: pageYOffset
|
|
258
|
-
} : state$1;
|
|
259
|
-
});
|
|
260
|
-
};
|
|
261
|
-
handler();
|
|
262
|
-
on(window, "scroll", handler, {
|
|
263
|
-
capture: false,
|
|
264
|
-
passive: true
|
|
265
|
-
});
|
|
266
|
-
return () => {
|
|
267
|
-
off(window, "scroll", handler);
|
|
268
|
-
};
|
|
269
|
-
}, [setState]);
|
|
270
|
-
return state;
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
//#endregion
|
|
274
|
-
export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
|