react-simplikit 0.0.48 → 0.0.50

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 (63) hide show
  1. package/dist/components/ImpressionArea/index.cjs +7 -4
  2. package/dist/components/ImpressionArea/index.d.cts +1 -1
  3. package/dist/components/Separated/index.cjs +1 -1
  4. package/dist/hooks/useCallbackOncePerRender/index.cjs +6 -3
  5. package/dist/hooks/useCounter/index.cjs +12 -14
  6. package/dist/hooks/useDebounce/index.cjs +14 -8
  7. package/dist/hooks/useDebouncedCallback/index.cjs +7 -4
  8. package/dist/hooks/useDoubleClick/index.cjs +6 -3
  9. package/dist/hooks/useImpressionRef/index.cjs +7 -4
  10. package/dist/hooks/useIntersectionObserver/index.cjs +6 -3
  11. package/dist/hooks/useInterval/index.cjs +24 -15
  12. package/dist/hooks/useIsClient/index.cjs +40 -0
  13. package/dist/hooks/useIsClient/index.d.cts +40 -0
  14. package/dist/hooks/useList/index.cjs +104 -0
  15. package/dist/hooks/useList/index.d.cts +50 -0
  16. package/dist/hooks/useLoading/index.cjs +9 -6
  17. package/dist/hooks/useLongPress/index.cjs +6 -3
  18. package/dist/hooks/useOutsideClickEffect/index.cjs +6 -3
  19. package/dist/hooks/usePreservedCallback/index.cjs +6 -3
  20. package/dist/hooks/usePrevious/index.d.cts +3 -3
  21. package/dist/hooks/useRefEffect/index.cjs +6 -3
  22. package/dist/hooks/useRefEffect/index.d.cts +3 -3
  23. package/dist/hooks/useSet/index.cjs +105 -0
  24. package/dist/hooks/useSet/index.d.cts +39 -0
  25. package/dist/hooks/useThrottle/index.cjs +6 -3
  26. package/dist/hooks/useThrottledCallback/index.cjs +172 -0
  27. package/dist/hooks/useThrottledCallback/index.d.cts +30 -0
  28. package/dist/hooks/useTimeout/index.cjs +8 -5
  29. package/dist/hooks/useTimeout/index.d.cts +1 -1
  30. package/dist/index.cjs +264 -110
  31. package/dist/index.d.cts +4 -0
  32. package/esm/components/ImpressionArea/index.d.ts +1 -1
  33. package/esm/components/ImpressionArea/index.js +7 -4
  34. package/esm/components/Separated/index.js +1 -1
  35. package/esm/hooks/useCallbackOncePerRender/index.js +6 -3
  36. package/esm/hooks/useCounter/index.js +12 -14
  37. package/esm/hooks/useDebounce/index.js +14 -8
  38. package/esm/hooks/useDebouncedCallback/index.js +7 -4
  39. package/esm/hooks/useDoubleClick/index.js +6 -3
  40. package/esm/hooks/useImpressionRef/index.js +7 -4
  41. package/esm/hooks/useIntersectionObserver/index.js +6 -3
  42. package/esm/hooks/useInterval/index.js +24 -15
  43. package/esm/hooks/useIsClient/index.d.ts +40 -0
  44. package/esm/hooks/useIsClient/index.js +14 -0
  45. package/esm/hooks/useList/index.d.ts +50 -0
  46. package/esm/hooks/useList/index.js +78 -0
  47. package/esm/hooks/useLoading/index.js +9 -6
  48. package/esm/hooks/useLongPress/index.js +6 -3
  49. package/esm/hooks/useOutsideClickEffect/index.js +6 -3
  50. package/esm/hooks/usePreservedCallback/index.js +6 -3
  51. package/esm/hooks/usePrevious/index.d.ts +3 -3
  52. package/esm/hooks/useRefEffect/index.d.ts +3 -3
  53. package/esm/hooks/useRefEffect/index.js +6 -3
  54. package/esm/hooks/useSet/index.d.ts +39 -0
  55. package/esm/hooks/useSet/index.js +79 -0
  56. package/esm/hooks/useThrottle/index.js +6 -3
  57. package/esm/hooks/useThrottledCallback/index.d.ts +30 -0
  58. package/esm/hooks/useThrottledCallback/index.js +146 -0
  59. package/esm/hooks/useTimeout/index.d.ts +1 -1
  60. package/esm/hooks/useTimeout/index.js +8 -5
  61. package/esm/index.d.ts +4 -0
  62. package/esm/index.js +234 -84
  63. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -41,7 +41,9 @@ __export(index_exports, {
41
41
  useInputState: () => useInputState,
42
42
  useIntersectionObserver: () => useIntersectionObserver,
43
43
  useInterval: () => useInterval,
44
+ useIsClient: () => useIsClient,
44
45
  useIsomorphicLayoutEffect: () => useIsomorphicLayoutEffect,
46
+ useList: () => useList,
45
47
  useLoading: () => useLoading,
46
48
  useLongPress: () => useLongPress,
47
49
  useMap: () => useMap,
@@ -50,8 +52,10 @@ __export(index_exports, {
50
52
  usePreservedReference: () => usePreservedReference,
51
53
  usePrevious: () => usePrevious,
52
54
  useRefEffect: () => useRefEffect,
55
+ useSet: () => useSet,
53
56
  useStorageState: () => useStorageState,
54
57
  useThrottle: () => useThrottle,
58
+ useThrottledCallback: () => useThrottledCallback,
55
59
  useTimeout: () => useTimeout,
56
60
  useToggle: () => useToggle,
57
61
  useVisibilityEvent: () => useVisibilityEvent
@@ -124,9 +128,12 @@ function debounce(func, debounceMs, { edges = ["leading", "trailing"] } = {}) {
124
128
  var import_react = require("react");
125
129
  function usePreservedCallback(callback) {
126
130
  const callbackRef = (0, import_react.useRef)(callback);
127
- (0, import_react.useEffect)(() => {
128
- callbackRef.current = callback;
129
- }, [callback]);
131
+ (0, import_react.useEffect)(
132
+ function syncCallbackRef() {
133
+ callbackRef.current = callback;
134
+ },
135
+ [callback]
136
+ );
130
137
  return (0, import_react.useCallback)((...args) => {
131
138
  return callbackRef.current(...args);
132
139
  }, []);
@@ -142,7 +149,7 @@ function useDebouncedCallback({
142
149
  const handleChange = usePreservedCallback(onChange);
143
150
  const ref = (0, import_react2.useRef)({ value: false, clearPreviousDebounce: () => {
144
151
  } });
145
- (0, import_react2.useEffect)(() => {
152
+ (0, import_react2.useEffect)(function clearDebouncedOnUnmount() {
146
153
  const current = ref.current;
147
154
  return () => {
148
155
  current.clearPreviousDebounce();
@@ -328,7 +335,7 @@ function Separated({ children, by: separator }) {
328
335
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: childrenArray.map((child, i, { length }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react8.Fragment, { children: [
329
336
  child,
330
337
  i + 1 !== length && separator
331
- ] }, i)) });
338
+ ] }, child.key ?? i)) });
332
339
  }
333
340
 
334
341
  // src/components/SwitchCase/SwitchCase.tsx
@@ -433,27 +440,25 @@ function isSetStateAction(next) {
433
440
 
434
441
  // src/hooks/useCounter/useCounter.ts
435
442
  var import_react14 = require("react");
443
+ var validateValue = (value, { min, max }) => {
444
+ if (min !== void 0 && value < min) {
445
+ return min;
446
+ }
447
+ if (max !== void 0 && value > max) {
448
+ return max;
449
+ }
450
+ return value;
451
+ };
436
452
  function useCounter(initialValue = 0, { min, max, step = 1 } = {}) {
437
- const validateValue = (value) => {
438
- let validatedValue = value;
439
- if (min !== void 0 && validatedValue < min) {
440
- validatedValue = min;
441
- }
442
- if (max !== void 0 && validatedValue > max) {
443
- validatedValue = max;
444
- }
445
- return validatedValue;
446
- };
447
- const [count, setCountState] = (0, import_react14.useState)(() => validateValue(initialValue));
448
- const validateValueMemoized = (0, import_react14.useCallback)(validateValue, [min, max]);
453
+ const [count, setCountState] = (0, import_react14.useState)(() => validateValue(initialValue, { min, max }));
449
454
  const setCount = (0, import_react14.useCallback)(
450
455
  (value) => {
451
456
  setCountState((prev) => {
452
457
  const nextValue = typeof value === "function" ? value(prev) : value;
453
- return validateValueMemoized(nextValue);
458
+ return validateValue(nextValue, { min, max });
454
459
  });
455
460
  },
456
- [validateValueMemoized]
461
+ [min, max]
457
462
  );
458
463
  const increment = (0, import_react14.useCallback)(() => {
459
464
  setCount((prev) => prev + step);
@@ -492,11 +497,14 @@ function useDebounce(callback, wait, options = {}) {
492
497
  const debounced = (0, import_react16.useMemo)(() => {
493
498
  return debounce(preservedCallback, wait, { edges });
494
499
  }, [preservedCallback, wait, edges]);
495
- (0, import_react15.useEffect)(() => {
496
- return () => {
497
- debounced.cancel();
498
- };
499
- }, [debounced]);
500
+ (0, import_react15.useEffect)(
501
+ function cancelDebouncedOnUnmount() {
502
+ return () => {
503
+ debounced.cancel();
504
+ };
505
+ },
506
+ [debounced]
507
+ );
500
508
  return debounced;
501
509
  }
502
510
 
@@ -679,31 +687,106 @@ function useInterval(callback, options) {
679
687
  const immediate = typeof options === "number" ? false : options.immediate;
680
688
  const enabled = typeof options === "number" ? true : options.enabled ?? true;
681
689
  const preservedCallback = usePreservedCallback(callback);
682
- (0, import_react20.useEffect)(() => {
683
- if (immediate === true && enabled) {
684
- preservedCallback();
685
- }
686
- }, [immediate, preservedCallback, enabled]);
687
- (0, import_react20.useEffect)(() => {
688
- if (!enabled) {
689
- return;
690
- }
691
- const id = window.setInterval(preservedCallback, delay);
692
- return () => window.clearInterval(id);
693
- }, [delay, preservedCallback, enabled]);
690
+ (0, import_react20.useEffect)(
691
+ function runImmediateCallback() {
692
+ if (immediate === true && enabled) {
693
+ preservedCallback();
694
+ }
695
+ },
696
+ [immediate, preservedCallback, enabled]
697
+ );
698
+ (0, import_react20.useEffect)(
699
+ function startInterval() {
700
+ if (!enabled) {
701
+ return;
702
+ }
703
+ const id = setInterval(preservedCallback, delay);
704
+ return () => clearInterval(id);
705
+ },
706
+ [delay, preservedCallback, enabled]
707
+ );
694
708
  }
695
709
 
696
- // src/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.ts
710
+ // src/hooks/useIsClient/useIsClient.ts
697
711
  var import_react21 = require("react");
712
+ function useIsClient() {
713
+ const [isClient, setIsClient] = (0, import_react21.useState)(false);
714
+ (0, import_react21.useEffect)(function syncClientState() {
715
+ setIsClient(true);
716
+ }, []);
717
+ return isClient;
718
+ }
719
+
720
+ // src/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.ts
721
+ var import_react22 = require("react");
698
722
  var isServer = typeof window === "undefined";
699
- var useIsomorphicLayoutEffect = isServer ? import_react21.useEffect : import_react21.useLayoutEffect;
723
+ var useIsomorphicLayoutEffect = isServer ? import_react22.useEffect : import_react22.useLayoutEffect;
724
+
725
+ // src/hooks/useList/useList.ts
726
+ var import_react24 = require("react");
727
+
728
+ // src/hooks/usePreservedReference/usePreservedReference.ts
729
+ var import_react23 = require("react");
730
+ function usePreservedReference(value, areValuesEqual = areDeeplyEqual) {
731
+ const ref = (0, import_react23.useRef)(value);
732
+ return (0, import_react23.useMemo)(() => {
733
+ if (!areValuesEqual(ref.current, value)) {
734
+ ref.current = value;
735
+ }
736
+ return ref.current;
737
+ }, [areValuesEqual, value]);
738
+ }
739
+ function areDeeplyEqual(x, y) {
740
+ return JSON.stringify(x) === JSON.stringify(y);
741
+ }
742
+
743
+ // src/hooks/useList/useList.ts
744
+ function useList(initialState = []) {
745
+ const [list, setList] = (0, import_react24.useState)(initialState);
746
+ const preservedInitialState = usePreservedReference(initialState);
747
+ const push = usePreservedCallback((value) => {
748
+ setList((prev) => [...prev, value]);
749
+ });
750
+ const insertAt = usePreservedCallback((index, value) => {
751
+ setList((prev) => {
752
+ const next = [...prev];
753
+ next.splice(index, 0, value);
754
+ return next;
755
+ });
756
+ });
757
+ const updateAt = usePreservedCallback((index, value) => {
758
+ setList((prev) => {
759
+ const next = [...prev];
760
+ next[index] = value;
761
+ return next;
762
+ });
763
+ });
764
+ const removeAt = usePreservedCallback((index) => {
765
+ setList((prev) => {
766
+ const next = [...prev];
767
+ next.splice(index, 1);
768
+ return next;
769
+ });
770
+ });
771
+ const setAll = usePreservedCallback((values) => {
772
+ setList(values);
773
+ });
774
+ const reset = usePreservedCallback(() => {
775
+ setList(preservedInitialState);
776
+ });
777
+ const actions = (0, import_react24.useMemo)(
778
+ () => ({ push, insertAt, updateAt, removeAt, setAll, reset }),
779
+ [push, insertAt, updateAt, removeAt, setAll, reset]
780
+ );
781
+ return [list, actions];
782
+ }
700
783
 
701
784
  // src/hooks/useLoading/useLoading.ts
702
- var import_react22 = require("react");
785
+ var import_react25 = require("react");
703
786
  function useLoading() {
704
- const [loading, setLoading] = (0, import_react22.useState)(false);
787
+ const [loading, setLoading] = (0, import_react25.useState)(false);
705
788
  const ref = useIsMountedRef();
706
- const startTransition = (0, import_react22.useCallback)(
789
+ const startTransition = (0, import_react25.useCallback)(
707
790
  async (promise) => {
708
791
  try {
709
792
  setLoading(true);
@@ -717,32 +800,35 @@ function useLoading() {
717
800
  },
718
801
  [ref.isMounted]
719
802
  );
720
- return (0, import_react22.useMemo)(() => [loading, startTransition], [loading, startTransition]);
803
+ return (0, import_react25.useMemo)(() => [loading, startTransition], [loading, startTransition]);
721
804
  }
722
805
  function useIsMountedRef() {
723
- const ref = (0, import_react22.useRef)({ isMounted: true }).current;
724
- (0, import_react22.useEffect)(() => {
725
- ref.isMounted = true;
726
- return () => {
727
- ref.isMounted = false;
728
- };
729
- }, [ref]);
806
+ const ref = (0, import_react25.useRef)({ isMounted: true }).current;
807
+ (0, import_react25.useEffect)(
808
+ function trackMountedState() {
809
+ ref.isMounted = true;
810
+ return () => {
811
+ ref.isMounted = false;
812
+ };
813
+ },
814
+ [ref]
815
+ );
730
816
  return ref;
731
817
  }
732
818
 
733
819
  // src/hooks/useLongPress/useLongPress.ts
734
- var import_react23 = require("react");
820
+ var import_react26 = require("react");
735
821
  function useLongPress(onLongPress, { delay = 500, moveThreshold, onClick, onLongPressEnd } = {}) {
736
- const timeoutRef = (0, import_react23.useRef)(null);
737
- const isLongPressActiveRef = (0, import_react23.useRef)(false);
738
- const initialPositionRef = (0, import_react23.useRef)({ x: 0, y: 0 });
822
+ const timeoutRef = (0, import_react26.useRef)(null);
823
+ const isLongPressActiveRef = (0, import_react26.useRef)(false);
824
+ const initialPositionRef = (0, import_react26.useRef)({ x: 0, y: 0 });
739
825
  const preservedOnLongPress = usePreservedCallback(onLongPress);
740
826
  const preservedOnClick = usePreservedCallback(onClick || (() => {
741
827
  }));
742
828
  const preservedOnLongPressEnd = usePreservedCallback(onLongPressEnd || (() => {
743
829
  }));
744
830
  const hasThreshold = moveThreshold?.x !== void 0 || moveThreshold?.y !== void 0;
745
- const getClientPosition = (0, import_react23.useCallback)((event) => {
831
+ const getClientPosition = (0, import_react26.useCallback)((event) => {
746
832
  if ("touches" in event.nativeEvent) {
747
833
  const touch = event.nativeEvent.touches[0];
748
834
  return { x: touch.clientX, y: touch.clientY };
@@ -752,7 +838,7 @@ function useLongPress(onLongPress, { delay = 500, moveThreshold, onClick, onLong
752
838
  y: event.nativeEvent.clientY
753
839
  };
754
840
  }, []);
755
- const isMovedBeyondThreshold = (0, import_react23.useCallback)(
841
+ const isMovedBeyondThreshold = (0, import_react26.useCallback)(
756
842
  (event) => {
757
843
  const { x, y } = getClientPosition(event);
758
844
  const deltaX = Math.abs(x - initialPositionRef.current.x);
@@ -761,13 +847,13 @@ function useLongPress(onLongPress, { delay = 500, moveThreshold, onClick, onLong
761
847
  },
762
848
  [getClientPosition, moveThreshold]
763
849
  );
764
- const cancelLongPress = (0, import_react23.useCallback)(() => {
850
+ const cancelLongPress = (0, import_react26.useCallback)(() => {
765
851
  if (timeoutRef.current !== null) {
766
852
  window.clearTimeout(timeoutRef.current);
767
853
  timeoutRef.current = null;
768
854
  }
769
855
  }, []);
770
- const handlePressStart = (0, import_react23.useCallback)(
856
+ const handlePressStart = (0, import_react26.useCallback)(
771
857
  (event) => {
772
858
  cancelLongPress();
773
859
  const position = getClientPosition(event);
@@ -780,7 +866,7 @@ function useLongPress(onLongPress, { delay = 500, moveThreshold, onClick, onLong
780
866
  },
781
867
  [cancelLongPress, delay, getClientPosition, preservedOnLongPress]
782
868
  );
783
- const handlePressEnd = (0, import_react23.useCallback)(
869
+ const handlePressEnd = (0, import_react26.useCallback)(
784
870
  (event) => {
785
871
  if (isLongPressActiveRef.current) {
786
872
  preservedOnLongPressEnd(event);
@@ -792,7 +878,7 @@ function useLongPress(onLongPress, { delay = 500, moveThreshold, onClick, onLong
792
878
  },
793
879
  [cancelLongPress, preservedOnClick, preservedOnLongPressEnd]
794
880
  );
795
- const handlePressMove = (0, import_react23.useCallback)(
881
+ const handlePressMove = (0, import_react26.useCallback)(
796
882
  (event) => {
797
883
  if (timeoutRef.current !== null && isMovedBeyondThreshold(event)) {
798
884
  cancelLongPress();
@@ -811,57 +897,40 @@ function useLongPress(onLongPress, { delay = 500, moveThreshold, onClick, onLong
811
897
  }
812
898
 
813
899
  // src/hooks/useMap/useMap.ts
814
- var import_react25 = require("react");
815
-
816
- // src/hooks/usePreservedReference/usePreservedReference.ts
817
- var import_react24 = require("react");
818
- function usePreservedReference(value, areValuesEqual = areDeeplyEqual) {
819
- const ref = (0, import_react24.useRef)(value);
820
- return (0, import_react24.useMemo)(() => {
821
- if (!areValuesEqual(ref.current, value)) {
822
- ref.current = value;
823
- }
824
- return ref.current;
825
- }, [areValuesEqual, value]);
826
- }
827
- function areDeeplyEqual(x, y) {
828
- return JSON.stringify(x) === JSON.stringify(y);
829
- }
830
-
831
- // src/hooks/useMap/useMap.ts
900
+ var import_react27 = require("react");
832
901
  function useMap(initialState = /* @__PURE__ */ new Map()) {
833
- const [map, setMap] = (0, import_react25.useState)(() => new Map(initialState));
902
+ const [map, setMap] = (0, import_react27.useState)(() => new Map(initialState));
834
903
  const preservedInitialState = usePreservedReference(initialState);
835
- const set = (0, import_react25.useCallback)((key, value) => {
904
+ const set = (0, import_react27.useCallback)((key, value) => {
836
905
  setMap((prev) => {
837
906
  const nextMap = new Map(prev);
838
907
  nextMap.set(key, value);
839
908
  return nextMap;
840
909
  });
841
910
  }, []);
842
- const setAll = (0, import_react25.useCallback)((entries) => {
911
+ const setAll = (0, import_react27.useCallback)((entries) => {
843
912
  setMap(() => new Map(entries));
844
913
  }, []);
845
- const remove = (0, import_react25.useCallback)((key) => {
914
+ const remove = (0, import_react27.useCallback)((key) => {
846
915
  setMap((prev) => {
847
916
  const nextMap = new Map(prev);
848
917
  nextMap.delete(key);
849
918
  return nextMap;
850
919
  });
851
920
  }, []);
852
- const reset = (0, import_react25.useCallback)(() => {
921
+ const reset = (0, import_react27.useCallback)(() => {
853
922
  setMap(() => new Map(preservedInitialState));
854
923
  }, [preservedInitialState]);
855
- const actions = (0, import_react25.useMemo)(() => {
924
+ const actions = (0, import_react27.useMemo)(() => {
856
925
  return { set, setAll, remove, reset };
857
926
  }, [set, setAll, remove, reset]);
858
927
  return [map, actions];
859
928
  }
860
929
 
861
930
  // src/hooks/useOutsideClickEffect/useOutsideClickEffect.ts
862
- var import_react26 = require("react");
931
+ var import_react28 = require("react");
863
932
  function useOutsideClickEffect(container, callback) {
864
- const containers = (0, import_react26.useRef)([]);
933
+ const containers = (0, import_react28.useRef)([]);
865
934
  const handleDocumentClick = usePreservedCallback(({ target }) => {
866
935
  if (target === null) {
867
936
  return;
@@ -874,10 +943,10 @@ function useOutsideClickEffect(container, callback) {
874
943
  }
875
944
  callback();
876
945
  });
877
- (0, import_react26.useEffect)(() => {
946
+ (0, import_react28.useEffect)(() => {
878
947
  containers.current = [container].flat(1).filter((item) => item != null);
879
948
  }, [container]);
880
- (0, import_react26.useEffect)(() => {
949
+ (0, import_react28.useEffect)(() => {
881
950
  document.addEventListener("click", handleDocumentClick);
882
951
  return () => {
883
952
  document.removeEventListener("click", handleDocumentClick);
@@ -886,12 +955,12 @@ function useOutsideClickEffect(container, callback) {
886
955
  }
887
956
 
888
957
  // src/hooks/usePrevious/usePrevious.ts
889
- var import_react27 = require("react");
958
+ var import_react29 = require("react");
890
959
  var strictEquals = (prev, next) => prev === next;
891
960
  function usePrevious(state, compare = strictEquals) {
892
- const prevRef = (0, import_react27.useRef)(state);
893
- const currentRef = (0, import_react27.useRef)(state);
894
- const isFirstRender = (0, import_react27.useRef)(true);
961
+ const prevRef = (0, import_react29.useRef)(state);
962
+ const currentRef = (0, import_react29.useRef)(state);
963
+ const isFirstRender = (0, import_react29.useRef)(true);
895
964
  if (isFirstRender.current) {
896
965
  isFirstRender.current = false;
897
966
  return prevRef.current;
@@ -903,8 +972,51 @@ function usePrevious(state, compare = strictEquals) {
903
972
  return prevRef.current;
904
973
  }
905
974
 
975
+ // src/hooks/useSet/useSet.ts
976
+ var import_react30 = require("react");
977
+ function useSet(initialState = /* @__PURE__ */ new Set()) {
978
+ const [set, setSet] = (0, import_react30.useState)(() => new Set(initialState));
979
+ const preservedInitialState = usePreservedReference(initialState);
980
+ const add = usePreservedCallback((value) => {
981
+ setSet((prev) => {
982
+ const nextSet = new Set(prev);
983
+ nextSet.add(value);
984
+ return nextSet;
985
+ });
986
+ });
987
+ const remove = usePreservedCallback((value) => {
988
+ setSet((prev) => {
989
+ const nextSet = new Set(prev);
990
+ nextSet.delete(value);
991
+ return nextSet;
992
+ });
993
+ });
994
+ const toggle2 = usePreservedCallback((value) => {
995
+ setSet((prev) => {
996
+ const nextSet = new Set(prev);
997
+ if (nextSet.has(value)) {
998
+ nextSet.delete(value);
999
+ } else {
1000
+ nextSet.add(value);
1001
+ }
1002
+ return nextSet;
1003
+ });
1004
+ });
1005
+ const setAll = usePreservedCallback((values) => {
1006
+ setSet(() => new Set(values));
1007
+ });
1008
+ const reset = usePreservedCallback(() => {
1009
+ setSet(() => new Set(preservedInitialState));
1010
+ });
1011
+ const actions = (0, import_react30.useMemo)(
1012
+ () => ({ add, remove, toggle: toggle2, setAll, reset }),
1013
+ [add, remove, toggle2, setAll, reset]
1014
+ );
1015
+ return [set, actions];
1016
+ }
1017
+
906
1018
  // src/hooks/useStorageState/useStorageState.ts
907
- var import_react28 = require("react");
1019
+ var import_react31 = require("react");
908
1020
 
909
1021
  // src/hooks/useStorageState/storage.ts
910
1022
  var MemoStorage = class {
@@ -1016,11 +1128,11 @@ function useStorageState(key, {
1016
1128
  ...options
1017
1129
  } = {}) {
1018
1130
  const serializedDefaultValue = defaultValue;
1019
- const cache = (0, import_react28.useRef)({
1131
+ const cache = (0, import_react31.useRef)({
1020
1132
  data: null,
1021
1133
  parsed: serializedDefaultValue
1022
1134
  });
1023
- const getSnapshot = (0, import_react28.useCallback)(() => {
1135
+ const getSnapshot = (0, import_react31.useCallback)(() => {
1024
1136
  const deserializer = "deserializer" in options ? options.deserializer : JSON.parse;
1025
1137
  const data = storage.get(key);
1026
1138
  if (data !== cache.current.data) {
@@ -1033,7 +1145,7 @@ function useStorageState(key, {
1033
1145
  }
1034
1146
  return cache.current.parsed;
1035
1147
  }, [defaultValue, key, storage]);
1036
- const storageState = (0, import_react28.useSyncExternalStore)(
1148
+ const storageState = (0, import_react31.useSyncExternalStore)(
1037
1149
  (onStoreChange) => {
1038
1150
  listeners.add(onStoreChange);
1039
1151
  const handler = (event) => {
@@ -1050,7 +1162,7 @@ function useStorageState(key, {
1050
1162
  () => getSnapshot(),
1051
1163
  () => serializedDefaultValue
1052
1164
  );
1053
- const setStorageState = (0, import_react28.useCallback)(
1165
+ const setStorageState = (0, import_react31.useCallback)(
1054
1166
  (value) => {
1055
1167
  const serializer = "serializer" in options ? options.serializer : JSON.stringify;
1056
1168
  const nextValue = typeof value === "function" ? value(getSnapshot()) : value;
@@ -1063,14 +1175,14 @@ function useStorageState(key, {
1063
1175
  },
1064
1176
  [getSnapshot, key, storage]
1065
1177
  );
1066
- const refreshStorageState = (0, import_react28.useCallback)(() => {
1178
+ const refreshStorageState = (0, import_react31.useCallback)(() => {
1067
1179
  setStorageState(getSnapshot());
1068
1180
  }, [storage, getSnapshot, setStorageState]);
1069
1181
  return ensureSerializable([storageState, setStorageState, refreshStorageState]);
1070
1182
  }
1071
1183
 
1072
1184
  // src/hooks/useThrottle/useThrottle.ts
1073
- var import_react29 = require("react");
1185
+ var import_react32 = require("react");
1074
1186
 
1075
1187
  // src/hooks/useThrottle/throttle.ts
1076
1188
  function throttle(func, throttleMs, { edges = ["leading", "trailing"] } = {}) {
@@ -1095,11 +1207,11 @@ function throttle(func, throttleMs, { edges = ["leading", "trailing"] } = {}) {
1095
1207
  function useThrottle(callback, wait, options) {
1096
1208
  const preservedCallback = usePreservedCallback(callback);
1097
1209
  const preservedOptions = usePreservedReference(options ?? {});
1098
- const throttledCallback = (0, import_react29.useMemo)(
1210
+ const throttledCallback = (0, import_react32.useMemo)(
1099
1211
  () => throttle(preservedCallback, wait, preservedOptions),
1100
1212
  [preservedOptions, preservedCallback, wait]
1101
1213
  );
1102
- (0, import_react29.useEffect)(() => {
1214
+ (0, import_react32.useEffect)(() => {
1103
1215
  return () => {
1104
1216
  throttledCallback.cancel();
1105
1217
  };
@@ -1107,30 +1219,68 @@ function useThrottle(callback, wait, options) {
1107
1219
  return throttledCallback;
1108
1220
  }
1109
1221
 
1222
+ // src/hooks/useThrottledCallback/useThrottledCallback.ts
1223
+ var import_react33 = require("react");
1224
+ function useThrottledCallback({
1225
+ onChange,
1226
+ timeThreshold,
1227
+ edges = ["leading", "trailing"]
1228
+ }) {
1229
+ const handleChange = usePreservedCallback(onChange);
1230
+ const ref = (0, import_react33.useRef)({ value: false, clearPreviousThrottle: () => {
1231
+ } });
1232
+ (0, import_react33.useEffect)(function cleanupThrottleOnUnmount() {
1233
+ const current = ref.current;
1234
+ return () => {
1235
+ current.clearPreviousThrottle();
1236
+ };
1237
+ }, []);
1238
+ const preservedEdges = usePreservedReference(edges);
1239
+ return (0, import_react33.useCallback)(
1240
+ (nextValue) => {
1241
+ if (nextValue === ref.current.value) {
1242
+ return;
1243
+ }
1244
+ const throttled = throttle(
1245
+ () => {
1246
+ handleChange(nextValue);
1247
+ ref.current.value = nextValue;
1248
+ },
1249
+ timeThreshold,
1250
+ { edges: preservedEdges }
1251
+ );
1252
+ ref.current.clearPreviousThrottle();
1253
+ throttled();
1254
+ ref.current.clearPreviousThrottle = throttled.cancel;
1255
+ },
1256
+ [handleChange, timeThreshold, preservedEdges]
1257
+ );
1258
+ }
1259
+
1110
1260
  // src/hooks/useTimeout/useTimeout.ts
1111
- var import_react30 = require("react");
1261
+ var import_react34 = require("react");
1112
1262
  function useTimeout(callback, delay = 0) {
1113
1263
  const preservedCallback = usePreservedCallback(callback);
1114
- (0, import_react30.useEffect)(() => {
1115
- const timeoutId = window.setTimeout(preservedCallback, delay);
1116
- return () => window.clearTimeout(timeoutId);
1264
+ (0, import_react34.useEffect)(() => {
1265
+ const timeoutId = setTimeout(preservedCallback, delay);
1266
+ return () => clearTimeout(timeoutId);
1117
1267
  }, [delay, preservedCallback]);
1118
1268
  }
1119
1269
 
1120
1270
  // src/hooks/useToggle/useToggle.ts
1121
- var import_react31 = require("react");
1271
+ var import_react35 = require("react");
1122
1272
  function useToggle(initialValue = false) {
1123
- return (0, import_react31.useReducer)(toggle, initialValue);
1273
+ return (0, import_react35.useReducer)(toggle, initialValue);
1124
1274
  }
1125
1275
  var toggle = (state) => !state;
1126
1276
 
1127
1277
  // src/utils/buildContext/buildContext.tsx
1128
- var import_react32 = require("react");
1278
+ var import_react36 = require("react");
1129
1279
  var import_jsx_runtime3 = require("react/jsx-runtime");
1130
1280
  function buildContext(contextName, defaultContextValues) {
1131
- const Context = (0, import_react32.createContext)(defaultContextValues ?? void 0);
1281
+ const Context = (0, import_react36.createContext)(defaultContextValues ?? void 0);
1132
1282
  function Provider({ children, ...contextValues }) {
1133
- const value = (0, import_react32.useMemo)(
1283
+ const value = (0, import_react36.useMemo)(
1134
1284
  () => Object.keys(contextValues).length > 0 ? contextValues : null,
1135
1285
  // eslint-disable-next-line react-hooks/exhaustive-deps
1136
1286
  [...Object.values(contextValues)]
@@ -1138,7 +1288,7 @@ function buildContext(contextName, defaultContextValues) {
1138
1288
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Context.Provider, { value, children });
1139
1289
  }
1140
1290
  function useInnerContext() {
1141
- const context = (0, import_react32.useContext)(Context);
1291
+ const context = (0, import_react36.useContext)(Context);
1142
1292
  if (context != null) {
1143
1293
  return context;
1144
1294
  }
@@ -1212,7 +1362,9 @@ function mergeFunction(a, b) {
1212
1362
  useInputState,
1213
1363
  useIntersectionObserver,
1214
1364
  useInterval,
1365
+ useIsClient,
1215
1366
  useIsomorphicLayoutEffect,
1367
+ useList,
1216
1368
  useLoading,
1217
1369
  useLongPress,
1218
1370
  useMap,
@@ -1221,8 +1373,10 @@ function mergeFunction(a, b) {
1221
1373
  usePreservedReference,
1222
1374
  usePrevious,
1223
1375
  useRefEffect,
1376
+ useSet,
1224
1377
  useStorageState,
1225
1378
  useThrottle,
1379
+ useThrottledCallback,
1226
1380
  useTimeout,
1227
1381
  useToggle,
1228
1382
  useVisibilityEvent
package/dist/index.d.cts CHANGED
@@ -15,7 +15,9 @@ export { useImpressionRef } from './hooks/useImpressionRef/index.cjs';
15
15
  export { useInputState } from './hooks/useInputState/index.cjs';
16
16
  export { useIntersectionObserver } from './hooks/useIntersectionObserver/index.cjs';
17
17
  export { useInterval } from './hooks/useInterval/index.cjs';
18
+ export { useIsClient } from './hooks/useIsClient/index.cjs';
18
19
  export { useIsomorphicLayoutEffect } from './hooks/useIsomorphicLayoutEffect/index.cjs';
20
+ export { useList } from './hooks/useList/index.cjs';
19
21
  export { useLoading } from './hooks/useLoading/index.cjs';
20
22
  export { useLongPress } from './hooks/useLongPress/index.cjs';
21
23
  export { useMap } from './hooks/useMap/index.cjs';
@@ -24,8 +26,10 @@ export { usePreservedCallback } from './hooks/usePreservedCallback/index.cjs';
24
26
  export { usePreservedReference } from './hooks/usePreservedReference/index.cjs';
25
27
  export { usePrevious } from './hooks/usePrevious/index.cjs';
26
28
  export { useRefEffect } from './hooks/useRefEffect/index.cjs';
29
+ export { useSet } from './hooks/useSet/index.cjs';
27
30
  export { useStorageState } from './hooks/useStorageState/index.cjs';
28
31
  export { useThrottle } from './hooks/useThrottle/index.cjs';
32
+ export { useThrottledCallback } from './hooks/useThrottledCallback/index.cjs';
29
33
  export { useTimeout } from './hooks/useTimeout/index.cjs';
30
34
  export { useToggle } from './hooks/useToggle/index.cjs';
31
35
  export { useVisibilityEvent } from './hooks/useVisibilityEvent/index.cjs';
@@ -1,7 +1,7 @@
1
1
  import { ElementType, ReactNode, Ref } from 'react';
2
2
  import { UseImpressionRefOptions } from '../../hooks/useImpressionRef/index.js';
3
3
 
4
- type Element<T extends ElementType, InstrinsicElements = T extends keyof React.JSX.IntrinsicElements ? React.JSX.IntrinsicElements[T] : HTMLElement> = InstrinsicElements extends React.ClassAttributes<infer E extends HTMLElement> ? E : HTMLElement;
4
+ type Element<T extends ElementType, IntrinsicElementsOf = T extends keyof React.JSX.IntrinsicElements ? React.JSX.IntrinsicElements[T] : HTMLElement> = IntrinsicElementsOf extends React.ClassAttributes<infer E extends HTMLElement> ? E : HTMLElement;
5
5
  type Props<Tag extends ElementType> = React.ComponentPropsWithoutRef<Tag> & UseImpressionRefOptions & {
6
6
  as?: Tag;
7
7
  children?: ReactNode;