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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/dist/components/ImpressionArea/index.d.ts +46 -0
  4. package/dist/components/ImpressionArea/index.js +276 -0
  5. package/dist/components/Separated/index.d.ts +38 -0
  6. package/dist/components/Separated/index.js +40 -0
  7. package/dist/components/SwitchCase/index.d.ts +46 -0
  8. package/dist/components/SwitchCase/index.js +35 -0
  9. package/dist/hooks/useAsyncEffect/index.d.ts +25 -0
  10. package/dist/hooks/useAsyncEffect/index.js +43 -0
  11. package/dist/hooks/useBooleanState/index.d.ts +19 -0
  12. package/dist/hooks/useBooleanState/index.js +45 -0
  13. package/dist/hooks/useCallbackOncePerRender/index.d.ts +41 -0
  14. package/dist/hooks/useCallbackOncePerRender/index.js +59 -0
  15. package/dist/hooks/useDebounce/index.d.ts +48 -0
  16. package/dist/hooks/useDebounce/index.js +123 -0
  17. package/dist/hooks/useImpressionRef/index.d.ts +38 -0
  18. package/dist/hooks/useImpressionRef/index.js +237 -0
  19. package/dist/hooks/useInputState/index.d.ts +27 -0
  20. package/dist/hooks/useInputState/index.js +45 -0
  21. package/dist/hooks/useIntersectionObserver/index.d.ts +33 -0
  22. package/dist/hooks/useIntersectionObserver/index.js +91 -0
  23. package/dist/hooks/useInterval/index.d.ts +37 -0
  24. package/dist/hooks/useInterval/index.js +64 -0
  25. package/dist/hooks/useLoading/index.d.ts +37 -0
  26. package/dist/hooks/useLoading/index.js +61 -0
  27. package/dist/hooks/useOutsideClickEffect/index.d.ts +27 -0
  28. package/dist/hooks/useOutsideClickEffect/index.js +70 -0
  29. package/dist/hooks/usePreservedCallback/index.d.ts +30 -0
  30. package/dist/hooks/usePreservedCallback/index.js +41 -0
  31. package/dist/hooks/usePreservedReference/index.d.ts +42 -0
  32. package/dist/hooks/usePreservedReference/index.js +44 -0
  33. package/dist/hooks/usePrevious/index.d.ts +21 -0
  34. package/dist/hooks/usePrevious/index.js +47 -0
  35. package/dist/hooks/useRefEffect/index.d.ts +31 -0
  36. package/dist/hooks/useRefEffect/index.js +68 -0
  37. package/dist/hooks/useStorageState/index.d.ts +50 -0
  38. package/dist/hooks/useStorageState/index.js +168 -0
  39. package/dist/hooks/useThrottle/index.d.ts +47 -0
  40. package/dist/hooks/useThrottle/index.js +147 -0
  41. package/dist/hooks/useTimeout/index.d.ts +30 -0
  42. package/dist/hooks/useTimeout/index.js +53 -0
  43. package/dist/hooks/useToggle/index.d.ts +30 -0
  44. package/dist/hooks/useToggle/index.js +36 -0
  45. package/dist/hooks/useVisibilityEvent/index.d.ts +27 -0
  46. package/dist/hooks/useVisibilityEvent/index.js +46 -0
  47. package/dist/index.d.ts +26 -0
  48. package/dist/index.js +761 -0
  49. package/dist/utils/buildContext/index.d.ts +38 -0
  50. package/dist/utils/buildContext/index.js +55 -0
  51. package/dist/utils/mergeRefs/index.d.ts +37 -0
  52. package/dist/utils/mergeRefs/index.js +45 -0
  53. package/esm/components/ImpressionArea/index.d.mts +46 -0
  54. package/esm/components/ImpressionArea/index.mjs +249 -0
  55. package/esm/components/Separated/index.d.mts +38 -0
  56. package/esm/components/Separated/index.mjs +13 -0
  57. package/esm/components/SwitchCase/index.d.mts +46 -0
  58. package/esm/components/SwitchCase/index.mjs +8 -0
  59. package/esm/hooks/useAsyncEffect/index.d.mts +25 -0
  60. package/esm/hooks/useAsyncEffect/index.mjs +16 -0
  61. package/esm/hooks/useBooleanState/index.d.mts +19 -0
  62. package/esm/hooks/useBooleanState/index.mjs +18 -0
  63. package/esm/hooks/useCallbackOncePerRender/index.d.mts +41 -0
  64. package/esm/hooks/useCallbackOncePerRender/index.mjs +32 -0
  65. package/esm/hooks/useDebounce/index.d.mts +48 -0
  66. package/esm/hooks/useDebounce/index.mjs +96 -0
  67. package/esm/hooks/useImpressionRef/index.d.mts +38 -0
  68. package/esm/hooks/useImpressionRef/index.mjs +210 -0
  69. package/esm/hooks/useInputState/index.d.mts +27 -0
  70. package/esm/hooks/useInputState/index.mjs +18 -0
  71. package/esm/hooks/useIntersectionObserver/index.d.mts +33 -0
  72. package/esm/hooks/useIntersectionObserver/index.mjs +64 -0
  73. package/esm/hooks/useInterval/index.d.mts +37 -0
  74. package/esm/hooks/useInterval/index.mjs +37 -0
  75. package/esm/hooks/useLoading/index.d.mts +37 -0
  76. package/esm/hooks/useLoading/index.mjs +34 -0
  77. package/esm/hooks/useOutsideClickEffect/index.d.mts +27 -0
  78. package/esm/hooks/useOutsideClickEffect/index.mjs +43 -0
  79. package/esm/hooks/usePreservedCallback/index.d.mts +30 -0
  80. package/esm/hooks/usePreservedCallback/index.mjs +14 -0
  81. package/esm/hooks/usePreservedReference/index.d.mts +42 -0
  82. package/esm/hooks/usePreservedReference/index.mjs +17 -0
  83. package/esm/hooks/usePrevious/index.d.mts +21 -0
  84. package/esm/hooks/usePrevious/index.mjs +20 -0
  85. package/esm/hooks/useRefEffect/index.d.mts +31 -0
  86. package/esm/hooks/useRefEffect/index.mjs +41 -0
  87. package/esm/hooks/useStorageState/index.d.mts +50 -0
  88. package/esm/hooks/useStorageState/index.mjs +141 -0
  89. package/esm/hooks/useThrottle/index.d.mts +47 -0
  90. package/esm/hooks/useThrottle/index.mjs +120 -0
  91. package/esm/hooks/useTimeout/index.d.mts +30 -0
  92. package/esm/hooks/useTimeout/index.mjs +26 -0
  93. package/esm/hooks/useToggle/index.d.mts +30 -0
  94. package/esm/hooks/useToggle/index.mjs +9 -0
  95. package/esm/hooks/useVisibilityEvent/index.d.mts +27 -0
  96. package/esm/hooks/useVisibilityEvent/index.mjs +19 -0
  97. package/esm/index.d.mts +26 -0
  98. package/esm/index.mjs +711 -0
  99. package/esm/utils/buildContext/index.d.mts +38 -0
  100. package/esm/utils/buildContext/index.mjs +28 -0
  101. package/esm/utils/mergeRefs/index.d.mts +37 -0
  102. package/esm/utils/mergeRefs/index.mjs +18 -0
  103. package/package.json +87 -7
@@ -0,0 +1,38 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ type ProviderProps<ContextValuesType> = (ContextValuesType & {
5
+ children: ReactNode;
6
+ }) | {
7
+ children: ReactNode;
8
+ };
9
+ /**
10
+ * @description
11
+ * `buildContext` is a helper function that reduces repetitive code when defining React Context.
12
+ *
13
+ * @param contextName - The name of the context.
14
+ * @param defaultContextValues - The default values to be passed to the context.
15
+ *
16
+ * @returns A tuple of the form [Provider, useContext]:
17
+ * - `Provider`: The component that provides the context.
18
+ * - `useContext`: The hook that uses the context.
19
+ *
20
+ * @example
21
+ * const [Provider, useContext] = buildContext<{ title: string }>('TestContext', null);
22
+ *
23
+ * function Inner() {
24
+ * const { title } = useContext();
25
+ * return <div>{title}</div>;
26
+ * }
27
+ *
28
+ * function Page() {
29
+ * return (
30
+ * <Provider title="Hello">
31
+ * <Inner />
32
+ * </Provider>
33
+ * );
34
+ * }
35
+ */
36
+ declare function buildContext<ContextValuesType extends object>(contextName: string, defaultContextValues?: ContextValuesType): readonly [({ children, ...contextValues }: ProviderProps<ContextValuesType>) => react_jsx_runtime.JSX.Element, () => ContextValuesType];
37
+
38
+ export { buildContext };
@@ -0,0 +1,55 @@
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/utils/buildContext/index.ts
21
+ var buildContext_exports = {};
22
+ __export(buildContext_exports, {
23
+ buildContext: () => buildContext
24
+ });
25
+ module.exports = __toCommonJS(buildContext_exports);
26
+
27
+ // src/utils/buildContext/buildContext.tsx
28
+ var import_react = require("react");
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ function buildContext(contextName, defaultContextValues) {
31
+ const Context = (0, import_react.createContext)(defaultContextValues ?? void 0);
32
+ function Provider({ children, ...contextValues }) {
33
+ const value = (0, import_react.useMemo)(
34
+ () => Object.keys(contextValues).length > 0 ? contextValues : null,
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ [...Object.values(contextValues)]
37
+ );
38
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Context.Provider, { value, children });
39
+ }
40
+ function useInnerContext() {
41
+ const context = (0, import_react.useContext)(Context);
42
+ if (context != null) {
43
+ return context;
44
+ }
45
+ if (defaultContextValues != null) {
46
+ return defaultContextValues;
47
+ }
48
+ throw new Error(`\`${contextName}Context\` must be used within \`${contextName}Provider\``);
49
+ }
50
+ return [Provider, useInnerContext];
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ buildContext
55
+ });
@@ -0,0 +1,37 @@
1
+ import { RefObject, RefCallback } from 'react';
2
+
3
+ /**
4
+ * @description
5
+ * This function takes multiple refs (RefObject or RefCallback) and returns a single ref that updates all provided refs.
6
+ * It's useful when you need to pass multiple refs to a single element.
7
+ *
8
+ * @param refs - An array of refs to be merged. Each ref can be either a RefObject or RefCallback.
9
+ *
10
+ * @returns A single ref callback that updates all provided refs.
11
+ *
12
+ * @example
13
+ * forwardRef(function Component(props, parentRef) {
14
+ * const myRef = useRef(null);
15
+ *
16
+ * return <div ref={mergeRefs(myRef, parentRef)} />;
17
+ * })
18
+ *
19
+ * @example
20
+ * function Component(props) {
21
+ * const ref = useRef(null);
22
+ * const [height, setHeight] = useState(0);
23
+ *
24
+ * const measuredRef = useCallback(node => {
25
+ * if(node == null) {
26
+ * return;
27
+ * }
28
+ *
29
+ * setHeight(node.offsetHeight);
30
+ * }, []);
31
+ *
32
+ * return <div ref={mergeRefs(measuredRef, ref)} />;
33
+ * }
34
+ */
35
+ declare function mergeRefs<T>(...refs: Array<RefObject<T> | RefCallback<T> | null | undefined>): RefCallback<T>;
36
+
37
+ export { mergeRefs };
@@ -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/utils/mergeRefs/index.ts
21
+ var mergeRefs_exports = {};
22
+ __export(mergeRefs_exports, {
23
+ mergeRefs: () => mergeRefs
24
+ });
25
+ module.exports = __toCommonJS(mergeRefs_exports);
26
+
27
+ // src/utils/mergeRefs/mergeRefs.ts
28
+ function mergeRefs(...refs) {
29
+ return (value) => {
30
+ for (const ref of refs) {
31
+ if (ref == null) {
32
+ continue;
33
+ }
34
+ if (typeof ref === "function") {
35
+ ref(value);
36
+ continue;
37
+ }
38
+ ref.current = value;
39
+ }
40
+ };
41
+ }
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ mergeRefs
45
+ });
@@ -0,0 +1,46 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default, { ElementType, Ref } from 'react';
3
+ import { UseImpressionRefOptions } from '../../hooks/useImpressionRef/index.mjs';
4
+
5
+ type Props<Tag extends ElementType> = React__default.ComponentPropsWithoutRef<Tag> & UseImpressionRefOptions & {
6
+ as?: Tag;
7
+ ref?: Ref<HTMLElement>;
8
+ children?: React__default.ReactNode;
9
+ className?: string;
10
+ };
11
+ /**
12
+ * @description
13
+ * `ImpressionArea` is a component that measures the time a specific DOM element is visible on the screen
14
+ * and executes callbacks when the element enters or exits the viewport. This component uses the `useImpressionRef`
15
+ * hook to track the element's visibility.
16
+ *
17
+ * @param {Object} props - The props for the component.
18
+ * @param {ElementType} [props.as='div'] - The HTML tag to render. Defaults to `div`.
19
+ * @param {string} [props.rootMargin] - Margin to adjust the detection area.
20
+ * @param {number} [props.areaThreshold] - Minimum ratio of the element that must be visible (0 to 1).
21
+ * @param {number} [props.timeThreshold] - Minimum time the element must be visible (in milliseconds).
22
+ * @param {() => void} [props.onImpressionStart] - Callback function executed when the element enters the view.
23
+ * @param {() => void} [props.onImpressionEnd] - Callback function executed when the element exits the view.
24
+ * @param {Ref<HTMLElement>} [props.ref] - Reference to the element.
25
+ * @param {React.ReactNode} [props.children] - Child elements to be rendered inside the component.
26
+ * @param {string} [props.className] - Additional class names for styling.
27
+ *
28
+ * @returns {JSX.Element} A React component that tracks the visibility of its child elements.
29
+ *
30
+ * @example
31
+ * function App() {
32
+ * return (
33
+ * <ImpressionArea
34
+ * onImpressionStart={() => console.log('Element entered view')}
35
+ * onImpressionEnd={() => console.log('Element exited view')}
36
+ * timeThreshold={1000}
37
+ * areaThreshold={0.5}
38
+ * >
39
+ * <div>Track me!</div>
40
+ * </ImpressionArea>
41
+ * );
42
+ * }
43
+ */
44
+ declare function ImpressionArea<T extends ElementType = 'div'>({ as, rootMargin, areaThreshold, timeThreshold, onImpressionStart, onImpressionEnd, ref, ...props }: Props<T>): react_jsx_runtime.JSX.Element;
45
+
46
+ export { ImpressionArea };
@@ -0,0 +1,249 @@
1
+ // src/hooks/useImpressionRef/useImpressionRef.ts
2
+ import { useRef as useRef4 } from "react";
3
+
4
+ // src/hooks/useIntersectionObserver/useIntersectionObserver.ts
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";
85
+
86
+ // src/hooks/useDebounce/debounce.ts
87
+ function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
88
+ let pendingThis = void 0;
89
+ let pendingArgs = null;
90
+ const leading = edges != null && edges.includes("leading");
91
+ const trailing = edges == null || edges.includes("trailing");
92
+ const invoke = () => {
93
+ if (pendingArgs !== null) {
94
+ func.apply(pendingThis, pendingArgs);
95
+ pendingThis = void 0;
96
+ pendingArgs = null;
97
+ }
98
+ };
99
+ const onTimerEnd = () => {
100
+ if (trailing) {
101
+ invoke();
102
+ }
103
+ cancel();
104
+ };
105
+ let timeoutId = null;
106
+ const schedule = () => {
107
+ if (timeoutId != null) {
108
+ clearTimeout(timeoutId);
109
+ }
110
+ timeoutId = setTimeout(() => {
111
+ timeoutId = null;
112
+ onTimerEnd();
113
+ }, debounceMs);
114
+ };
115
+ const cancelTimer = () => {
116
+ if (timeoutId !== null) {
117
+ clearTimeout(timeoutId);
118
+ timeoutId = null;
119
+ }
120
+ };
121
+ const cancel = () => {
122
+ cancelTimer();
123
+ pendingThis = void 0;
124
+ pendingArgs = null;
125
+ };
126
+ const debounced = function(...args) {
127
+ pendingThis = this;
128
+ pendingArgs = args;
129
+ const isFirstCall = timeoutId == null;
130
+ schedule();
131
+ if (leading && isFirstCall) {
132
+ invoke();
133
+ }
134
+ };
135
+ debounced.cancel = cancel;
136
+ return debounced;
137
+ }
138
+
139
+ // src/hooks/useImpressionRef/useDebouncedCallback.ts
140
+ function useDebouncedCallback({
141
+ onChange,
142
+ timeThreshold
143
+ }) {
144
+ const handleChange = usePreservedCallback(onChange);
145
+ const ref = useRef3({ value: false, clearPreviousDebounce: () => {
146
+ } });
147
+ useEffect3(() => {
148
+ const current = ref.current;
149
+ return () => {
150
+ current.clearPreviousDebounce();
151
+ };
152
+ }, []);
153
+ return useCallback4(
154
+ (nextValue) => {
155
+ if (nextValue === ref.current.value) {
156
+ return;
157
+ }
158
+ const debounced = debounce(() => {
159
+ handleChange(nextValue);
160
+ ref.current.value = nextValue;
161
+ }, timeThreshold);
162
+ ref.current.clearPreviousDebounce();
163
+ debounced();
164
+ ref.current.clearPreviousDebounce = debounced.cancel;
165
+ },
166
+ [handleChange, timeThreshold]
167
+ );
168
+ }
169
+
170
+ // src/hooks/useImpressionRef/useImpressionRef.ts
171
+ function useImpressionRef({
172
+ onImpressionStart = () => {
173
+ },
174
+ onImpressionEnd = () => {
175
+ },
176
+ rootMargin,
177
+ areaThreshold = 0,
178
+ timeThreshold = 0
179
+ }) {
180
+ const impressionStartHandler = usePreservedCallback(onImpressionStart);
181
+ const impressionEndHandler = usePreservedCallback(onImpressionEnd);
182
+ const isIntersectingRef = useRef4(false);
183
+ const impressionEventHandler = useDebouncedCallback({
184
+ timeThreshold,
185
+ onChange: (impressed) => {
186
+ (impressed ? impressionStartHandler : impressionEndHandler)();
187
+ }
188
+ });
189
+ useVisibilityEvent((documentVisible) => {
190
+ if (!isIntersectingRef.current) {
191
+ return;
192
+ }
193
+ impressionEventHandler(documentVisible === "visible");
194
+ });
195
+ return useIntersectionObserver(
196
+ (entry) => {
197
+ if (document.visibilityState === "hidden") {
198
+ return;
199
+ }
200
+ const currentRatio = entry.intersectionRatio;
201
+ const isIntersecting = areaThreshold === 0 ? entry.isIntersecting : currentRatio >= areaThreshold;
202
+ isIntersectingRef.current = isIntersecting;
203
+ impressionEventHandler(isIntersecting);
204
+ },
205
+ { rootMargin, threshold: areaThreshold }
206
+ );
207
+ }
208
+
209
+ // src/utils/mergeRefs/mergeRefs.ts
210
+ function mergeRefs(...refs) {
211
+ return (value) => {
212
+ for (const ref of refs) {
213
+ if (ref == null) {
214
+ continue;
215
+ }
216
+ if (typeof ref === "function") {
217
+ ref(value);
218
+ continue;
219
+ }
220
+ ref.current = value;
221
+ }
222
+ };
223
+ }
224
+
225
+ // src/components/ImpressionArea/ImpressionArea.tsx
226
+ import { jsx } from "react/jsx-runtime";
227
+ function ImpressionArea({
228
+ as,
229
+ rootMargin,
230
+ areaThreshold,
231
+ timeThreshold,
232
+ onImpressionStart,
233
+ onImpressionEnd,
234
+ ref,
235
+ ...props
236
+ }) {
237
+ const Component = as ?? "div";
238
+ const impressionRef = useImpressionRef({
239
+ onImpressionStart,
240
+ onImpressionEnd,
241
+ areaThreshold,
242
+ timeThreshold,
243
+ rootMargin
244
+ });
245
+ return /* @__PURE__ */ jsx(Component, { ref: mergeRefs(ref, impressionRef), ...props });
246
+ }
247
+ export {
248
+ ImpressionArea
249
+ };
@@ -0,0 +1,38 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ type Props = {
5
+ with: ReactNode;
6
+ children: ReactNode;
7
+ };
8
+ /**
9
+ * @description
10
+ * `Separated` is a component that inserts a specified component between each child element.
11
+ * It is useful for adding separators, spacing, or other repeating elements in lists.
12
+ *
13
+ * @param {React.ReactNode} children - The child elements to render.
14
+ * Only valid React elements (`React.isValidElement`) will be rendered.
15
+ * @param {React.ReactNode} with - The component to insert between child elements.
16
+ *
17
+ * @returns {JSX.Element} A React component that separates children with a specified separator.
18
+ *
19
+ * @example
20
+ * function App() {
21
+ * return (
22
+ * <Separated with={<Border type="padding24" />}>
23
+ * {['hello', 'react', 'world'].map(item => (
24
+ * <div key={item}>{item}</div>
25
+ * ))}
26
+ * </Separated>
27
+ * );
28
+ * // Expected output:
29
+ * // <div>hello</div>
30
+ * // <Border type="padding24" />
31
+ * // <div>react</div>
32
+ * // <Border type="padding24" />
33
+ * // <div>world</div>
34
+ * }
35
+ */
36
+ declare function Separated({ children, with: separator }: Props): react_jsx_runtime.JSX.Element;
37
+
38
+ export { Separated };
@@ -0,0 +1,13 @@
1
+ // src/components/Separated/Separated.tsx
2
+ import { Children, Fragment, isValidElement } from "react";
3
+ import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
4
+ function Separated({ children, with: separator }) {
5
+ const childrenArray = Children.toArray(children).filter(isValidElement);
6
+ return /* @__PURE__ */ jsx(Fragment2, { children: childrenArray.map((child, i, { length }) => /* @__PURE__ */ jsxs(Fragment, { children: [
7
+ child,
8
+ i + 1 !== length ? separator : null
9
+ ] }, i)) });
10
+ }
11
+ export {
12
+ Separated
13
+ };
@@ -0,0 +1,46 @@
1
+ import { ReactElement } from 'react';
2
+
3
+ type StringifiedValue<T> = T extends boolean ? 'true' | 'false' : T extends number ? `${T}` : T extends string ? T : never;
4
+ type Props<Case> = {
5
+ value: Case;
6
+ caseBy: Partial<{
7
+ [P in StringifiedValue<Case>]: () => ReactElement | null;
8
+ }>;
9
+ defaultComponent?: () => ReactElement | null;
10
+ };
11
+ /**
12
+ * @description
13
+ * `SwitchCase` is a component that allows you to declaratively render components based on a given value,
14
+ * similar to a `switch-case` statement. It is useful when you need to conditionally render different
15
+ * components depending on a specific state.
16
+ *
17
+ * @param {string | number} value - The value to compare against.
18
+ * The component associated with the matching key in `caseBy` will be rendered.
19
+ * @param {Record<string | number, () => JSX.Element>} caseBy - An object that maps values to
20
+ * components to render. The keys represent possible values, and the values are functions returning
21
+ * the corresponding components.
22
+ * @param {() => JSX.Element} defaultComponent - The component to render if `value` does not match
23
+ * any key in `caseBy`.
24
+ *
25
+ * @returns {JSX.Element} A React component that conditionally renders based on cases.
26
+ *
27
+ * @example
28
+ * function App() {
29
+ * return (
30
+ * <SwitchCase
31
+ * value={status}
32
+ * // Renders TypeA, TypeB, or TypeC based on the status value.
33
+ * caseBy={{
34
+ * a: () => <TypeA />,
35
+ * b: () => <TypeB />,
36
+ * c: () => <TypeC />,
37
+ * }}
38
+ * // Renders Default when the status value does not match any case.
39
+ * defaultComponent={() => <Default />}
40
+ * />
41
+ * );
42
+ * }
43
+ */
44
+ declare function SwitchCase<Case>({ value, caseBy, defaultComponent }: Props<Case>): ReactElement | null;
45
+
46
+ export { SwitchCase };
@@ -0,0 +1,8 @@
1
+ // src/components/SwitchCase/SwitchCase.tsx
2
+ function SwitchCase({ value, caseBy, defaultComponent = () => null }) {
3
+ const stringifiedValue = String(value);
4
+ return (caseBy[stringifiedValue] ?? defaultComponent)();
5
+ }
6
+ export {
7
+ SwitchCase
8
+ };
@@ -0,0 +1,25 @@
1
+ import { DependencyList } from 'react';
2
+
3
+ /**
4
+ * @description
5
+ * `useAsyncEffect` is a custom hook for handling asynchronous side effects in React components.
6
+ * It follows the same cleanup pattern as `useEffect` while ensuring async operations are handled safely.
7
+ *
8
+ * @param {() => Promise<void | (() => void)>} effect - An asynchronous function executed in the `useEffect` pattern.
9
+ * This function can optionally return a cleanup function.
10
+ * @param {DependencyList} [deps] - A dependency array.
11
+ * The effect will re-run whenever any value in this array changes. If omitted, it runs only once when the component mounts.
12
+ *
13
+ * @example
14
+ * useAsyncEffect(async () => {
15
+ * const data = await fetchData();
16
+ * setData(data);
17
+ *
18
+ * return () => {
19
+ * console.log('Cleanup on unmount or dependencies change');
20
+ * };
21
+ * }, [dependencies]);
22
+ */
23
+ declare function useAsyncEffect(effect: () => Promise<void | (() => void)>, deps?: DependencyList): void;
24
+
25
+ export { useAsyncEffect };
@@ -0,0 +1,16 @@
1
+ // src/hooks/useAsyncEffect/useAsyncEffect.ts
2
+ import { useEffect } from "react";
3
+ function useAsyncEffect(effect, deps) {
4
+ useEffect(() => {
5
+ let cleanup;
6
+ effect().then((result) => {
7
+ cleanup = result;
8
+ });
9
+ return () => {
10
+ cleanup?.();
11
+ };
12
+ }, deps);
13
+ }
14
+ export {
15
+ useAsyncEffect
16
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @description
3
+ * `useBooleanState` is a React hook that simplifies managing a boolean state.
4
+ * It provides functions to set the state to `true`, set it to `false`, and toggle its value.
5
+ *
6
+ * @param {boolean} [defaultValue=false] - The initial value of the state. Defaults to `false`.
7
+ *
8
+ * @returns {readonly [state: boolean, setTrue: () => void, setFalse: () => void, toggle: () => void]} A tuple containing:
9
+ * - state `boolean` - The current state value.
10
+ * - setTrue `() => void` - A function to set the state to `true`.
11
+ * - setFalse `() => void` - A function to set the state to `false`.
12
+ * - toggle `() => void` - A function to toggle the state.
13
+ *
14
+ * @example
15
+ * const [open, openBottomSheet, closeBottomSheet, toggleBottomSheet] = useBooleanState(false);
16
+ */
17
+ declare const useBooleanState: (defaultValue?: boolean) => readonly [boolean, () => void, () => void, () => void];
18
+
19
+ export { useBooleanState };
@@ -0,0 +1,18 @@
1
+ // src/hooks/useBooleanState/useBooleanState.ts
2
+ import { useCallback, useState } from "react";
3
+ var useBooleanState = (defaultValue = false) => {
4
+ const [bool, setBool] = useState(defaultValue);
5
+ const setTrue = useCallback(() => {
6
+ setBool(true);
7
+ }, []);
8
+ const setFalse = useCallback(() => {
9
+ setBool(false);
10
+ }, []);
11
+ const toggle = useCallback(() => {
12
+ setBool((b) => !b);
13
+ }, []);
14
+ return [bool, setTrue, setFalse, toggle];
15
+ };
16
+ export {
17
+ useBooleanState
18
+ };