@jbpark/use-hooks 2.11.0 → 4.0.0
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/README.ko.md +40 -22
- package/README.md +40 -22
- package/dist/hooks/index.d.mts +14 -3
- package/dist/hooks/index.mjs +14 -3
- package/dist/hooks/use-click-outside.d.mts +9 -2
- package/dist/hooks/use-click-outside.mjs +27 -11
- package/dist/hooks/use-click-outside.mjs.map +1 -1
- package/dist/hooks/use-debounced-callback.d.mts +14 -0
- package/dist/hooks/{use-debounce.mjs → use-debounced-callback.mjs} +4 -4
- package/dist/hooks/use-debounced-callback.mjs.map +1 -0
- package/dist/hooks/use-debounced-value.d.mts +5 -0
- package/dist/hooks/use-debounced-value.mjs +20 -0
- package/dist/hooks/use-debounced-value.mjs.map +1 -0
- package/dist/hooks/use-event-listener.d.mts +21 -0
- package/dist/hooks/use-event-listener.mjs +50 -0
- package/dist/hooks/use-event-listener.mjs.map +1 -0
- package/dist/hooks/use-file-drop.d.mts +14 -0
- package/dist/hooks/use-file-drop.mjs +85 -0
- package/dist/hooks/use-file-drop.mjs.map +1 -0
- package/dist/hooks/use-image.d.mts +2 -1
- package/dist/hooks/use-image.mjs +4 -3
- package/dist/hooks/use-image.mjs.map +1 -1
- package/dist/hooks/use-intersection-observer.d.mts +8 -1
- package/dist/hooks/use-intersection-observer.mjs +37 -5
- package/dist/hooks/use-intersection-observer.mjs.map +1 -1
- package/dist/hooks/use-interval.d.mts +5 -0
- package/dist/hooks/use-interval.mjs +20 -0
- package/dist/hooks/use-interval.mjs.map +1 -0
- package/dist/hooks/use-key-press.d.mts +14 -0
- package/dist/hooks/use-key-press.mjs +85 -0
- package/dist/hooks/use-key-press.mjs.map +1 -0
- package/dist/hooks/use-merged-ref.d.mts +8 -0
- package/dist/hooks/use-merged-ref.mjs +31 -0
- package/dist/hooks/use-merged-ref.mjs.map +1 -0
- package/dist/hooks/use-mutation-observer.d.mts +11 -0
- package/dist/hooks/use-mutation-observer.mjs +47 -0
- package/dist/hooks/use-mutation-observer.mjs.map +1 -0
- package/dist/hooks/use-previous.d.mts +5 -0
- package/dist/hooks/use-previous.mjs +14 -0
- package/dist/hooks/use-previous.mjs.map +1 -0
- package/dist/hooks/use-resize-observer.d.mts +12 -0
- package/dist/hooks/use-resize-observer.mjs +53 -0
- package/dist/hooks/use-resize-observer.mjs.map +1 -0
- package/dist/hooks/use-responsive-size.mjs +2 -2
- package/dist/hooks/use-responsive-size.mjs.map +1 -1
- package/dist/hooks/use-scroll-to-elements.d.mts +7 -5
- package/dist/hooks/use-scroll-to-elements.mjs +52 -27
- package/dist/hooks/use-scroll-to-elements.mjs.map +1 -1
- package/dist/hooks/use-throttled-callback.d.mts +12 -0
- package/dist/hooks/use-throttled-callback.mjs +54 -0
- package/dist/hooks/use-throttled-callback.mjs.map +1 -0
- package/dist/hooks/use-throttled-value.d.mts +9 -0
- package/dist/hooks/use-throttled-value.mjs +16 -0
- package/dist/hooks/use-throttled-value.mjs.map +1 -0
- package/dist/hooks/use-timeout.d.mts +8 -0
- package/dist/hooks/use-timeout.mjs +38 -0
- package/dist/hooks/use-timeout.mjs.map +1 -0
- package/dist/hooks/use-toggle.d.mts +5 -0
- package/dist/hooks/use-toggle.mjs +17 -0
- package/dist/hooks/use-toggle.mjs.map +1 -0
- package/dist/index.d.mts +15 -4
- package/dist/index.mjs +15 -4
- package/package.json +1 -1
- package/dist/hooks/use-debounce.d.mts +0 -14
- package/dist/hooks/use-debounce.mjs.map +0 -1
- package/dist/hooks/use-throttle.d.mts +0 -5
- package/dist/hooks/use-throttle.mjs +0 -42
- package/dist/hooks/use-throttle.mjs.map +0 -1
- package/dist/hooks/use-timeline.d.mts +0 -50
- package/dist/hooks/use-timeline.mjs +0 -211
- package/dist/hooks/use-timeline.mjs.map +0 -1
|
@@ -1,37 +1,62 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
|
|
3
3
|
//#region src/hooks/use-scroll-to-elements.ts
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const resolveContainer = (container) => {
|
|
5
|
+
if (!container) return null;
|
|
6
|
+
return "current" in container ? container.current : container;
|
|
7
|
+
};
|
|
8
|
+
const useScrollToElements = (defaultOptions) => {
|
|
9
|
+
const elementsRef = useRef(/* @__PURE__ */ new Map());
|
|
10
|
+
const registerCallbacksRef = useRef(/* @__PURE__ */ new Map());
|
|
11
|
+
const defaultOptionsRef = useRef(defaultOptions);
|
|
7
12
|
useEffect(() => {
|
|
8
|
-
|
|
13
|
+
defaultOptionsRef.current = defaultOptions;
|
|
9
14
|
});
|
|
10
|
-
const scrollToElement = useCallback((index) => {
|
|
11
|
-
const element = elementRefs.current[index];
|
|
12
|
-
if (!element) return;
|
|
13
|
-
const { offset, ...scrollIntoViewOptions } = optionsRef.current ?? {};
|
|
14
|
-
if (offset != null) {
|
|
15
|
-
const top = element.getBoundingClientRect().top + window.scrollY - offset;
|
|
16
|
-
window.scrollTo({
|
|
17
|
-
top,
|
|
18
|
-
behavior: scrollIntoViewOptions.behavior || "smooth"
|
|
19
|
-
});
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
element.scrollIntoView({
|
|
23
|
-
behavior: "smooth",
|
|
24
|
-
block: "start",
|
|
25
|
-
inline: "start",
|
|
26
|
-
...scrollIntoViewOptions
|
|
27
|
-
});
|
|
28
|
-
}, []);
|
|
29
15
|
return {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
16
|
+
register: useCallback((key) => {
|
|
17
|
+
let callback = registerCallbacksRef.current.get(key);
|
|
18
|
+
if (!callback) {
|
|
19
|
+
callback = (node) => {
|
|
20
|
+
if (node) elementsRef.current.set(key, node);
|
|
21
|
+
else elementsRef.current.delete(key);
|
|
22
|
+
};
|
|
23
|
+
registerCallbacksRef.current.set(key, callback);
|
|
24
|
+
}
|
|
25
|
+
return callback;
|
|
33
26
|
}, []),
|
|
34
|
-
|
|
27
|
+
scrollTo: useCallback((key, options) => {
|
|
28
|
+
const element = elementsRef.current.get(key);
|
|
29
|
+
if (!element) return;
|
|
30
|
+
const { offset, container, ...scrollIntoViewOptions } = {
|
|
31
|
+
...defaultOptionsRef.current,
|
|
32
|
+
...options
|
|
33
|
+
};
|
|
34
|
+
if (offset != null) {
|
|
35
|
+
const containerElement = resolveContainer(container ?? null);
|
|
36
|
+
if (containerElement) {
|
|
37
|
+
const containerRect = containerElement.getBoundingClientRect();
|
|
38
|
+
const elementRect = element.getBoundingClientRect();
|
|
39
|
+
const top = containerElement.scrollTop + (elementRect.top - containerRect.top) - offset;
|
|
40
|
+
containerElement.scrollTo({
|
|
41
|
+
top,
|
|
42
|
+
behavior: scrollIntoViewOptions.behavior || "smooth"
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const top = element.getBoundingClientRect().top + window.scrollY - offset;
|
|
47
|
+
window.scrollTo({
|
|
48
|
+
top,
|
|
49
|
+
behavior: scrollIntoViewOptions.behavior || "smooth"
|
|
50
|
+
});
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
element.scrollIntoView({
|
|
54
|
+
behavior: "smooth",
|
|
55
|
+
block: "start",
|
|
56
|
+
inline: "start",
|
|
57
|
+
...scrollIntoViewOptions
|
|
58
|
+
});
|
|
59
|
+
}, [])
|
|
35
60
|
};
|
|
36
61
|
};
|
|
37
62
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-scroll-to-elements.mjs","names":[],"sources":["../../src/hooks/use-scroll-to-elements.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\ninterface Options extends ScrollIntoViewOptions {\n offset?: number;\n}\n\nconst useScrollToElements = (
|
|
1
|
+
{"version":3,"file":"use-scroll-to-elements.mjs","names":[],"sources":["../../src/hooks/use-scroll-to-elements.ts"],"sourcesContent":["import { type RefObject, useCallback, useEffect, useRef } from 'react';\n\ntype ElementKey = string;\n\ntype ScrollContainer = HTMLElement | RefObject<HTMLElement | null> | null;\n\ninterface Options extends ScrollIntoViewOptions {\n offset?: number;\n // Element to scroll instead of `window` when `offset` is set — e.g. a\n // modal's own scrollable body. `scrollIntoView` (the no-offset path)\n // already finds its nearest scrollable ancestor on its own and doesn't\n // need this.\n container?: ScrollContainer;\n}\n\nconst resolveContainer = (container: ScrollContainer): HTMLElement | null => {\n if (!container) {\n return null;\n }\n return 'current' in container ? container.current : container;\n};\n\nconst useScrollToElements = (defaultOptions?: Options) => {\n const elementsRef = useRef(new Map<ElementKey, HTMLElement>());\n const registerCallbacksRef = useRef(\n new Map<ElementKey, (node: HTMLElement | null) => void>(),\n );\n\n // `defaultOptions` is almost always an inline object literal at the call\n // site, so depending on it directly would recreate `scrollTo` on every\n // render — read the latest value from a ref instead.\n const defaultOptionsRef = useRef(defaultOptions);\n\n useEffect(() => {\n defaultOptionsRef.current = defaultOptions;\n });\n\n // Returns a stable callback per key so React doesn't detach/reattach the\n // ref (and thrash the Map) on every render — only a genuine unmount\n // (node === null) removes the entry.\n const register = useCallback((key: ElementKey) => {\n let callback = registerCallbacksRef.current.get(key);\n\n if (!callback) {\n callback = (node: HTMLElement | null) => {\n if (node) {\n elementsRef.current.set(key, node);\n } else {\n elementsRef.current.delete(key);\n }\n };\n registerCallbacksRef.current.set(key, callback);\n }\n\n return callback;\n }, []);\n\n const scrollTo = useCallback((key: ElementKey, options?: Options) => {\n const element = elementsRef.current.get(key);\n\n if (!element) {\n return;\n }\n\n const { offset, container, ...scrollIntoViewOptions } = {\n ...defaultOptionsRef.current,\n ...options,\n };\n\n // With an offset, `scrollIntoView` and `scrollTo` would both animate\n // the same scroll, fighting each other and settling in the wrong\n // place — use `scrollTo` alone, computed from the element's position\n // before any scrolling starts (not after `scrollIntoView`, where the\n // rect would reflect a mid-animation position).\n if (offset != null) {\n const containerElement = resolveContainer(container ?? null);\n\n if (containerElement) {\n const containerRect = containerElement.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n const top =\n containerElement.scrollTop +\n (elementRect.top - containerRect.top) -\n offset;\n\n containerElement.scrollTo({\n top,\n behavior: scrollIntoViewOptions.behavior || 'smooth',\n });\n return;\n }\n\n const top = element.getBoundingClientRect().top + window.scrollY - offset;\n\n window.scrollTo({\n top,\n behavior: scrollIntoViewOptions.behavior || 'smooth',\n });\n return;\n }\n\n element.scrollIntoView({\n behavior: 'smooth',\n block: 'start',\n inline: 'start',\n ...scrollIntoViewOptions,\n });\n }, []);\n\n return { register, scrollTo };\n};\n\nexport default useScrollToElements;\n"],"mappings":";;;AAeA,MAAM,oBAAoB,cAAmD;AAC3E,KAAI,CAAC,UACH,QAAO;AAET,QAAO,aAAa,YAAY,UAAU,UAAU;;AAGtD,MAAM,uBAAuB,mBAA6B;CACxD,MAAM,cAAc,uBAAO,IAAI,KAA8B,CAAC;CAC9D,MAAM,uBAAuB,uBAC3B,IAAI,KAAqD,CAC1D;CAKD,MAAM,oBAAoB,OAAO,eAAe;AAEhD,iBAAgB;AACd,oBAAkB,UAAU;GAC5B;AA0EF,QAAO;EAAE,UArEQ,aAAa,QAAoB;GAChD,IAAI,WAAW,qBAAqB,QAAQ,IAAI,IAAI;AAEpD,OAAI,CAAC,UAAU;AACb,gBAAY,SAA6B;AACvC,SAAI,KACF,aAAY,QAAQ,IAAI,KAAK,KAAK;SAElC,aAAY,QAAQ,OAAO,IAAI;;AAGnC,yBAAqB,QAAQ,IAAI,KAAK,SAAS;;AAGjD,UAAO;KACN,EAAE,CAAC;EAsDa,UApDF,aAAa,KAAiB,YAAsB;GACnE,MAAM,UAAU,YAAY,QAAQ,IAAI,IAAI;AAE5C,OAAI,CAAC,QACH;GAGF,MAAM,EAAE,QAAQ,WAAW,GAAG,0BAA0B;IACtD,GAAG,kBAAkB;IACrB,GAAG;IACJ;AAOD,OAAI,UAAU,MAAM;IAClB,MAAM,mBAAmB,iBAAiB,aAAa,KAAK;AAE5D,QAAI,kBAAkB;KACpB,MAAM,gBAAgB,iBAAiB,uBAAuB;KAC9D,MAAM,cAAc,QAAQ,uBAAuB;KACnD,MAAM,MACJ,iBAAiB,aAChB,YAAY,MAAM,cAAc,OACjC;AAEF,sBAAiB,SAAS;MACxB;MACA,UAAU,sBAAsB,YAAY;MAC7C,CAAC;AACF;;IAGF,MAAM,MAAM,QAAQ,uBAAuB,CAAC,MAAM,OAAO,UAAU;AAEnE,WAAO,SAAS;KACd;KACA,UAAU,sBAAsB,YAAY;KAC7C,CAAC;AACF;;AAGF,WAAQ,eAAe;IACrB,UAAU;IACV,OAAO;IACP,QAAQ;IACR,GAAG;IACJ,CAAC;KACD,EAAE,CAAC;EAEuB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/hooks/use-throttled-callback.d.ts
|
|
2
|
+
interface Options {
|
|
3
|
+
leading?: boolean;
|
|
4
|
+
trailing?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare const useThrottledCallback: <Args extends unknown[]>(callback: (...args: Args) => void, delay?: number, {
|
|
7
|
+
leading,
|
|
8
|
+
trailing
|
|
9
|
+
}?: Options) => (...args: Args) => void;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { useThrottledCallback };
|
|
12
|
+
//# sourceMappingURL=use-throttled-callback.d.mts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-throttled-callback.ts
|
|
4
|
+
const useThrottledCallback = (callback, delay = 100, { leading = true, trailing = true } = {}) => {
|
|
5
|
+
const callbackRef = useRef(callback);
|
|
6
|
+
const delayRef = useRef(delay);
|
|
7
|
+
const leadingRef = useRef(leading);
|
|
8
|
+
const trailingRef = useRef(trailing);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
callbackRef.current = callback;
|
|
11
|
+
delayRef.current = delay;
|
|
12
|
+
leadingRef.current = leading;
|
|
13
|
+
trailingRef.current = trailing;
|
|
14
|
+
});
|
|
15
|
+
const lastExecutedRef = useRef(null);
|
|
16
|
+
const timeoutRef = useRef(null);
|
|
17
|
+
const lastArgsRef = useRef(null);
|
|
18
|
+
const stableThrottledCallback = useRef(null);
|
|
19
|
+
if (!stableThrottledCallback.current) {
|
|
20
|
+
const invoke = () => {
|
|
21
|
+
lastExecutedRef.current = Date.now();
|
|
22
|
+
timeoutRef.current = null;
|
|
23
|
+
if (lastArgsRef.current) callbackRef.current(...lastArgsRef.current);
|
|
24
|
+
};
|
|
25
|
+
stableThrottledCallback.current = (...args) => {
|
|
26
|
+
lastArgsRef.current = args;
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
const elapsed = lastExecutedRef.current === null ? Infinity : now - lastExecutedRef.current;
|
|
29
|
+
if (elapsed >= delayRef.current) {
|
|
30
|
+
if (timeoutRef.current) {
|
|
31
|
+
clearTimeout(timeoutRef.current);
|
|
32
|
+
timeoutRef.current = null;
|
|
33
|
+
}
|
|
34
|
+
if (leadingRef.current) invoke();
|
|
35
|
+
else {
|
|
36
|
+
lastExecutedRef.current = now;
|
|
37
|
+
if (trailingRef.current) timeoutRef.current = setTimeout(invoke, delayRef.current);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (trailingRef.current && !timeoutRef.current) timeoutRef.current = setTimeout(invoke, delayRef.current - elapsed);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
return () => {
|
|
46
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
47
|
+
};
|
|
48
|
+
}, []);
|
|
49
|
+
return stableThrottledCallback.current;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
export { useThrottledCallback as default };
|
|
54
|
+
//# sourceMappingURL=use-throttled-callback.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-throttled-callback.mjs","names":[],"sources":["../../src/hooks/use-throttled-callback.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\ninterface Options {\n leading?: boolean;\n trailing?: boolean;\n}\n\n// Invokes `callback` at most once per `delay`ms, regardless of how often\n// the returned function is called — the callback-shaped counterpart to\n// useThrottle (which throttles a value). `leading` fires on the first call\n// of a burst immediately; `trailing` schedules one more call (with\n// whatever args arrived last) at the end of the window if calls kept\n// coming. Both default to true, matching useThrottle's fixed behavior.\nconst useThrottledCallback = <Args extends unknown[]>(\n callback: (...args: Args) => void,\n delay = 100,\n { leading = true, trailing = true }: Options = {},\n) => {\n const callbackRef = useRef(callback);\n const delayRef = useRef(delay);\n const leadingRef = useRef(leading);\n const trailingRef = useRef(trailing);\n\n useEffect(() => {\n callbackRef.current = callback;\n delayRef.current = delay;\n leadingRef.current = leading;\n trailingRef.current = trailing;\n });\n\n const lastExecutedRef = useRef<number | null>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastArgsRef = useRef<Args | null>(null);\n\n const stableThrottledCallback = useRef<((...args: Args) => void) | null>(\n null,\n );\n\n if (!stableThrottledCallback.current) {\n const invoke = () => {\n lastExecutedRef.current = Date.now();\n timeoutRef.current = null;\n\n if (lastArgsRef.current) {\n callbackRef.current(...lastArgsRef.current);\n }\n };\n\n stableThrottledCallback.current = (...args: Args) => {\n lastArgsRef.current = args;\n\n const now = Date.now();\n const elapsed =\n lastExecutedRef.current === null\n ? Infinity\n : now - lastExecutedRef.current;\n\n if (elapsed >= delayRef.current) {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n if (leadingRef.current) {\n invoke();\n } else {\n lastExecutedRef.current = now;\n\n if (trailingRef.current) {\n timeoutRef.current = setTimeout(invoke, delayRef.current);\n }\n }\n return;\n }\n\n if (trailingRef.current && !timeoutRef.current) {\n timeoutRef.current = setTimeout(invoke, delayRef.current - elapsed);\n }\n };\n }\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return stableThrottledCallback.current;\n};\n\nexport default useThrottledCallback;\n"],"mappings":";;;AAaA,MAAM,wBACJ,UACA,QAAQ,KACR,EAAE,UAAU,MAAM,WAAW,SAAkB,EAAE,KAC9C;CACH,MAAM,cAAc,OAAO,SAAS;CACpC,MAAM,WAAW,OAAO,MAAM;CAC9B,MAAM,aAAa,OAAO,QAAQ;CAClC,MAAM,cAAc,OAAO,SAAS;AAEpC,iBAAgB;AACd,cAAY,UAAU;AACtB,WAAS,UAAU;AACnB,aAAW,UAAU;AACrB,cAAY,UAAU;GACtB;CAEF,MAAM,kBAAkB,OAAsB,KAAK;CACnD,MAAM,aAAa,OAA6C,KAAK;CACrE,MAAM,cAAc,OAAoB,KAAK;CAE7C,MAAM,0BAA0B,OAC9B,KACD;AAED,KAAI,CAAC,wBAAwB,SAAS;EACpC,MAAM,eAAe;AACnB,mBAAgB,UAAU,KAAK,KAAK;AACpC,cAAW,UAAU;AAErB,OAAI,YAAY,QACd,aAAY,QAAQ,GAAG,YAAY,QAAQ;;AAI/C,0BAAwB,WAAW,GAAG,SAAe;AACnD,eAAY,UAAU;GAEtB,MAAM,MAAM,KAAK,KAAK;GACtB,MAAM,UACJ,gBAAgB,YAAY,OACxB,WACA,MAAM,gBAAgB;AAE5B,OAAI,WAAW,SAAS,SAAS;AAC/B,QAAI,WAAW,SAAS;AACtB,kBAAa,WAAW,QAAQ;AAChC,gBAAW,UAAU;;AAGvB,QAAI,WAAW,QACb,SAAQ;SACH;AACL,qBAAgB,UAAU;AAE1B,SAAI,YAAY,QACd,YAAW,UAAU,WAAW,QAAQ,SAAS,QAAQ;;AAG7D;;AAGF,OAAI,YAAY,WAAW,CAAC,WAAW,QACrC,YAAW,UAAU,WAAW,QAAQ,SAAS,UAAU,QAAQ;;;AAKzE,iBAAgB;AACd,eAAa;AACX,OAAI,WAAW,QACb,cAAa,WAAW,QAAQ;;IAGnC,EAAE,CAAC;AAEN,QAAO,wBAAwB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/hooks/use-throttled-value.d.ts
|
|
2
|
+
interface Options {
|
|
3
|
+
leading?: boolean;
|
|
4
|
+
trailing?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare const useThrottledValue: <T>(value: T, delay?: number, options?: Options) => T;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { useThrottledValue };
|
|
9
|
+
//# sourceMappingURL=use-throttled-value.d.mts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import useThrottledCallback from "./use-throttled-callback.mjs";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/hooks/use-throttled-value.ts
|
|
5
|
+
const useThrottledValue = (value, delay = 100, options = {}) => {
|
|
6
|
+
const [throttledValue, setThrottledValue] = useState(value);
|
|
7
|
+
const throttledSetValue = useThrottledCallback(setThrottledValue, delay, options);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
throttledSetValue(value);
|
|
10
|
+
}, [value, throttledSetValue]);
|
|
11
|
+
return throttledValue;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { useThrottledValue as default };
|
|
16
|
+
//# sourceMappingURL=use-throttled-value.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-throttled-value.mjs","names":[],"sources":["../../src/hooks/use-throttled-value.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport useThrottledCallback from './use-throttled-callback';\n\ninterface Options {\n leading?: boolean;\n trailing?: boolean;\n}\n\nconst useThrottledValue = <T>(\n value: T,\n delay = 100,\n options: Options = {},\n): T => {\n const [throttledValue, setThrottledValue] = useState(value);\n\n const throttledSetValue = useThrottledCallback(\n setThrottledValue,\n delay,\n options,\n );\n\n useEffect(() => {\n throttledSetValue(value);\n // `throttledSetValue`'s identity is stable for the lifetime of the\n // component (see useThrottledCallback), so listing it here doesn't\n // cause any extra re-runs beyond `value` actually changing.\n }, [value, throttledSetValue]);\n\n return throttledValue;\n};\n\nexport default useThrottledValue;\n"],"mappings":";;;;AASA,MAAM,qBACJ,OACA,QAAQ,KACR,UAAmB,EAAE,KACf;CACN,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,MAAM;CAE3D,MAAM,oBAAoB,qBACxB,mBACA,OACA,QACD;AAED,iBAAgB;AACd,oBAAkB,MAAM;IAIvB,CAAC,OAAO,kBAAkB,CAAC;AAE9B,QAAO"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-timeout.ts
|
|
4
|
+
const useTimeout = (callback, delay) => {
|
|
5
|
+
const callbackRef = useRef(callback);
|
|
6
|
+
const delayRef = useRef(delay);
|
|
7
|
+
const timeoutRef = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
callbackRef.current = callback;
|
|
10
|
+
delayRef.current = delay;
|
|
11
|
+
});
|
|
12
|
+
const clear = useCallback(() => {
|
|
13
|
+
if (timeoutRef.current !== null) {
|
|
14
|
+
clearTimeout(timeoutRef.current);
|
|
15
|
+
timeoutRef.current = null;
|
|
16
|
+
}
|
|
17
|
+
}, []);
|
|
18
|
+
const reset = useCallback(() => {
|
|
19
|
+
clear();
|
|
20
|
+
if (delayRef.current === null) return;
|
|
21
|
+
timeoutRef.current = setTimeout(() => {
|
|
22
|
+
timeoutRef.current = null;
|
|
23
|
+
callbackRef.current();
|
|
24
|
+
}, delayRef.current);
|
|
25
|
+
}, [clear]);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
reset();
|
|
28
|
+
return clear;
|
|
29
|
+
}, [delay]);
|
|
30
|
+
return {
|
|
31
|
+
reset,
|
|
32
|
+
clear
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
export { useTimeout as default };
|
|
38
|
+
//# sourceMappingURL=use-timeout.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-timeout.mjs","names":[],"sources":["../../src/hooks/use-timeout.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\n// `delay === null` means inactive (no timer scheduled) — `0` is a valid,\n// distinct delay, same rule useRecursiveTimeout uses. A bare `if (!delay)`\n// guard (as opposed to `if (delay === null)`) is the classic bug this\n// hook exists to avoid: it silently no-ops for a delay of 0 too.\nconst useTimeout = (callback: () => void, delay: number | null) => {\n const callbackRef = useRef(callback);\n const delayRef = useRef(delay);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n callbackRef.current = callback;\n delayRef.current = delay;\n });\n\n const clear = useCallback(() => {\n if (timeoutRef.current !== null) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n }, []);\n\n // Restarts the timer from now, using whatever `delay` is current —\n // e.g. a toast's auto-dismiss timer that should start over each time\n // the user hovers away from it.\n const reset = useCallback(() => {\n clear();\n\n if (delayRef.current === null) {\n return;\n }\n\n timeoutRef.current = setTimeout(() => {\n timeoutRef.current = null;\n callbackRef.current();\n }, delayRef.current);\n }, [clear]);\n\n useEffect(() => {\n reset();\n return clear;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [delay]);\n\n return { reset, clear };\n};\n\nexport default useTimeout;\n"],"mappings":";;;AAMA,MAAM,cAAc,UAAsB,UAAyB;CACjE,MAAM,cAAc,OAAO,SAAS;CACpC,MAAM,WAAW,OAAO,MAAM;CAC9B,MAAM,aAAa,OAA6C,KAAK;AAErE,iBAAgB;AACd,cAAY,UAAU;AACtB,WAAS,UAAU;GACnB;CAEF,MAAM,QAAQ,kBAAkB;AAC9B,MAAI,WAAW,YAAY,MAAM;AAC/B,gBAAa,WAAW,QAAQ;AAChC,cAAW,UAAU;;IAEtB,EAAE,CAAC;CAKN,MAAM,QAAQ,kBAAkB;AAC9B,SAAO;AAEP,MAAI,SAAS,YAAY,KACvB;AAGF,aAAW,UAAU,iBAAiB;AACpC,cAAW,UAAU;AACrB,eAAY,SAAS;KACpB,SAAS,QAAQ;IACnB,CAAC,MAAM,CAAC;AAEX,iBAAgB;AACd,SAAO;AACP,SAAO;IAEN,CAAC,MAAM,CAAC;AAEX,QAAO;EAAE;EAAO;EAAO"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-toggle.ts
|
|
4
|
+
const useToggle = (initial = false) => {
|
|
5
|
+
const [value, setValue] = useState(initial);
|
|
6
|
+
return [
|
|
7
|
+
value,
|
|
8
|
+
useCallback(() => {
|
|
9
|
+
setValue((prev) => !prev);
|
|
10
|
+
}, []),
|
|
11
|
+
setValue
|
|
12
|
+
];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { useToggle as default };
|
|
17
|
+
//# sourceMappingURL=use-toggle.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-toggle.mjs","names":[],"sources":["../../src/hooks/use-toggle.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\n\nconst useToggle = (\n initial = false,\n): [boolean, () => void, (value: boolean) => void] => {\n const [value, setValue] = useState(initial);\n\n const toggle = useCallback(() => {\n setValue(prev => !prev);\n }, []);\n\n return [value, toggle, setValue];\n};\n\nexport default useToggle;\n"],"mappings":";;;AAEA,MAAM,aACJ,UAAU,UAC0C;CACpD,MAAM,CAAC,OAAO,YAAY,SAAS,QAAQ;AAM3C,QAAO;EAAC;EAJO,kBAAkB;AAC/B,aAAS,SAAQ,CAAC,KAAK;KACtB,EAAE,CAAC;EAEiB;EAAS"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useDebouncedCallback } from "./hooks/use-debounced-callback.mjs";
|
|
2
|
+
import { useDebouncedValue } from "./hooks/use-debounced-value.mjs";
|
|
2
3
|
import { useBodyScrollLock } from "./hooks/use-body-scroll-lock.mjs";
|
|
3
4
|
import { useClickOutside } from "./hooks/use-click-outside.mjs";
|
|
4
5
|
import { useControllableState } from "./hooks/use-controllable-state.mjs";
|
|
5
6
|
import { useElementPosition } from "./hooks/use-element-position.mjs";
|
|
6
7
|
import { useElementScroll } from "./hooks/use-element-scroll.mjs";
|
|
8
|
+
import { useEventListener } from "./hooks/use-event-listener.mjs";
|
|
9
|
+
import { useFileDrop } from "./hooks/use-file-drop.mjs";
|
|
7
10
|
import { useFileToDataUrl } from "./hooks/use-file-to-data-url.mjs";
|
|
8
11
|
import { useHistoryState } from "./hooks/use-history-state.mjs";
|
|
9
12
|
import { useIntersectionObserver } from "./hooks/use-intersection-observer.mjs";
|
|
13
|
+
import { useInterval } from "./hooks/use-interval.mjs";
|
|
10
14
|
import { useResponsiveSize } from "./hooks/use-responsive-size.mjs";
|
|
11
15
|
import { useImage } from "./hooks/use-image.mjs";
|
|
16
|
+
import { useKeyPress } from "./hooks/use-key-press.mjs";
|
|
12
17
|
import { useLocalStorage } from "./hooks/use-local-storage.mjs";
|
|
18
|
+
import { useMergedRef } from "./hooks/use-merged-ref.mjs";
|
|
13
19
|
import { useMultiSelect } from "./hooks/use-multi-select.mjs";
|
|
20
|
+
import { useMutationObserver } from "./hooks/use-mutation-observer.mjs";
|
|
21
|
+
import { usePrevious } from "./hooks/use-previous.mjs";
|
|
14
22
|
import { useRecursiveTimeout } from "./hooks/use-recursive-timeout.mjs";
|
|
23
|
+
import { useResizeObserver } from "./hooks/use-resize-observer.mjs";
|
|
15
24
|
import { useScrollToElements } from "./hooks/use-scroll-to-elements.mjs";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
25
|
+
import { useThrottledValue } from "./hooks/use-throttled-value.mjs";
|
|
26
|
+
import { useThrottledCallback } from "./hooks/use-throttled-callback.mjs";
|
|
27
|
+
import { useTimeout } from "./hooks/use-timeout.mjs";
|
|
28
|
+
import { useToggle } from "./hooks/use-toggle.mjs";
|
|
18
29
|
import { useWindowScroll } from "./hooks/use-window-scroll.mjs";
|
|
19
30
|
import { useViewport } from "./hooks/use-viewport.mjs";
|
|
20
31
|
import "./hooks/index.mjs";
|
|
21
|
-
export { useBodyScrollLock, useClickOutside, useControllableState, useDebounce, useElementPosition, useElementScroll, useFileToDataUrl, useHistoryState, useImage, useIntersectionObserver, useLocalStorage, useMultiSelect, useRecursiveTimeout, useResponsiveSize, useScrollToElements, useThrottle,
|
|
32
|
+
export { useBodyScrollLock, useClickOutside, useControllableState, useDebouncedCallback as useDebounce, useDebouncedCallback, useDebouncedValue, useElementPosition, useElementScroll, useEventListener, useFileDrop, useFileToDataUrl, useHistoryState, useImage, useIntersectionObserver, useInterval, useKeyPress, useLocalStorage, useMergedRef, useMultiSelect, useMutationObserver, usePrevious, useRecursiveTimeout, useResizeObserver, useResponsiveSize, useScrollToElements, useThrottledValue as useThrottle, useThrottledCallback, useThrottledValue, useTimeout, useToggle, useViewport, useWindowScroll };
|
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
|
-
import
|
|
1
|
+
import useDebouncedCallback from "./hooks/use-debounced-callback.mjs";
|
|
2
|
+
import useDebouncedValue from "./hooks/use-debounced-value.mjs";
|
|
2
3
|
import useBodyScrollLock from "./hooks/use-body-scroll-lock.mjs";
|
|
3
4
|
import useClickOutside from "./hooks/use-click-outside.mjs";
|
|
4
5
|
import useControllableState from "./hooks/use-controllable-state.mjs";
|
|
5
6
|
import useElementPosition from "./hooks/use-element-position.mjs";
|
|
6
7
|
import useElementScroll from "./hooks/use-element-scroll.mjs";
|
|
8
|
+
import useEventListener from "./hooks/use-event-listener.mjs";
|
|
9
|
+
import useFileDrop from "./hooks/use-file-drop.mjs";
|
|
7
10
|
import useFileToDataUrl from "./hooks/use-file-to-data-url.mjs";
|
|
8
11
|
import useHistoryState from "./hooks/use-history-state.mjs";
|
|
9
12
|
import useIntersectionObserver from "./hooks/use-intersection-observer.mjs";
|
|
13
|
+
import useInterval from "./hooks/use-interval.mjs";
|
|
10
14
|
import useResponsiveSize from "./hooks/use-responsive-size.mjs";
|
|
11
15
|
import useImage from "./hooks/use-image.mjs";
|
|
16
|
+
import useKeyPress from "./hooks/use-key-press.mjs";
|
|
12
17
|
import useLocalStorage from "./hooks/use-local-storage.mjs";
|
|
18
|
+
import useMergedRef from "./hooks/use-merged-ref.mjs";
|
|
13
19
|
import useMultiSelect from "./hooks/use-multi-select.mjs";
|
|
20
|
+
import useMutationObserver from "./hooks/use-mutation-observer.mjs";
|
|
21
|
+
import usePrevious from "./hooks/use-previous.mjs";
|
|
14
22
|
import useRecursiveTimeout from "./hooks/use-recursive-timeout.mjs";
|
|
23
|
+
import useResizeObserver from "./hooks/use-resize-observer.mjs";
|
|
15
24
|
import useScrollToElements from "./hooks/use-scroll-to-elements.mjs";
|
|
16
|
-
import
|
|
17
|
-
import
|
|
25
|
+
import useThrottledCallback from "./hooks/use-throttled-callback.mjs";
|
|
26
|
+
import useThrottledValue from "./hooks/use-throttled-value.mjs";
|
|
27
|
+
import useTimeout from "./hooks/use-timeout.mjs";
|
|
28
|
+
import useToggle from "./hooks/use-toggle.mjs";
|
|
18
29
|
import useWindowScroll from "./hooks/use-window-scroll.mjs";
|
|
19
30
|
import useViewport from "./hooks/use-viewport.mjs";
|
|
20
31
|
import "./hooks/index.mjs";
|
|
21
32
|
|
|
22
|
-
export { useBodyScrollLock, useClickOutside, useControllableState, useDebounce, useElementPosition, useElementScroll, useFileToDataUrl, useHistoryState, useImage, useIntersectionObserver, useLocalStorage, useMultiSelect, useRecursiveTimeout, useResponsiveSize, useScrollToElements, useThrottle,
|
|
33
|
+
export { useBodyScrollLock, useClickOutside, useControllableState, useDebouncedCallback as useDebounce, useDebouncedCallback, useDebouncedValue, useElementPosition, useElementScroll, useEventListener, useFileDrop, useFileToDataUrl, useHistoryState, useImage, useIntersectionObserver, useInterval, useKeyPress, useLocalStorage, useMergedRef, useMultiSelect, useMutationObserver, usePrevious, useRecursiveTimeout, useResizeObserver, useResponsiveSize, useScrollToElements, useThrottledValue as useThrottle, useThrottledCallback, useThrottledValue, useTimeout, useToggle, useViewport, useWindowScroll };
|
package/package.json
CHANGED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
//#region src/hooks/use-debounce.d.ts
|
|
2
|
-
interface Options {
|
|
3
|
-
delay?: number;
|
|
4
|
-
autoInvoke?: boolean;
|
|
5
|
-
leading?: boolean;
|
|
6
|
-
}
|
|
7
|
-
declare const useDebounce: (callback: () => unknown, {
|
|
8
|
-
delay,
|
|
9
|
-
autoInvoke,
|
|
10
|
-
leading
|
|
11
|
-
}: Options, deps?: React.DependencyList) => () => void;
|
|
12
|
-
//#endregion
|
|
13
|
-
export { useDebounce };
|
|
14
|
-
//# sourceMappingURL=use-debounce.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-debounce.mjs","names":[],"sources":["../../src/hooks/use-debounce.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\ninterface Options {\n delay?: number;\n autoInvoke?: boolean;\n leading?: boolean;\n}\n\n// Auto-invokes `callback` (debounced by `delay`ms) whenever `deps` change,\n// and also returns a stable debounced version of `callback` for manual use.\n// `callback` intentionally takes no arguments — the deps-triggered\n// auto-invoke has no natural argument to supply, so an arg-taking callback\n// here was a latent type hole (it was always invoked with zero args\n// regardless of what the callback's own signature claimed).\nconst useDebounce = (\n callback: () => unknown,\n { delay = 100, autoInvoke = true, leading = true }: Options,\n deps: React.DependencyList = [],\n) => {\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const callbackRef = useRef(callback);\n // Read the latest `delay` when the timeout actually fires, instead of\n // baking in whatever `delay` was on the render that created the stable\n // debounced function (which otherwise never updates again).\n const delayRef = useRef(delay);\n const prevDeps = useRef<React.DependencyList | undefined>(undefined);\n\n useEffect(() => {\n callbackRef.current = callback;\n delayRef.current = delay;\n });\n\n const stableDebouncedCallback = useRef<(() => void) | null>(null);\n\n if (!stableDebouncedCallback.current) {\n stableDebouncedCallback.current = () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n timeoutRef.current = setTimeout(() => {\n callbackRef.current();\n }, delayRef.current);\n };\n }\n\n useEffect(() => {\n const depsChanged =\n prevDeps.current === undefined ||\n prevDeps.current.length !== deps.length ||\n prevDeps.current.some((dep, i) => dep !== deps[i]);\n\n if (depsChanged && timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n if (autoInvoke && depsChanged) {\n const isFirstRender = prevDeps.current === undefined;\n\n // `leading` makes the \"first invocation fires immediately, without\n // waiting `delay`ms\" behavior explicit and opt-out-able, instead of\n // an unconditional special case baked into the first render.\n if (isFirstRender && leading) {\n callbackRef.current();\n } else {\n stableDebouncedCallback.current?.();\n }\n }\n\n prevDeps.current = deps;\n });\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return stableDebouncedCallback.current;\n};\n\nexport default useDebounce;\n"],"mappings":";;;AAcA,MAAM,eACJ,UACA,EAAE,QAAQ,KAAK,aAAa,MAAM,UAAU,QAC5C,OAA6B,EAAE,KAC5B;CACH,MAAM,aAAa,OAA6C,KAAK;CACrE,MAAM,cAAc,OAAO,SAAS;CAIpC,MAAM,WAAW,OAAO,MAAM;CAC9B,MAAM,WAAW,OAAyC,OAAU;AAEpE,iBAAgB;AACd,cAAY,UAAU;AACtB,WAAS,UAAU;GACnB;CAEF,MAAM,0BAA0B,OAA4B,KAAK;AAEjE,KAAI,CAAC,wBAAwB,QAC3B,yBAAwB,gBAAgB;AACtC,MAAI,WAAW,QACb,cAAa,WAAW,QAAQ;AAGlC,aAAW,UAAU,iBAAiB;AACpC,eAAY,SAAS;KACpB,SAAS,QAAQ;;AAIxB,iBAAgB;EACd,MAAM,cACJ,SAAS,YAAY,UACrB,SAAS,QAAQ,WAAW,KAAK,UACjC,SAAS,QAAQ,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG;AAEpD,MAAI,eAAe,WAAW,QAC5B,cAAa,WAAW,QAAQ;AAGlC,MAAI,cAAc,YAMhB,KALsB,SAAS,YAAY,UAKtB,QACnB,aAAY,SAAS;MAErB,yBAAwB,WAAW;AAIvC,WAAS,UAAU;GACnB;AAEF,iBAAgB;AACd,eAAa;AACX,OAAI,WAAW,QACb,cAAa,WAAW,QAAQ;;IAGnC,EAAE,CAAC;AAEN,QAAO,wBAAwB"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
|
|
3
|
-
//#region src/hooks/use-throttle.ts
|
|
4
|
-
const useThrottle = (value, delay = 100) => {
|
|
5
|
-
const [throttledValue, setThrottledValue] = useState(value);
|
|
6
|
-
const lastExecutedRef = useRef(0);
|
|
7
|
-
const timeoutRef = useRef(null);
|
|
8
|
-
const latestValueRef = useRef(value);
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
latestValueRef.current = value;
|
|
11
|
-
}, [value]);
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
const now = Date.now();
|
|
14
|
-
const elapsed = now - lastExecutedRef.current;
|
|
15
|
-
if (elapsed >= delay) {
|
|
16
|
-
if (timeoutRef.current) {
|
|
17
|
-
clearTimeout(timeoutRef.current);
|
|
18
|
-
timeoutRef.current = null;
|
|
19
|
-
}
|
|
20
|
-
lastExecutedRef.current = now;
|
|
21
|
-
setThrottledValue(latestValueRef.current);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
const remaining = delay - elapsed;
|
|
25
|
-
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
26
|
-
timeoutRef.current = setTimeout(() => {
|
|
27
|
-
lastExecutedRef.current = Date.now();
|
|
28
|
-
setThrottledValue(latestValueRef.current);
|
|
29
|
-
}, remaining);
|
|
30
|
-
return () => {
|
|
31
|
-
if (timeoutRef.current) {
|
|
32
|
-
clearTimeout(timeoutRef.current);
|
|
33
|
-
timeoutRef.current = null;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
}, [value, delay]);
|
|
37
|
-
return throttledValue;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
//#endregion
|
|
41
|
-
export { useThrottle as default };
|
|
42
|
-
//# sourceMappingURL=use-throttle.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-throttle.mjs","names":[],"sources":["../../src/hooks/use-throttle.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nconst useThrottle = <T>(value: T, delay = 100): T => {\n const [throttledValue, setThrottledValue] = useState(value);\n const lastExecutedRef = useRef(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const latestValueRef = useRef(value);\n\n useEffect(() => {\n latestValueRef.current = value;\n }, [value]);\n\n useEffect(() => {\n const now = Date.now();\n const elapsed = now - lastExecutedRef.current;\n\n if (elapsed >= delay) {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n lastExecutedRef.current = now;\n setThrottledValue(latestValueRef.current);\n return;\n }\n\n const remaining = delay - elapsed;\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n timeoutRef.current = setTimeout(() => {\n lastExecutedRef.current = Date.now();\n setThrottledValue(latestValueRef.current);\n }, remaining);\n\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n };\n }, [value, delay]);\n\n return throttledValue;\n};\n\nexport default useThrottle;\n"],"mappings":";;;AAEA,MAAM,eAAkB,OAAU,QAAQ,QAAW;CACnD,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,MAAM;CAC3D,MAAM,kBAAkB,OAAO,EAAE;CACjC,MAAM,aAAa,OAA6C,KAAK;CACrE,MAAM,iBAAiB,OAAO,MAAM;AAEpC,iBAAgB;AACd,iBAAe,UAAU;IACxB,CAAC,MAAM,CAAC;AAEX,iBAAgB;EACd,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,UAAU,MAAM,gBAAgB;AAEtC,MAAI,WAAW,OAAO;AACpB,OAAI,WAAW,SAAS;AACtB,iBAAa,WAAW,QAAQ;AAChC,eAAW,UAAU;;AAGvB,mBAAgB,UAAU;AAC1B,qBAAkB,eAAe,QAAQ;AACzC;;EAGF,MAAM,YAAY,QAAQ;AAE1B,MAAI,WAAW,QACb,cAAa,WAAW,QAAQ;AAGlC,aAAW,UAAU,iBAAiB;AACpC,mBAAgB,UAAU,KAAK,KAAK;AACpC,qBAAkB,eAAe,QAAQ;KACxC,UAAU;AAEb,eAAa;AACX,OAAI,WAAW,SAAS;AACtB,iBAAa,WAAW,QAAQ;AAChC,eAAW,UAAU;;;IAGxB,CAAC,OAAO,MAAM,CAAC;AAElB,QAAO"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import * as react from "react";
|
|
2
|
-
|
|
3
|
-
//#region src/hooks/use-timeline.d.ts
|
|
4
|
-
interface TimelineStep {
|
|
5
|
-
scale?: number;
|
|
6
|
-
rotate?: {
|
|
7
|
-
x?: number;
|
|
8
|
-
y?: number;
|
|
9
|
-
z?: number;
|
|
10
|
-
};
|
|
11
|
-
position?: {
|
|
12
|
-
x?: number;
|
|
13
|
-
y?: number;
|
|
14
|
-
};
|
|
15
|
-
top?: number;
|
|
16
|
-
left?: number;
|
|
17
|
-
width?: number;
|
|
18
|
-
height?: number;
|
|
19
|
-
zIndex?: number;
|
|
20
|
-
filter?: string;
|
|
21
|
-
backgroundColor?: string;
|
|
22
|
-
opacity?: number;
|
|
23
|
-
selector: string;
|
|
24
|
-
transition: Transition;
|
|
25
|
-
}
|
|
26
|
-
interface Transition {
|
|
27
|
-
duration: number;
|
|
28
|
-
ease?: string;
|
|
29
|
-
delay?: number;
|
|
30
|
-
easeX?: string;
|
|
31
|
-
easeY?: string;
|
|
32
|
-
}
|
|
33
|
-
interface Options {
|
|
34
|
-
steps?: TimelineStep[];
|
|
35
|
-
loading?: boolean;
|
|
36
|
-
immediate?: boolean;
|
|
37
|
-
loop?: boolean;
|
|
38
|
-
}
|
|
39
|
-
declare const useTimeline: ({
|
|
40
|
-
steps,
|
|
41
|
-
loading,
|
|
42
|
-
immediate,
|
|
43
|
-
loop
|
|
44
|
-
}: Options) => {
|
|
45
|
-
ref: react.RefObject<HTMLDivElement | null>;
|
|
46
|
-
completed: boolean;
|
|
47
|
-
};
|
|
48
|
-
//#endregion
|
|
49
|
-
export { useTimeline };
|
|
50
|
-
//# sourceMappingURL=use-timeline.d.mts.map
|