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
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/hooks/useSet/useSet.d.ts
|
|
1
3
|
type SetOrValues<T> = Set<T> | T[];
|
|
2
4
|
type SetActions<T> = {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
add: (value: T) => void;
|
|
6
|
+
remove: (value: T) => void;
|
|
7
|
+
toggle: (value: T) => void;
|
|
8
|
+
setAll: (values: SetOrValues<T>) => void;
|
|
9
|
+
reset: () => void;
|
|
8
10
|
};
|
|
9
11
|
type UseSetReturn<T> = [Omit<Set<T>, 'add' | 'clear' | 'delete'>, SetActions<T>];
|
|
10
12
|
/**
|
|
@@ -35,5 +37,5 @@ type UseSetReturn<T> = [Omit<Set<T>, 'add' | 'clear' | 'delete'>, SetActions<T>]
|
|
|
35
37
|
* ```
|
|
36
38
|
*/
|
|
37
39
|
declare function useSet<T>(initialState?: SetOrValues<T>): UseSetReturn<T>;
|
|
38
|
-
|
|
39
|
-
export { useSet };
|
|
40
|
+
//#endregion
|
|
41
|
+
export { useSet };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/hooks/useSet/useSet.d.ts
|
|
1
3
|
type SetOrValues<T> = Set<T> | T[];
|
|
2
4
|
type SetActions<T> = {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
add: (value: T) => void;
|
|
6
|
+
remove: (value: T) => void;
|
|
7
|
+
toggle: (value: T) => void;
|
|
8
|
+
setAll: (values: SetOrValues<T>) => void;
|
|
9
|
+
reset: () => void;
|
|
8
10
|
};
|
|
9
11
|
type UseSetReturn<T> = [Omit<Set<T>, 'add' | 'clear' | 'delete'>, SetActions<T>];
|
|
10
12
|
/**
|
|
@@ -35,5 +37,5 @@ type UseSetReturn<T> = [Omit<Set<T>, 'add' | 'clear' | 'delete'>, SetActions<T>]
|
|
|
35
37
|
* ```
|
|
36
38
|
*/
|
|
37
39
|
declare function useSet<T>(initialState?: SetOrValues<T>): UseSetReturn<T>;
|
|
38
|
-
|
|
39
|
-
export { useSet };
|
|
40
|
+
//#endregion
|
|
41
|
+
export { useSet };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePreservedCallback } from "../usePreservedCallback/usePreservedCallback.mjs";
|
|
3
|
+
import { usePreservedReference } from "../usePreservedReference/usePreservedReference.mjs";
|
|
4
|
+
import { useMemo, useState } from "react";
|
|
5
|
+
//#region src/hooks/useSet/useSet.ts
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* A React hook that manages a Set as state.
|
|
9
|
+
* Provides efficient state management and stable action functions.
|
|
10
|
+
*
|
|
11
|
+
* @param {SetOrValues<T>} initialState - Initial Set state (Set object or array of values)
|
|
12
|
+
* @returns {UseSetReturn<T>} A tuple containing the Set state and actions to manipulate it
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { useSet } from 'react-simplikit';
|
|
17
|
+
*
|
|
18
|
+
* function TagSelector() {
|
|
19
|
+
* const [selectedTags, { add, remove, toggle }] = useSet<string>(['react']);
|
|
20
|
+
*
|
|
21
|
+
* return (
|
|
22
|
+
* <div>
|
|
23
|
+
* {['react', 'vue', 'svelte'].map(tag => (
|
|
24
|
+
* <button key={tag} onClick={() => toggle(tag)}>
|
|
25
|
+
* {selectedTags.has(tag) ? '✓' : ''} {tag}
|
|
26
|
+
* </button>
|
|
27
|
+
* ))}
|
|
28
|
+
* </div>
|
|
29
|
+
* );
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function useSet(initialState = /* @__PURE__ */ new Set()) {
|
|
34
|
+
const [set, setSet] = useState(() => new Set(initialState));
|
|
35
|
+
const preservedInitialState = usePreservedReference(initialState);
|
|
36
|
+
const add = usePreservedCallback((value) => {
|
|
37
|
+
setSet((prev) => {
|
|
38
|
+
const nextSet = new Set(prev);
|
|
39
|
+
nextSet.add(value);
|
|
40
|
+
return nextSet;
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
const remove = usePreservedCallback((value) => {
|
|
44
|
+
setSet((prev) => {
|
|
45
|
+
const nextSet = new Set(prev);
|
|
46
|
+
nextSet.delete(value);
|
|
47
|
+
return nextSet;
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
const toggle = usePreservedCallback((value) => {
|
|
51
|
+
setSet((prev) => {
|
|
52
|
+
const nextSet = new Set(prev);
|
|
53
|
+
if (nextSet.has(value)) nextSet.delete(value);
|
|
54
|
+
else nextSet.add(value);
|
|
55
|
+
return nextSet;
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
const setAll = usePreservedCallback((values) => {
|
|
59
|
+
setSet(() => new Set(values));
|
|
60
|
+
});
|
|
61
|
+
const reset = usePreservedCallback(() => {
|
|
62
|
+
setSet(() => new Set(preservedInitialState));
|
|
63
|
+
});
|
|
64
|
+
return [set, useMemo(() => ({
|
|
65
|
+
add,
|
|
66
|
+
remove,
|
|
67
|
+
toggle,
|
|
68
|
+
setAll,
|
|
69
|
+
reset
|
|
70
|
+
}), [
|
|
71
|
+
add,
|
|
72
|
+
remove,
|
|
73
|
+
toggle,
|
|
74
|
+
setAll,
|
|
75
|
+
reset
|
|
76
|
+
])];
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
export { useSet };
|
|
@@ -1,61 +1,3 @@
|
|
|
1
|
-
import { SetStateAction } from 'react';
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
set(key: string, value: string): void;
|
|
6
|
-
remove(key: string): void;
|
|
7
|
-
clear(): void;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
type ToObject<T> = T extends unknown[] | Record<string, unknown> ? T : never;
|
|
11
|
-
type Serializable<T> = T extends string | number | boolean ? T : ToObject<T>;
|
|
12
|
-
type StorageStateOptions<T> = {
|
|
13
|
-
storage?: Storage;
|
|
14
|
-
defaultValue?: T;
|
|
15
|
-
};
|
|
16
|
-
type StorageStateOptionsWithDefaultValue<T> = StorageStateOptions<T> & {
|
|
17
|
-
defaultValue: T;
|
|
18
|
-
};
|
|
19
|
-
type StorageStateOptionsWithSerializer<T> = StorageStateOptions<T> & {
|
|
20
|
-
serializer: (value: Serializable<T>) => string;
|
|
21
|
-
deserializer: (value: string) => Serializable<T>;
|
|
22
|
-
};
|
|
23
|
-
type SerializableGuard<T extends readonly any[]> = T[0] extends any ? T : T[0] extends never ? 'Received a non-serializable value' : T;
|
|
24
|
-
/**
|
|
25
|
-
* @deprecated This hook is deprecated as it depends on browser-specific APIs (localStorage/sessionStorage).
|
|
26
|
-
* react-simplikit is now focused on platform-independent, pure state/logic hooks.
|
|
27
|
-
* This hook will be removed in a future major version.
|
|
28
|
-
*
|
|
29
|
-
* @description
|
|
30
|
-
* `useStorageState` is a React that functions like `useState` but persists the state value in browser storage.
|
|
31
|
-
* The value is retained across page reloads and can be shared between tabs when using `localStorage`.
|
|
32
|
-
*
|
|
33
|
-
* @param {string} key - The key used to store the value in storage.
|
|
34
|
-
* @param {Object} [options] - Configuration options for storage behavior.
|
|
35
|
-
* @param {Storage} [options.storage=localStorage] - The storage type (`localStorage` or `sessionStorage`). Defaults to `localStorage`.
|
|
36
|
-
* @param {T} [options.defaultValue] - The initial value if no existing value is found.
|
|
37
|
-
* @param {Function} [options.serializer] - A function to serialize the state value to a string.
|
|
38
|
-
* @param {Function} [options.deserializer] - A function to deserialize the state value from a string.
|
|
39
|
-
*
|
|
40
|
-
* @returns {readonly [state: Serializable<T> | undefined, setState: (value: SetStateAction<Serializable<T> | undefined>) => void, refreshState: () => void]} A tuple:
|
|
41
|
-
* - state `Serializable<T> | undefined` - The current state value retrieved from storage;
|
|
42
|
-
* - setState `(value: SetStateAction<Serializable<T> | undefined>) => void` - A function to update and persist the state;
|
|
43
|
-
* - refreshState `() => void` - A function to refresh the state from storage;
|
|
44
|
-
* @example
|
|
45
|
-
* // Counter with persistent state
|
|
46
|
-
* import { useStorageState } from 'react-simplikit';
|
|
47
|
-
*
|
|
48
|
-
* function Counter() {
|
|
49
|
-
* const [count, setCount] = useStorageState<number>('counter', {
|
|
50
|
-
* defaultValue: 0,
|
|
51
|
-
* });
|
|
52
|
-
*
|
|
53
|
-
* return <button onClick={() => setCount(prev => prev + 1)}>Count: {count}</button>;
|
|
54
|
-
* }
|
|
55
|
-
*/
|
|
56
|
-
declare function useStorageState<T>(key: string): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
57
|
-
declare function useStorageState<T>(key: string, options: StorageStateOptionsWithDefaultValue<T>): SerializableGuard<readonly [Serializable<T>, (value: SetStateAction<Serializable<T>>) => void, () => void]>;
|
|
58
|
-
declare function useStorageState<T>(key: string, options: StorageStateOptions<T>): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
59
|
-
declare function useStorageState<T>(key: string, options: StorageStateOptionsWithSerializer<T>): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
60
|
-
|
|
61
|
-
export { type Serializable, useStorageState };
|
|
2
|
+
import { Serializable, useStorageState } from "./useStorageState.cjs";
|
|
3
|
+
export { useStorageState };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/hooks/useStorageState/storage.ts
|
|
3
|
+
var MemoStorage = class {
|
|
4
|
+
storage = /* @__PURE__ */ new Map();
|
|
5
|
+
get(key) {
|
|
6
|
+
return this.storage.get(key) ?? null;
|
|
7
|
+
}
|
|
8
|
+
set(key, value) {
|
|
9
|
+
this.storage.set(key, value);
|
|
10
|
+
}
|
|
11
|
+
remove(key) {
|
|
12
|
+
this.storage.delete(key);
|
|
13
|
+
}
|
|
14
|
+
clear() {
|
|
15
|
+
this.storage.clear();
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var LocalStorage = class {
|
|
19
|
+
static canUse() {
|
|
20
|
+
const TEST_KEY = generateTestKey();
|
|
21
|
+
try {
|
|
22
|
+
localStorage.setItem(TEST_KEY, "test");
|
|
23
|
+
localStorage.removeItem(TEST_KEY);
|
|
24
|
+
return true;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
get(key) {
|
|
30
|
+
return localStorage.getItem(key);
|
|
31
|
+
}
|
|
32
|
+
set(key, value) {
|
|
33
|
+
localStorage.setItem(key, value);
|
|
34
|
+
}
|
|
35
|
+
remove(key) {
|
|
36
|
+
localStorage.removeItem(key);
|
|
37
|
+
}
|
|
38
|
+
clear() {
|
|
39
|
+
localStorage.clear();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var SessionStorage = class {
|
|
43
|
+
static canUse() {
|
|
44
|
+
const TEST_KEY = generateTestKey();
|
|
45
|
+
try {
|
|
46
|
+
sessionStorage.setItem(TEST_KEY, "test");
|
|
47
|
+
sessionStorage.removeItem(TEST_KEY);
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
get(key) {
|
|
54
|
+
return sessionStorage.getItem(key);
|
|
55
|
+
}
|
|
56
|
+
set(key, value) {
|
|
57
|
+
sessionStorage.setItem(key, value);
|
|
58
|
+
}
|
|
59
|
+
remove(key) {
|
|
60
|
+
sessionStorage.removeItem(key);
|
|
61
|
+
}
|
|
62
|
+
clear() {
|
|
63
|
+
sessionStorage.clear();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
function generateTestKey() {
|
|
67
|
+
return new Array(4).fill(null).map(() => Math.random().toString(36).slice(2)).join("");
|
|
68
|
+
}
|
|
69
|
+
function generateStorage() {
|
|
70
|
+
if (LocalStorage.canUse()) return new LocalStorage();
|
|
71
|
+
return new MemoStorage();
|
|
72
|
+
}
|
|
73
|
+
function generateSessionStorage() {
|
|
74
|
+
if (SessionStorage.canUse()) return new SessionStorage();
|
|
75
|
+
return new MemoStorage();
|
|
76
|
+
}
|
|
77
|
+
const safeLocalStorage = generateStorage();
|
|
78
|
+
generateSessionStorage();
|
|
79
|
+
//#endregion
|
|
80
|
+
exports.LocalStorage = LocalStorage;
|
|
81
|
+
exports.MemoStorage = MemoStorage;
|
|
82
|
+
exports.SessionStorage = SessionStorage;
|
|
83
|
+
exports.generateSessionStorage = generateSessionStorage;
|
|
84
|
+
exports.generateStorage = generateStorage;
|
|
85
|
+
exports.safeLocalStorage = safeLocalStorage;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/hooks/useStorageState/storage.ts
|
|
3
|
+
var MemoStorage = class {
|
|
4
|
+
storage = /* @__PURE__ */ new Map();
|
|
5
|
+
get(key) {
|
|
6
|
+
return this.storage.get(key) ?? null;
|
|
7
|
+
}
|
|
8
|
+
set(key, value) {
|
|
9
|
+
this.storage.set(key, value);
|
|
10
|
+
}
|
|
11
|
+
remove(key) {
|
|
12
|
+
this.storage.delete(key);
|
|
13
|
+
}
|
|
14
|
+
clear() {
|
|
15
|
+
this.storage.clear();
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var LocalStorage = class {
|
|
19
|
+
static canUse() {
|
|
20
|
+
const TEST_KEY = generateTestKey();
|
|
21
|
+
try {
|
|
22
|
+
localStorage.setItem(TEST_KEY, "test");
|
|
23
|
+
localStorage.removeItem(TEST_KEY);
|
|
24
|
+
return true;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
get(key) {
|
|
30
|
+
return localStorage.getItem(key);
|
|
31
|
+
}
|
|
32
|
+
set(key, value) {
|
|
33
|
+
localStorage.setItem(key, value);
|
|
34
|
+
}
|
|
35
|
+
remove(key) {
|
|
36
|
+
localStorage.removeItem(key);
|
|
37
|
+
}
|
|
38
|
+
clear() {
|
|
39
|
+
localStorage.clear();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var SessionStorage = class {
|
|
43
|
+
static canUse() {
|
|
44
|
+
const TEST_KEY = generateTestKey();
|
|
45
|
+
try {
|
|
46
|
+
sessionStorage.setItem(TEST_KEY, "test");
|
|
47
|
+
sessionStorage.removeItem(TEST_KEY);
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
get(key) {
|
|
54
|
+
return sessionStorage.getItem(key);
|
|
55
|
+
}
|
|
56
|
+
set(key, value) {
|
|
57
|
+
sessionStorage.setItem(key, value);
|
|
58
|
+
}
|
|
59
|
+
remove(key) {
|
|
60
|
+
sessionStorage.removeItem(key);
|
|
61
|
+
}
|
|
62
|
+
clear() {
|
|
63
|
+
sessionStorage.clear();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
function generateTestKey() {
|
|
67
|
+
return new Array(4).fill(null).map(() => Math.random().toString(36).slice(2)).join("");
|
|
68
|
+
}
|
|
69
|
+
function generateStorage() {
|
|
70
|
+
if (LocalStorage.canUse()) return new LocalStorage();
|
|
71
|
+
return new MemoStorage();
|
|
72
|
+
}
|
|
73
|
+
function generateSessionStorage() {
|
|
74
|
+
if (SessionStorage.canUse()) return new SessionStorage();
|
|
75
|
+
return new MemoStorage();
|
|
76
|
+
}
|
|
77
|
+
const safeLocalStorage = generateStorage();
|
|
78
|
+
generateSessionStorage();
|
|
79
|
+
//#endregion
|
|
80
|
+
export { LocalStorage, MemoStorage, SessionStorage, generateSessionStorage, generateStorage, safeLocalStorage };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_storage = require("./storage.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
//#region src/hooks/useStorageState/useStorageState.ts
|
|
5
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
const emitListeners = () => {
|
|
7
|
+
listeners.forEach((listener) => listener());
|
|
8
|
+
};
|
|
9
|
+
function isPlainObject(value) {
|
|
10
|
+
if (typeof value !== "object") return false;
|
|
11
|
+
if (!(Object.getPrototypeOf(value) === Object.prototype)) return false;
|
|
12
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
13
|
+
}
|
|
14
|
+
const ensureSerializable = (value) => {
|
|
15
|
+
if (value[0] != null && ![
|
|
16
|
+
"string",
|
|
17
|
+
"number",
|
|
18
|
+
"boolean"
|
|
19
|
+
].includes(typeof value[0]) && !(isPlainObject(value[0]) || Array.isArray(value[0]))) throw new Error("Received a non-serializable value");
|
|
20
|
+
return value;
|
|
21
|
+
};
|
|
22
|
+
function useStorageState(key, { storage = require_storage.safeLocalStorage, defaultValue, ...options } = {}) {
|
|
23
|
+
const serializedDefaultValue = defaultValue;
|
|
24
|
+
const cache = (0, react.useRef)({
|
|
25
|
+
data: null,
|
|
26
|
+
parsed: serializedDefaultValue
|
|
27
|
+
});
|
|
28
|
+
const getSnapshot = (0, react.useCallback)(() => {
|
|
29
|
+
const deserializer = "deserializer" in options ? options.deserializer : JSON.parse;
|
|
30
|
+
const data = storage.get(key);
|
|
31
|
+
if (data !== cache.current.data) {
|
|
32
|
+
try {
|
|
33
|
+
cache.current.parsed = data != null ? deserializer(data) : defaultValue;
|
|
34
|
+
} catch {
|
|
35
|
+
cache.current.parsed = serializedDefaultValue;
|
|
36
|
+
}
|
|
37
|
+
cache.current.data = data;
|
|
38
|
+
}
|
|
39
|
+
return cache.current.parsed;
|
|
40
|
+
}, [
|
|
41
|
+
defaultValue,
|
|
42
|
+
key,
|
|
43
|
+
storage
|
|
44
|
+
]);
|
|
45
|
+
const storageState = (0, react.useSyncExternalStore)((onStoreChange) => {
|
|
46
|
+
listeners.add(onStoreChange);
|
|
47
|
+
const handler = (event) => {
|
|
48
|
+
if (event.key === key) onStoreChange();
|
|
49
|
+
};
|
|
50
|
+
window.addEventListener("storage", handler);
|
|
51
|
+
return () => {
|
|
52
|
+
listeners.delete(onStoreChange);
|
|
53
|
+
window.removeEventListener("storage", handler);
|
|
54
|
+
};
|
|
55
|
+
}, () => getSnapshot(), () => serializedDefaultValue);
|
|
56
|
+
const setStorageState = (0, react.useCallback)((value) => {
|
|
57
|
+
const serializer = "serializer" in options ? options.serializer : JSON.stringify;
|
|
58
|
+
const nextValue = typeof value === "function" ? value(getSnapshot()) : value;
|
|
59
|
+
if (nextValue == null) storage.remove(key);
|
|
60
|
+
else storage.set(key, serializer(nextValue));
|
|
61
|
+
emitListeners();
|
|
62
|
+
}, [
|
|
63
|
+
getSnapshot,
|
|
64
|
+
key,
|
|
65
|
+
storage
|
|
66
|
+
]);
|
|
67
|
+
const refreshStorageState = (0, react.useCallback)(() => {
|
|
68
|
+
setStorageState(getSnapshot());
|
|
69
|
+
}, [
|
|
70
|
+
storage,
|
|
71
|
+
getSnapshot,
|
|
72
|
+
setStorageState
|
|
73
|
+
]);
|
|
74
|
+
return ensureSerializable([
|
|
75
|
+
storageState,
|
|
76
|
+
setStorageState,
|
|
77
|
+
refreshStorageState
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
exports.useStorageState = useStorageState;
|
package/{esm/hooks/useStorageState/index.d.ts → dist/hooks/useStorageState/useStorageState.d.cts}
RENAMED
|
@@ -1,24 +1,19 @@
|
|
|
1
|
-
import { SetStateAction } from 'react';
|
|
2
|
-
|
|
3
|
-
type Storage = {
|
|
4
|
-
get(key: string): string | null;
|
|
5
|
-
set(key: string, value: string): void;
|
|
6
|
-
remove(key: string): void;
|
|
7
|
-
clear(): void;
|
|
8
|
-
};
|
|
9
1
|
|
|
2
|
+
import { Storage } from "./storage.cjs";
|
|
3
|
+
import { SetStateAction } from "react";
|
|
4
|
+
//#region src/hooks/useStorageState/useStorageState.d.ts
|
|
10
5
|
type ToObject<T> = T extends unknown[] | Record<string, unknown> ? T : never;
|
|
11
6
|
type Serializable<T> = T extends string | number | boolean ? T : ToObject<T>;
|
|
12
7
|
type StorageStateOptions<T> = {
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
storage?: Storage;
|
|
9
|
+
defaultValue?: T;
|
|
15
10
|
};
|
|
16
11
|
type StorageStateOptionsWithDefaultValue<T> = StorageStateOptions<T> & {
|
|
17
|
-
|
|
12
|
+
defaultValue: T;
|
|
18
13
|
};
|
|
19
14
|
type StorageStateOptionsWithSerializer<T> = StorageStateOptions<T> & {
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
serializer: (value: Serializable<T>) => string;
|
|
16
|
+
deserializer: (value: string) => Serializable<T>;
|
|
22
17
|
};
|
|
23
18
|
type SerializableGuard<T extends readonly any[]> = T[0] extends any ? T : T[0] extends never ? 'Received a non-serializable value' : T;
|
|
24
19
|
/**
|
|
@@ -57,5 +52,5 @@ declare function useStorageState<T>(key: string): SerializableGuard<readonly [Se
|
|
|
57
52
|
declare function useStorageState<T>(key: string, options: StorageStateOptionsWithDefaultValue<T>): SerializableGuard<readonly [Serializable<T>, (value: SetStateAction<Serializable<T>>) => void, () => void]>;
|
|
58
53
|
declare function useStorageState<T>(key: string, options: StorageStateOptions<T>): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
59
54
|
declare function useStorageState<T>(key: string, options: StorageStateOptionsWithSerializer<T>): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
60
|
-
|
|
61
|
-
export {
|
|
55
|
+
//#endregion
|
|
56
|
+
export { Serializable, useStorageState };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
import { Storage } from "./storage.mjs";
|
|
3
|
+
import { SetStateAction } from "react";
|
|
4
|
+
//#region src/hooks/useStorageState/useStorageState.d.ts
|
|
5
|
+
type ToObject<T> = T extends unknown[] | Record<string, unknown> ? T : never;
|
|
6
|
+
type Serializable<T> = T extends string | number | boolean ? T : ToObject<T>;
|
|
7
|
+
type StorageStateOptions<T> = {
|
|
8
|
+
storage?: Storage;
|
|
9
|
+
defaultValue?: T;
|
|
10
|
+
};
|
|
11
|
+
type StorageStateOptionsWithDefaultValue<T> = StorageStateOptions<T> & {
|
|
12
|
+
defaultValue: T;
|
|
13
|
+
};
|
|
14
|
+
type StorageStateOptionsWithSerializer<T> = StorageStateOptions<T> & {
|
|
15
|
+
serializer: (value: Serializable<T>) => string;
|
|
16
|
+
deserializer: (value: string) => Serializable<T>;
|
|
17
|
+
};
|
|
18
|
+
type SerializableGuard<T extends readonly any[]> = T[0] extends any ? T : T[0] extends never ? 'Received a non-serializable value' : T;
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated This hook is deprecated as it depends on browser-specific APIs (localStorage/sessionStorage).
|
|
21
|
+
* react-simplikit is now focused on platform-independent, pure state/logic hooks.
|
|
22
|
+
* This hook will be removed in a future major version.
|
|
23
|
+
*
|
|
24
|
+
* @description
|
|
25
|
+
* `useStorageState` is a React that functions like `useState` but persists the state value in browser storage.
|
|
26
|
+
* The value is retained across page reloads and can be shared between tabs when using `localStorage`.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} key - The key used to store the value in storage.
|
|
29
|
+
* @param {Object} [options] - Configuration options for storage behavior.
|
|
30
|
+
* @param {Storage} [options.storage=localStorage] - The storage type (`localStorage` or `sessionStorage`). Defaults to `localStorage`.
|
|
31
|
+
* @param {T} [options.defaultValue] - The initial value if no existing value is found.
|
|
32
|
+
* @param {Function} [options.serializer] - A function to serialize the state value to a string.
|
|
33
|
+
* @param {Function} [options.deserializer] - A function to deserialize the state value from a string.
|
|
34
|
+
*
|
|
35
|
+
* @returns {readonly [state: Serializable<T> | undefined, setState: (value: SetStateAction<Serializable<T> | undefined>) => void, refreshState: () => void]} A tuple:
|
|
36
|
+
* - state `Serializable<T> | undefined` - The current state value retrieved from storage;
|
|
37
|
+
* - setState `(value: SetStateAction<Serializable<T> | undefined>) => void` - A function to update and persist the state;
|
|
38
|
+
* - refreshState `() => void` - A function to refresh the state from storage;
|
|
39
|
+
* @example
|
|
40
|
+
* // Counter with persistent state
|
|
41
|
+
* import { useStorageState } from 'react-simplikit';
|
|
42
|
+
*
|
|
43
|
+
* function Counter() {
|
|
44
|
+
* const [count, setCount] = useStorageState<number>('counter', {
|
|
45
|
+
* defaultValue: 0,
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* return <button onClick={() => setCount(prev => prev + 1)}>Count: {count}</button>;
|
|
49
|
+
* }
|
|
50
|
+
*/
|
|
51
|
+
declare function useStorageState<T>(key: string): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
52
|
+
declare function useStorageState<T>(key: string, options: StorageStateOptionsWithDefaultValue<T>): SerializableGuard<readonly [Serializable<T>, (value: SetStateAction<Serializable<T>>) => void, () => void]>;
|
|
53
|
+
declare function useStorageState<T>(key: string, options: StorageStateOptions<T>): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
54
|
+
declare function useStorageState<T>(key: string, options: StorageStateOptionsWithSerializer<T>): SerializableGuard<readonly [Serializable<T> | undefined, (value: SetStateAction<Serializable<T> | undefined>) => void, () => void]>;
|
|
55
|
+
//#endregion
|
|
56
|
+
export { Serializable, useStorageState };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { safeLocalStorage } from "./storage.mjs";
|
|
3
|
+
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
4
|
+
//#region src/hooks/useStorageState/useStorageState.ts
|
|
5
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
const emitListeners = () => {
|
|
7
|
+
listeners.forEach((listener) => listener());
|
|
8
|
+
};
|
|
9
|
+
function isPlainObject(value) {
|
|
10
|
+
if (typeof value !== "object") return false;
|
|
11
|
+
if (!(Object.getPrototypeOf(value) === Object.prototype)) return false;
|
|
12
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
13
|
+
}
|
|
14
|
+
const ensureSerializable = (value) => {
|
|
15
|
+
if (value[0] != null && ![
|
|
16
|
+
"string",
|
|
17
|
+
"number",
|
|
18
|
+
"boolean"
|
|
19
|
+
].includes(typeof value[0]) && !(isPlainObject(value[0]) || Array.isArray(value[0]))) throw new Error("Received a non-serializable value");
|
|
20
|
+
return value;
|
|
21
|
+
};
|
|
22
|
+
function useStorageState(key, { storage = safeLocalStorage, defaultValue, ...options } = {}) {
|
|
23
|
+
const serializedDefaultValue = defaultValue;
|
|
24
|
+
const cache = useRef({
|
|
25
|
+
data: null,
|
|
26
|
+
parsed: serializedDefaultValue
|
|
27
|
+
});
|
|
28
|
+
const getSnapshot = useCallback(() => {
|
|
29
|
+
const deserializer = "deserializer" in options ? options.deserializer : JSON.parse;
|
|
30
|
+
const data = storage.get(key);
|
|
31
|
+
if (data !== cache.current.data) {
|
|
32
|
+
try {
|
|
33
|
+
cache.current.parsed = data != null ? deserializer(data) : defaultValue;
|
|
34
|
+
} catch {
|
|
35
|
+
cache.current.parsed = serializedDefaultValue;
|
|
36
|
+
}
|
|
37
|
+
cache.current.data = data;
|
|
38
|
+
}
|
|
39
|
+
return cache.current.parsed;
|
|
40
|
+
}, [
|
|
41
|
+
defaultValue,
|
|
42
|
+
key,
|
|
43
|
+
storage
|
|
44
|
+
]);
|
|
45
|
+
const storageState = useSyncExternalStore((onStoreChange) => {
|
|
46
|
+
listeners.add(onStoreChange);
|
|
47
|
+
const handler = (event) => {
|
|
48
|
+
if (event.key === key) onStoreChange();
|
|
49
|
+
};
|
|
50
|
+
window.addEventListener("storage", handler);
|
|
51
|
+
return () => {
|
|
52
|
+
listeners.delete(onStoreChange);
|
|
53
|
+
window.removeEventListener("storage", handler);
|
|
54
|
+
};
|
|
55
|
+
}, () => getSnapshot(), () => serializedDefaultValue);
|
|
56
|
+
const setStorageState = useCallback((value) => {
|
|
57
|
+
const serializer = "serializer" in options ? options.serializer : JSON.stringify;
|
|
58
|
+
const nextValue = typeof value === "function" ? value(getSnapshot()) : value;
|
|
59
|
+
if (nextValue == null) storage.remove(key);
|
|
60
|
+
else storage.set(key, serializer(nextValue));
|
|
61
|
+
emitListeners();
|
|
62
|
+
}, [
|
|
63
|
+
getSnapshot,
|
|
64
|
+
key,
|
|
65
|
+
storage
|
|
66
|
+
]);
|
|
67
|
+
const refreshStorageState = useCallback(() => {
|
|
68
|
+
setStorageState(getSnapshot());
|
|
69
|
+
}, [
|
|
70
|
+
storage,
|
|
71
|
+
getSnapshot,
|
|
72
|
+
setStorageState
|
|
73
|
+
]);
|
|
74
|
+
return ensureSerializable([
|
|
75
|
+
storageState,
|
|
76
|
+
setStorageState,
|
|
77
|
+
refreshStorageState
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { useStorageState };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_debounce = require("../useDebounce/debounce.cjs");
|
|
3
|
+
//#region src/hooks/useThrottle/throttle.ts
|
|
4
|
+
function throttle(func, throttleMs, { edges = ["leading", "trailing"] } = {}) {
|
|
5
|
+
let pendingAt = null;
|
|
6
|
+
const debounced = require_debounce.debounce(func, throttleMs, { edges });
|
|
7
|
+
const throttled = function(...args) {
|
|
8
|
+
if (pendingAt == null) pendingAt = Date.now();
|
|
9
|
+
else if (Date.now() - pendingAt >= throttleMs) {
|
|
10
|
+
pendingAt = Date.now();
|
|
11
|
+
debounced.cancel();
|
|
12
|
+
}
|
|
13
|
+
debounced(...args);
|
|
14
|
+
};
|
|
15
|
+
throttled.cancel = debounced.cancel;
|
|
16
|
+
return throttled;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
exports.throttle = throttle;
|