react-simplikit 0.0.2 → 0.0.4
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/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/components/ImpressionArea/index.d.ts +46 -0
- package/dist/components/ImpressionArea/index.js +276 -0
- package/dist/components/Separated/index.d.ts +38 -0
- package/dist/components/Separated/index.js +40 -0
- package/dist/components/SwitchCase/index.d.ts +46 -0
- package/dist/components/SwitchCase/index.js +35 -0
- package/dist/hooks/useAsyncEffect/index.d.ts +25 -0
- package/dist/hooks/useAsyncEffect/index.js +43 -0
- package/dist/hooks/useBooleanState/index.d.ts +19 -0
- package/dist/hooks/useBooleanState/index.js +45 -0
- package/dist/hooks/useCallbackOncePerRender/index.d.ts +41 -0
- package/dist/hooks/useCallbackOncePerRender/index.js +59 -0
- package/dist/hooks/useDebounce/index.d.ts +48 -0
- package/dist/hooks/useDebounce/index.js +123 -0
- package/dist/hooks/useImpressionRef/index.d.ts +38 -0
- package/dist/hooks/useImpressionRef/index.js +237 -0
- package/dist/hooks/useInputState/index.d.ts +27 -0
- package/dist/hooks/useInputState/index.js +45 -0
- package/dist/hooks/useIntersectionObserver/index.d.ts +33 -0
- package/dist/hooks/useIntersectionObserver/index.js +91 -0
- package/dist/hooks/useInterval/index.d.ts +37 -0
- package/dist/hooks/useInterval/index.js +64 -0
- package/dist/hooks/useLoading/index.d.ts +37 -0
- package/dist/hooks/useLoading/index.js +61 -0
- package/dist/hooks/useOutsideClickEffect/index.d.ts +27 -0
- package/dist/hooks/useOutsideClickEffect/index.js +70 -0
- package/dist/hooks/usePreservedCallback/index.d.ts +30 -0
- package/dist/hooks/usePreservedCallback/index.js +41 -0
- package/dist/hooks/usePreservedReference/index.d.ts +42 -0
- package/dist/hooks/usePreservedReference/index.js +44 -0
- package/dist/hooks/usePrevious/index.d.ts +21 -0
- package/dist/hooks/usePrevious/index.js +47 -0
- package/dist/hooks/useRefEffect/index.d.ts +31 -0
- package/dist/hooks/useRefEffect/index.js +68 -0
- package/dist/hooks/useStorageState/index.d.ts +50 -0
- package/dist/hooks/useStorageState/index.js +168 -0
- package/dist/hooks/useThrottle/index.d.ts +47 -0
- package/dist/hooks/useThrottle/index.js +147 -0
- package/dist/hooks/useTimeout/index.d.ts +30 -0
- package/dist/hooks/useTimeout/index.js +53 -0
- package/dist/hooks/useToggle/index.d.ts +30 -0
- package/dist/hooks/useToggle/index.js +36 -0
- package/dist/hooks/useVisibilityEvent/index.d.ts +27 -0
- package/dist/hooks/useVisibilityEvent/index.js +46 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +761 -0
- package/dist/utils/buildContext/index.d.ts +38 -0
- package/dist/utils/buildContext/index.js +55 -0
- package/dist/utils/mergeRefs/index.d.ts +37 -0
- package/dist/utils/mergeRefs/index.js +45 -0
- package/esm/components/ImpressionArea/index.d.mts +46 -0
- package/esm/components/ImpressionArea/index.mjs +249 -0
- package/esm/components/Separated/index.d.mts +38 -0
- package/esm/components/Separated/index.mjs +13 -0
- package/esm/components/SwitchCase/index.d.mts +46 -0
- package/esm/components/SwitchCase/index.mjs +8 -0
- package/esm/hooks/useAsyncEffect/index.d.mts +25 -0
- package/esm/hooks/useAsyncEffect/index.mjs +16 -0
- package/esm/hooks/useBooleanState/index.d.mts +19 -0
- package/esm/hooks/useBooleanState/index.mjs +18 -0
- package/esm/hooks/useCallbackOncePerRender/index.d.mts +41 -0
- package/esm/hooks/useCallbackOncePerRender/index.mjs +32 -0
- package/esm/hooks/useDebounce/index.d.mts +48 -0
- package/esm/hooks/useDebounce/index.mjs +96 -0
- package/esm/hooks/useImpressionRef/index.d.mts +38 -0
- package/esm/hooks/useImpressionRef/index.mjs +210 -0
- package/esm/hooks/useInputState/index.d.mts +27 -0
- package/esm/hooks/useInputState/index.mjs +18 -0
- package/esm/hooks/useIntersectionObserver/index.d.mts +33 -0
- package/esm/hooks/useIntersectionObserver/index.mjs +64 -0
- package/esm/hooks/useInterval/index.d.mts +37 -0
- package/esm/hooks/useInterval/index.mjs +37 -0
- package/esm/hooks/useLoading/index.d.mts +37 -0
- package/esm/hooks/useLoading/index.mjs +34 -0
- package/esm/hooks/useOutsideClickEffect/index.d.mts +27 -0
- package/esm/hooks/useOutsideClickEffect/index.mjs +43 -0
- package/esm/hooks/usePreservedCallback/index.d.mts +30 -0
- package/esm/hooks/usePreservedCallback/index.mjs +14 -0
- package/esm/hooks/usePreservedReference/index.d.mts +42 -0
- package/esm/hooks/usePreservedReference/index.mjs +17 -0
- package/esm/hooks/usePrevious/index.d.mts +21 -0
- package/esm/hooks/usePrevious/index.mjs +20 -0
- package/esm/hooks/useRefEffect/index.d.mts +31 -0
- package/esm/hooks/useRefEffect/index.mjs +41 -0
- package/esm/hooks/useStorageState/index.d.mts +50 -0
- package/esm/hooks/useStorageState/index.mjs +141 -0
- package/esm/hooks/useThrottle/index.d.mts +47 -0
- package/esm/hooks/useThrottle/index.mjs +120 -0
- package/esm/hooks/useTimeout/index.d.mts +30 -0
- package/esm/hooks/useTimeout/index.mjs +26 -0
- package/esm/hooks/useToggle/index.d.mts +30 -0
- package/esm/hooks/useToggle/index.mjs +9 -0
- package/esm/hooks/useVisibilityEvent/index.d.mts +27 -0
- package/esm/hooks/useVisibilityEvent/index.mjs +19 -0
- package/esm/index.d.mts +26 -0
- package/esm/index.mjs +711 -0
- package/esm/utils/buildContext/index.d.mts +38 -0
- package/esm/utils/buildContext/index.mjs +28 -0
- package/esm/utils/mergeRefs/index.d.mts +37 -0
- package/esm/utils/mergeRefs/index.mjs +18 -0
- package/package.json +87 -7
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DependencyList } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* A React hook that ensures a callback function is executed only once, regardless of
|
|
6
|
+
* how many times it's called. This is useful for one-time operations that should not
|
|
7
|
+
* be repeated, even if the component re-renders.
|
|
8
|
+
*
|
|
9
|
+
* @param {() => void} callback - The callback function to be executed once.
|
|
10
|
+
* @param {DependencyList} deps - Dependencies array that will trigger a new one-time execution when changed.
|
|
11
|
+
*
|
|
12
|
+
* @returns {(...args: any[]) => void} A memoized function that will only execute once until dependencies change.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* import { useCallbackOncePerRender } from 'react-simplikit';
|
|
16
|
+
*
|
|
17
|
+
* function Component() {
|
|
18
|
+
* const handleOneTimeEvent = useCallbackOncePerRender(() => {
|
|
19
|
+
* console.log('This will only run once');
|
|
20
|
+
* }, []);
|
|
21
|
+
*
|
|
22
|
+
* return <button onClick={handleOneTimeEvent}>Click me</button>;
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // With dependencies
|
|
27
|
+
* function TrackingComponent({ userId }: { userId: string }) {
|
|
28
|
+
* const trackUserVisit = useCallbackOncePerRender(() => {
|
|
29
|
+
* analytics.trackVisit(userId);
|
|
30
|
+
* }, [userId]);
|
|
31
|
+
*
|
|
32
|
+
* useEffect(() => {
|
|
33
|
+
* trackUserVisit();
|
|
34
|
+
* }, [trackUserVisit]);
|
|
35
|
+
*
|
|
36
|
+
* return <div>User page</div>;
|
|
37
|
+
* }
|
|
38
|
+
*/
|
|
39
|
+
declare function useCallbackOncePerRender<F extends (...args: any[]) => void>(callback: F, deps: DependencyList): (...args: Parameters<F>) => void;
|
|
40
|
+
|
|
41
|
+
export { useCallbackOncePerRender };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/hooks/useCallbackOncePerRender/index.ts
|
|
21
|
+
var useCallbackOncePerRender_exports = {};
|
|
22
|
+
__export(useCallbackOncePerRender_exports, {
|
|
23
|
+
useCallbackOncePerRender: () => useCallbackOncePerRender
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(useCallbackOncePerRender_exports);
|
|
26
|
+
|
|
27
|
+
// src/hooks/useCallbackOncePerRender/useCallbackOncePerRender.ts
|
|
28
|
+
var import_react2 = require("react");
|
|
29
|
+
|
|
30
|
+
// src/hooks/usePreservedCallback/usePreservedCallback.ts
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
function usePreservedCallback(callback) {
|
|
33
|
+
const callbackRef = (0, import_react.useRef)(callback);
|
|
34
|
+
(0, import_react.useEffect)(() => {
|
|
35
|
+
callbackRef.current = callback;
|
|
36
|
+
}, [callback]);
|
|
37
|
+
return (0, import_react.useCallback)((...args) => {
|
|
38
|
+
return callbackRef.current(...args);
|
|
39
|
+
}, []);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/hooks/useCallbackOncePerRender/useCallbackOncePerRender.ts
|
|
43
|
+
function useCallbackOncePerRender(callback, deps) {
|
|
44
|
+
const hasFired = (0, import_react2.useRef)(false);
|
|
45
|
+
(0, import_react2.useEffect)(() => {
|
|
46
|
+
hasFired.current = false;
|
|
47
|
+
}, deps);
|
|
48
|
+
return usePreservedCallback((...args) => {
|
|
49
|
+
if (hasFired.current) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
callback(...args);
|
|
53
|
+
hasFired.current = true;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
57
|
+
0 && (module.exports = {
|
|
58
|
+
useCallbackOncePerRender
|
|
59
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
type DebouncedFunction<F extends (...args: any[]) => void> = {
|
|
2
|
+
(...args: Parameters<F>): void;
|
|
3
|
+
cancel: () => void;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
type DebounceOptions = {
|
|
7
|
+
leading?: boolean;
|
|
8
|
+
trailing?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* @description
|
|
12
|
+
* `useDebounce` is a React hook that returns a debounced version of the provided callback function.
|
|
13
|
+
* It helps optimize event handling by delaying function execution and grouping multiple calls into one.
|
|
14
|
+
*
|
|
15
|
+
* @template {(...args: unknown[]) => unknown} F - The type of the callback function.
|
|
16
|
+
* @param {F} callback - The function to debounce.
|
|
17
|
+
* @param {number} wait - The number of milliseconds to delay the function execution.
|
|
18
|
+
* @param {DebounceOptions} [options] - Configuration options for debounce behavior.
|
|
19
|
+
* @param {boolean} [options.leading=false] - If `true`, the function is called at the start of the sequence.
|
|
20
|
+
* @param {boolean} [options.trailing=true] - If `true`, the function is called at the end of the sequence.
|
|
21
|
+
*
|
|
22
|
+
* @returns {F & { cancel: () => void }} A debounced function that delays invoking the callback.
|
|
23
|
+
* It also includes a `cancel` method to cancel any pending debounced execution.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* function SearchInput() {
|
|
27
|
+
* const [query, setQuery] = useState('');
|
|
28
|
+
*
|
|
29
|
+
* const debouncedSearch = useDebounce((value: string) => {
|
|
30
|
+
* // Actual API call
|
|
31
|
+
* searchAPI(value);
|
|
32
|
+
* }, 300);
|
|
33
|
+
*
|
|
34
|
+
* return (
|
|
35
|
+
* <input
|
|
36
|
+
* value={query}
|
|
37
|
+
* onChange={e => {
|
|
38
|
+
* setQuery(e.target.value);
|
|
39
|
+
* debouncedSearch(e.target.value);
|
|
40
|
+
* }}
|
|
41
|
+
* placeholder="Enter search term"
|
|
42
|
+
* />
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
*/
|
|
46
|
+
declare function useDebounce<F extends (...args: any[]) => unknown>(callback: F, wait: number, options?: DebounceOptions): DebouncedFunction<F>;
|
|
47
|
+
|
|
48
|
+
export { useDebounce };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/hooks/useDebounce/index.ts
|
|
21
|
+
var useDebounce_exports = {};
|
|
22
|
+
__export(useDebounce_exports, {
|
|
23
|
+
useDebounce: () => useDebounce
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(useDebounce_exports);
|
|
26
|
+
|
|
27
|
+
// src/hooks/useDebounce/useDebounce.ts
|
|
28
|
+
var import_react2 = require("react");
|
|
29
|
+
var import_react3 = require("react");
|
|
30
|
+
|
|
31
|
+
// src/hooks/usePreservedCallback/usePreservedCallback.ts
|
|
32
|
+
var import_react = require("react");
|
|
33
|
+
function usePreservedCallback(callback) {
|
|
34
|
+
const callbackRef = (0, import_react.useRef)(callback);
|
|
35
|
+
(0, import_react.useEffect)(() => {
|
|
36
|
+
callbackRef.current = callback;
|
|
37
|
+
}, [callback]);
|
|
38
|
+
return (0, import_react.useCallback)((...args) => {
|
|
39
|
+
return callbackRef.current(...args);
|
|
40
|
+
}, []);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/hooks/useDebounce/debounce.ts
|
|
44
|
+
function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
45
|
+
let pendingThis = void 0;
|
|
46
|
+
let pendingArgs = null;
|
|
47
|
+
const leading = edges != null && edges.includes("leading");
|
|
48
|
+
const trailing = edges == null || edges.includes("trailing");
|
|
49
|
+
const invoke = () => {
|
|
50
|
+
if (pendingArgs !== null) {
|
|
51
|
+
func.apply(pendingThis, pendingArgs);
|
|
52
|
+
pendingThis = void 0;
|
|
53
|
+
pendingArgs = null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const onTimerEnd = () => {
|
|
57
|
+
if (trailing) {
|
|
58
|
+
invoke();
|
|
59
|
+
}
|
|
60
|
+
cancel();
|
|
61
|
+
};
|
|
62
|
+
let timeoutId = null;
|
|
63
|
+
const schedule = () => {
|
|
64
|
+
if (timeoutId != null) {
|
|
65
|
+
clearTimeout(timeoutId);
|
|
66
|
+
}
|
|
67
|
+
timeoutId = setTimeout(() => {
|
|
68
|
+
timeoutId = null;
|
|
69
|
+
onTimerEnd();
|
|
70
|
+
}, debounceMs);
|
|
71
|
+
};
|
|
72
|
+
const cancelTimer = () => {
|
|
73
|
+
if (timeoutId !== null) {
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
timeoutId = null;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const cancel = () => {
|
|
79
|
+
cancelTimer();
|
|
80
|
+
pendingThis = void 0;
|
|
81
|
+
pendingArgs = null;
|
|
82
|
+
};
|
|
83
|
+
const debounced = function(...args) {
|
|
84
|
+
pendingThis = this;
|
|
85
|
+
pendingArgs = args;
|
|
86
|
+
const isFirstCall = timeoutId == null;
|
|
87
|
+
schedule();
|
|
88
|
+
if (leading && isFirstCall) {
|
|
89
|
+
invoke();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
debounced.cancel = cancel;
|
|
93
|
+
return debounced;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/hooks/useDebounce/useDebounce.ts
|
|
97
|
+
function useDebounce(callback, wait, options = {}) {
|
|
98
|
+
const preservedCallback = usePreservedCallback(callback);
|
|
99
|
+
const { leading = false, trailing = true } = options;
|
|
100
|
+
const edges = (0, import_react3.useMemo)(() => {
|
|
101
|
+
const _edges = [];
|
|
102
|
+
if (leading) {
|
|
103
|
+
_edges.push("leading");
|
|
104
|
+
}
|
|
105
|
+
if (trailing) {
|
|
106
|
+
_edges.push("trailing");
|
|
107
|
+
}
|
|
108
|
+
return _edges;
|
|
109
|
+
}, [leading, trailing]);
|
|
110
|
+
const debounced = (0, import_react3.useMemo)(() => {
|
|
111
|
+
return debounce(preservedCallback, wait, { edges });
|
|
112
|
+
}, [preservedCallback, wait, edges]);
|
|
113
|
+
(0, import_react2.useEffect)(() => {
|
|
114
|
+
return () => {
|
|
115
|
+
debounced.cancel();
|
|
116
|
+
};
|
|
117
|
+
}, [debounced]);
|
|
118
|
+
return debounced;
|
|
119
|
+
}
|
|
120
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
121
|
+
0 && (module.exports = {
|
|
122
|
+
useDebounce
|
|
123
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
type UseImpressionRefOptions = Partial<{
|
|
2
|
+
onImpressionStart: () => void;
|
|
3
|
+
onImpressionEnd: () => void;
|
|
4
|
+
rootMargin: string;
|
|
5
|
+
areaThreshold: number;
|
|
6
|
+
timeThreshold: number;
|
|
7
|
+
}>;
|
|
8
|
+
/**
|
|
9
|
+
* @description
|
|
10
|
+
* `useImpressionRef` is a custom hook that measures the time a specific DOM element is visible on the screen and executes callbacks when the element enters or exits the viewport.
|
|
11
|
+
* This hook uses `IntersectionObserver` and the `Visibility API` to track the element's visibility.
|
|
12
|
+
*
|
|
13
|
+
* @param options - An options object for tracking the element's visibility.
|
|
14
|
+
* - `onImpressionStart`: Callback function executed when the element enters the view
|
|
15
|
+
* - `onImpressionEnd`: Callback function executed when the element exits the view
|
|
16
|
+
* - `timeThreshold`: Minimum time the element must be visible (in milliseconds)
|
|
17
|
+
* - `areaThreshold`: Minimum ratio of the element that must be visible (0 to 1)
|
|
18
|
+
* - `rootMargin`: Margin to adjust the detection area
|
|
19
|
+
*
|
|
20
|
+
* @returns A function to set the element. Attach this function to the `ref` attribute, and the callbacks will be executed whenever the element's visibility changes.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* import { useImpressionRef } from 'react-simplikit';
|
|
24
|
+
*
|
|
25
|
+
* function Component() {
|
|
26
|
+
* const ref = useImpressionRef<HTMLDivElement>({
|
|
27
|
+
* onImpressionStart: () => console.log('Element entered view'),
|
|
28
|
+
* onImpressionEnd: () => console.log('Element exited view'),
|
|
29
|
+
* timeThreshold: 1000,
|
|
30
|
+
* areaThreshold: 0.5,
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* return <div ref={ref}>Track my visibility!</div>;
|
|
34
|
+
* }
|
|
35
|
+
*/
|
|
36
|
+
declare function useImpressionRef<Element extends HTMLElement>({ onImpressionStart, onImpressionEnd, rootMargin, areaThreshold, timeThreshold, }: UseImpressionRefOptions): (element: Element | null) => void;
|
|
37
|
+
|
|
38
|
+
export { type UseImpressionRefOptions, useImpressionRef };
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/hooks/useImpressionRef/index.ts
|
|
21
|
+
var useImpressionRef_exports = {};
|
|
22
|
+
__export(useImpressionRef_exports, {
|
|
23
|
+
useImpressionRef: () => useImpressionRef
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(useImpressionRef_exports);
|
|
26
|
+
|
|
27
|
+
// src/hooks/useImpressionRef/useImpressionRef.ts
|
|
28
|
+
var import_react6 = require("react");
|
|
29
|
+
|
|
30
|
+
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
31
|
+
var import_react3 = require("react");
|
|
32
|
+
|
|
33
|
+
// src/hooks/usePreservedCallback/usePreservedCallback.ts
|
|
34
|
+
var import_react = require("react");
|
|
35
|
+
function usePreservedCallback(callback) {
|
|
36
|
+
const callbackRef = (0, import_react.useRef)(callback);
|
|
37
|
+
(0, import_react.useEffect)(() => {
|
|
38
|
+
callbackRef.current = callback;
|
|
39
|
+
}, [callback]);
|
|
40
|
+
return (0, import_react.useCallback)((...args) => {
|
|
41
|
+
return callbackRef.current(...args);
|
|
42
|
+
}, []);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/hooks/useRefEffect/useRefEffect.ts
|
|
46
|
+
var import_react2 = require("react");
|
|
47
|
+
function useRefEffect(callback, deps) {
|
|
48
|
+
const preservedCallback = usePreservedCallback(callback);
|
|
49
|
+
const cleanupCallbackRef = (0, import_react2.useRef)(() => {
|
|
50
|
+
});
|
|
51
|
+
const effect = (0, import_react2.useCallback)(
|
|
52
|
+
(element) => {
|
|
53
|
+
cleanupCallbackRef.current();
|
|
54
|
+
cleanupCallbackRef.current = () => {
|
|
55
|
+
};
|
|
56
|
+
if (element == null) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const cleanup = preservedCallback(element);
|
|
60
|
+
if (typeof cleanup === "function") {
|
|
61
|
+
cleanupCallbackRef.current = cleanup;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
65
|
+
[preservedCallback, ...deps]
|
|
66
|
+
);
|
|
67
|
+
return effect;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
71
|
+
function useIntersectionObserver(callback, options) {
|
|
72
|
+
const preservedCallback = usePreservedCallback(callback);
|
|
73
|
+
const observer = (0, import_react3.useMemo)(() => {
|
|
74
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
return new IntersectionObserver(([entry]) => {
|
|
78
|
+
preservedCallback(entry);
|
|
79
|
+
}, options);
|
|
80
|
+
}, [preservedCallback, options]);
|
|
81
|
+
return useRefEffect(
|
|
82
|
+
(element) => {
|
|
83
|
+
observer?.observe(element);
|
|
84
|
+
return () => {
|
|
85
|
+
observer?.unobserve(element);
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
[preservedCallback, options]
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/hooks/useVisibilityEvent/useVisibilityEvent.ts
|
|
93
|
+
var import_react4 = require("react");
|
|
94
|
+
function useVisibilityEvent(callback, options = {}) {
|
|
95
|
+
const handleVisibilityChange = (0, import_react4.useCallback)(() => {
|
|
96
|
+
callback(document.visibilityState);
|
|
97
|
+
}, [callback]);
|
|
98
|
+
(0, import_react4.useEffect)(() => {
|
|
99
|
+
if (options?.immediate ?? false) {
|
|
100
|
+
handleVisibilityChange();
|
|
101
|
+
}
|
|
102
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
103
|
+
return () => {
|
|
104
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
105
|
+
};
|
|
106
|
+
}, [handleVisibilityChange, options?.immediate]);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/hooks/useImpressionRef/useDebouncedCallback.ts
|
|
110
|
+
var import_react5 = require("react");
|
|
111
|
+
|
|
112
|
+
// src/hooks/useDebounce/debounce.ts
|
|
113
|
+
function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
114
|
+
let pendingThis = void 0;
|
|
115
|
+
let pendingArgs = null;
|
|
116
|
+
const leading = edges != null && edges.includes("leading");
|
|
117
|
+
const trailing = edges == null || edges.includes("trailing");
|
|
118
|
+
const invoke = () => {
|
|
119
|
+
if (pendingArgs !== null) {
|
|
120
|
+
func.apply(pendingThis, pendingArgs);
|
|
121
|
+
pendingThis = void 0;
|
|
122
|
+
pendingArgs = null;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const onTimerEnd = () => {
|
|
126
|
+
if (trailing) {
|
|
127
|
+
invoke();
|
|
128
|
+
}
|
|
129
|
+
cancel();
|
|
130
|
+
};
|
|
131
|
+
let timeoutId = null;
|
|
132
|
+
const schedule = () => {
|
|
133
|
+
if (timeoutId != null) {
|
|
134
|
+
clearTimeout(timeoutId);
|
|
135
|
+
}
|
|
136
|
+
timeoutId = setTimeout(() => {
|
|
137
|
+
timeoutId = null;
|
|
138
|
+
onTimerEnd();
|
|
139
|
+
}, debounceMs);
|
|
140
|
+
};
|
|
141
|
+
const cancelTimer = () => {
|
|
142
|
+
if (timeoutId !== null) {
|
|
143
|
+
clearTimeout(timeoutId);
|
|
144
|
+
timeoutId = null;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const cancel = () => {
|
|
148
|
+
cancelTimer();
|
|
149
|
+
pendingThis = void 0;
|
|
150
|
+
pendingArgs = null;
|
|
151
|
+
};
|
|
152
|
+
const debounced = function(...args) {
|
|
153
|
+
pendingThis = this;
|
|
154
|
+
pendingArgs = args;
|
|
155
|
+
const isFirstCall = timeoutId == null;
|
|
156
|
+
schedule();
|
|
157
|
+
if (leading && isFirstCall) {
|
|
158
|
+
invoke();
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
debounced.cancel = cancel;
|
|
162
|
+
return debounced;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/hooks/useImpressionRef/useDebouncedCallback.ts
|
|
166
|
+
function useDebouncedCallback({
|
|
167
|
+
onChange,
|
|
168
|
+
timeThreshold
|
|
169
|
+
}) {
|
|
170
|
+
const handleChange = usePreservedCallback(onChange);
|
|
171
|
+
const ref = (0, import_react5.useRef)({ value: false, clearPreviousDebounce: () => {
|
|
172
|
+
} });
|
|
173
|
+
(0, import_react5.useEffect)(() => {
|
|
174
|
+
const current = ref.current;
|
|
175
|
+
return () => {
|
|
176
|
+
current.clearPreviousDebounce();
|
|
177
|
+
};
|
|
178
|
+
}, []);
|
|
179
|
+
return (0, import_react5.useCallback)(
|
|
180
|
+
(nextValue) => {
|
|
181
|
+
if (nextValue === ref.current.value) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const debounced = debounce(() => {
|
|
185
|
+
handleChange(nextValue);
|
|
186
|
+
ref.current.value = nextValue;
|
|
187
|
+
}, timeThreshold);
|
|
188
|
+
ref.current.clearPreviousDebounce();
|
|
189
|
+
debounced();
|
|
190
|
+
ref.current.clearPreviousDebounce = debounced.cancel;
|
|
191
|
+
},
|
|
192
|
+
[handleChange, timeThreshold]
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/hooks/useImpressionRef/useImpressionRef.ts
|
|
197
|
+
function useImpressionRef({
|
|
198
|
+
onImpressionStart = () => {
|
|
199
|
+
},
|
|
200
|
+
onImpressionEnd = () => {
|
|
201
|
+
},
|
|
202
|
+
rootMargin,
|
|
203
|
+
areaThreshold = 0,
|
|
204
|
+
timeThreshold = 0
|
|
205
|
+
}) {
|
|
206
|
+
const impressionStartHandler = usePreservedCallback(onImpressionStart);
|
|
207
|
+
const impressionEndHandler = usePreservedCallback(onImpressionEnd);
|
|
208
|
+
const isIntersectingRef = (0, import_react6.useRef)(false);
|
|
209
|
+
const impressionEventHandler = useDebouncedCallback({
|
|
210
|
+
timeThreshold,
|
|
211
|
+
onChange: (impressed) => {
|
|
212
|
+
(impressed ? impressionStartHandler : impressionEndHandler)();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
useVisibilityEvent((documentVisible) => {
|
|
216
|
+
if (!isIntersectingRef.current) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
impressionEventHandler(documentVisible === "visible");
|
|
220
|
+
});
|
|
221
|
+
return useIntersectionObserver(
|
|
222
|
+
(entry) => {
|
|
223
|
+
if (document.visibilityState === "hidden") {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const currentRatio = entry.intersectionRatio;
|
|
227
|
+
const isIntersecting = areaThreshold === 0 ? entry.isIntersecting : currentRatio >= areaThreshold;
|
|
228
|
+
isIntersectingRef.current = isIntersecting;
|
|
229
|
+
impressionEventHandler(isIntersecting);
|
|
230
|
+
},
|
|
231
|
+
{ rootMargin, threshold: areaThreshold }
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
235
|
+
0 && (module.exports = {
|
|
236
|
+
useImpressionRef
|
|
237
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ChangeEventHandler } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* `useInputState` is a React hook that manages an input state with optional value transformation.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} [initialValue=""] - The initial value of the input. Defaults to an empty string (`""`).
|
|
8
|
+
* @param {(value: string) => string} [transformValue=(v: string) => v] - A function to transform the input value.
|
|
9
|
+
* Defaults to an identity function that returns the input unchanged.
|
|
10
|
+
*
|
|
11
|
+
* @returns {readonly [value: string, onChange: (value: string) => void]} A tuple containing:
|
|
12
|
+
* - value `string` - The current state value.
|
|
13
|
+
* - onChange `(value: string) => void` - A function to update the state.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import { useInputState } from 'react-simplikit';
|
|
17
|
+
*
|
|
18
|
+
* function Example() {
|
|
19
|
+
* const [value, setValue] = useInputState('');
|
|
20
|
+
* return <input type="text" value={value} onChange={setValue} />;
|
|
21
|
+
* }
|
|
22
|
+
*/
|
|
23
|
+
declare function useInputState(initialValue?: string, transformValue?: (value: string) => string): readonly [string, ChangeEventHandler<HTMLElement & {
|
|
24
|
+
value: string;
|
|
25
|
+
}>];
|
|
26
|
+
|
|
27
|
+
export { useInputState };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/hooks/useInputState/index.ts
|
|
21
|
+
var useInputState_exports = {};
|
|
22
|
+
__export(useInputState_exports, {
|
|
23
|
+
useInputState: () => useInputState
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(useInputState_exports);
|
|
26
|
+
|
|
27
|
+
// src/hooks/useInputState/useInputState.ts
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
function useInputState(initialValue = "", transformValue = echo) {
|
|
30
|
+
const [value, setValue] = (0, import_react.useState)(initialValue);
|
|
31
|
+
const handleValueChange = (0, import_react.useCallback)(
|
|
32
|
+
({ target: { value: value2 } }) => {
|
|
33
|
+
setValue(transformValue(value2));
|
|
34
|
+
},
|
|
35
|
+
[transformValue]
|
|
36
|
+
);
|
|
37
|
+
return [value, handleValueChange];
|
|
38
|
+
}
|
|
39
|
+
function echo(v) {
|
|
40
|
+
return v;
|
|
41
|
+
}
|
|
42
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
43
|
+
0 && (module.exports = {
|
|
44
|
+
useInputState
|
|
45
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* `useIntersectionObserver` is a custom hook that detects whether a specific DOM element is visible on the screen.
|
|
4
|
+
* This hook uses the `IntersectionObserver` API to execute a callback when the element enters or exits the viewport.
|
|
5
|
+
*
|
|
6
|
+
* @param callback - A callback function that is executed when the visibility of the element changes.
|
|
7
|
+
* You can check `entry.isIntersecting` to determine if the element is in view.
|
|
8
|
+
* @param options - Options for the `IntersectionObserver`.
|
|
9
|
+
* You can specify values such as `root`, `rootMargin`, and `threshold`.
|
|
10
|
+
*
|
|
11
|
+
* @returns A function to set the element. Attach this function to the `ref` attribute, and the `callback` will be executed whenever the element's visibility changes.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* import { useIntersectionObserver } from 'react-simplikit';
|
|
15
|
+
*
|
|
16
|
+
* function Component() {
|
|
17
|
+
* const ref = useIntersectionObserver<HTMLDivElement>(
|
|
18
|
+
* entry => {
|
|
19
|
+
* if (entry.isIntersecting) {
|
|
20
|
+
* console.log('Element is in view:', entry.target);
|
|
21
|
+
* } else {
|
|
22
|
+
* console.log('Element is out of view:', entry.target);
|
|
23
|
+
* }
|
|
24
|
+
* },
|
|
25
|
+
* { threshold: 0.5 }
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* return <div ref={ref}>Observe me!</div>;
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
declare function useIntersectionObserver<Element extends HTMLElement>(callback: (entry: IntersectionObserverEntry) => void, options: IntersectionObserverInit): (element: Element | null) => void;
|
|
32
|
+
|
|
33
|
+
export { useIntersectionObserver };
|