react-simplikit 0.0.5 → 0.0.7
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/components/ImpressionArea/index.js +108 -91
- package/dist/hooks/useAsyncEffect/index.d.ts +1 -1
- package/dist/hooks/useBooleanState/index.d.ts +1 -1
- package/dist/hooks/useImpressionRef/index.js +108 -91
- package/dist/hooks/useInputState/index.d.ts +1 -3
- package/dist/hooks/useStorageState/index.d.ts +1 -1
- package/dist/index.js +108 -91
- package/esm/components/ImpressionArea/index.mjs +109 -92
- package/esm/hooks/useAsyncEffect/index.d.mts +1 -1
- package/esm/hooks/useBooleanState/index.d.mts +1 -1
- package/esm/hooks/useImpressionRef/index.mjs +109 -92
- package/esm/hooks/useInputState/index.d.mts +1 -3
- package/esm/hooks/useStorageState/index.d.mts +1 -1
- package/esm/index.mjs +120 -103
- package/package.json +8 -3
|
@@ -1,87 +1,8 @@
|
|
|
1
1
|
// src/hooks/useImpressionRef/useImpressionRef.ts
|
|
2
2
|
import { useRef as useRef4 } from "react";
|
|
3
3
|
|
|
4
|
-
// src/hooks/
|
|
5
|
-
import { useMemo } from "react";
|
|
6
|
-
|
|
7
|
-
// src/hooks/usePreservedCallback/usePreservedCallback.ts
|
|
8
|
-
import { useCallback, useEffect, useRef } from "react";
|
|
9
|
-
function usePreservedCallback(callback) {
|
|
10
|
-
const callbackRef = useRef(callback);
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
callbackRef.current = callback;
|
|
13
|
-
}, [callback]);
|
|
14
|
-
return useCallback((...args) => {
|
|
15
|
-
return callbackRef.current(...args);
|
|
16
|
-
}, []);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// src/hooks/useRefEffect/useRefEffect.ts
|
|
20
|
-
import { useCallback as useCallback2, useRef as useRef2 } from "react";
|
|
21
|
-
function useRefEffect(callback, deps) {
|
|
22
|
-
const preservedCallback = usePreservedCallback(callback);
|
|
23
|
-
const cleanupCallbackRef = useRef2(() => {
|
|
24
|
-
});
|
|
25
|
-
const effect = useCallback2(
|
|
26
|
-
(element) => {
|
|
27
|
-
cleanupCallbackRef.current();
|
|
28
|
-
cleanupCallbackRef.current = () => {
|
|
29
|
-
};
|
|
30
|
-
if (element == null) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
const cleanup = preservedCallback(element);
|
|
34
|
-
if (typeof cleanup === "function") {
|
|
35
|
-
cleanupCallbackRef.current = cleanup;
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39
|
-
[preservedCallback, ...deps]
|
|
40
|
-
);
|
|
41
|
-
return effect;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
45
|
-
function useIntersectionObserver(callback, options) {
|
|
46
|
-
const preservedCallback = usePreservedCallback(callback);
|
|
47
|
-
const observer = useMemo(() => {
|
|
48
|
-
if (typeof IntersectionObserver === "undefined") {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
return new IntersectionObserver(([entry]) => {
|
|
52
|
-
preservedCallback(entry);
|
|
53
|
-
}, options);
|
|
54
|
-
}, [preservedCallback, options]);
|
|
55
|
-
return useRefEffect(
|
|
56
|
-
(element) => {
|
|
57
|
-
observer?.observe(element);
|
|
58
|
-
return () => {
|
|
59
|
-
observer?.unobserve(element);
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
[preservedCallback, options]
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/hooks/useVisibilityEvent/useVisibilityEvent.ts
|
|
67
|
-
import { useCallback as useCallback3, useEffect as useEffect2 } from "react";
|
|
68
|
-
function useVisibilityEvent(callback, options = {}) {
|
|
69
|
-
const handleVisibilityChange = useCallback3(() => {
|
|
70
|
-
callback(document.visibilityState);
|
|
71
|
-
}, [callback]);
|
|
72
|
-
useEffect2(() => {
|
|
73
|
-
if (options?.immediate ?? false) {
|
|
74
|
-
handleVisibilityChange();
|
|
75
|
-
}
|
|
76
|
-
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
77
|
-
return () => {
|
|
78
|
-
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
79
|
-
};
|
|
80
|
-
}, [handleVisibilityChange, options?.immediate]);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// src/hooks/useImpressionRef/useDebouncedCallback.ts
|
|
84
|
-
import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
4
|
+
// src/hooks/useDebouncedCallback/useDebouncedCallback.ts
|
|
5
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useRef as useRef2 } from "react";
|
|
85
6
|
|
|
86
7
|
// src/hooks/useDebounce/debounce.ts
|
|
87
8
|
function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
@@ -136,35 +57,130 @@ function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
|
136
57
|
return debounced;
|
|
137
58
|
}
|
|
138
59
|
|
|
139
|
-
// src/hooks/
|
|
60
|
+
// src/hooks/usePreservedCallback/usePreservedCallback.ts
|
|
61
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
62
|
+
function usePreservedCallback(callback) {
|
|
63
|
+
const callbackRef = useRef(callback);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
callbackRef.current = callback;
|
|
66
|
+
}, [callback]);
|
|
67
|
+
return useCallback((...args) => {
|
|
68
|
+
return callbackRef.current(...args);
|
|
69
|
+
}, []);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/hooks/useDebouncedCallback/useDebouncedCallback.ts
|
|
140
73
|
function useDebouncedCallback({
|
|
141
74
|
onChange,
|
|
142
|
-
timeThreshold
|
|
75
|
+
timeThreshold,
|
|
76
|
+
leading = false,
|
|
77
|
+
trailing = true
|
|
143
78
|
}) {
|
|
144
79
|
const handleChange = usePreservedCallback(onChange);
|
|
145
|
-
const ref =
|
|
80
|
+
const ref = useRef2({ value: false, clearPreviousDebounce: () => {
|
|
146
81
|
} });
|
|
147
|
-
|
|
82
|
+
useEffect2(() => {
|
|
148
83
|
const current = ref.current;
|
|
149
84
|
return () => {
|
|
150
85
|
current.clearPreviousDebounce();
|
|
151
86
|
};
|
|
152
87
|
}, []);
|
|
153
|
-
|
|
88
|
+
const edges = useMemo(() => {
|
|
89
|
+
const _edges = [];
|
|
90
|
+
if (leading) {
|
|
91
|
+
_edges.push("leading");
|
|
92
|
+
}
|
|
93
|
+
if (trailing) {
|
|
94
|
+
_edges.push("trailing");
|
|
95
|
+
}
|
|
96
|
+
return _edges;
|
|
97
|
+
}, [leading, trailing]);
|
|
98
|
+
return useCallback2(
|
|
154
99
|
(nextValue) => {
|
|
155
100
|
if (nextValue === ref.current.value) {
|
|
156
101
|
return;
|
|
157
102
|
}
|
|
158
|
-
const debounced = debounce(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
103
|
+
const debounced = debounce(
|
|
104
|
+
() => {
|
|
105
|
+
handleChange(nextValue);
|
|
106
|
+
ref.current.value = nextValue;
|
|
107
|
+
},
|
|
108
|
+
timeThreshold,
|
|
109
|
+
{ edges }
|
|
110
|
+
);
|
|
162
111
|
ref.current.clearPreviousDebounce();
|
|
163
112
|
debounced();
|
|
164
113
|
ref.current.clearPreviousDebounce = debounced.cancel;
|
|
165
114
|
},
|
|
166
|
-
[handleChange, timeThreshold]
|
|
115
|
+
[handleChange, timeThreshold, edges]
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
120
|
+
import { useMemo as useMemo2 } from "react";
|
|
121
|
+
|
|
122
|
+
// src/hooks/useRefEffect/useRefEffect.ts
|
|
123
|
+
import { useCallback as useCallback3, useRef as useRef3 } from "react";
|
|
124
|
+
function useRefEffect(callback, deps) {
|
|
125
|
+
const preservedCallback = usePreservedCallback(callback);
|
|
126
|
+
const cleanupCallbackRef = useRef3(() => {
|
|
127
|
+
});
|
|
128
|
+
const effect = useCallback3(
|
|
129
|
+
(element) => {
|
|
130
|
+
cleanupCallbackRef.current();
|
|
131
|
+
cleanupCallbackRef.current = () => {
|
|
132
|
+
};
|
|
133
|
+
if (element == null) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const cleanup = preservedCallback(element);
|
|
137
|
+
if (typeof cleanup === "function") {
|
|
138
|
+
cleanupCallbackRef.current = cleanup;
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
142
|
+
[preservedCallback, ...deps]
|
|
167
143
|
);
|
|
144
|
+
return effect;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
148
|
+
function useIntersectionObserver(callback, options) {
|
|
149
|
+
const preservedCallback = usePreservedCallback(callback);
|
|
150
|
+
const observer = useMemo2(() => {
|
|
151
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
return new IntersectionObserver(([entry]) => {
|
|
155
|
+
preservedCallback(entry);
|
|
156
|
+
}, options);
|
|
157
|
+
}, [preservedCallback, options]);
|
|
158
|
+
return useRefEffect(
|
|
159
|
+
(element) => {
|
|
160
|
+
observer?.observe(element);
|
|
161
|
+
return () => {
|
|
162
|
+
observer?.unobserve(element);
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
[preservedCallback, options]
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/hooks/useVisibilityEvent/useVisibilityEvent.ts
|
|
170
|
+
import { useCallback as useCallback4, useEffect as useEffect3 } from "react";
|
|
171
|
+
function useVisibilityEvent(callback, options = {}) {
|
|
172
|
+
const handleVisibilityChange = useCallback4(() => {
|
|
173
|
+
callback(document.visibilityState);
|
|
174
|
+
}, [callback]);
|
|
175
|
+
useEffect3(() => {
|
|
176
|
+
if (options?.immediate ?? false) {
|
|
177
|
+
handleVisibilityChange();
|
|
178
|
+
}
|
|
179
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
180
|
+
return () => {
|
|
181
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
182
|
+
};
|
|
183
|
+
}, [handleVisibilityChange, options?.immediate]);
|
|
168
184
|
}
|
|
169
185
|
|
|
170
186
|
// src/hooks/useImpressionRef/useImpressionRef.ts
|
|
@@ -184,7 +200,8 @@ function useImpressionRef({
|
|
|
184
200
|
timeThreshold,
|
|
185
201
|
onChange: (impressed) => {
|
|
186
202
|
(impressed ? impressionStartHandler : impressionEndHandler)();
|
|
187
|
-
}
|
|
203
|
+
},
|
|
204
|
+
leading: true
|
|
188
205
|
});
|
|
189
206
|
useVisibilityEvent((documentVisible) => {
|
|
190
207
|
if (!isIntersectingRef.current) {
|
|
@@ -8,13 +8,11 @@ import { ChangeEventHandler } from 'react';
|
|
|
8
8
|
* @param {(value: string) => string} [transformValue=(v: string) => v] - A function to transform the input value.
|
|
9
9
|
* Defaults to an identity function that returns the input unchanged.
|
|
10
10
|
*
|
|
11
|
-
* @returns {
|
|
11
|
+
* @returns {[value: string, onChange: (value: string) => void]} A tuple containing:
|
|
12
12
|
* - value `string` - The current state value;
|
|
13
13
|
* - onChange `(value: string) => void` - A function to update the state;
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
|
-
* import { useInputState } from 'react-simplikit';
|
|
17
|
-
*
|
|
18
16
|
* function Example() {
|
|
19
17
|
* const [value, setValue] = useInputState('');
|
|
20
18
|
* return <input type="text" value={value} onChange={setValue} />;
|
|
@@ -23,7 +23,7 @@ type StorageStateOptionsWithDefaultValue<T> = StorageStateOptions<T> & {
|
|
|
23
23
|
* The value is retained across page reloads and can be shared between tabs when using `localStorage`.
|
|
24
24
|
*
|
|
25
25
|
* @param {string} key - The key used to store the value in storage.
|
|
26
|
-
* @param {
|
|
26
|
+
* @param {Object} [options] - Configuration options for storage behavior.
|
|
27
27
|
* @param {Storage} [options.storage=localStorage] - The storage type (`localStorage` or `sessionStorage`). Defaults to `localStorage`.
|
|
28
28
|
* @param {T} [options.defaultValue] - The initial value if no existing value is found.
|
|
29
29
|
*
|
package/esm/index.mjs
CHANGED
|
@@ -1,87 +1,8 @@
|
|
|
1
1
|
// src/hooks/useImpressionRef/useImpressionRef.ts
|
|
2
2
|
import { useRef as useRef4 } from "react";
|
|
3
3
|
|
|
4
|
-
// src/hooks/
|
|
5
|
-
import { useMemo } from "react";
|
|
6
|
-
|
|
7
|
-
// src/hooks/usePreservedCallback/usePreservedCallback.ts
|
|
8
|
-
import { useCallback, useEffect, useRef } from "react";
|
|
9
|
-
function usePreservedCallback(callback) {
|
|
10
|
-
const callbackRef = useRef(callback);
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
callbackRef.current = callback;
|
|
13
|
-
}, [callback]);
|
|
14
|
-
return useCallback((...args) => {
|
|
15
|
-
return callbackRef.current(...args);
|
|
16
|
-
}, []);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// src/hooks/useRefEffect/useRefEffect.ts
|
|
20
|
-
import { useCallback as useCallback2, useRef as useRef2 } from "react";
|
|
21
|
-
function useRefEffect(callback, deps) {
|
|
22
|
-
const preservedCallback = usePreservedCallback(callback);
|
|
23
|
-
const cleanupCallbackRef = useRef2(() => {
|
|
24
|
-
});
|
|
25
|
-
const effect = useCallback2(
|
|
26
|
-
(element) => {
|
|
27
|
-
cleanupCallbackRef.current();
|
|
28
|
-
cleanupCallbackRef.current = () => {
|
|
29
|
-
};
|
|
30
|
-
if (element == null) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
const cleanup = preservedCallback(element);
|
|
34
|
-
if (typeof cleanup === "function") {
|
|
35
|
-
cleanupCallbackRef.current = cleanup;
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39
|
-
[preservedCallback, ...deps]
|
|
40
|
-
);
|
|
41
|
-
return effect;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
45
|
-
function useIntersectionObserver(callback, options) {
|
|
46
|
-
const preservedCallback = usePreservedCallback(callback);
|
|
47
|
-
const observer = useMemo(() => {
|
|
48
|
-
if (typeof IntersectionObserver === "undefined") {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
return new IntersectionObserver(([entry]) => {
|
|
52
|
-
preservedCallback(entry);
|
|
53
|
-
}, options);
|
|
54
|
-
}, [preservedCallback, options]);
|
|
55
|
-
return useRefEffect(
|
|
56
|
-
(element) => {
|
|
57
|
-
observer?.observe(element);
|
|
58
|
-
return () => {
|
|
59
|
-
observer?.unobserve(element);
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
[preservedCallback, options]
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/hooks/useVisibilityEvent/useVisibilityEvent.ts
|
|
67
|
-
import { useCallback as useCallback3, useEffect as useEffect2 } from "react";
|
|
68
|
-
function useVisibilityEvent(callback, options = {}) {
|
|
69
|
-
const handleVisibilityChange = useCallback3(() => {
|
|
70
|
-
callback(document.visibilityState);
|
|
71
|
-
}, [callback]);
|
|
72
|
-
useEffect2(() => {
|
|
73
|
-
if (options?.immediate ?? false) {
|
|
74
|
-
handleVisibilityChange();
|
|
75
|
-
}
|
|
76
|
-
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
77
|
-
return () => {
|
|
78
|
-
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
79
|
-
};
|
|
80
|
-
}, [handleVisibilityChange, options?.immediate]);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// src/hooks/useImpressionRef/useDebouncedCallback.ts
|
|
84
|
-
import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
4
|
+
// src/hooks/useDebouncedCallback/useDebouncedCallback.ts
|
|
5
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useRef as useRef2 } from "react";
|
|
85
6
|
|
|
86
7
|
// src/hooks/useDebounce/debounce.ts
|
|
87
8
|
function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
@@ -136,37 +57,132 @@ function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
|
136
57
|
return debounced;
|
|
137
58
|
}
|
|
138
59
|
|
|
139
|
-
// src/hooks/
|
|
60
|
+
// src/hooks/usePreservedCallback/usePreservedCallback.ts
|
|
61
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
62
|
+
function usePreservedCallback(callback) {
|
|
63
|
+
const callbackRef = useRef(callback);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
callbackRef.current = callback;
|
|
66
|
+
}, [callback]);
|
|
67
|
+
return useCallback((...args) => {
|
|
68
|
+
return callbackRef.current(...args);
|
|
69
|
+
}, []);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/hooks/useDebouncedCallback/useDebouncedCallback.ts
|
|
140
73
|
function useDebouncedCallback({
|
|
141
74
|
onChange,
|
|
142
|
-
timeThreshold
|
|
75
|
+
timeThreshold,
|
|
76
|
+
leading = false,
|
|
77
|
+
trailing = true
|
|
143
78
|
}) {
|
|
144
79
|
const handleChange = usePreservedCallback(onChange);
|
|
145
|
-
const ref =
|
|
80
|
+
const ref = useRef2({ value: false, clearPreviousDebounce: () => {
|
|
146
81
|
} });
|
|
147
|
-
|
|
82
|
+
useEffect2(() => {
|
|
148
83
|
const current = ref.current;
|
|
149
84
|
return () => {
|
|
150
85
|
current.clearPreviousDebounce();
|
|
151
86
|
};
|
|
152
87
|
}, []);
|
|
153
|
-
|
|
88
|
+
const edges = useMemo(() => {
|
|
89
|
+
const _edges = [];
|
|
90
|
+
if (leading) {
|
|
91
|
+
_edges.push("leading");
|
|
92
|
+
}
|
|
93
|
+
if (trailing) {
|
|
94
|
+
_edges.push("trailing");
|
|
95
|
+
}
|
|
96
|
+
return _edges;
|
|
97
|
+
}, [leading, trailing]);
|
|
98
|
+
return useCallback2(
|
|
154
99
|
(nextValue) => {
|
|
155
100
|
if (nextValue === ref.current.value) {
|
|
156
101
|
return;
|
|
157
102
|
}
|
|
158
|
-
const debounced = debounce(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
103
|
+
const debounced = debounce(
|
|
104
|
+
() => {
|
|
105
|
+
handleChange(nextValue);
|
|
106
|
+
ref.current.value = nextValue;
|
|
107
|
+
},
|
|
108
|
+
timeThreshold,
|
|
109
|
+
{ edges }
|
|
110
|
+
);
|
|
162
111
|
ref.current.clearPreviousDebounce();
|
|
163
112
|
debounced();
|
|
164
113
|
ref.current.clearPreviousDebounce = debounced.cancel;
|
|
165
114
|
},
|
|
166
|
-
[handleChange, timeThreshold]
|
|
115
|
+
[handleChange, timeThreshold, edges]
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
120
|
+
import { useMemo as useMemo2 } from "react";
|
|
121
|
+
|
|
122
|
+
// src/hooks/useRefEffect/useRefEffect.ts
|
|
123
|
+
import { useCallback as useCallback3, useRef as useRef3 } from "react";
|
|
124
|
+
function useRefEffect(callback, deps) {
|
|
125
|
+
const preservedCallback = usePreservedCallback(callback);
|
|
126
|
+
const cleanupCallbackRef = useRef3(() => {
|
|
127
|
+
});
|
|
128
|
+
const effect = useCallback3(
|
|
129
|
+
(element) => {
|
|
130
|
+
cleanupCallbackRef.current();
|
|
131
|
+
cleanupCallbackRef.current = () => {
|
|
132
|
+
};
|
|
133
|
+
if (element == null) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const cleanup = preservedCallback(element);
|
|
137
|
+
if (typeof cleanup === "function") {
|
|
138
|
+
cleanupCallbackRef.current = cleanup;
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
142
|
+
[preservedCallback, ...deps]
|
|
143
|
+
);
|
|
144
|
+
return effect;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/hooks/useIntersectionObserver/useIntersectionObserver.ts
|
|
148
|
+
function useIntersectionObserver(callback, options) {
|
|
149
|
+
const preservedCallback = usePreservedCallback(callback);
|
|
150
|
+
const observer = useMemo2(() => {
|
|
151
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
return new IntersectionObserver(([entry]) => {
|
|
155
|
+
preservedCallback(entry);
|
|
156
|
+
}, options);
|
|
157
|
+
}, [preservedCallback, options]);
|
|
158
|
+
return useRefEffect(
|
|
159
|
+
(element) => {
|
|
160
|
+
observer?.observe(element);
|
|
161
|
+
return () => {
|
|
162
|
+
observer?.unobserve(element);
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
[preservedCallback, options]
|
|
167
166
|
);
|
|
168
167
|
}
|
|
169
168
|
|
|
169
|
+
// src/hooks/useVisibilityEvent/useVisibilityEvent.ts
|
|
170
|
+
import { useCallback as useCallback4, useEffect as useEffect3 } from "react";
|
|
171
|
+
function useVisibilityEvent(callback, options = {}) {
|
|
172
|
+
const handleVisibilityChange = useCallback4(() => {
|
|
173
|
+
callback(document.visibilityState);
|
|
174
|
+
}, [callback]);
|
|
175
|
+
useEffect3(() => {
|
|
176
|
+
if (options?.immediate ?? false) {
|
|
177
|
+
handleVisibilityChange();
|
|
178
|
+
}
|
|
179
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
180
|
+
return () => {
|
|
181
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
182
|
+
};
|
|
183
|
+
}, [handleVisibilityChange, options?.immediate]);
|
|
184
|
+
}
|
|
185
|
+
|
|
170
186
|
// src/hooks/useImpressionRef/useImpressionRef.ts
|
|
171
187
|
function useImpressionRef({
|
|
172
188
|
onImpressionStart = () => {
|
|
@@ -184,7 +200,8 @@ function useImpressionRef({
|
|
|
184
200
|
timeThreshold,
|
|
185
201
|
onChange: (impressed) => {
|
|
186
202
|
(impressed ? impressionStartHandler : impressionEndHandler)();
|
|
187
|
-
}
|
|
203
|
+
},
|
|
204
|
+
leading: true
|
|
188
205
|
});
|
|
189
206
|
useVisibilityEvent((documentVisible) => {
|
|
190
207
|
if (!isIntersectingRef.current) {
|
|
@@ -310,11 +327,11 @@ function useCallbackOncePerRender(callback, deps) {
|
|
|
310
327
|
|
|
311
328
|
// src/hooks/useDebounce/useDebounce.ts
|
|
312
329
|
import { useEffect as useEffect6 } from "react";
|
|
313
|
-
import { useMemo as
|
|
330
|
+
import { useMemo as useMemo3 } from "react";
|
|
314
331
|
function useDebounce(callback, wait, options = {}) {
|
|
315
332
|
const preservedCallback = usePreservedCallback(callback);
|
|
316
333
|
const { leading = false, trailing = true } = options;
|
|
317
|
-
const edges =
|
|
334
|
+
const edges = useMemo3(() => {
|
|
318
335
|
const _edges = [];
|
|
319
336
|
if (leading) {
|
|
320
337
|
_edges.push("leading");
|
|
@@ -324,7 +341,7 @@ function useDebounce(callback, wait, options = {}) {
|
|
|
324
341
|
}
|
|
325
342
|
return _edges;
|
|
326
343
|
}, [leading, trailing]);
|
|
327
|
-
const debounced =
|
|
344
|
+
const debounced = useMemo3(() => {
|
|
328
345
|
return debounce(preservedCallback, wait, { edges });
|
|
329
346
|
}, [preservedCallback, wait, edges]);
|
|
330
347
|
useEffect6(() => {
|
|
@@ -373,7 +390,7 @@ function useInterval(callback, options) {
|
|
|
373
390
|
}
|
|
374
391
|
|
|
375
392
|
// src/hooks/useLoading/useLoading.ts
|
|
376
|
-
import { useCallback as useCallback7, useEffect as useEffect8, useMemo as
|
|
393
|
+
import { useCallback as useCallback7, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef6, useState as useState3 } from "react";
|
|
377
394
|
function useLoading() {
|
|
378
395
|
const [loading, setLoading] = useState3(false);
|
|
379
396
|
const ref = useIsMountedRef();
|
|
@@ -391,7 +408,7 @@ function useLoading() {
|
|
|
391
408
|
},
|
|
392
409
|
[ref.isMounted]
|
|
393
410
|
);
|
|
394
|
-
return
|
|
411
|
+
return useMemo4(() => [loading, startTransition], [loading, startTransition]);
|
|
395
412
|
}
|
|
396
413
|
function useIsMountedRef() {
|
|
397
414
|
const ref = useRef6({ isMounted: true }).current;
|
|
@@ -432,10 +449,10 @@ function useOutsideClickEffect(container, callback) {
|
|
|
432
449
|
}
|
|
433
450
|
|
|
434
451
|
// src/hooks/usePreservedReference/usePreservedReference.ts
|
|
435
|
-
import { useMemo as
|
|
452
|
+
import { useMemo as useMemo5, useRef as useRef8 } from "react";
|
|
436
453
|
function usePreservedReference(value, areValuesEqual = areDeeplyEqual) {
|
|
437
454
|
const ref = useRef8(value);
|
|
438
|
-
return
|
|
455
|
+
return useMemo5(() => {
|
|
439
456
|
if (!areValuesEqual(ref.current, value)) {
|
|
440
457
|
ref.current = value;
|
|
441
458
|
}
|
|
@@ -604,7 +621,7 @@ function useStorageState(key, { storage = safeLocalStorage, defaultValue } = {})
|
|
|
604
621
|
}
|
|
605
622
|
|
|
606
623
|
// src/hooks/useThrottle/useThrottle.ts
|
|
607
|
-
import { useEffect as useEffect11, useMemo as
|
|
624
|
+
import { useEffect as useEffect11, useMemo as useMemo6 } from "react";
|
|
608
625
|
|
|
609
626
|
// src/hooks/useThrottle/throttle.ts
|
|
610
627
|
function throttle(func, throttleMs, { edges = ["leading", "trailing"] } = {}) {
|
|
@@ -630,7 +647,7 @@ function throttle(func, throttleMs, { edges = ["leading", "trailing"] } = {}) {
|
|
|
630
647
|
function useThrottle(callback, wait, options) {
|
|
631
648
|
const preservedCallback = usePreservedCallback(callback);
|
|
632
649
|
const preservedOptions = usePreservedReference(options ?? {});
|
|
633
|
-
const throttledCallback =
|
|
650
|
+
const throttledCallback = useMemo6(() => {
|
|
634
651
|
return throttle(preservedCallback, wait, preservedOptions);
|
|
635
652
|
}, [preservedOptions, preservedCallback, wait]);
|
|
636
653
|
useEffect11(() => {
|
|
@@ -659,12 +676,12 @@ function useToggle(initialValue = false) {
|
|
|
659
676
|
var toggle = (state) => !state;
|
|
660
677
|
|
|
661
678
|
// src/utils/buildContext/buildContext.tsx
|
|
662
|
-
import { createContext, useContext, useMemo as
|
|
679
|
+
import { createContext, useContext, useMemo as useMemo7 } from "react";
|
|
663
680
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
664
681
|
function buildContext(contextName, defaultContextValues) {
|
|
665
682
|
const Context = createContext(defaultContextValues ?? void 0);
|
|
666
683
|
function Provider({ children, ...contextValues }) {
|
|
667
|
-
const value =
|
|
684
|
+
const value = useMemo7(
|
|
668
685
|
() => Object.keys(contextValues).length > 0 ? contextValues : null,
|
|
669
686
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
670
687
|
[...Object.values(contextValues)]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-simplikit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"files": [
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"esm/**/*"
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
|
+
"scaffold": "tsx .scripts/index.ts scaffold",
|
|
11
12
|
"docs:gen": "tsx .scripts/index.ts generate-docs",
|
|
12
13
|
"docs:dev": "vitepress dev",
|
|
13
14
|
"docs:build": "vitepress build",
|
|
@@ -35,13 +36,13 @@
|
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@eslint/js": "^9.16.0",
|
|
38
|
-
"@openai/openai": "npm:@jsr/openai__openai@^4.93.0",
|
|
39
39
|
"@testing-library/dom": "^10.4.0",
|
|
40
40
|
"@testing-library/jest-dom": "^6.6.3",
|
|
41
41
|
"@testing-library/react": "^16.1.0",
|
|
42
42
|
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
|
|
43
43
|
"@types/node": "^22.10.2",
|
|
44
|
-
"@types/react": "^19.0.
|
|
44
|
+
"@types/react": "^19.0.0",
|
|
45
|
+
"@types/react-dom": "^19.0.0",
|
|
45
46
|
"@vitest/coverage-v8": "^2.1.8",
|
|
46
47
|
"commander": "^13.1.0",
|
|
47
48
|
"comment-parser": "^1.4.1",
|
|
@@ -60,6 +61,7 @@
|
|
|
60
61
|
"globals": "^15.13.0",
|
|
61
62
|
"jsdom": "^25.0.1",
|
|
62
63
|
"listr2": "^8.2.5",
|
|
64
|
+
"nanoid": "^5.1.5",
|
|
63
65
|
"ora": "^8.2.0",
|
|
64
66
|
"prettier": "^3.4.2",
|
|
65
67
|
"prettier-plugin-sort-re-exports": "^0.1.0",
|
|
@@ -78,6 +80,9 @@
|
|
|
78
80
|
"react-dom": "*"
|
|
79
81
|
},
|
|
80
82
|
"packageManager": "yarn@4.5.3",
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"openai": "^4.93.0"
|
|
85
|
+
},
|
|
81
86
|
"module": "./esm/index.mjs",
|
|
82
87
|
"exports": {
|
|
83
88
|
".": {
|