@reactuses/core 2.0.1 → 2.2.0

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/index.cjs CHANGED
@@ -501,6 +501,13 @@ function getTargetElement(target, defaultElement) {
501
501
  }
502
502
  return targetElement;
503
503
  }
504
+ function useLatestElement(target, defaultElement) {
505
+ const ref = React.useRef(getTargetElement(target, defaultElement));
506
+ React.useEffect(() => {
507
+ ref.current = getTargetElement(target, defaultElement);
508
+ }, [defaultElement, target]);
509
+ return ref;
510
+ }
504
511
 
505
512
  const isPrimitive$1 = (val) => val !== Object(val);
506
513
  function useCustomCompareEffect(effect, deps, depsEqual) {
@@ -547,17 +554,21 @@ function useDeepCompareEffect(effect, deps) {
547
554
 
548
555
  function useEventListener(eventName, handler, element, options) {
549
556
  const savedHandler = useLatest(handler);
550
- const targetElement = getTargetElement(element, window);
557
+ const targetElementRef = useLatestElement(element, defaultWindow);
551
558
  useDeepCompareEffect(() => {
559
+ const targetElement = targetElementRef.current;
552
560
  if (!(targetElement && targetElement.addEventListener)) {
553
561
  return;
554
562
  }
555
563
  const eventListener = (event) => savedHandler.current(event);
556
564
  on(targetElement, eventName, eventListener, options);
557
565
  return () => {
566
+ if (!(targetElement && targetElement.removeEventListener)) {
567
+ return;
568
+ }
558
569
  off(targetElement, eventName, eventListener);
559
570
  };
560
- }, [eventName, targetElement, options, savedHandler]);
571
+ }, [eventName, targetElementRef.current, options, savedHandler]);
561
572
  }
562
573
 
563
574
  function useCounter(initialValue = 0, max = null, min = null) {
@@ -701,20 +712,20 @@ function useFavicon(href, baseUrl = "", rel = "icon") {
701
712
  function useMutationObserver(callback, target, options = {}) {
702
713
  const callbackRef = useLatest(callback);
703
714
  const observerRef = React.useRef();
704
- const element = getTargetElement(target);
715
+ const element = useLatestElement(target);
705
716
  const stop = React.useCallback(() => {
706
717
  if (observerRef.current) {
707
718
  observerRef.current.disconnect();
708
719
  }
709
720
  }, []);
710
721
  useDeepCompareEffect(() => {
711
- if (!element) {
722
+ if (!element.current) {
712
723
  return;
713
724
  }
714
725
  observerRef.current = new MutationObserver(callbackRef.current);
715
- observerRef.current.observe(element, options);
726
+ observerRef.current.observe(element.current, options);
716
727
  return stop;
717
- }, [options, element]);
728
+ }, [options, element.current]);
718
729
  return stop;
719
730
  }
720
731
 
@@ -997,7 +1008,7 @@ function useMediaDevices() {
997
1008
  }, []);
998
1009
  return state;
999
1010
  }
1000
- const useMediaDevicesMock = () => ({});
1011
+ const useMediaDevicesMock = () => ({ devices: [] });
1001
1012
  var useMediaDevices$1 = isNavigator && !!navigator.mediaDevices ? useMediaDevices : useMediaDevicesMock;
1002
1013
 
1003
1014
  function useTextDirection(options = {}) {
@@ -1499,23 +1510,23 @@ function useOrientation(initialState = defaultState) {
1499
1510
  function useIntersectionObserver(target, callback, options = {}) {
1500
1511
  const savedCallback = useLatest(callback);
1501
1512
  const observerRef = React.useRef();
1502
- const element = getTargetElement(target);
1513
+ const element = useLatestElement(target);
1503
1514
  const stop = React.useCallback(() => {
1504
1515
  if (observerRef.current) {
1505
1516
  observerRef.current.disconnect();
1506
1517
  }
1507
1518
  }, []);
1508
1519
  useDeepCompareEffect(() => {
1509
- if (!element) {
1520
+ if (!element.current) {
1510
1521
  return;
1511
1522
  }
1512
1523
  observerRef.current = new IntersectionObserver(
1513
1524
  savedCallback.current,
1514
1525
  options
1515
1526
  );
1516
- observerRef.current.observe(element);
1527
+ observerRef.current.observe(element.current);
1517
1528
  return stop;
1518
- }, [options, element]);
1529
+ }, [options, element.current]);
1519
1530
  return stop;
1520
1531
  }
1521
1532
 
@@ -1555,27 +1566,26 @@ function useDocumentVisibility() {
1555
1566
  function useResizeObserver(target, callback, options = {}) {
1556
1567
  const savedCallback = useLatest(callback);
1557
1568
  const observerRef = React.useRef();
1558
- const element = getTargetElement(target);
1569
+ const element = useLatestElement(target);
1559
1570
  const stop = React.useCallback(() => {
1560
1571
  if (observerRef.current) {
1561
1572
  observerRef.current.disconnect();
1562
1573
  }
1563
1574
  }, []);
1564
1575
  useDeepCompareEffect(() => {
1565
- if (!element) {
1576
+ if (!element.current) {
1566
1577
  return;
1567
1578
  }
1568
1579
  observerRef.current = new ResizeObserver(savedCallback.current);
1569
- observerRef.current.observe(element, options);
1580
+ observerRef.current.observe(element.current, options);
1570
1581
  return stop;
1571
- }, [options, element]);
1582
+ }, [options, element.current]);
1572
1583
  return stop;
1573
1584
  }
1574
1585
 
1575
1586
  function useDropZone(target, onDrop) {
1576
1587
  const [over, setOver] = React.useState(false);
1577
1588
  const counter = React.useRef(0);
1578
- const element = getTargetElement(target);
1579
1589
  useEventListener(
1580
1590
  "dragenter",
1581
1591
  (event) => {
@@ -1583,14 +1593,14 @@ function useDropZone(target, onDrop) {
1583
1593
  counter.current += 1;
1584
1594
  setOver(true);
1585
1595
  },
1586
- element
1596
+ target
1587
1597
  );
1588
1598
  useEventListener(
1589
1599
  "dragover",
1590
1600
  (event) => {
1591
1601
  event.preventDefault();
1592
1602
  },
1593
- element
1603
+ target
1594
1604
  );
1595
1605
  useEventListener(
1596
1606
  "dragleave",
@@ -1601,7 +1611,7 @@ function useDropZone(target, onDrop) {
1601
1611
  setOver(false);
1602
1612
  }
1603
1613
  },
1604
- element
1614
+ target
1605
1615
  );
1606
1616
  useEventListener(
1607
1617
  "drop",
@@ -1613,7 +1623,7 @@ function useDropZone(target, onDrop) {
1613
1623
  const files = Array.from((_b = (_a = event.dataTransfer) == null ? void 0 : _a.files) != null ? _b : []);
1614
1624
  onDrop == null ? void 0 : onDrop(files.length === 0 ? null : files);
1615
1625
  },
1616
- element
1626
+ target
1617
1627
  );
1618
1628
  return over;
1619
1629
  }
@@ -1764,7 +1774,7 @@ var __spreadValues = (a, b) => {
1764
1774
  return a;
1765
1775
  };
1766
1776
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
1767
- var __async$1 = (__this, __arguments, generator) => {
1777
+ var __async$2 = (__this, __arguments, generator) => {
1768
1778
  return new Promise((resolve, reject) => {
1769
1779
  var fulfilled = (value) => {
1770
1780
  try {
@@ -1793,25 +1803,27 @@ function useInfiniteScroll(target, onLoadMore, options = {}) {
1793
1803
  [direction]: (_b = options.distance) != null ? _b : 0
1794
1804
  }, options.offset)
1795
1805
  }));
1796
- const element = getTargetElement(target);
1806
+ const element = useLatestElement(target);
1807
+ const latestOptions = useLatest(options);
1797
1808
  const di = state[3][direction];
1798
1809
  useUpdateEffect(() => {
1799
- const fn = () => __async$1(this, null, function* () {
1800
- var _a2, _b2;
1810
+ const opts = latestOptions.current;
1811
+ const fn = () => __async$2(this, null, function* () {
1812
+ var _a2, _b2, _c, _d;
1801
1813
  const previous = {
1802
- height: (_a2 = element == null ? void 0 : element.scrollHeight) != null ? _a2 : 0,
1803
- width: (_b2 = element == null ? void 0 : element.scrollWidth) != null ? _b2 : 0
1814
+ height: (_b2 = (_a2 = element.current) == null ? void 0 : _a2.scrollHeight) != null ? _b2 : 0,
1815
+ width: (_d = (_c = element.current) == null ? void 0 : _c.scrollWidth) != null ? _d : 0
1804
1816
  };
1805
1817
  yield savedLoadMore.current(state);
1806
- if (options.preserveScrollPosition && element) {
1807
- element.scrollTo({
1808
- top: element.scrollHeight - previous.height,
1809
- left: element.scrollWidth - previous.width
1818
+ if (opts.preserveScrollPosition && element.current) {
1819
+ element.current.scrollTo({
1820
+ top: element.current.scrollHeight - previous.height,
1821
+ left: element.current.scrollWidth - previous.width
1810
1822
  });
1811
1823
  }
1812
1824
  });
1813
1825
  fn();
1814
- }, [di, options.preserveScrollPosition, element]);
1826
+ }, [di]);
1815
1827
  }
1816
1828
 
1817
1829
  const defaultEvents = [
@@ -1848,7 +1860,7 @@ function useMousePressed(target, options = {}) {
1848
1860
  const { touch = true, drag = true, initialValue = false } = options;
1849
1861
  const [pressed, setPressed] = React.useState(initialValue);
1850
1862
  const [sourceType, setSourceType] = React.useState(null);
1851
- const element = getTargetElement(target);
1863
+ const elementRef = useLatestElement(target);
1852
1864
  const onPressed = React.useCallback(
1853
1865
  (srcType) => () => {
1854
1866
  setPressed(true);
@@ -1864,6 +1876,7 @@ function useMousePressed(target, options = {}) {
1864
1876
  useEventListener("mouseleave", onReleased, () => window, { passive: true });
1865
1877
  useEventListener("mouseup", onReleased, () => window, { passive: true });
1866
1878
  React.useEffect(() => {
1879
+ const element = elementRef.current;
1867
1880
  if (drag) {
1868
1881
  element == null ? void 0 : element.addEventListener("dragstart", onPressed("mouse"), {
1869
1882
  passive: true
@@ -1898,7 +1911,7 @@ function useMousePressed(target, options = {}) {
1898
1911
  element == null ? void 0 : element.removeEventListener("touchcancel", onReleased);
1899
1912
  }
1900
1913
  };
1901
- }, [drag, onPressed, onReleased, element, touch]);
1914
+ }, [drag, onPressed, onReleased, touch, elementRef.current]);
1902
1915
  return [pressed, sourceType];
1903
1916
  }
1904
1917
 
@@ -1915,32 +1928,34 @@ function preventDefault(rawEvent) {
1915
1928
  function useScrollLock(target, initialState = false) {
1916
1929
  const [locked, setLocked] = React.useState(initialState);
1917
1930
  const initialOverflowRef = React.useRef("scroll");
1918
- const element = getTargetElement(target);
1931
+ const element = useLatestElement(target);
1919
1932
  React.useEffect(() => {
1920
- if (element) {
1921
- initialOverflowRef.current = element.style.overflow;
1933
+ if (element.current) {
1934
+ initialOverflowRef.current = element.current.style.overflow;
1922
1935
  if (locked) {
1923
- element.style.overflow = "hidden";
1936
+ element.current.style.overflow = "hidden";
1924
1937
  }
1925
1938
  }
1926
- }, [locked, element]);
1939
+ }, [locked, element.current]);
1927
1940
  const lock = useEvent(() => {
1928
- if (!element || locked) {
1941
+ if (!element.current || locked) {
1929
1942
  return;
1930
1943
  }
1931
1944
  if (isIOS) {
1932
- element.addEventListener("touchmove", preventDefault, { passive: false });
1945
+ element.current.addEventListener("touchmove", preventDefault, {
1946
+ passive: false
1947
+ });
1933
1948
  }
1934
1949
  setLocked(true);
1935
1950
  });
1936
1951
  const unlock = useEvent(() => {
1937
- if (!element || !locked) {
1952
+ if (!element.current || !locked) {
1938
1953
  return;
1939
1954
  }
1940
1955
  if (isIOS) {
1941
- element.removeEventListener("touchmove", preventDefault);
1956
+ element.current.removeEventListener("touchmove", preventDefault);
1942
1957
  }
1943
- element.style.overflow = initialOverflowRef.current;
1958
+ element.current.style.overflow = initialOverflowRef.current;
1944
1959
  setLocked(false);
1945
1960
  });
1946
1961
  const set = useEvent((flag) => {
@@ -2124,14 +2139,15 @@ function useActiveElement() {
2124
2139
 
2125
2140
  function useDraggable(target, options = {}) {
2126
2141
  var _a, _b;
2127
- const draggingElement = getTargetElement(
2128
- options.draggingElement,
2129
- defaultWindow
2130
- );
2131
- const draggingHandle = getTargetElement((_a = options.handle) != null ? _a : target);
2142
+ const draggingElement = options.draggingElement;
2143
+ const draggingHandle = (_a = options.handle) != null ? _a : target;
2132
2144
  const [position, setPositon] = React.useState(
2133
2145
  (_b = options.initialValue) != null ? _b : { x: 0, y: 0 }
2134
2146
  );
2147
+ React.useEffect(() => {
2148
+ var _a2;
2149
+ setPositon((_a2 = options.initialValue) != null ? _a2 : { x: 0, y: 0 });
2150
+ }, [options.initialValue]);
2135
2151
  const [pressedDelta, setPressedDelta] = React.useState();
2136
2152
  const filterEvent = (e) => {
2137
2153
  if (options.pointerTypes) {
@@ -2339,7 +2355,7 @@ function useWindowScroll() {
2339
2355
  return state;
2340
2356
  }
2341
2357
 
2342
- var __async = (__this, __arguments, generator) => {
2358
+ var __async$1 = (__this, __arguments, generator) => {
2343
2359
  return new Promise((resolve, reject) => {
2344
2360
  var fulfilled = (value) => {
2345
2361
  try {
@@ -2368,7 +2384,7 @@ function useClipBorad() {
2368
2384
  }, []);
2369
2385
  useEventListener("copy", updateText);
2370
2386
  useEventListener("cut", updateText);
2371
- const copy = React.useCallback((txt) => __async(this, null, function* () {
2387
+ const copy = React.useCallback((txt) => __async$1(this, null, function* () {
2372
2388
  setText(txt);
2373
2389
  yield window.navigator.clipboard.writeText(txt);
2374
2390
  }), []);
@@ -2623,11 +2639,11 @@ function useScrollIntoView({
2623
2639
  cancelAnimationFrame(frameID.current);
2624
2640
  }
2625
2641
  };
2642
+ const element = useLatestElement(targetElement);
2626
2643
  const scrollIntoView = useEvent(
2627
2644
  ({ alignment = "start" } = {}) => {
2628
2645
  var _a;
2629
- const element = getTargetElement(targetElement);
2630
- const parent = getTargetElement(scrollElement) || getScrollParent(axis, element);
2646
+ const parent = getTargetElement(scrollElement) || getScrollParent(axis, element.current);
2631
2647
  shouldStop.current = false;
2632
2648
  if (frameID.current) {
2633
2649
  cancel();
@@ -2635,7 +2651,7 @@ function useScrollIntoView({
2635
2651
  const start = (_a = getScrollStart({ parent, axis })) != null ? _a : 0;
2636
2652
  const change = getRelativePosition({
2637
2653
  parent,
2638
- target: element,
2654
+ target: element.current,
2639
2655
  axis,
2640
2656
  alignment,
2641
2657
  offset,
@@ -2687,13 +2703,12 @@ const useSticky = ({
2687
2703
  nav = 0
2688
2704
  }) => {
2689
2705
  const [isSticky, setSticky] = React.useState(false);
2690
- const element = getTargetElement(targetElement);
2691
- const scrollParent = getTargetElement(scrollElement) || getScrollParent(axis, element);
2706
+ const element = useLatestElement(targetElement);
2692
2707
  const { run: scrollHandler } = useThrottleFn(() => {
2693
- if (!element) {
2708
+ if (!element.current) {
2694
2709
  return;
2695
2710
  }
2696
- const rect = element.getBoundingClientRect();
2711
+ const rect = element.current.getBoundingClientRect();
2697
2712
  if (axis === "y") {
2698
2713
  setSticky((rect == null ? void 0 : rect.top) <= nav);
2699
2714
  } else {
@@ -2701,7 +2716,8 @@ const useSticky = ({
2701
2716
  }
2702
2717
  }, 50);
2703
2718
  React.useEffect(() => {
2704
- if (!element || !scrollParent) {
2719
+ const scrollParent = getTargetElement(scrollElement) || getScrollParent(axis, element.current);
2720
+ if (!element.current || !scrollParent) {
2705
2721
  return;
2706
2722
  }
2707
2723
  scrollParent.addEventListener("scroll", scrollHandler);
@@ -2709,11 +2725,48 @@ const useSticky = ({
2709
2725
  return () => {
2710
2726
  scrollParent.removeEventListener("scroll", scrollHandler);
2711
2727
  };
2712
- }, [axis, element, scrollHandler, scrollParent]);
2728
+ }, [axis, element, scrollElement, scrollHandler]);
2713
2729
  return [isSticky, setSticky];
2714
2730
  };
2715
2731
 
2732
+ var __async = (__this, __arguments, generator) => {
2733
+ return new Promise((resolve, reject) => {
2734
+ var fulfilled = (value) => {
2735
+ try {
2736
+ step(generator.next(value));
2737
+ } catch (e) {
2738
+ reject(e);
2739
+ }
2740
+ };
2741
+ var rejected = (value) => {
2742
+ try {
2743
+ step(generator.throw(value));
2744
+ } catch (e) {
2745
+ reject(e);
2746
+ }
2747
+ };
2748
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
2749
+ step((generator = generator.apply(__this, __arguments)).next());
2750
+ });
2751
+ };
2752
+ function useAsyncEffect(effect, cleanup = noop, deps) {
2753
+ const mounted = useMountedState();
2754
+ React.useEffect(() => {
2755
+ const execute = () => __async(this, null, function* () {
2756
+ if (!mounted()) {
2757
+ return;
2758
+ }
2759
+ yield effect();
2760
+ });
2761
+ execute();
2762
+ return () => {
2763
+ cleanup();
2764
+ };
2765
+ }, deps);
2766
+ }
2767
+
2716
2768
  exports.useActiveElement = useActiveElement;
2769
+ exports.useAsyncEffect = useAsyncEffect;
2717
2770
  exports.useClickOutside = useClickOutSide;
2718
2771
  exports.useClipboard = useClipBorad;
2719
2772
  exports.useControlled = useControlled;
package/dist/index.d.ts CHANGED
@@ -275,7 +275,15 @@ declare function useObjectUrl(object: Blob | MediaSource | undefined): string |
275
275
 
276
276
  declare function useIdle(ms?: number, initialState?: boolean, events?: (keyof WindowEventMap)[]): boolean;
277
277
 
278
- declare const _default$3: () => {};
278
+ declare function useMediaDevices(): {
279
+ devices: {
280
+ deviceId: string;
281
+ groupId: string;
282
+ kind: MediaDeviceKind;
283
+ label: string;
284
+ }[];
285
+ };
286
+ declare const _default$3: typeof useMediaDevices;
279
287
 
280
288
  type UseTextDirectionValue = "ltr" | "rtl" | "auto";
281
289
  interface UseTextDirectionOptions {
@@ -416,7 +424,7 @@ declare function useDocumentVisibility(): DocumentVisibilityState;
416
424
 
417
425
  declare function useResizeObserver(target: BasicTarget, callback: ResizeObserverCallback, options?: ResizeObserverOptions): () => void;
418
426
 
419
- declare function useDropZone(target: BasicTarget<HTMLElement>, onDrop?: (files: File[] | null) => void): boolean;
427
+ declare function useDropZone(target: BasicTarget<EventTarget>, onDrop?: (files: File[] | null) => void): boolean;
420
428
 
421
429
  interface UseFileDialogOptions {
422
430
  /**
@@ -518,7 +526,7 @@ interface UseInfiniteScrollOptions extends UseScrollOptions {
518
526
  */
519
527
  preserveScrollPosition?: boolean;
520
528
  }
521
- declare function useInfiniteScroll(target: BasicTarget<HTMLElement | SVGElement | Window | Document>, onLoadMore: (state: ReturnType<typeof useScroll>) => void | Promise<void>, options?: UseInfiniteScrollOptions): void;
529
+ declare function useInfiniteScroll(target: BasicTarget<HTMLElement | SVGElement>, onLoadMore: (state: ReturnType<typeof useScroll>) => void | Promise<void>, options?: UseInfiniteScrollOptions): void;
522
530
 
523
531
  type KeyModifier = "Alt" | "AltGraph" | "CapsLock" | "Control" | "Fn" | "FnLock" | "Meta" | "NumLock" | "ScrollLock" | "Shift" | "Symbol" | "SymbolLock";
524
532
  interface UseModifierOptions {
@@ -563,7 +571,7 @@ interface MousePressedOptions {
563
571
  type MouseSourceType = "mouse" | "touch" | null;
564
572
  declare function useMousePressed(target?: BasicTarget, options?: MousePressedOptions): readonly [boolean, MouseSourceType];
565
573
 
566
- declare function useScrollLock(target: BasicTarget<HTMLElement | SVGElement | Window | Document>, initialState?: boolean): readonly [boolean, (flag: boolean) => void];
574
+ declare function useScrollLock(target: BasicTarget<HTMLElement>, initialState?: boolean): readonly [boolean, (flag: boolean) => void];
567
575
 
568
576
  declare function useElementSize(target: BasicTarget, options?: ResizeObserverOptions): readonly [number, number];
569
577
 
@@ -792,4 +800,6 @@ declare const useSticky: ({ targetElement, scrollElement, axis, nav, }: UseStick
792
800
  react__default.Dispatch<react__default.SetStateAction<boolean>>
793
801
  ];
794
802
 
795
- export { ColorScheme, Contrast, CursorState, GeneralPermissionDescriptor, IDisposable, IEvent, IEventOnce, IListener, INetworkInformation, IState, IUseNetworkState, KeyModifier, MousePressedOptions, MouseSourceType, OrientationState, RafLoopReturns, ScrollIntoViewAnimation, ScrollIntoViewParams, State, Status, Target, UseDarkOptions, UseDraggableOptions, UseElementBoundingOptions, UseEventEmitterReturn, UseFileDialogOptions, UseFpsOptions, UseFullScreenOptions, UseInfiniteScrollOptions, UseLongPressOptions, UseModifierOptions, UseScriptTagOptions, UseScrollOptions, UseStickyParams, UseTextDirectionOptions, UseTextDirectionValue, UseTimeoutFnOptions, UseVirtualListItem, UseVirtualListOptions, UseVirtualListReturn, WindowSize, useActiveElement, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useFavicon, useFileDialog, useFirstMountState, useFocus, _default$2 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, _default$3 as useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, _default$1 as useOnceEffect, _default as useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSticky, useTextDirection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, _default$5 as useUpdateEffect, _default$4 as useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
803
+ declare function useAsyncEffect<T extends void>(effect: () => Promise<T> | T, cleanup?: typeof effect, deps?: DependencyList): void;
804
+
805
+ export { ColorScheme, Contrast, CursorState, GeneralPermissionDescriptor, IDisposable, IEvent, IEventOnce, IListener, INetworkInformation, IState, IUseNetworkState, KeyModifier, MousePressedOptions, MouseSourceType, OrientationState, RafLoopReturns, ScrollIntoViewAnimation, ScrollIntoViewParams, State, Status, Target, UseDarkOptions, UseDraggableOptions, UseElementBoundingOptions, UseEventEmitterReturn, UseFileDialogOptions, UseFpsOptions, UseFullScreenOptions, UseInfiniteScrollOptions, UseLongPressOptions, UseModifierOptions, UseScriptTagOptions, UseScrollOptions, UseStickyParams, UseTextDirectionOptions, UseTextDirectionValue, UseTimeoutFnOptions, UseVirtualListItem, UseVirtualListOptions, UseVirtualListReturn, WindowSize, useActiveElement, useAsyncEffect, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useFavicon, useFileDialog, useFirstMountState, useFocus, _default$2 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, _default$3 as useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, _default$1 as useOnceEffect, _default as useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSticky, useTextDirection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, _default$5 as useUpdateEffect, _default$4 as useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
package/dist/index.mjs CHANGED
@@ -493,6 +493,13 @@ function getTargetElement(target, defaultElement) {
493
493
  }
494
494
  return targetElement;
495
495
  }
496
+ function useLatestElement(target, defaultElement) {
497
+ const ref = useRef(getTargetElement(target, defaultElement));
498
+ useEffect(() => {
499
+ ref.current = getTargetElement(target, defaultElement);
500
+ }, [defaultElement, target]);
501
+ return ref;
502
+ }
496
503
 
497
504
  const isPrimitive$1 = (val) => val !== Object(val);
498
505
  function useCustomCompareEffect(effect, deps, depsEqual) {
@@ -539,17 +546,21 @@ function useDeepCompareEffect(effect, deps) {
539
546
 
540
547
  function useEventListener(eventName, handler, element, options) {
541
548
  const savedHandler = useLatest(handler);
542
- const targetElement = getTargetElement(element, window);
549
+ const targetElementRef = useLatestElement(element, defaultWindow);
543
550
  useDeepCompareEffect(() => {
551
+ const targetElement = targetElementRef.current;
544
552
  if (!(targetElement && targetElement.addEventListener)) {
545
553
  return;
546
554
  }
547
555
  const eventListener = (event) => savedHandler.current(event);
548
556
  on(targetElement, eventName, eventListener, options);
549
557
  return () => {
558
+ if (!(targetElement && targetElement.removeEventListener)) {
559
+ return;
560
+ }
550
561
  off(targetElement, eventName, eventListener);
551
562
  };
552
- }, [eventName, targetElement, options, savedHandler]);
563
+ }, [eventName, targetElementRef.current, options, savedHandler]);
553
564
  }
554
565
 
555
566
  function useCounter(initialValue = 0, max = null, min = null) {
@@ -693,20 +704,20 @@ function useFavicon(href, baseUrl = "", rel = "icon") {
693
704
  function useMutationObserver(callback, target, options = {}) {
694
705
  const callbackRef = useLatest(callback);
695
706
  const observerRef = useRef();
696
- const element = getTargetElement(target);
707
+ const element = useLatestElement(target);
697
708
  const stop = useCallback(() => {
698
709
  if (observerRef.current) {
699
710
  observerRef.current.disconnect();
700
711
  }
701
712
  }, []);
702
713
  useDeepCompareEffect(() => {
703
- if (!element) {
714
+ if (!element.current) {
704
715
  return;
705
716
  }
706
717
  observerRef.current = new MutationObserver(callbackRef.current);
707
- observerRef.current.observe(element, options);
718
+ observerRef.current.observe(element.current, options);
708
719
  return stop;
709
- }, [options, element]);
720
+ }, [options, element.current]);
710
721
  return stop;
711
722
  }
712
723
 
@@ -989,7 +1000,7 @@ function useMediaDevices() {
989
1000
  }, []);
990
1001
  return state;
991
1002
  }
992
- const useMediaDevicesMock = () => ({});
1003
+ const useMediaDevicesMock = () => ({ devices: [] });
993
1004
  var useMediaDevices$1 = isNavigator && !!navigator.mediaDevices ? useMediaDevices : useMediaDevicesMock;
994
1005
 
995
1006
  function useTextDirection(options = {}) {
@@ -1491,23 +1502,23 @@ function useOrientation(initialState = defaultState) {
1491
1502
  function useIntersectionObserver(target, callback, options = {}) {
1492
1503
  const savedCallback = useLatest(callback);
1493
1504
  const observerRef = useRef();
1494
- const element = getTargetElement(target);
1505
+ const element = useLatestElement(target);
1495
1506
  const stop = useCallback(() => {
1496
1507
  if (observerRef.current) {
1497
1508
  observerRef.current.disconnect();
1498
1509
  }
1499
1510
  }, []);
1500
1511
  useDeepCompareEffect(() => {
1501
- if (!element) {
1512
+ if (!element.current) {
1502
1513
  return;
1503
1514
  }
1504
1515
  observerRef.current = new IntersectionObserver(
1505
1516
  savedCallback.current,
1506
1517
  options
1507
1518
  );
1508
- observerRef.current.observe(element);
1519
+ observerRef.current.observe(element.current);
1509
1520
  return stop;
1510
- }, [options, element]);
1521
+ }, [options, element.current]);
1511
1522
  return stop;
1512
1523
  }
1513
1524
 
@@ -1547,27 +1558,26 @@ function useDocumentVisibility() {
1547
1558
  function useResizeObserver(target, callback, options = {}) {
1548
1559
  const savedCallback = useLatest(callback);
1549
1560
  const observerRef = useRef();
1550
- const element = getTargetElement(target);
1561
+ const element = useLatestElement(target);
1551
1562
  const stop = useCallback(() => {
1552
1563
  if (observerRef.current) {
1553
1564
  observerRef.current.disconnect();
1554
1565
  }
1555
1566
  }, []);
1556
1567
  useDeepCompareEffect(() => {
1557
- if (!element) {
1568
+ if (!element.current) {
1558
1569
  return;
1559
1570
  }
1560
1571
  observerRef.current = new ResizeObserver(savedCallback.current);
1561
- observerRef.current.observe(element, options);
1572
+ observerRef.current.observe(element.current, options);
1562
1573
  return stop;
1563
- }, [options, element]);
1574
+ }, [options, element.current]);
1564
1575
  return stop;
1565
1576
  }
1566
1577
 
1567
1578
  function useDropZone(target, onDrop) {
1568
1579
  const [over, setOver] = useState(false);
1569
1580
  const counter = useRef(0);
1570
- const element = getTargetElement(target);
1571
1581
  useEventListener(
1572
1582
  "dragenter",
1573
1583
  (event) => {
@@ -1575,14 +1585,14 @@ function useDropZone(target, onDrop) {
1575
1585
  counter.current += 1;
1576
1586
  setOver(true);
1577
1587
  },
1578
- element
1588
+ target
1579
1589
  );
1580
1590
  useEventListener(
1581
1591
  "dragover",
1582
1592
  (event) => {
1583
1593
  event.preventDefault();
1584
1594
  },
1585
- element
1595
+ target
1586
1596
  );
1587
1597
  useEventListener(
1588
1598
  "dragleave",
@@ -1593,7 +1603,7 @@ function useDropZone(target, onDrop) {
1593
1603
  setOver(false);
1594
1604
  }
1595
1605
  },
1596
- element
1606
+ target
1597
1607
  );
1598
1608
  useEventListener(
1599
1609
  "drop",
@@ -1605,7 +1615,7 @@ function useDropZone(target, onDrop) {
1605
1615
  const files = Array.from((_b = (_a = event.dataTransfer) == null ? void 0 : _a.files) != null ? _b : []);
1606
1616
  onDrop == null ? void 0 : onDrop(files.length === 0 ? null : files);
1607
1617
  },
1608
- element
1618
+ target
1609
1619
  );
1610
1620
  return over;
1611
1621
  }
@@ -1756,7 +1766,7 @@ var __spreadValues = (a, b) => {
1756
1766
  return a;
1757
1767
  };
1758
1768
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
1759
- var __async$1 = (__this, __arguments, generator) => {
1769
+ var __async$2 = (__this, __arguments, generator) => {
1760
1770
  return new Promise((resolve, reject) => {
1761
1771
  var fulfilled = (value) => {
1762
1772
  try {
@@ -1785,25 +1795,27 @@ function useInfiniteScroll(target, onLoadMore, options = {}) {
1785
1795
  [direction]: (_b = options.distance) != null ? _b : 0
1786
1796
  }, options.offset)
1787
1797
  }));
1788
- const element = getTargetElement(target);
1798
+ const element = useLatestElement(target);
1799
+ const latestOptions = useLatest(options);
1789
1800
  const di = state[3][direction];
1790
1801
  useUpdateEffect(() => {
1791
- const fn = () => __async$1(this, null, function* () {
1792
- var _a2, _b2;
1802
+ const opts = latestOptions.current;
1803
+ const fn = () => __async$2(this, null, function* () {
1804
+ var _a2, _b2, _c, _d;
1793
1805
  const previous = {
1794
- height: (_a2 = element == null ? void 0 : element.scrollHeight) != null ? _a2 : 0,
1795
- width: (_b2 = element == null ? void 0 : element.scrollWidth) != null ? _b2 : 0
1806
+ height: (_b2 = (_a2 = element.current) == null ? void 0 : _a2.scrollHeight) != null ? _b2 : 0,
1807
+ width: (_d = (_c = element.current) == null ? void 0 : _c.scrollWidth) != null ? _d : 0
1796
1808
  };
1797
1809
  yield savedLoadMore.current(state);
1798
- if (options.preserveScrollPosition && element) {
1799
- element.scrollTo({
1800
- top: element.scrollHeight - previous.height,
1801
- left: element.scrollWidth - previous.width
1810
+ if (opts.preserveScrollPosition && element.current) {
1811
+ element.current.scrollTo({
1812
+ top: element.current.scrollHeight - previous.height,
1813
+ left: element.current.scrollWidth - previous.width
1802
1814
  });
1803
1815
  }
1804
1816
  });
1805
1817
  fn();
1806
- }, [di, options.preserveScrollPosition, element]);
1818
+ }, [di]);
1807
1819
  }
1808
1820
 
1809
1821
  const defaultEvents = [
@@ -1840,7 +1852,7 @@ function useMousePressed(target, options = {}) {
1840
1852
  const { touch = true, drag = true, initialValue = false } = options;
1841
1853
  const [pressed, setPressed] = useState(initialValue);
1842
1854
  const [sourceType, setSourceType] = useState(null);
1843
- const element = getTargetElement(target);
1855
+ const elementRef = useLatestElement(target);
1844
1856
  const onPressed = useCallback(
1845
1857
  (srcType) => () => {
1846
1858
  setPressed(true);
@@ -1856,6 +1868,7 @@ function useMousePressed(target, options = {}) {
1856
1868
  useEventListener("mouseleave", onReleased, () => window, { passive: true });
1857
1869
  useEventListener("mouseup", onReleased, () => window, { passive: true });
1858
1870
  useEffect(() => {
1871
+ const element = elementRef.current;
1859
1872
  if (drag) {
1860
1873
  element == null ? void 0 : element.addEventListener("dragstart", onPressed("mouse"), {
1861
1874
  passive: true
@@ -1890,7 +1903,7 @@ function useMousePressed(target, options = {}) {
1890
1903
  element == null ? void 0 : element.removeEventListener("touchcancel", onReleased);
1891
1904
  }
1892
1905
  };
1893
- }, [drag, onPressed, onReleased, element, touch]);
1906
+ }, [drag, onPressed, onReleased, touch, elementRef.current]);
1894
1907
  return [pressed, sourceType];
1895
1908
  }
1896
1909
 
@@ -1907,32 +1920,34 @@ function preventDefault(rawEvent) {
1907
1920
  function useScrollLock(target, initialState = false) {
1908
1921
  const [locked, setLocked] = useState(initialState);
1909
1922
  const initialOverflowRef = useRef("scroll");
1910
- const element = getTargetElement(target);
1923
+ const element = useLatestElement(target);
1911
1924
  useEffect(() => {
1912
- if (element) {
1913
- initialOverflowRef.current = element.style.overflow;
1925
+ if (element.current) {
1926
+ initialOverflowRef.current = element.current.style.overflow;
1914
1927
  if (locked) {
1915
- element.style.overflow = "hidden";
1928
+ element.current.style.overflow = "hidden";
1916
1929
  }
1917
1930
  }
1918
- }, [locked, element]);
1931
+ }, [locked, element.current]);
1919
1932
  const lock = useEvent(() => {
1920
- if (!element || locked) {
1933
+ if (!element.current || locked) {
1921
1934
  return;
1922
1935
  }
1923
1936
  if (isIOS) {
1924
- element.addEventListener("touchmove", preventDefault, { passive: false });
1937
+ element.current.addEventListener("touchmove", preventDefault, {
1938
+ passive: false
1939
+ });
1925
1940
  }
1926
1941
  setLocked(true);
1927
1942
  });
1928
1943
  const unlock = useEvent(() => {
1929
- if (!element || !locked) {
1944
+ if (!element.current || !locked) {
1930
1945
  return;
1931
1946
  }
1932
1947
  if (isIOS) {
1933
- element.removeEventListener("touchmove", preventDefault);
1948
+ element.current.removeEventListener("touchmove", preventDefault);
1934
1949
  }
1935
- element.style.overflow = initialOverflowRef.current;
1950
+ element.current.style.overflow = initialOverflowRef.current;
1936
1951
  setLocked(false);
1937
1952
  });
1938
1953
  const set = useEvent((flag) => {
@@ -2116,14 +2131,15 @@ function useActiveElement() {
2116
2131
 
2117
2132
  function useDraggable(target, options = {}) {
2118
2133
  var _a, _b;
2119
- const draggingElement = getTargetElement(
2120
- options.draggingElement,
2121
- defaultWindow
2122
- );
2123
- const draggingHandle = getTargetElement((_a = options.handle) != null ? _a : target);
2134
+ const draggingElement = options.draggingElement;
2135
+ const draggingHandle = (_a = options.handle) != null ? _a : target;
2124
2136
  const [position, setPositon] = useState(
2125
2137
  (_b = options.initialValue) != null ? _b : { x: 0, y: 0 }
2126
2138
  );
2139
+ useEffect(() => {
2140
+ var _a2;
2141
+ setPositon((_a2 = options.initialValue) != null ? _a2 : { x: 0, y: 0 });
2142
+ }, [options.initialValue]);
2127
2143
  const [pressedDelta, setPressedDelta] = useState();
2128
2144
  const filterEvent = (e) => {
2129
2145
  if (options.pointerTypes) {
@@ -2331,7 +2347,7 @@ function useWindowScroll() {
2331
2347
  return state;
2332
2348
  }
2333
2349
 
2334
- var __async = (__this, __arguments, generator) => {
2350
+ var __async$1 = (__this, __arguments, generator) => {
2335
2351
  return new Promise((resolve, reject) => {
2336
2352
  var fulfilled = (value) => {
2337
2353
  try {
@@ -2360,7 +2376,7 @@ function useClipBorad() {
2360
2376
  }, []);
2361
2377
  useEventListener("copy", updateText);
2362
2378
  useEventListener("cut", updateText);
2363
- const copy = useCallback((txt) => __async(this, null, function* () {
2379
+ const copy = useCallback((txt) => __async$1(this, null, function* () {
2364
2380
  setText(txt);
2365
2381
  yield window.navigator.clipboard.writeText(txt);
2366
2382
  }), []);
@@ -2615,11 +2631,11 @@ function useScrollIntoView({
2615
2631
  cancelAnimationFrame(frameID.current);
2616
2632
  }
2617
2633
  };
2634
+ const element = useLatestElement(targetElement);
2618
2635
  const scrollIntoView = useEvent(
2619
2636
  ({ alignment = "start" } = {}) => {
2620
2637
  var _a;
2621
- const element = getTargetElement(targetElement);
2622
- const parent = getTargetElement(scrollElement) || getScrollParent(axis, element);
2638
+ const parent = getTargetElement(scrollElement) || getScrollParent(axis, element.current);
2623
2639
  shouldStop.current = false;
2624
2640
  if (frameID.current) {
2625
2641
  cancel();
@@ -2627,7 +2643,7 @@ function useScrollIntoView({
2627
2643
  const start = (_a = getScrollStart({ parent, axis })) != null ? _a : 0;
2628
2644
  const change = getRelativePosition({
2629
2645
  parent,
2630
- target: element,
2646
+ target: element.current,
2631
2647
  axis,
2632
2648
  alignment,
2633
2649
  offset,
@@ -2679,13 +2695,12 @@ const useSticky = ({
2679
2695
  nav = 0
2680
2696
  }) => {
2681
2697
  const [isSticky, setSticky] = useState(false);
2682
- const element = getTargetElement(targetElement);
2683
- const scrollParent = getTargetElement(scrollElement) || getScrollParent(axis, element);
2698
+ const element = useLatestElement(targetElement);
2684
2699
  const { run: scrollHandler } = useThrottleFn(() => {
2685
- if (!element) {
2700
+ if (!element.current) {
2686
2701
  return;
2687
2702
  }
2688
- const rect = element.getBoundingClientRect();
2703
+ const rect = element.current.getBoundingClientRect();
2689
2704
  if (axis === "y") {
2690
2705
  setSticky((rect == null ? void 0 : rect.top) <= nav);
2691
2706
  } else {
@@ -2693,7 +2708,8 @@ const useSticky = ({
2693
2708
  }
2694
2709
  }, 50);
2695
2710
  useEffect(() => {
2696
- if (!element || !scrollParent) {
2711
+ const scrollParent = getTargetElement(scrollElement) || getScrollParent(axis, element.current);
2712
+ if (!element.current || !scrollParent) {
2697
2713
  return;
2698
2714
  }
2699
2715
  scrollParent.addEventListener("scroll", scrollHandler);
@@ -2701,8 +2717,44 @@ const useSticky = ({
2701
2717
  return () => {
2702
2718
  scrollParent.removeEventListener("scroll", scrollHandler);
2703
2719
  };
2704
- }, [axis, element, scrollHandler, scrollParent]);
2720
+ }, [axis, element, scrollElement, scrollHandler]);
2705
2721
  return [isSticky, setSticky];
2706
2722
  };
2707
2723
 
2708
- export { useActiveElement, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useFavicon, useFileDialog, useFirstMountState, useFocus, useFps$1 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, useMediaDevices$1 as useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, useOnceEffect, useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSticky, useTextDirection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, useUpdateEffect, useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
2724
+ var __async = (__this, __arguments, generator) => {
2725
+ return new Promise((resolve, reject) => {
2726
+ var fulfilled = (value) => {
2727
+ try {
2728
+ step(generator.next(value));
2729
+ } catch (e) {
2730
+ reject(e);
2731
+ }
2732
+ };
2733
+ var rejected = (value) => {
2734
+ try {
2735
+ step(generator.throw(value));
2736
+ } catch (e) {
2737
+ reject(e);
2738
+ }
2739
+ };
2740
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
2741
+ step((generator = generator.apply(__this, __arguments)).next());
2742
+ });
2743
+ };
2744
+ function useAsyncEffect(effect, cleanup = noop, deps) {
2745
+ const mounted = useMountedState();
2746
+ useEffect(() => {
2747
+ const execute = () => __async(this, null, function* () {
2748
+ if (!mounted()) {
2749
+ return;
2750
+ }
2751
+ yield effect();
2752
+ });
2753
+ execute();
2754
+ return () => {
2755
+ cleanup();
2756
+ };
2757
+ }, deps);
2758
+ }
2759
+
2760
+ export { useActiveElement, useAsyncEffect, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useFavicon, useFileDialog, useFirstMountState, useFocus, useFps$1 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, useMediaDevices$1 as useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, useOnceEffect, useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSticky, useTextDirection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, useUpdateEffect, useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactuses/core",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",