react-simplikit 0.0.50 → 0.0.52
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/ImpressionArea.cjs +57 -0
- package/{esm/components/ImpressionArea/index.d.ts → dist/components/ImpressionArea/ImpressionArea.d.cts} +9 -8
- package/dist/components/ImpressionArea/ImpressionArea.d.mts +48 -0
- package/dist/components/ImpressionArea/ImpressionArea.mjs +57 -0
- package/dist/components/ImpressionArea/index.d.cts +2 -46
- package/dist/components/ImpressionArea/index.d.mts +3 -0
- package/dist/components/Separated/Separated.cjs +38 -0
- package/{esm/components/Separated/index.d.ts → dist/components/Separated/Separated.d.cts} +7 -7
- package/dist/components/Separated/Separated.d.mts +38 -0
- package/dist/components/Separated/Separated.mjs +38 -0
- package/dist/components/Separated/index.d.cts +2 -37
- package/dist/components/Separated/index.d.mts +3 -0
- package/dist/components/SwitchCase/SwitchCase.cjs +40 -0
- package/{esm/components/SwitchCase/index.d.ts → dist/components/SwitchCase/SwitchCase.d.cts} +7 -8
- package/dist/components/SwitchCase/SwitchCase.d.mts +45 -0
- package/dist/components/SwitchCase/SwitchCase.mjs +40 -0
- package/dist/components/SwitchCase/index.d.cts +2 -45
- package/dist/components/SwitchCase/index.d.mts +3 -0
- package/dist/hooks/useAsyncEffect/index.d.cts +2 -24
- package/dist/hooks/useAsyncEffect/index.d.mts +3 -0
- package/dist/hooks/useAsyncEffect/useAsyncEffect.cjs +39 -0
- package/{esm/hooks/useAsyncEffect/index.d.ts → dist/hooks/useAsyncEffect/useAsyncEffect.d.cts} +4 -3
- package/dist/hooks/useAsyncEffect/useAsyncEffect.d.mts +26 -0
- package/dist/hooks/useAsyncEffect/useAsyncEffect.mjs +39 -0
- package/dist/hooks/useBooleanState/useBooleanState.cjs +36 -0
- package/dist/hooks/useBooleanState/{index.d.cts → useBooleanState.d.cts} +4 -2
- package/{esm/hooks/useBooleanState/index.d.ts → dist/hooks/useBooleanState/useBooleanState.d.mts} +4 -2
- package/dist/hooks/useBooleanState/useBooleanState.mjs +36 -0
- package/dist/hooks/useCallbackOncePerRender/index.d.cts +2 -39
- package/dist/hooks/useCallbackOncePerRender/index.d.mts +3 -0
- package/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.cjs +52 -0
- package/{esm/hooks/useCallbackOncePerRender/index.d.ts → dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.d.cts} +4 -3
- package/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.d.mts +41 -0
- package/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.mjs +52 -0
- package/dist/hooks/useConditionalEffect/index.d.cts +2 -42
- package/dist/hooks/useConditionalEffect/index.d.mts +3 -0
- package/dist/hooks/useConditionalEffect/useConditionalEffect.cjs +57 -0
- package/{esm/hooks/useConditionalEffect/index.d.ts → dist/hooks/useConditionalEffect/useConditionalEffect.d.cts} +4 -3
- package/dist/hooks/useConditionalEffect/useConditionalEffect.d.mts +44 -0
- package/dist/hooks/useConditionalEffect/useConditionalEffect.mjs +57 -0
- package/dist/hooks/useControlledState/index.d.cts +2 -50
- package/dist/hooks/useControlledState/index.d.mts +3 -0
- package/dist/hooks/useControlledState/useControlledState.cjs +60 -0
- package/{esm/hooks/useControlledState/index.d.ts → dist/hooks/useControlledState/useControlledState.d.cts} +11 -10
- package/dist/hooks/useControlledState/useControlledState.d.mts +52 -0
- package/dist/hooks/useControlledState/useControlledState.mjs +60 -0
- package/dist/hooks/useCounter/useCounter.cjs +75 -0
- package/{esm/hooks/useCounter/index.d.ts → dist/hooks/useCounter/useCounter.d.cts} +12 -10
- package/dist/hooks/useCounter/{index.d.cts → useCounter.d.mts} +12 -10
- package/dist/hooks/useCounter/useCounter.mjs +75 -0
- package/dist/hooks/useDebounce/debounce.cjs +49 -0
- package/dist/hooks/useDebounce/debounce.d.cts +8 -0
- package/dist/hooks/useDebounce/debounce.d.mts +8 -0
- package/dist/hooks/useDebounce/debounce.mjs +49 -0
- package/dist/hooks/useDebounce/useDebounce.cjs +66 -0
- package/{esm/hooks/useDebounce/index.d.ts → dist/hooks/useDebounce/useDebounce.d.cts} +6 -8
- package/dist/hooks/useDebounce/{index.d.cts → useDebounce.d.mts} +6 -8
- package/dist/hooks/useDebounce/useDebounce.mjs +66 -0
- package/dist/hooks/useDebouncedCallback/useDebouncedCallback.cjs +62 -0
- package/{esm/hooks/useDebouncedCallback/index.d.ts → dist/hooks/useDebouncedCallback/useDebouncedCallback.d.cts} +9 -7
- package/dist/hooks/useDebouncedCallback/{index.d.cts → useDebouncedCallback.d.mts} +9 -7
- package/dist/hooks/useDebouncedCallback/useDebouncedCallback.mjs +62 -0
- package/dist/hooks/useDoubleClick/index.d.cts +2 -45
- package/dist/hooks/useDoubleClick/index.d.mts +3 -0
- package/dist/hooks/useDoubleClick/useDoubleClick.cjs +64 -0
- package/{esm/hooks/useDoubleClick/index.d.ts → dist/hooks/useDoubleClick/useDoubleClick.d.cts} +8 -7
- package/dist/hooks/useDoubleClick/useDoubleClick.d.mts +47 -0
- package/dist/hooks/useDoubleClick/useDoubleClick.mjs +64 -0
- package/dist/hooks/useGeolocation/useGeolocation.cjs +210 -0
- package/{esm/hooks/useGeolocation/index.d.ts → dist/hooks/useGeolocation/useGeolocation.d.cts} +26 -24
- package/dist/hooks/useGeolocation/{index.d.cts → useGeolocation.d.mts} +26 -24
- package/dist/hooks/useGeolocation/useGeolocation.mjs +209 -0
- package/dist/hooks/useImpressionRef/useImpressionRef.cjs +67 -0
- package/{esm/hooks/useImpressionRef/index.d.ts → dist/hooks/useImpressionRef/useImpressionRef.d.cts} +10 -8
- package/dist/hooks/useImpressionRef/{index.d.cts → useImpressionRef.d.mts} +10 -8
- package/dist/hooks/useImpressionRef/useImpressionRef.mjs +67 -0
- package/dist/hooks/useInputState/index.d.cts +2 -22
- package/dist/hooks/useInputState/index.d.mts +3 -0
- package/dist/hooks/useInputState/useInputState.cjs +32 -0
- package/{esm/hooks/useInputState/index.d.ts → dist/hooks/useInputState/useInputState.d.cts} +4 -3
- package/dist/hooks/useInputState/useInputState.d.mts +24 -0
- package/dist/hooks/useInputState/useInputState.mjs +32 -0
- package/dist/hooks/useIntersectionObserver/useIntersectionObserver.cjs +58 -0
- package/dist/hooks/useIntersectionObserver/{index.d.cts → useIntersectionObserver.d.cts} +4 -2
- package/{esm/hooks/useIntersectionObserver/index.d.ts → dist/hooks/useIntersectionObserver/useIntersectionObserver.d.mts} +4 -2
- package/dist/hooks/useIntersectionObserver/useIntersectionObserver.mjs +58 -0
- package/dist/hooks/useInterval/useInterval.cjs +65 -0
- package/dist/hooks/useInterval/{index.d.cts → useInterval.d.cts} +7 -5
- package/{esm/hooks/useInterval/index.d.ts → dist/hooks/useInterval/useInterval.d.mts} +7 -5
- package/dist/hooks/useInterval/useInterval.mjs +65 -0
- package/dist/hooks/useIsClient/useIsClient.cjs +49 -0
- package/dist/hooks/useIsClient/{index.d.cts → useIsClient.d.cts} +4 -2
- package/{esm/hooks/useIsClient/index.d.ts → dist/hooks/useIsClient/useIsClient.d.mts} +4 -2
- package/dist/hooks/useIsClient/useIsClient.mjs +49 -0
- package/dist/hooks/useIsomorphicLayoutEffect/index.d.cts +2 -24
- package/dist/hooks/useIsomorphicLayoutEffect/index.d.mts +3 -0
- package/dist/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.cjs +25 -0
- package/{esm/hooks/useIsomorphicLayoutEffect/index.d.ts → dist/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.d.cts} +4 -3
- package/dist/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.d.mts +26 -0
- package/dist/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.mjs +25 -0
- package/dist/hooks/useList/useList.cjs +94 -0
- package/{esm/hooks/useList/index.d.ts → dist/hooks/useList/useList.d.cts} +10 -8
- package/dist/hooks/useList/{index.d.cts → useList.d.mts} +10 -8
- package/dist/hooks/useList/useList.mjs +94 -0
- package/dist/hooks/useLoading/useLoading.cjs +61 -0
- package/dist/hooks/useLoading/{index.d.cts → useLoading.d.cts} +4 -2
- package/{esm/hooks/useLoading/index.d.ts → dist/hooks/useLoading/useLoading.d.mts} +4 -2
- package/dist/hooks/useLoading/useLoading.mjs +61 -0
- package/dist/hooks/useLongPress/index.d.cts +2 -73
- package/dist/hooks/useLongPress/index.d.mts +3 -0
- package/dist/hooks/useLongPress/useLongPress.cjs +133 -0
- package/{esm/hooks/useLongPress/index.d.ts → dist/hooks/useLongPress/useLongPress.d.cts} +18 -17
- package/dist/hooks/useLongPress/useLongPress.d.mts +75 -0
- package/dist/hooks/useLongPress/useLongPress.mjs +133 -0
- package/dist/hooks/useMap/useMap.cjs +64 -0
- package/dist/hooks/useMap/{index.d.cts → useMap.d.cts} +12 -10
- package/{esm/hooks/useMap/index.d.ts → dist/hooks/useMap/useMap.d.mts} +12 -10
- package/dist/hooks/useMap/useMap.mjs +64 -0
- package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.cjs +51 -0
- package/{esm/hooks/useOutsideClickEffect/index.d.ts → dist/hooks/useOutsideClickEffect/useOutsideClickEffect.d.cts} +4 -2
- package/dist/hooks/useOutsideClickEffect/{index.d.cts → useOutsideClickEffect.d.mts} +4 -2
- package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.mjs +51 -0
- package/dist/hooks/usePreservedCallback/usePreservedCallback.cjs +41 -0
- package/dist/hooks/usePreservedCallback/{index.d.cts → usePreservedCallback.d.cts} +4 -2
- package/{esm/hooks/usePreservedCallback/index.d.ts → dist/hooks/usePreservedCallback/usePreservedCallback.d.mts} +4 -2
- package/dist/hooks/usePreservedCallback/usePreservedCallback.mjs +41 -0
- package/dist/hooks/usePreservedReference/usePreservedReference.cjs +55 -0
- package/dist/hooks/usePreservedReference/{index.d.cts → usePreservedReference.d.cts} +4 -2
- package/{esm/hooks/usePreservedReference/index.d.ts → dist/hooks/usePreservedReference/usePreservedReference.d.mts} +4 -2
- package/dist/hooks/usePreservedReference/usePreservedReference.mjs +55 -0
- package/dist/hooks/usePrevious/usePrevious.cjs +38 -0
- package/{esm/hooks/usePrevious/index.d.ts → dist/hooks/usePrevious/usePrevious.d.cts} +4 -2
- package/dist/hooks/usePrevious/{index.d.cts → usePrevious.d.mts} +4 -2
- package/dist/hooks/usePrevious/usePrevious.mjs +38 -0
- package/dist/hooks/useRefEffect/index.d.cts +2 -30
- package/dist/hooks/useRefEffect/index.d.mts +3 -0
- package/dist/hooks/useRefEffect/useRefEffect.cjs +42 -0
- package/{esm/hooks/useRefEffect/index.d.ts → dist/hooks/useRefEffect/useRefEffect.d.cts} +4 -3
- package/dist/hooks/useRefEffect/useRefEffect.d.mts +32 -0
- package/dist/hooks/useRefEffect/useRefEffect.mjs +42 -0
- package/dist/hooks/useSet/useSet.cjs +79 -0
- package/dist/hooks/useSet/{index.d.cts → useSet.d.cts} +9 -7
- package/{esm/hooks/useSet/index.d.ts → dist/hooks/useSet/useSet.d.mts} +9 -7
- package/dist/hooks/useSet/useSet.mjs +79 -0
- package/dist/hooks/useStorageState/index.d.cts +2 -60
- package/dist/hooks/useStorageState/index.d.mts +3 -0
- package/dist/hooks/useStorageState/storage.cjs +85 -0
- package/dist/hooks/useStorageState/storage.d.cts +10 -0
- package/dist/hooks/useStorageState/storage.d.mts +10 -0
- package/dist/hooks/useStorageState/storage.mjs +80 -0
- package/dist/hooks/useStorageState/useStorageState.cjs +81 -0
- package/{esm/hooks/useStorageState/index.d.ts → dist/hooks/useStorageState/useStorageState.d.cts} +10 -15
- package/dist/hooks/useStorageState/useStorageState.d.mts +56 -0
- package/dist/hooks/useStorageState/useStorageState.mjs +81 -0
- package/dist/hooks/useThrottle/throttle.cjs +19 -0
- package/dist/hooks/useThrottle/throttle.d.cts +19 -0
- package/dist/hooks/useThrottle/throttle.d.mts +19 -0
- package/dist/hooks/useThrottle/throttle.mjs +19 -0
- package/dist/hooks/useThrottle/useThrottle.cjs +49 -0
- package/dist/hooks/useThrottle/{index.d.cts → useThrottle.d.cts} +6 -19
- package/{esm/hooks/useThrottle/index.d.ts → dist/hooks/useThrottle/useThrottle.d.mts} +6 -19
- package/dist/hooks/useThrottle/useThrottle.mjs +49 -0
- package/dist/hooks/useThrottledCallback/useThrottledCallback.cjs +57 -0
- package/{esm/hooks/useThrottledCallback/index.d.ts → dist/hooks/useThrottledCallback/useThrottledCallback.d.cts} +8 -6
- package/dist/hooks/useThrottledCallback/{index.d.cts → useThrottledCallback.d.mts} +8 -6
- package/dist/hooks/useThrottledCallback/useThrottledCallback.mjs +57 -0
- package/dist/hooks/useTimeout/useTimeout.cjs +40 -0
- package/dist/hooks/useTimeout/{index.d.cts → useTimeout.d.cts} +4 -2
- package/{esm/hooks/useTimeout/index.d.ts → dist/hooks/useTimeout/useTimeout.d.mts} +4 -2
- package/dist/hooks/useTimeout/useTimeout.mjs +40 -0
- package/dist/hooks/useToggle/useToggle.cjs +34 -0
- package/dist/hooks/useToggle/{index.d.cts → useToggle.d.cts} +4 -4
- package/{esm/hooks/useToggle/index.d.ts → dist/hooks/useToggle/useToggle.d.mts} +4 -4
- package/dist/hooks/useToggle/useToggle.mjs +34 -0
- package/dist/hooks/useVisibilityEvent/useVisibilityEvent.cjs +42 -0
- package/{esm/hooks/useVisibilityEvent/index.d.ts → dist/hooks/useVisibilityEvent/useVisibilityEvent.d.cts} +5 -3
- package/dist/hooks/useVisibilityEvent/{index.d.cts → useVisibilityEvent.d.mts} +5 -3
- package/dist/hooks/useVisibilityEvent/useVisibilityEvent.mjs +42 -0
- package/dist/index.cjs +77 -1382
- package/dist/index.d.cts +56 -40
- package/dist/index.d.mts +56 -0
- package/dist/index.mjs +40 -0
- package/dist/utils/buildContext/buildContext.cjs +50 -0
- package/{esm/utils/buildContext/index.d.ts → dist/utils/buildContext/buildContext.d.cts} +7 -7
- package/dist/utils/buildContext/buildContext.d.mts +38 -0
- package/dist/utils/buildContext/buildContext.mjs +50 -0
- package/dist/utils/buildContext/index.d.cts +2 -37
- package/dist/utils/buildContext/index.d.mts +3 -0
- package/dist/utils/mergeProps/index.d.cts +2 -25
- package/dist/utils/mergeProps/index.d.mts +3 -0
- package/dist/utils/mergeProps/mergeProps.cjs +53 -0
- package/{esm/utils/mergeProps/index.d.ts → dist/utils/mergeProps/mergeProps.d.cts} +7 -8
- package/dist/utils/mergeProps/mergeProps.d.mts +25 -0
- package/dist/utils/mergeProps/mergeProps.mjs +53 -0
- package/dist/utils/mergeRefs/index.d.cts +2 -38
- package/dist/utils/mergeRefs/index.d.mts +3 -0
- package/dist/utils/mergeRefs/mergeRefs.cjs +50 -0
- package/{esm/utils/mergeRefs/index.d.ts → dist/utils/mergeRefs/mergeRefs.d.cts} +4 -3
- package/dist/utils/mergeRefs/mergeRefs.d.mts +40 -0
- package/dist/utils/mergeRefs/mergeRefs.mjs +50 -0
- package/package.json +9 -11
- package/dist/components/ImpressionArea/index.cjs +0 -295
- package/dist/components/Separated/index.cjs +0 -41
- package/dist/components/SwitchCase/index.cjs +0 -36
- package/dist/hooks/useAsyncEffect/index.cjs +0 -44
- package/dist/hooks/useBooleanState/index.cjs +0 -46
- package/dist/hooks/useCallbackOncePerRender/index.cjs +0 -63
- package/dist/hooks/useConditionalEffect/index.cjs +0 -51
- package/dist/hooks/useControlledState/index.cjs +0 -57
- package/dist/hooks/useCounter/index.cjs +0 -70
- package/dist/hooks/useDebounce/index.cjs +0 -130
- package/dist/hooks/useDebouncedCallback/index.cjs +0 -148
- package/dist/hooks/useDoubleClick/index.cjs +0 -79
- package/dist/hooks/useGeolocation/index.cjs +0 -154
- package/dist/hooks/useImpressionRef/index.cjs +0 -258
- package/dist/hooks/useInputState/index.cjs +0 -46
- package/dist/hooks/useIntersectionObserver/index.cjs +0 -95
- package/dist/hooks/useInterval/index.cjs +0 -74
- package/dist/hooks/useIsClient/index.cjs +0 -40
- package/dist/hooks/useIsomorphicLayoutEffect/index.cjs +0 -35
- package/dist/hooks/useList/index.cjs +0 -104
- package/dist/hooks/useLoading/index.cjs +0 -65
- package/dist/hooks/useLongPress/index.cjs +0 -127
- package/dist/hooks/useMap/index.cjs +0 -78
- package/dist/hooks/useOutsideClickEffect/index.cjs +0 -74
- package/dist/hooks/usePreservedCallback/index.cjs +0 -45
- package/dist/hooks/usePreservedReference/index.cjs +0 -45
- package/dist/hooks/usePrevious/index.cjs +0 -48
- package/dist/hooks/useRefEffect/index.cjs +0 -72
- package/dist/hooks/useSet/index.cjs +0 -105
- package/dist/hooks/useStorageState/index.cjs +0 -196
- package/dist/hooks/useThrottle/index.cjs +0 -151
- package/dist/hooks/useThrottledCallback/index.cjs +0 -172
- package/dist/hooks/useTimeout/index.cjs +0 -57
- package/dist/hooks/useToggle/index.cjs +0 -37
- package/dist/hooks/useVisibilityEvent/index.cjs +0 -47
- package/dist/utils/buildContext/index.cjs +0 -56
- package/dist/utils/mergeProps/index.cjs +0 -71
- package/dist/utils/mergeRefs/index.cjs +0 -46
- package/esm/components/ImpressionArea/index.js +0 -269
- package/esm/components/Separated/index.js +0 -15
- package/esm/components/SwitchCase/index.js +0 -10
- package/esm/hooks/useAsyncEffect/index.js +0 -18
- package/esm/hooks/useBooleanState/index.js +0 -20
- package/esm/hooks/useCallbackOncePerRender/index.js +0 -37
- package/esm/hooks/useConditionalEffect/index.js +0 -25
- package/esm/hooks/useControlledState/index.js +0 -31
- package/esm/hooks/useCounter/index.js +0 -44
- package/esm/hooks/useDebounce/index.js +0 -104
- package/esm/hooks/useDebouncedCallback/index.js +0 -122
- package/esm/hooks/useDoubleClick/index.js +0 -53
- package/esm/hooks/useGeolocation/index.js +0 -128
- package/esm/hooks/useImpressionRef/index.js +0 -232
- package/esm/hooks/useInputState/index.js +0 -20
- package/esm/hooks/useIntersectionObserver/index.js +0 -69
- package/esm/hooks/useInterval/index.js +0 -48
- package/esm/hooks/useIsClient/index.js +0 -14
- package/esm/hooks/useIsomorphicLayoutEffect/index.js +0 -9
- package/esm/hooks/useList/index.js +0 -78
- package/esm/hooks/useLoading/index.js +0 -39
- package/esm/hooks/useLongPress/index.js +0 -101
- package/esm/hooks/useMap/index.js +0 -52
- package/esm/hooks/useOutsideClickEffect/index.js +0 -48
- package/esm/hooks/usePreservedCallback/index.js +0 -19
- package/esm/hooks/usePreservedReference/index.js +0 -19
- package/esm/hooks/usePrevious/index.js +0 -22
- package/esm/hooks/useRefEffect/index.js +0 -46
- package/esm/hooks/useSet/index.js +0 -79
- package/esm/hooks/useStorageState/index.js +0 -170
- package/esm/hooks/useThrottle/index.js +0 -125
- package/esm/hooks/useThrottledCallback/index.js +0 -146
- package/esm/hooks/useTimeout/index.js +0 -31
- package/esm/hooks/useToggle/index.js +0 -11
- package/esm/hooks/useVisibilityEvent/index.js +0 -21
- package/esm/index.d.ts +0 -40
- package/esm/index.js +0 -1320
- package/esm/utils/buildContext/index.js +0 -30
- package/esm/utils/mergeProps/index.js +0 -45
- package/esm/utils/mergeRefs/index.js +0 -20
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
3
|
+
//#region src/hooks/useConditionalEffect/useConditionalEffect.ts
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* `useConditionalEffect` is a React hook that conditionally executes effects based on a predicate function.
|
|
7
|
+
* This provides more control over when effects run beyond just dependency changes.
|
|
8
|
+
*
|
|
9
|
+
* @param {EffectCallback} effect - The effect callback to run.
|
|
10
|
+
* @param {DependencyList} deps - Dependencies array, similar to useEffect.
|
|
11
|
+
* @param {(prevDeps: T | undefined, currentDeps: T) => boolean} condition - Function that determines if the effect should run based on previous and current deps.
|
|
12
|
+
* - On the initial render, `prevDeps` will be `undefined`. Your `condition` function should handle this case.
|
|
13
|
+
* - If you want your effect to run on the initial render, return `true` when `prevDeps` is `undefined`.
|
|
14
|
+
* - If you don't want your effect to run on the initial render, return `false` when `prevDeps` is `undefined`.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* import { useConditionalEffect } from 'react-simplikit';
|
|
18
|
+
*
|
|
19
|
+
* function Component() {
|
|
20
|
+
* const [count, setCount] = useState(0);
|
|
21
|
+
*
|
|
22
|
+
* // Only run effect when count increases
|
|
23
|
+
* useConditionalEffect(
|
|
24
|
+
* () => {
|
|
25
|
+
* console.log(`Count increased to ${count}`);
|
|
26
|
+
* },
|
|
27
|
+
* [count],
|
|
28
|
+
* (prevDeps, currentDeps) => {
|
|
29
|
+
* // Only run when count is defined and has increased
|
|
30
|
+
* return prevDeps && currentDeps[0] > prevDeps[0];
|
|
31
|
+
* }
|
|
32
|
+
* );
|
|
33
|
+
*
|
|
34
|
+
* return (
|
|
35
|
+
* <button onClick={() => setCount(prev => prev + 1)}>
|
|
36
|
+
* Increment: {count}
|
|
37
|
+
* </button>
|
|
38
|
+
* );
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
function useConditionalEffect(effect, deps, condition) {
|
|
43
|
+
const prevDepsRef = useRef(void 0);
|
|
44
|
+
const memoizedCondition = useCallback(condition, deps);
|
|
45
|
+
if (deps.length === 0) console.warn("useConditionalEffect received an empty dependency array. This may indicate missing dependencies and could lead to unexpected behavior.");
|
|
46
|
+
const shouldRun = memoizedCondition(prevDepsRef.current, deps);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (shouldRun) {
|
|
49
|
+
const cleanup = effect();
|
|
50
|
+
prevDepsRef.current = deps;
|
|
51
|
+
return cleanup;
|
|
52
|
+
}
|
|
53
|
+
prevDepsRef.current = deps;
|
|
54
|
+
}, deps);
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { useConditionalEffect };
|
|
@@ -1,51 +1,3 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction } from 'react';
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
defaultValue?: never;
|
|
6
|
-
} | {
|
|
7
|
-
defaultValue: T;
|
|
8
|
-
value?: T;
|
|
9
|
-
};
|
|
10
|
-
type UseControlledStateProps<T> = ControlledState<T> & {
|
|
11
|
-
onChange?: (value: T) => void;
|
|
12
|
-
equalityFn?: (prev: T, next: T) => boolean;
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* @description
|
|
16
|
-
* `useControlledState` is a React hook that allows you to control both controlled and uncontrolled states.
|
|
17
|
-
* If you pass the state to `value`, it will be a controlled state, and if you pass the state to `defaultValue`, it will be an uncontrolled state.
|
|
18
|
-
* If both `value` and `defaultValue` are passed, `value` will take precedence.
|
|
19
|
-
*
|
|
20
|
-
* @param {Object} props
|
|
21
|
-
* @param {T} [props.value] - The value of the state.
|
|
22
|
-
* @param {T} [props.defaultValue] - The default value of the state.
|
|
23
|
-
* @param {(value: T) => void} [props.onChange] - The callback function that is called when the state changes.
|
|
24
|
-
* @param {(prev: T, next: T) => boolean} [props.equalityFn] - The function that is used to compare the previous and next values.
|
|
25
|
-
*
|
|
26
|
-
* @returns {[T, Dispatch<SetStateAction<T>>]} - The state and the setter function.
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* type ToggleProps = {
|
|
30
|
-
* value?: boolean;
|
|
31
|
-
* defaultValue?: boolean;
|
|
32
|
-
* onChange?: (value: boolean) => void;
|
|
33
|
-
* }
|
|
34
|
-
*
|
|
35
|
-
* function Toggle({ value, defaultValue, onChange }: ToggleProps) {
|
|
36
|
-
* const [on, setOn] = useControlledState({
|
|
37
|
-
* value,
|
|
38
|
-
* defaultValue: defaultValue ?? false,
|
|
39
|
-
* onChange,
|
|
40
|
-
* });
|
|
41
|
-
*
|
|
42
|
-
* return (
|
|
43
|
-
* <button onClick={() => setOn((prev) => !prev)}>
|
|
44
|
-
* {on ? 'ON' : 'OFF'}
|
|
45
|
-
* </button>
|
|
46
|
-
* )
|
|
47
|
-
* }
|
|
48
|
-
*/
|
|
49
|
-
declare function useControlledState<T>({ value: valueProp, defaultValue, onChange, equalityFn, }: UseControlledStateProps<T>): [T, Dispatch<SetStateAction<T>>];
|
|
50
|
-
|
|
51
|
-
export { useControlledState };
|
|
2
|
+
import { useControlledState } from "./useControlledState.cjs";
|
|
3
|
+
export { useControlledState };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
let react = require("react");
|
|
3
|
+
//#region src/hooks/useControlledState/useControlledState.ts
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* `useControlledState` is a React hook that allows you to control both controlled and uncontrolled states.
|
|
7
|
+
* If you pass the state to `value`, it will be a controlled state, and if you pass the state to `defaultValue`, it will be an uncontrolled state.
|
|
8
|
+
* If both `value` and `defaultValue` are passed, `value` will take precedence.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} props
|
|
11
|
+
* @param {T} [props.value] - The value of the state.
|
|
12
|
+
* @param {T} [props.defaultValue] - The default value of the state.
|
|
13
|
+
* @param {(value: T) => void} [props.onChange] - The callback function that is called when the state changes.
|
|
14
|
+
* @param {(prev: T, next: T) => boolean} [props.equalityFn] - The function that is used to compare the previous and next values.
|
|
15
|
+
*
|
|
16
|
+
* @returns {[T, Dispatch<SetStateAction<T>>]} - The state and the setter function.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* type ToggleProps = {
|
|
20
|
+
* value?: boolean;
|
|
21
|
+
* defaultValue?: boolean;
|
|
22
|
+
* onChange?: (value: boolean) => void;
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* function Toggle({ value, defaultValue, onChange }: ToggleProps) {
|
|
26
|
+
* const [on, setOn] = useControlledState({
|
|
27
|
+
* value,
|
|
28
|
+
* defaultValue: defaultValue ?? false,
|
|
29
|
+
* onChange,
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* return (
|
|
33
|
+
* <button onClick={() => setOn((prev) => !prev)}>
|
|
34
|
+
* {on ? 'ON' : 'OFF'}
|
|
35
|
+
* </button>
|
|
36
|
+
* )
|
|
37
|
+
* }
|
|
38
|
+
*/
|
|
39
|
+
function useControlledState({ value: valueProp, defaultValue, onChange, equalityFn = Object.is }) {
|
|
40
|
+
const [uncontrolledState, setUncontrolledState] = (0, react.useState)(defaultValue);
|
|
41
|
+
const controlled = valueProp !== void 0;
|
|
42
|
+
const value = controlled ? valueProp : uncontrolledState;
|
|
43
|
+
return [value, (0, react.useCallback)((next) => {
|
|
44
|
+
const nextValue = isSetStateAction(next) ? next(value) : next;
|
|
45
|
+
if (equalityFn(value, nextValue) === true) return;
|
|
46
|
+
if (controlled === false) setUncontrolledState(nextValue);
|
|
47
|
+
if (controlled === true && nextValue === void 0) setUncontrolledState(nextValue);
|
|
48
|
+
onChange?.(nextValue);
|
|
49
|
+
}, [
|
|
50
|
+
controlled,
|
|
51
|
+
onChange,
|
|
52
|
+
equalityFn,
|
|
53
|
+
value
|
|
54
|
+
])];
|
|
55
|
+
}
|
|
56
|
+
function isSetStateAction(next) {
|
|
57
|
+
return typeof next === "function";
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.useControlledState = useControlledState;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction } from 'react';
|
|
2
1
|
|
|
2
|
+
import { Dispatch, SetStateAction } from "react";
|
|
3
|
+
//#region src/hooks/useControlledState/useControlledState.d.ts
|
|
3
4
|
type ControlledState<T> = {
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
value: T;
|
|
6
|
+
defaultValue?: never;
|
|
6
7
|
} | {
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
defaultValue: T;
|
|
9
|
+
value?: T;
|
|
9
10
|
};
|
|
10
11
|
type UseControlledStateProps<T> = ControlledState<T> & {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
onChange?: (value: T) => void;
|
|
13
|
+
equalityFn?: (prev: T, next: T) => boolean;
|
|
13
14
|
};
|
|
14
15
|
/**
|
|
15
16
|
* @description
|
|
@@ -46,6 +47,6 @@ type UseControlledStateProps<T> = ControlledState<T> & {
|
|
|
46
47
|
* )
|
|
47
48
|
* }
|
|
48
49
|
*/
|
|
49
|
-
declare function useControlledState<T>({ value: valueProp, defaultValue, onChange, equalityFn
|
|
50
|
-
|
|
51
|
-
export { useControlledState };
|
|
50
|
+
declare function useControlledState<T>({ value: valueProp, defaultValue, onChange, equalityFn }: UseControlledStateProps<T>): [T, Dispatch<SetStateAction<T>>];
|
|
51
|
+
//#endregion
|
|
52
|
+
export { UseControlledStateProps, useControlledState };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
import { Dispatch, SetStateAction } from "react";
|
|
3
|
+
//#region src/hooks/useControlledState/useControlledState.d.ts
|
|
4
|
+
type ControlledState<T> = {
|
|
5
|
+
value: T;
|
|
6
|
+
defaultValue?: never;
|
|
7
|
+
} | {
|
|
8
|
+
defaultValue: T;
|
|
9
|
+
value?: T;
|
|
10
|
+
};
|
|
11
|
+
type UseControlledStateProps<T> = ControlledState<T> & {
|
|
12
|
+
onChange?: (value: T) => void;
|
|
13
|
+
equalityFn?: (prev: T, next: T) => boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* @description
|
|
17
|
+
* `useControlledState` is a React hook that allows you to control both controlled and uncontrolled states.
|
|
18
|
+
* If you pass the state to `value`, it will be a controlled state, and if you pass the state to `defaultValue`, it will be an uncontrolled state.
|
|
19
|
+
* If both `value` and `defaultValue` are passed, `value` will take precedence.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object} props
|
|
22
|
+
* @param {T} [props.value] - The value of the state.
|
|
23
|
+
* @param {T} [props.defaultValue] - The default value of the state.
|
|
24
|
+
* @param {(value: T) => void} [props.onChange] - The callback function that is called when the state changes.
|
|
25
|
+
* @param {(prev: T, next: T) => boolean} [props.equalityFn] - The function that is used to compare the previous and next values.
|
|
26
|
+
*
|
|
27
|
+
* @returns {[T, Dispatch<SetStateAction<T>>]} - The state and the setter function.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* type ToggleProps = {
|
|
31
|
+
* value?: boolean;
|
|
32
|
+
* defaultValue?: boolean;
|
|
33
|
+
* onChange?: (value: boolean) => void;
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* function Toggle({ value, defaultValue, onChange }: ToggleProps) {
|
|
37
|
+
* const [on, setOn] = useControlledState({
|
|
38
|
+
* value,
|
|
39
|
+
* defaultValue: defaultValue ?? false,
|
|
40
|
+
* onChange,
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* return (
|
|
44
|
+
* <button onClick={() => setOn((prev) => !prev)}>
|
|
45
|
+
* {on ? 'ON' : 'OFF'}
|
|
46
|
+
* </button>
|
|
47
|
+
* )
|
|
48
|
+
* }
|
|
49
|
+
*/
|
|
50
|
+
declare function useControlledState<T>({ value: valueProp, defaultValue, onChange, equalityFn }: UseControlledStateProps<T>): [T, Dispatch<SetStateAction<T>>];
|
|
51
|
+
//#endregion
|
|
52
|
+
export { UseControlledStateProps, useControlledState };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useState } from "react";
|
|
3
|
+
//#region src/hooks/useControlledState/useControlledState.ts
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* `useControlledState` is a React hook that allows you to control both controlled and uncontrolled states.
|
|
7
|
+
* If you pass the state to `value`, it will be a controlled state, and if you pass the state to `defaultValue`, it will be an uncontrolled state.
|
|
8
|
+
* If both `value` and `defaultValue` are passed, `value` will take precedence.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} props
|
|
11
|
+
* @param {T} [props.value] - The value of the state.
|
|
12
|
+
* @param {T} [props.defaultValue] - The default value of the state.
|
|
13
|
+
* @param {(value: T) => void} [props.onChange] - The callback function that is called when the state changes.
|
|
14
|
+
* @param {(prev: T, next: T) => boolean} [props.equalityFn] - The function that is used to compare the previous and next values.
|
|
15
|
+
*
|
|
16
|
+
* @returns {[T, Dispatch<SetStateAction<T>>]} - The state and the setter function.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* type ToggleProps = {
|
|
20
|
+
* value?: boolean;
|
|
21
|
+
* defaultValue?: boolean;
|
|
22
|
+
* onChange?: (value: boolean) => void;
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* function Toggle({ value, defaultValue, onChange }: ToggleProps) {
|
|
26
|
+
* const [on, setOn] = useControlledState({
|
|
27
|
+
* value,
|
|
28
|
+
* defaultValue: defaultValue ?? false,
|
|
29
|
+
* onChange,
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* return (
|
|
33
|
+
* <button onClick={() => setOn((prev) => !prev)}>
|
|
34
|
+
* {on ? 'ON' : 'OFF'}
|
|
35
|
+
* </button>
|
|
36
|
+
* )
|
|
37
|
+
* }
|
|
38
|
+
*/
|
|
39
|
+
function useControlledState({ value: valueProp, defaultValue, onChange, equalityFn = Object.is }) {
|
|
40
|
+
const [uncontrolledState, setUncontrolledState] = useState(defaultValue);
|
|
41
|
+
const controlled = valueProp !== void 0;
|
|
42
|
+
const value = controlled ? valueProp : uncontrolledState;
|
|
43
|
+
return [value, useCallback((next) => {
|
|
44
|
+
const nextValue = isSetStateAction(next) ? next(value) : next;
|
|
45
|
+
if (equalityFn(value, nextValue) === true) return;
|
|
46
|
+
if (controlled === false) setUncontrolledState(nextValue);
|
|
47
|
+
if (controlled === true && nextValue === void 0) setUncontrolledState(nextValue);
|
|
48
|
+
onChange?.(nextValue);
|
|
49
|
+
}, [
|
|
50
|
+
controlled,
|
|
51
|
+
onChange,
|
|
52
|
+
equalityFn,
|
|
53
|
+
value
|
|
54
|
+
])];
|
|
55
|
+
}
|
|
56
|
+
function isSetStateAction(next) {
|
|
57
|
+
return typeof next === "function";
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { useControlledState };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
let react = require("react");
|
|
3
|
+
//#region src/hooks/useCounter/useCounter.ts
|
|
4
|
+
const validateValue = (value, { min, max }) => {
|
|
5
|
+
if (min !== void 0 && value < min) return min;
|
|
6
|
+
if (max !== void 0 && value > max) return max;
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* @description
|
|
11
|
+
* `useCounter` is a React hook that manages a numeric counter state with increment, decrement, and reset capabilities.
|
|
12
|
+
* Optionally, you can provide minimum and maximum values to constrain the counter's range.
|
|
13
|
+
*
|
|
14
|
+
* @param {number} [initialValue=0] - Initial value for the counter. Defaults to 0.
|
|
15
|
+
* @param {UseCounterOptions} options - The options for the counter.
|
|
16
|
+
* @param {number} [options.min] - Minimum value the counter can reach. If not provided, there is no lower limit.
|
|
17
|
+
* @param {number} [options.max] - Maximum value the counter can reach. If not provided, there is no upper limit.
|
|
18
|
+
* @param {number} [options.step=1] - Value to increment or decrement by. Defaults to 1.
|
|
19
|
+
*
|
|
20
|
+
* @returns {UseCounterReturn} An object with count value and control functions.
|
|
21
|
+
* - count `number` - The current count value;
|
|
22
|
+
* - increment `() => void` - A function to increment the count;
|
|
23
|
+
* - decrement `() => void` - A function to decrement the count;
|
|
24
|
+
* - reset `() => void` - A function to reset the count to the initial value;
|
|
25
|
+
* - setCount `(value: number | ((prev: number) => number)) => void` - A function to set the count to a specific value or a function that returns a new value;
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* import { useCounter } from 'react-simplikit';
|
|
29
|
+
*
|
|
30
|
+
* function ShoppingCart() {
|
|
31
|
+
* const { count, increment, decrement, reset } = useCounter(1, {
|
|
32
|
+
* min: 1,
|
|
33
|
+
* max: 10,
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* return (
|
|
37
|
+
* <div>
|
|
38
|
+
* <span>Quantity: {count}</span>
|
|
39
|
+
* <button type="button" onClick={decrement}>-</button>
|
|
40
|
+
* <button type="button" onClick={increment}>+</button>
|
|
41
|
+
* <button type="button" onClick={reset}>Reset</button>
|
|
42
|
+
* </div>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
*/
|
|
46
|
+
function useCounter(initialValue = 0, { min, max, step = 1 } = {}) {
|
|
47
|
+
const [count, setCountState] = (0, react.useState)(() => validateValue(initialValue, {
|
|
48
|
+
min,
|
|
49
|
+
max
|
|
50
|
+
}));
|
|
51
|
+
const setCount = (0, react.useCallback)((value) => {
|
|
52
|
+
setCountState((prev) => {
|
|
53
|
+
const nextValue = typeof value === "function" ? value(prev) : value;
|
|
54
|
+
return validateValue(nextValue, {
|
|
55
|
+
min,
|
|
56
|
+
max
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}, [min, max]);
|
|
60
|
+
return {
|
|
61
|
+
count,
|
|
62
|
+
increment: (0, react.useCallback)(() => {
|
|
63
|
+
setCount((prev) => prev + step);
|
|
64
|
+
}, [setCount, step]),
|
|
65
|
+
decrement: (0, react.useCallback)(() => {
|
|
66
|
+
setCount((prev) => prev - step);
|
|
67
|
+
}, [setCount, step]),
|
|
68
|
+
reset: (0, react.useCallback)(() => {
|
|
69
|
+
setCount(initialValue);
|
|
70
|
+
}, [setCount, initialValue]),
|
|
71
|
+
setCount
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
exports.useCounter = useCounter;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/hooks/useCounter/useCounter.d.ts
|
|
1
3
|
type UseCounterOptions = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
min?: number;
|
|
5
|
+
max?: number;
|
|
6
|
+
step?: number;
|
|
5
7
|
};
|
|
6
8
|
type UseCounterReturn = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
count: number;
|
|
10
|
+
increment: () => void;
|
|
11
|
+
decrement: () => void;
|
|
12
|
+
reset: () => void;
|
|
13
|
+
setCount: (value: number | ((prev: number) => number)) => void;
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* @description
|
|
@@ -48,5 +50,5 @@ type UseCounterReturn = {
|
|
|
48
50
|
* }
|
|
49
51
|
*/
|
|
50
52
|
declare function useCounter(initialValue?: number, { min, max, step }?: UseCounterOptions): UseCounterReturn;
|
|
51
|
-
|
|
52
|
-
export { useCounter };
|
|
53
|
+
//#endregion
|
|
54
|
+
export { useCounter };
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/hooks/useCounter/useCounter.d.ts
|
|
1
3
|
type UseCounterOptions = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
min?: number;
|
|
5
|
+
max?: number;
|
|
6
|
+
step?: number;
|
|
5
7
|
};
|
|
6
8
|
type UseCounterReturn = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
count: number;
|
|
10
|
+
increment: () => void;
|
|
11
|
+
decrement: () => void;
|
|
12
|
+
reset: () => void;
|
|
13
|
+
setCount: (value: number | ((prev: number) => number)) => void;
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* @description
|
|
@@ -48,5 +50,5 @@ type UseCounterReturn = {
|
|
|
48
50
|
* }
|
|
49
51
|
*/
|
|
50
52
|
declare function useCounter(initialValue?: number, { min, max, step }?: UseCounterOptions): UseCounterReturn;
|
|
51
|
-
|
|
52
|
-
export { useCounter };
|
|
53
|
+
//#endregion
|
|
54
|
+
export { useCounter };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useState } from "react";
|
|
3
|
+
//#region src/hooks/useCounter/useCounter.ts
|
|
4
|
+
const validateValue = (value, { min, max }) => {
|
|
5
|
+
if (min !== void 0 && value < min) return min;
|
|
6
|
+
if (max !== void 0 && value > max) return max;
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* @description
|
|
11
|
+
* `useCounter` is a React hook that manages a numeric counter state with increment, decrement, and reset capabilities.
|
|
12
|
+
* Optionally, you can provide minimum and maximum values to constrain the counter's range.
|
|
13
|
+
*
|
|
14
|
+
* @param {number} [initialValue=0] - Initial value for the counter. Defaults to 0.
|
|
15
|
+
* @param {UseCounterOptions} options - The options for the counter.
|
|
16
|
+
* @param {number} [options.min] - Minimum value the counter can reach. If not provided, there is no lower limit.
|
|
17
|
+
* @param {number} [options.max] - Maximum value the counter can reach. If not provided, there is no upper limit.
|
|
18
|
+
* @param {number} [options.step=1] - Value to increment or decrement by. Defaults to 1.
|
|
19
|
+
*
|
|
20
|
+
* @returns {UseCounterReturn} An object with count value and control functions.
|
|
21
|
+
* - count `number` - The current count value;
|
|
22
|
+
* - increment `() => void` - A function to increment the count;
|
|
23
|
+
* - decrement `() => void` - A function to decrement the count;
|
|
24
|
+
* - reset `() => void` - A function to reset the count to the initial value;
|
|
25
|
+
* - setCount `(value: number | ((prev: number) => number)) => void` - A function to set the count to a specific value or a function that returns a new value;
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* import { useCounter } from 'react-simplikit';
|
|
29
|
+
*
|
|
30
|
+
* function ShoppingCart() {
|
|
31
|
+
* const { count, increment, decrement, reset } = useCounter(1, {
|
|
32
|
+
* min: 1,
|
|
33
|
+
* max: 10,
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* return (
|
|
37
|
+
* <div>
|
|
38
|
+
* <span>Quantity: {count}</span>
|
|
39
|
+
* <button type="button" onClick={decrement}>-</button>
|
|
40
|
+
* <button type="button" onClick={increment}>+</button>
|
|
41
|
+
* <button type="button" onClick={reset}>Reset</button>
|
|
42
|
+
* </div>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
*/
|
|
46
|
+
function useCounter(initialValue = 0, { min, max, step = 1 } = {}) {
|
|
47
|
+
const [count, setCountState] = useState(() => validateValue(initialValue, {
|
|
48
|
+
min,
|
|
49
|
+
max
|
|
50
|
+
}));
|
|
51
|
+
const setCount = useCallback((value) => {
|
|
52
|
+
setCountState((prev) => {
|
|
53
|
+
const nextValue = typeof value === "function" ? value(prev) : value;
|
|
54
|
+
return validateValue(nextValue, {
|
|
55
|
+
min,
|
|
56
|
+
max
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}, [min, max]);
|
|
60
|
+
return {
|
|
61
|
+
count,
|
|
62
|
+
increment: useCallback(() => {
|
|
63
|
+
setCount((prev) => prev + step);
|
|
64
|
+
}, [setCount, step]),
|
|
65
|
+
decrement: useCallback(() => {
|
|
66
|
+
setCount((prev) => prev - step);
|
|
67
|
+
}, [setCount, step]),
|
|
68
|
+
reset: useCallback(() => {
|
|
69
|
+
setCount(initialValue);
|
|
70
|
+
}, [setCount, initialValue]),
|
|
71
|
+
setCount
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { useCounter };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/hooks/useDebounce/debounce.ts
|
|
3
|
+
function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
4
|
+
let pendingThis = void 0;
|
|
5
|
+
let pendingArgs = null;
|
|
6
|
+
const leading = edges != null && edges.includes("leading");
|
|
7
|
+
const trailing = edges == null || edges.includes("trailing");
|
|
8
|
+
const invoke = () => {
|
|
9
|
+
if (pendingArgs !== null) {
|
|
10
|
+
func.apply(pendingThis, pendingArgs);
|
|
11
|
+
pendingThis = void 0;
|
|
12
|
+
pendingArgs = null;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const onTimerEnd = () => {
|
|
16
|
+
if (trailing) invoke();
|
|
17
|
+
cancel();
|
|
18
|
+
};
|
|
19
|
+
let timeoutId = null;
|
|
20
|
+
const schedule = () => {
|
|
21
|
+
if (timeoutId != null) clearTimeout(timeoutId);
|
|
22
|
+
timeoutId = setTimeout(() => {
|
|
23
|
+
timeoutId = null;
|
|
24
|
+
onTimerEnd();
|
|
25
|
+
}, debounceMs);
|
|
26
|
+
};
|
|
27
|
+
const cancelTimer = () => {
|
|
28
|
+
if (timeoutId !== null) {
|
|
29
|
+
clearTimeout(timeoutId);
|
|
30
|
+
timeoutId = null;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const cancel = () => {
|
|
34
|
+
cancelTimer();
|
|
35
|
+
pendingThis = void 0;
|
|
36
|
+
pendingArgs = null;
|
|
37
|
+
};
|
|
38
|
+
const debounced = function(...args) {
|
|
39
|
+
pendingThis = this;
|
|
40
|
+
pendingArgs = args;
|
|
41
|
+
const isFirstCall = timeoutId == null;
|
|
42
|
+
schedule();
|
|
43
|
+
if (leading && isFirstCall) invoke();
|
|
44
|
+
};
|
|
45
|
+
debounced.cancel = cancel;
|
|
46
|
+
return debounced;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
exports.debounce = debounce;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/hooks/useDebounce/debounce.ts
|
|
3
|
+
function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
|
|
4
|
+
let pendingThis = void 0;
|
|
5
|
+
let pendingArgs = null;
|
|
6
|
+
const leading = edges != null && edges.includes("leading");
|
|
7
|
+
const trailing = edges == null || edges.includes("trailing");
|
|
8
|
+
const invoke = () => {
|
|
9
|
+
if (pendingArgs !== null) {
|
|
10
|
+
func.apply(pendingThis, pendingArgs);
|
|
11
|
+
pendingThis = void 0;
|
|
12
|
+
pendingArgs = null;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const onTimerEnd = () => {
|
|
16
|
+
if (trailing) invoke();
|
|
17
|
+
cancel();
|
|
18
|
+
};
|
|
19
|
+
let timeoutId = null;
|
|
20
|
+
const schedule = () => {
|
|
21
|
+
if (timeoutId != null) clearTimeout(timeoutId);
|
|
22
|
+
timeoutId = setTimeout(() => {
|
|
23
|
+
timeoutId = null;
|
|
24
|
+
onTimerEnd();
|
|
25
|
+
}, debounceMs);
|
|
26
|
+
};
|
|
27
|
+
const cancelTimer = () => {
|
|
28
|
+
if (timeoutId !== null) {
|
|
29
|
+
clearTimeout(timeoutId);
|
|
30
|
+
timeoutId = null;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const cancel = () => {
|
|
34
|
+
cancelTimer();
|
|
35
|
+
pendingThis = void 0;
|
|
36
|
+
pendingArgs = null;
|
|
37
|
+
};
|
|
38
|
+
const debounced = function(...args) {
|
|
39
|
+
pendingThis = this;
|
|
40
|
+
pendingArgs = args;
|
|
41
|
+
const isFirstCall = timeoutId == null;
|
|
42
|
+
schedule();
|
|
43
|
+
if (leading && isFirstCall) invoke();
|
|
44
|
+
};
|
|
45
|
+
debounced.cancel = cancel;
|
|
46
|
+
return debounced;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { debounce };
|