@reactuses/core 1.1.5 → 2.0.1
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 +278 -42
- package/dist/index.d.ts +47 -4
- package/dist/index.mjs +276 -43
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -131,7 +131,7 @@ function useStorage(key, defaults, getStorage, options = {}) {
|
|
|
131
131
|
}
|
|
132
132
|
const type = guessSerializerType(defaults);
|
|
133
133
|
const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
|
|
134
|
-
const getStoredValue = () => {
|
|
134
|
+
const getStoredValue = useEvent(() => {
|
|
135
135
|
try {
|
|
136
136
|
const raw = storage == null ? void 0 : storage.getItem(key);
|
|
137
137
|
if (raw !== void 0 && raw !== null) {
|
|
@@ -143,11 +143,11 @@ function useStorage(key, defaults, getStorage, options = {}) {
|
|
|
143
143
|
} catch (e) {
|
|
144
144
|
onError(e);
|
|
145
145
|
}
|
|
146
|
-
};
|
|
147
|
-
const [state, setState] = React.useState(
|
|
148
|
-
|
|
146
|
+
});
|
|
147
|
+
const [state, setState] = React.useState(defaults);
|
|
148
|
+
React.useEffect(() => {
|
|
149
149
|
setState(getStoredValue());
|
|
150
|
-
}, [key]);
|
|
150
|
+
}, [getStoredValue, key]);
|
|
151
151
|
const updateState = useEvent(
|
|
152
152
|
(valOrFunc) => {
|
|
153
153
|
const currentState = isFunction(valOrFunc) ? valOrFunc(state) : valOrFunc;
|
|
@@ -205,12 +205,12 @@ function useInterval(callback, delay, options) {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
const getInitialState = (query, defaultState) => {
|
|
208
|
-
if (isBrowser) {
|
|
209
|
-
return window.matchMedia(query).matches;
|
|
210
|
-
}
|
|
211
208
|
if (defaultState !== void 0) {
|
|
212
209
|
return defaultState;
|
|
213
210
|
}
|
|
211
|
+
if (isBrowser) {
|
|
212
|
+
return window.matchMedia(query).matches;
|
|
213
|
+
}
|
|
214
214
|
if (process.env.NODE_ENV !== "production") {
|
|
215
215
|
console.warn(
|
|
216
216
|
"`useMediaQuery` When server side rendering, defaultState should be defined to prevent a hydration mismatches."
|
|
@@ -262,21 +262,24 @@ function useDarkMode(options = {}) {
|
|
|
262
262
|
const prefersDarkMode = usePreferredDark(false);
|
|
263
263
|
const value = initialValue ? initialValue : prefersDarkMode ? "dark" : "light";
|
|
264
264
|
const [dark, setDark] = useStorage(storageKey, value, storage);
|
|
265
|
-
React.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
265
|
+
const wrappedSetDark = React.useCallback(
|
|
266
|
+
(latestDark) => {
|
|
267
|
+
const element = window == null ? void 0 : window.document.querySelector(selector);
|
|
268
|
+
if (!element) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (attribute === "class") {
|
|
272
|
+
latestDark && element.classList.add(latestDark);
|
|
273
|
+
dark && element.classList.remove(dark);
|
|
274
|
+
} else {
|
|
275
|
+
latestDark && element.setAttribute(attribute, latestDark);
|
|
276
|
+
dark && element.removeAttribute(attribute);
|
|
277
|
+
}
|
|
278
|
+
setDark(latestDark);
|
|
279
|
+
},
|
|
280
|
+
[attribute, dark, selector, setDark]
|
|
281
|
+
);
|
|
282
|
+
return [dark, wrappedSetDark];
|
|
280
283
|
}
|
|
281
284
|
|
|
282
285
|
function useMount(fn) {
|
|
@@ -544,8 +547,8 @@ function useDeepCompareEffect(effect, deps) {
|
|
|
544
547
|
|
|
545
548
|
function useEventListener(eventName, handler, element, options) {
|
|
546
549
|
const savedHandler = useLatest(handler);
|
|
550
|
+
const targetElement = getTargetElement(element, window);
|
|
547
551
|
useDeepCompareEffect(() => {
|
|
548
|
-
const targetElement = getTargetElement(element, window);
|
|
549
552
|
if (!(targetElement && targetElement.addEventListener)) {
|
|
550
553
|
return;
|
|
551
554
|
}
|
|
@@ -554,7 +557,7 @@ function useEventListener(eventName, handler, element, options) {
|
|
|
554
557
|
return () => {
|
|
555
558
|
off(targetElement, eventName, eventListener);
|
|
556
559
|
};
|
|
557
|
-
}, [eventName,
|
|
560
|
+
}, [eventName, targetElement, options, savedHandler]);
|
|
558
561
|
}
|
|
559
562
|
|
|
560
563
|
function useCounter(initialValue = 0, max = null, min = null) {
|
|
@@ -698,20 +701,20 @@ function useFavicon(href, baseUrl = "", rel = "icon") {
|
|
|
698
701
|
function useMutationObserver(callback, target, options = {}) {
|
|
699
702
|
const callbackRef = useLatest(callback);
|
|
700
703
|
const observerRef = React.useRef();
|
|
704
|
+
const element = getTargetElement(target);
|
|
701
705
|
const stop = React.useCallback(() => {
|
|
702
706
|
if (observerRef.current) {
|
|
703
707
|
observerRef.current.disconnect();
|
|
704
708
|
}
|
|
705
709
|
}, []);
|
|
706
710
|
useDeepCompareEffect(() => {
|
|
707
|
-
const element = getTargetElement(target);
|
|
708
711
|
if (!element) {
|
|
709
712
|
return;
|
|
710
713
|
}
|
|
711
714
|
observerRef.current = new MutationObserver(callbackRef.current);
|
|
712
715
|
observerRef.current.observe(element, options);
|
|
713
716
|
return stop;
|
|
714
|
-
}, [options]);
|
|
717
|
+
}, [options, element]);
|
|
715
718
|
return stop;
|
|
716
719
|
}
|
|
717
720
|
|
|
@@ -1496,13 +1499,13 @@ function useOrientation(initialState = defaultState) {
|
|
|
1496
1499
|
function useIntersectionObserver(target, callback, options = {}) {
|
|
1497
1500
|
const savedCallback = useLatest(callback);
|
|
1498
1501
|
const observerRef = React.useRef();
|
|
1502
|
+
const element = getTargetElement(target);
|
|
1499
1503
|
const stop = React.useCallback(() => {
|
|
1500
1504
|
if (observerRef.current) {
|
|
1501
1505
|
observerRef.current.disconnect();
|
|
1502
1506
|
}
|
|
1503
1507
|
}, []);
|
|
1504
1508
|
useDeepCompareEffect(() => {
|
|
1505
|
-
const element = getTargetElement(target);
|
|
1506
1509
|
if (!element) {
|
|
1507
1510
|
return;
|
|
1508
1511
|
}
|
|
@@ -1512,7 +1515,7 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
1512
1515
|
);
|
|
1513
1516
|
observerRef.current.observe(element);
|
|
1514
1517
|
return stop;
|
|
1515
|
-
}, [options]);
|
|
1518
|
+
}, [options, element]);
|
|
1516
1519
|
return stop;
|
|
1517
1520
|
}
|
|
1518
1521
|
|
|
@@ -1552,20 +1555,20 @@ function useDocumentVisibility() {
|
|
|
1552
1555
|
function useResizeObserver(target, callback, options = {}) {
|
|
1553
1556
|
const savedCallback = useLatest(callback);
|
|
1554
1557
|
const observerRef = React.useRef();
|
|
1558
|
+
const element = getTargetElement(target);
|
|
1555
1559
|
const stop = React.useCallback(() => {
|
|
1556
1560
|
if (observerRef.current) {
|
|
1557
1561
|
observerRef.current.disconnect();
|
|
1558
1562
|
}
|
|
1559
1563
|
}, []);
|
|
1560
1564
|
useDeepCompareEffect(() => {
|
|
1561
|
-
const element = getTargetElement(target);
|
|
1562
1565
|
if (!element) {
|
|
1563
1566
|
return;
|
|
1564
1567
|
}
|
|
1565
1568
|
observerRef.current = new ResizeObserver(savedCallback.current);
|
|
1566
1569
|
observerRef.current.observe(element, options);
|
|
1567
1570
|
return stop;
|
|
1568
|
-
}, [options]);
|
|
1571
|
+
}, [options, element]);
|
|
1569
1572
|
return stop;
|
|
1570
1573
|
}
|
|
1571
1574
|
|
|
@@ -1790,11 +1793,11 @@ function useInfiniteScroll(target, onLoadMore, options = {}) {
|
|
|
1790
1793
|
[direction]: (_b = options.distance) != null ? _b : 0
|
|
1791
1794
|
}, options.offset)
|
|
1792
1795
|
}));
|
|
1796
|
+
const element = getTargetElement(target);
|
|
1793
1797
|
const di = state[3][direction];
|
|
1794
1798
|
useUpdateEffect(() => {
|
|
1795
1799
|
const fn = () => __async$1(this, null, function* () {
|
|
1796
1800
|
var _a2, _b2;
|
|
1797
|
-
const element = getTargetElement(target);
|
|
1798
1801
|
const previous = {
|
|
1799
1802
|
height: (_a2 = element == null ? void 0 : element.scrollHeight) != null ? _a2 : 0,
|
|
1800
1803
|
width: (_b2 = element == null ? void 0 : element.scrollWidth) != null ? _b2 : 0
|
|
@@ -1808,7 +1811,7 @@ function useInfiniteScroll(target, onLoadMore, options = {}) {
|
|
|
1808
1811
|
}
|
|
1809
1812
|
});
|
|
1810
1813
|
fn();
|
|
1811
|
-
}, [di, options.preserveScrollPosition]);
|
|
1814
|
+
}, [di, options.preserveScrollPosition, element]);
|
|
1812
1815
|
}
|
|
1813
1816
|
|
|
1814
1817
|
const defaultEvents = [
|
|
@@ -1845,6 +1848,7 @@ function useMousePressed(target, options = {}) {
|
|
|
1845
1848
|
const { touch = true, drag = true, initialValue = false } = options;
|
|
1846
1849
|
const [pressed, setPressed] = React.useState(initialValue);
|
|
1847
1850
|
const [sourceType, setSourceType] = React.useState(null);
|
|
1851
|
+
const element = getTargetElement(target);
|
|
1848
1852
|
const onPressed = React.useCallback(
|
|
1849
1853
|
(srcType) => () => {
|
|
1850
1854
|
setPressed(true);
|
|
@@ -1859,8 +1863,7 @@ function useMousePressed(target, options = {}) {
|
|
|
1859
1863
|
useEventListener("mousedown", onPressed("mouse"), target, { passive: true });
|
|
1860
1864
|
useEventListener("mouseleave", onReleased, () => window, { passive: true });
|
|
1861
1865
|
useEventListener("mouseup", onReleased, () => window, { passive: true });
|
|
1862
|
-
|
|
1863
|
-
const element = getTargetElement(target);
|
|
1866
|
+
React.useEffect(() => {
|
|
1864
1867
|
if (drag) {
|
|
1865
1868
|
element == null ? void 0 : element.addEventListener("dragstart", onPressed("mouse"), {
|
|
1866
1869
|
passive: true
|
|
@@ -1895,7 +1898,7 @@ function useMousePressed(target, options = {}) {
|
|
|
1895
1898
|
element == null ? void 0 : element.removeEventListener("touchcancel", onReleased);
|
|
1896
1899
|
}
|
|
1897
1900
|
};
|
|
1898
|
-
});
|
|
1901
|
+
}, [drag, onPressed, onReleased, element, touch]);
|
|
1899
1902
|
return [pressed, sourceType];
|
|
1900
1903
|
}
|
|
1901
1904
|
|
|
@@ -1912,28 +1915,25 @@ function preventDefault(rawEvent) {
|
|
|
1912
1915
|
function useScrollLock(target, initialState = false) {
|
|
1913
1916
|
const [locked, setLocked] = React.useState(initialState);
|
|
1914
1917
|
const initialOverflowRef = React.useRef("scroll");
|
|
1915
|
-
|
|
1916
|
-
|
|
1918
|
+
const element = getTargetElement(target);
|
|
1919
|
+
React.useEffect(() => {
|
|
1917
1920
|
if (element) {
|
|
1918
1921
|
initialOverflowRef.current = element.style.overflow;
|
|
1919
1922
|
if (locked) {
|
|
1920
1923
|
element.style.overflow = "hidden";
|
|
1921
1924
|
}
|
|
1922
1925
|
}
|
|
1923
|
-
});
|
|
1926
|
+
}, [locked, element]);
|
|
1924
1927
|
const lock = useEvent(() => {
|
|
1925
|
-
const element = getTargetElement(target);
|
|
1926
1928
|
if (!element || locked) {
|
|
1927
1929
|
return;
|
|
1928
1930
|
}
|
|
1929
1931
|
if (isIOS) {
|
|
1930
1932
|
element.addEventListener("touchmove", preventDefault, { passive: false });
|
|
1931
1933
|
}
|
|
1932
|
-
element.style.overflow = "hidden";
|
|
1933
1934
|
setLocked(true);
|
|
1934
1935
|
});
|
|
1935
1936
|
const unlock = useEvent(() => {
|
|
1936
|
-
const element = getTargetElement(target);
|
|
1937
1937
|
if (!element || !locked) {
|
|
1938
1938
|
return;
|
|
1939
1939
|
}
|
|
@@ -2480,6 +2480,239 @@ var useOnceEffect = createOnceEffect(React.useEffect);
|
|
|
2480
2480
|
|
|
2481
2481
|
var useOnceLayoutEffect = createOnceEffect(React.useLayoutEffect);
|
|
2482
2482
|
|
|
2483
|
+
function useReducedMotion(defaultState) {
|
|
2484
|
+
return useMediaQuery("(prefers-reduced-motion: reduce)", defaultState);
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
const setScrollParam = ({
|
|
2488
|
+
axis,
|
|
2489
|
+
parent,
|
|
2490
|
+
distance
|
|
2491
|
+
}) => {
|
|
2492
|
+
if (!parent && typeof document === "undefined") {
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
const method = axis === "y" ? "scrollTop" : "scrollLeft";
|
|
2496
|
+
if (parent) {
|
|
2497
|
+
parent[method] = distance;
|
|
2498
|
+
} else {
|
|
2499
|
+
const { body, documentElement } = document;
|
|
2500
|
+
body[method] = distance;
|
|
2501
|
+
documentElement[method] = distance;
|
|
2502
|
+
}
|
|
2503
|
+
};
|
|
2504
|
+
const isScrollElement = (axis, node) => {
|
|
2505
|
+
if (!node) {
|
|
2506
|
+
return false;
|
|
2507
|
+
}
|
|
2508
|
+
const AXIS = axis === "x" ? "X" : "Y";
|
|
2509
|
+
return getComputedStyle(node)[`overflow${AXIS}`] === "auto" || getComputedStyle(node)[`overflow${AXIS}`] === "scroll";
|
|
2510
|
+
};
|
|
2511
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2512
|
+
const getScrollParent = (axis, node) => {
|
|
2513
|
+
if (!node || !node.parentElement) {
|
|
2514
|
+
return null;
|
|
2515
|
+
}
|
|
2516
|
+
if (cache.has(node)) {
|
|
2517
|
+
return cache.get(node) || null;
|
|
2518
|
+
}
|
|
2519
|
+
let parent = node.parentElement;
|
|
2520
|
+
while (parent && !isScrollElement(axis, parent)) {
|
|
2521
|
+
parent = parent.parentElement;
|
|
2522
|
+
}
|
|
2523
|
+
if (parent) {
|
|
2524
|
+
cache.set(node, parent);
|
|
2525
|
+
}
|
|
2526
|
+
return parent;
|
|
2527
|
+
};
|
|
2528
|
+
const getScrollStart = ({
|
|
2529
|
+
axis,
|
|
2530
|
+
parent
|
|
2531
|
+
}) => {
|
|
2532
|
+
if (!parent && typeof document === "undefined") {
|
|
2533
|
+
return 0;
|
|
2534
|
+
}
|
|
2535
|
+
const method = axis === "y" ? "scrollTop" : "scrollLeft";
|
|
2536
|
+
if (parent) {
|
|
2537
|
+
return parent[method];
|
|
2538
|
+
}
|
|
2539
|
+
const { body, documentElement } = document;
|
|
2540
|
+
return body[method] + documentElement[method];
|
|
2541
|
+
};
|
|
2542
|
+
|
|
2543
|
+
const easeInOutQuad = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
2544
|
+
|
|
2545
|
+
const getRelativePosition = ({
|
|
2546
|
+
axis,
|
|
2547
|
+
target,
|
|
2548
|
+
parent,
|
|
2549
|
+
alignment,
|
|
2550
|
+
offset,
|
|
2551
|
+
isList
|
|
2552
|
+
}) => {
|
|
2553
|
+
if (!target || !parent && typeof document === "undefined") {
|
|
2554
|
+
return 0;
|
|
2555
|
+
}
|
|
2556
|
+
const isCustomParent = !!parent;
|
|
2557
|
+
const parentElement = parent || document.body;
|
|
2558
|
+
const parentPosition = parentElement.getBoundingClientRect();
|
|
2559
|
+
const targetPosition = target.getBoundingClientRect();
|
|
2560
|
+
const getDiff = (property) => targetPosition[property] - parentPosition[property];
|
|
2561
|
+
if (axis === "y") {
|
|
2562
|
+
const diff = getDiff("top");
|
|
2563
|
+
if (diff === 0) {
|
|
2564
|
+
return 0;
|
|
2565
|
+
}
|
|
2566
|
+
if (alignment === "start") {
|
|
2567
|
+
const distance = diff - offset;
|
|
2568
|
+
const shouldScroll = distance <= targetPosition.height * (isList ? 0 : 1) || !isList;
|
|
2569
|
+
return shouldScroll ? distance : 0;
|
|
2570
|
+
}
|
|
2571
|
+
const parentHeight = isCustomParent ? parentPosition.height : window.innerHeight;
|
|
2572
|
+
if (alignment === "end") {
|
|
2573
|
+
const distance = diff + offset - parentHeight + targetPosition.height;
|
|
2574
|
+
const shouldScroll = distance >= -targetPosition.height * (isList ? 0 : 1) || !isList;
|
|
2575
|
+
return shouldScroll ? distance : 0;
|
|
2576
|
+
}
|
|
2577
|
+
if (alignment === "center") {
|
|
2578
|
+
return diff - parentHeight / 2 + targetPosition.height / 2;
|
|
2579
|
+
}
|
|
2580
|
+
return 0;
|
|
2581
|
+
}
|
|
2582
|
+
if (axis === "x") {
|
|
2583
|
+
const diff = getDiff("left");
|
|
2584
|
+
if (diff === 0) {
|
|
2585
|
+
return 0;
|
|
2586
|
+
}
|
|
2587
|
+
if (alignment === "start") {
|
|
2588
|
+
const distance = diff - offset;
|
|
2589
|
+
const shouldScroll = distance <= targetPosition.width || !isList;
|
|
2590
|
+
return shouldScroll ? distance : 0;
|
|
2591
|
+
}
|
|
2592
|
+
const parentWidth = isCustomParent ? parentPosition.width : window.innerWidth;
|
|
2593
|
+
if (alignment === "end") {
|
|
2594
|
+
const distance = diff + offset - parentWidth + targetPosition.width;
|
|
2595
|
+
const shouldScroll = distance >= -targetPosition.width || !isList;
|
|
2596
|
+
return shouldScroll ? distance : 0;
|
|
2597
|
+
}
|
|
2598
|
+
if (alignment === "center") {
|
|
2599
|
+
return diff - parentWidth / 2 + targetPosition.width / 2;
|
|
2600
|
+
}
|
|
2601
|
+
return 0;
|
|
2602
|
+
}
|
|
2603
|
+
return 0;
|
|
2604
|
+
};
|
|
2605
|
+
|
|
2606
|
+
function useScrollIntoView({
|
|
2607
|
+
duration = 1250,
|
|
2608
|
+
axis = "y",
|
|
2609
|
+
onScrollFinish,
|
|
2610
|
+
easing = easeInOutQuad,
|
|
2611
|
+
offset = 0,
|
|
2612
|
+
cancelable = true,
|
|
2613
|
+
isList = false,
|
|
2614
|
+
targetElement,
|
|
2615
|
+
scrollElement
|
|
2616
|
+
}) {
|
|
2617
|
+
const frameID = React.useRef(0);
|
|
2618
|
+
const startTime = React.useRef(0);
|
|
2619
|
+
const shouldStop = React.useRef(false);
|
|
2620
|
+
const reducedMotion = useReducedMotion(false);
|
|
2621
|
+
const cancel = () => {
|
|
2622
|
+
if (frameID.current) {
|
|
2623
|
+
cancelAnimationFrame(frameID.current);
|
|
2624
|
+
}
|
|
2625
|
+
};
|
|
2626
|
+
const scrollIntoView = useEvent(
|
|
2627
|
+
({ alignment = "start" } = {}) => {
|
|
2628
|
+
var _a;
|
|
2629
|
+
const element = getTargetElement(targetElement);
|
|
2630
|
+
const parent = getTargetElement(scrollElement) || getScrollParent(axis, element);
|
|
2631
|
+
shouldStop.current = false;
|
|
2632
|
+
if (frameID.current) {
|
|
2633
|
+
cancel();
|
|
2634
|
+
}
|
|
2635
|
+
const start = (_a = getScrollStart({ parent, axis })) != null ? _a : 0;
|
|
2636
|
+
const change = getRelativePosition({
|
|
2637
|
+
parent,
|
|
2638
|
+
target: element,
|
|
2639
|
+
axis,
|
|
2640
|
+
alignment,
|
|
2641
|
+
offset,
|
|
2642
|
+
isList
|
|
2643
|
+
}) - (parent ? 0 : start);
|
|
2644
|
+
const animateScroll = () => {
|
|
2645
|
+
if (startTime.current === 0) {
|
|
2646
|
+
startTime.current = performance.now();
|
|
2647
|
+
}
|
|
2648
|
+
const now = performance.now();
|
|
2649
|
+
const elapsed = now - startTime.current;
|
|
2650
|
+
const t = reducedMotion || duration === 0 ? 1 : elapsed / duration;
|
|
2651
|
+
const distance = start + change * easing(t);
|
|
2652
|
+
setScrollParam({
|
|
2653
|
+
parent,
|
|
2654
|
+
axis,
|
|
2655
|
+
distance
|
|
2656
|
+
});
|
|
2657
|
+
if (!shouldStop.current && t < 1) {
|
|
2658
|
+
frameID.current = requestAnimationFrame(animateScroll);
|
|
2659
|
+
} else {
|
|
2660
|
+
typeof onScrollFinish === "function" && onScrollFinish();
|
|
2661
|
+
startTime.current = 0;
|
|
2662
|
+
frameID.current = 0;
|
|
2663
|
+
cancel();
|
|
2664
|
+
}
|
|
2665
|
+
};
|
|
2666
|
+
animateScroll();
|
|
2667
|
+
}
|
|
2668
|
+
);
|
|
2669
|
+
const handleStop = () => {
|
|
2670
|
+
if (cancelable) {
|
|
2671
|
+
shouldStop.current = true;
|
|
2672
|
+
}
|
|
2673
|
+
};
|
|
2674
|
+
useEventListener("wheel", handleStop, null, { passive: true });
|
|
2675
|
+
useEventListener("touchmove", handleStop, null, { passive: true });
|
|
2676
|
+
React.useEffect(() => cancel, []);
|
|
2677
|
+
return {
|
|
2678
|
+
scrollIntoView,
|
|
2679
|
+
cancel
|
|
2680
|
+
};
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
const useSticky = ({
|
|
2684
|
+
targetElement,
|
|
2685
|
+
scrollElement,
|
|
2686
|
+
axis = "y",
|
|
2687
|
+
nav = 0
|
|
2688
|
+
}) => {
|
|
2689
|
+
const [isSticky, setSticky] = React.useState(false);
|
|
2690
|
+
const element = getTargetElement(targetElement);
|
|
2691
|
+
const scrollParent = getTargetElement(scrollElement) || getScrollParent(axis, element);
|
|
2692
|
+
const { run: scrollHandler } = useThrottleFn(() => {
|
|
2693
|
+
if (!element) {
|
|
2694
|
+
return;
|
|
2695
|
+
}
|
|
2696
|
+
const rect = element.getBoundingClientRect();
|
|
2697
|
+
if (axis === "y") {
|
|
2698
|
+
setSticky((rect == null ? void 0 : rect.top) <= nav);
|
|
2699
|
+
} else {
|
|
2700
|
+
setSticky((rect == null ? void 0 : rect.left) <= nav);
|
|
2701
|
+
}
|
|
2702
|
+
}, 50);
|
|
2703
|
+
React.useEffect(() => {
|
|
2704
|
+
if (!element || !scrollParent) {
|
|
2705
|
+
return;
|
|
2706
|
+
}
|
|
2707
|
+
scrollParent.addEventListener("scroll", scrollHandler);
|
|
2708
|
+
scrollHandler();
|
|
2709
|
+
return () => {
|
|
2710
|
+
scrollParent.removeEventListener("scroll", scrollHandler);
|
|
2711
|
+
};
|
|
2712
|
+
}, [axis, element, scrollHandler, scrollParent]);
|
|
2713
|
+
return [isSticky, setSticky];
|
|
2714
|
+
};
|
|
2715
|
+
|
|
2483
2716
|
exports.useActiveElement = useActiveElement;
|
|
2484
2717
|
exports.useClickOutside = useClickOutSide;
|
|
2485
2718
|
exports.useClipboard = useClipBorad;
|
|
@@ -2537,11 +2770,14 @@ exports.usePreferredDark = usePreferredDark;
|
|
|
2537
2770
|
exports.usePrevious = usePrevious;
|
|
2538
2771
|
exports.useRafFn = useRafFn;
|
|
2539
2772
|
exports.useRafState = useRafState;
|
|
2773
|
+
exports.useReducedMotion = useReducedMotion;
|
|
2540
2774
|
exports.useResizeObserver = useResizeObserver;
|
|
2541
2775
|
exports.useScriptTag = useScriptTag;
|
|
2542
2776
|
exports.useScroll = useScroll;
|
|
2777
|
+
exports.useScrollIntoView = useScrollIntoView;
|
|
2543
2778
|
exports.useScrollLock = useScrollLock;
|
|
2544
2779
|
exports.useSessionStorage = useSessionStorage;
|
|
2780
|
+
exports.useSticky = useSticky;
|
|
2545
2781
|
exports.useTextDirection = useTextDirection;
|
|
2546
2782
|
exports.useThrottle = useThrottle;
|
|
2547
2783
|
exports.useThrottleFn = useThrottleFn;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { MutableRefObject, useEffect, useLayoutEffect, Dispatch, SetStateAction, DependencyList, EffectCallback, RefObject, CSSProperties } from 'react';
|
|
2
|
+
import react__default, { MutableRefObject, useEffect, useLayoutEffect, Dispatch, SetStateAction, DependencyList, EffectCallback, RefObject, CSSProperties } from 'react';
|
|
3
3
|
import * as lodash from 'lodash';
|
|
4
4
|
|
|
5
5
|
declare function usePrevious<T>(state: T): T | undefined;
|
|
@@ -74,7 +74,8 @@ interface UseDarkOptions<T> {
|
|
|
74
74
|
*/
|
|
75
75
|
attribute?: string;
|
|
76
76
|
/**
|
|
77
|
-
* The initial value write the target element
|
|
77
|
+
* The initial value write the target element, defaultValue follow system prefer color
|
|
78
|
+
* must be set in SSR
|
|
78
79
|
* @default 'light | dark'
|
|
79
80
|
*/
|
|
80
81
|
initialValue?: T;
|
|
@@ -91,7 +92,7 @@ interface UseDarkOptions<T> {
|
|
|
91
92
|
*/
|
|
92
93
|
storage?: () => Storage;
|
|
93
94
|
}
|
|
94
|
-
declare function useDarkMode<T extends string | "light" | "dark">(options?: UseDarkOptions<T>): readonly [T | null,
|
|
95
|
+
declare function useDarkMode<T extends string | "light" | "dark">(options?: UseDarkOptions<T>): readonly [T | null, (latestDark: T) => void];
|
|
95
96
|
|
|
96
97
|
declare function useMediaQuery(query: string, defaultState?: boolean): boolean;
|
|
97
98
|
|
|
@@ -749,4 +750,46 @@ declare const _default$1: typeof useEffect | typeof react.useLayoutEffect;
|
|
|
749
750
|
|
|
750
751
|
declare const _default: typeof react.useEffect | typeof useLayoutEffect;
|
|
751
752
|
|
|
752
|
-
|
|
753
|
+
declare function useReducedMotion(defaultState?: boolean): boolean;
|
|
754
|
+
|
|
755
|
+
interface ScrollIntoViewAnimation {
|
|
756
|
+
/** target element alignment relatively to parent based on current axis */
|
|
757
|
+
alignment?: "start" | "end" | "center";
|
|
758
|
+
}
|
|
759
|
+
interface ScrollIntoViewParams {
|
|
760
|
+
/** callback fired after scroll */
|
|
761
|
+
onScrollFinish?: () => void;
|
|
762
|
+
/** duration of scroll in milliseconds */
|
|
763
|
+
duration?: number;
|
|
764
|
+
/** axis of scroll */
|
|
765
|
+
axis?: "x" | "y";
|
|
766
|
+
/** custom mathematical easing function */
|
|
767
|
+
easing?: (t: number) => number;
|
|
768
|
+
/** additional distance between nearest edge and element */
|
|
769
|
+
offset?: number;
|
|
770
|
+
/** indicator if animation may be interrupted by user scrolling */
|
|
771
|
+
cancelable?: boolean;
|
|
772
|
+
/** prevents content jumping in scrolling lists with multiple targets */
|
|
773
|
+
isList?: boolean;
|
|
774
|
+
targetElement: BasicTarget<HTMLElement>;
|
|
775
|
+
scrollElement?: BasicTarget<HTMLElement>;
|
|
776
|
+
}
|
|
777
|
+
declare function useScrollIntoView({ duration, axis, onScrollFinish, easing, offset, cancelable, isList, targetElement, scrollElement, }: ScrollIntoViewParams): {
|
|
778
|
+
scrollIntoView: ({ alignment }?: ScrollIntoViewAnimation) => void;
|
|
779
|
+
cancel: () => void;
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
interface UseStickyParams {
|
|
783
|
+
targetElement: BasicTarget<HTMLElement>;
|
|
784
|
+
scrollElement?: BasicTarget<HTMLElement>;
|
|
785
|
+
/** axis of scroll */
|
|
786
|
+
axis?: "x" | "y";
|
|
787
|
+
/** cover height or width */
|
|
788
|
+
nav: number;
|
|
789
|
+
}
|
|
790
|
+
declare const useSticky: ({ targetElement, scrollElement, axis, nav, }: UseStickyParams) => [
|
|
791
|
+
boolean,
|
|
792
|
+
react__default.Dispatch<react__default.SetStateAction<boolean>>
|
|
793
|
+
];
|
|
794
|
+
|
|
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 };
|
package/dist/index.mjs
CHANGED
|
@@ -123,7 +123,7 @@ function useStorage(key, defaults, getStorage, options = {}) {
|
|
|
123
123
|
}
|
|
124
124
|
const type = guessSerializerType(defaults);
|
|
125
125
|
const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
|
|
126
|
-
const getStoredValue = () => {
|
|
126
|
+
const getStoredValue = useEvent(() => {
|
|
127
127
|
try {
|
|
128
128
|
const raw = storage == null ? void 0 : storage.getItem(key);
|
|
129
129
|
if (raw !== void 0 && raw !== null) {
|
|
@@ -135,11 +135,11 @@ function useStorage(key, defaults, getStorage, options = {}) {
|
|
|
135
135
|
} catch (e) {
|
|
136
136
|
onError(e);
|
|
137
137
|
}
|
|
138
|
-
};
|
|
139
|
-
const [state, setState] = useState(
|
|
140
|
-
|
|
138
|
+
});
|
|
139
|
+
const [state, setState] = useState(defaults);
|
|
140
|
+
useEffect(() => {
|
|
141
141
|
setState(getStoredValue());
|
|
142
|
-
}, [key]);
|
|
142
|
+
}, [getStoredValue, key]);
|
|
143
143
|
const updateState = useEvent(
|
|
144
144
|
(valOrFunc) => {
|
|
145
145
|
const currentState = isFunction(valOrFunc) ? valOrFunc(state) : valOrFunc;
|
|
@@ -197,12 +197,12 @@ function useInterval(callback, delay, options) {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
const getInitialState = (query, defaultState) => {
|
|
200
|
-
if (isBrowser) {
|
|
201
|
-
return window.matchMedia(query).matches;
|
|
202
|
-
}
|
|
203
200
|
if (defaultState !== void 0) {
|
|
204
201
|
return defaultState;
|
|
205
202
|
}
|
|
203
|
+
if (isBrowser) {
|
|
204
|
+
return window.matchMedia(query).matches;
|
|
205
|
+
}
|
|
206
206
|
if (process.env.NODE_ENV !== "production") {
|
|
207
207
|
console.warn(
|
|
208
208
|
"`useMediaQuery` When server side rendering, defaultState should be defined to prevent a hydration mismatches."
|
|
@@ -254,21 +254,24 @@ function useDarkMode(options = {}) {
|
|
|
254
254
|
const prefersDarkMode = usePreferredDark(false);
|
|
255
255
|
const value = initialValue ? initialValue : prefersDarkMode ? "dark" : "light";
|
|
256
256
|
const [dark, setDark] = useStorage(storageKey, value, storage);
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
257
|
+
const wrappedSetDark = useCallback(
|
|
258
|
+
(latestDark) => {
|
|
259
|
+
const element = window == null ? void 0 : window.document.querySelector(selector);
|
|
260
|
+
if (!element) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (attribute === "class") {
|
|
264
|
+
latestDark && element.classList.add(latestDark);
|
|
265
|
+
dark && element.classList.remove(dark);
|
|
266
|
+
} else {
|
|
267
|
+
latestDark && element.setAttribute(attribute, latestDark);
|
|
268
|
+
dark && element.removeAttribute(attribute);
|
|
269
|
+
}
|
|
270
|
+
setDark(latestDark);
|
|
271
|
+
},
|
|
272
|
+
[attribute, dark, selector, setDark]
|
|
273
|
+
);
|
|
274
|
+
return [dark, wrappedSetDark];
|
|
272
275
|
}
|
|
273
276
|
|
|
274
277
|
function useMount(fn) {
|
|
@@ -536,8 +539,8 @@ function useDeepCompareEffect(effect, deps) {
|
|
|
536
539
|
|
|
537
540
|
function useEventListener(eventName, handler, element, options) {
|
|
538
541
|
const savedHandler = useLatest(handler);
|
|
542
|
+
const targetElement = getTargetElement(element, window);
|
|
539
543
|
useDeepCompareEffect(() => {
|
|
540
|
-
const targetElement = getTargetElement(element, window);
|
|
541
544
|
if (!(targetElement && targetElement.addEventListener)) {
|
|
542
545
|
return;
|
|
543
546
|
}
|
|
@@ -546,7 +549,7 @@ function useEventListener(eventName, handler, element, options) {
|
|
|
546
549
|
return () => {
|
|
547
550
|
off(targetElement, eventName, eventListener);
|
|
548
551
|
};
|
|
549
|
-
}, [eventName,
|
|
552
|
+
}, [eventName, targetElement, options, savedHandler]);
|
|
550
553
|
}
|
|
551
554
|
|
|
552
555
|
function useCounter(initialValue = 0, max = null, min = null) {
|
|
@@ -690,20 +693,20 @@ function useFavicon(href, baseUrl = "", rel = "icon") {
|
|
|
690
693
|
function useMutationObserver(callback, target, options = {}) {
|
|
691
694
|
const callbackRef = useLatest(callback);
|
|
692
695
|
const observerRef = useRef();
|
|
696
|
+
const element = getTargetElement(target);
|
|
693
697
|
const stop = useCallback(() => {
|
|
694
698
|
if (observerRef.current) {
|
|
695
699
|
observerRef.current.disconnect();
|
|
696
700
|
}
|
|
697
701
|
}, []);
|
|
698
702
|
useDeepCompareEffect(() => {
|
|
699
|
-
const element = getTargetElement(target);
|
|
700
703
|
if (!element) {
|
|
701
704
|
return;
|
|
702
705
|
}
|
|
703
706
|
observerRef.current = new MutationObserver(callbackRef.current);
|
|
704
707
|
observerRef.current.observe(element, options);
|
|
705
708
|
return stop;
|
|
706
|
-
}, [options]);
|
|
709
|
+
}, [options, element]);
|
|
707
710
|
return stop;
|
|
708
711
|
}
|
|
709
712
|
|
|
@@ -1488,13 +1491,13 @@ function useOrientation(initialState = defaultState) {
|
|
|
1488
1491
|
function useIntersectionObserver(target, callback, options = {}) {
|
|
1489
1492
|
const savedCallback = useLatest(callback);
|
|
1490
1493
|
const observerRef = useRef();
|
|
1494
|
+
const element = getTargetElement(target);
|
|
1491
1495
|
const stop = useCallback(() => {
|
|
1492
1496
|
if (observerRef.current) {
|
|
1493
1497
|
observerRef.current.disconnect();
|
|
1494
1498
|
}
|
|
1495
1499
|
}, []);
|
|
1496
1500
|
useDeepCompareEffect(() => {
|
|
1497
|
-
const element = getTargetElement(target);
|
|
1498
1501
|
if (!element) {
|
|
1499
1502
|
return;
|
|
1500
1503
|
}
|
|
@@ -1504,7 +1507,7 @@ function useIntersectionObserver(target, callback, options = {}) {
|
|
|
1504
1507
|
);
|
|
1505
1508
|
observerRef.current.observe(element);
|
|
1506
1509
|
return stop;
|
|
1507
|
-
}, [options]);
|
|
1510
|
+
}, [options, element]);
|
|
1508
1511
|
return stop;
|
|
1509
1512
|
}
|
|
1510
1513
|
|
|
@@ -1544,20 +1547,20 @@ function useDocumentVisibility() {
|
|
|
1544
1547
|
function useResizeObserver(target, callback, options = {}) {
|
|
1545
1548
|
const savedCallback = useLatest(callback);
|
|
1546
1549
|
const observerRef = useRef();
|
|
1550
|
+
const element = getTargetElement(target);
|
|
1547
1551
|
const stop = useCallback(() => {
|
|
1548
1552
|
if (observerRef.current) {
|
|
1549
1553
|
observerRef.current.disconnect();
|
|
1550
1554
|
}
|
|
1551
1555
|
}, []);
|
|
1552
1556
|
useDeepCompareEffect(() => {
|
|
1553
|
-
const element = getTargetElement(target);
|
|
1554
1557
|
if (!element) {
|
|
1555
1558
|
return;
|
|
1556
1559
|
}
|
|
1557
1560
|
observerRef.current = new ResizeObserver(savedCallback.current);
|
|
1558
1561
|
observerRef.current.observe(element, options);
|
|
1559
1562
|
return stop;
|
|
1560
|
-
}, [options]);
|
|
1563
|
+
}, [options, element]);
|
|
1561
1564
|
return stop;
|
|
1562
1565
|
}
|
|
1563
1566
|
|
|
@@ -1782,11 +1785,11 @@ function useInfiniteScroll(target, onLoadMore, options = {}) {
|
|
|
1782
1785
|
[direction]: (_b = options.distance) != null ? _b : 0
|
|
1783
1786
|
}, options.offset)
|
|
1784
1787
|
}));
|
|
1788
|
+
const element = getTargetElement(target);
|
|
1785
1789
|
const di = state[3][direction];
|
|
1786
1790
|
useUpdateEffect(() => {
|
|
1787
1791
|
const fn = () => __async$1(this, null, function* () {
|
|
1788
1792
|
var _a2, _b2;
|
|
1789
|
-
const element = getTargetElement(target);
|
|
1790
1793
|
const previous = {
|
|
1791
1794
|
height: (_a2 = element == null ? void 0 : element.scrollHeight) != null ? _a2 : 0,
|
|
1792
1795
|
width: (_b2 = element == null ? void 0 : element.scrollWidth) != null ? _b2 : 0
|
|
@@ -1800,7 +1803,7 @@ function useInfiniteScroll(target, onLoadMore, options = {}) {
|
|
|
1800
1803
|
}
|
|
1801
1804
|
});
|
|
1802
1805
|
fn();
|
|
1803
|
-
}, [di, options.preserveScrollPosition]);
|
|
1806
|
+
}, [di, options.preserveScrollPosition, element]);
|
|
1804
1807
|
}
|
|
1805
1808
|
|
|
1806
1809
|
const defaultEvents = [
|
|
@@ -1837,6 +1840,7 @@ function useMousePressed(target, options = {}) {
|
|
|
1837
1840
|
const { touch = true, drag = true, initialValue = false } = options;
|
|
1838
1841
|
const [pressed, setPressed] = useState(initialValue);
|
|
1839
1842
|
const [sourceType, setSourceType] = useState(null);
|
|
1843
|
+
const element = getTargetElement(target);
|
|
1840
1844
|
const onPressed = useCallback(
|
|
1841
1845
|
(srcType) => () => {
|
|
1842
1846
|
setPressed(true);
|
|
@@ -1851,8 +1855,7 @@ function useMousePressed(target, options = {}) {
|
|
|
1851
1855
|
useEventListener("mousedown", onPressed("mouse"), target, { passive: true });
|
|
1852
1856
|
useEventListener("mouseleave", onReleased, () => window, { passive: true });
|
|
1853
1857
|
useEventListener("mouseup", onReleased, () => window, { passive: true });
|
|
1854
|
-
|
|
1855
|
-
const element = getTargetElement(target);
|
|
1858
|
+
useEffect(() => {
|
|
1856
1859
|
if (drag) {
|
|
1857
1860
|
element == null ? void 0 : element.addEventListener("dragstart", onPressed("mouse"), {
|
|
1858
1861
|
passive: true
|
|
@@ -1887,7 +1890,7 @@ function useMousePressed(target, options = {}) {
|
|
|
1887
1890
|
element == null ? void 0 : element.removeEventListener("touchcancel", onReleased);
|
|
1888
1891
|
}
|
|
1889
1892
|
};
|
|
1890
|
-
});
|
|
1893
|
+
}, [drag, onPressed, onReleased, element, touch]);
|
|
1891
1894
|
return [pressed, sourceType];
|
|
1892
1895
|
}
|
|
1893
1896
|
|
|
@@ -1904,28 +1907,25 @@ function preventDefault(rawEvent) {
|
|
|
1904
1907
|
function useScrollLock(target, initialState = false) {
|
|
1905
1908
|
const [locked, setLocked] = useState(initialState);
|
|
1906
1909
|
const initialOverflowRef = useRef("scroll");
|
|
1907
|
-
|
|
1908
|
-
|
|
1910
|
+
const element = getTargetElement(target);
|
|
1911
|
+
useEffect(() => {
|
|
1909
1912
|
if (element) {
|
|
1910
1913
|
initialOverflowRef.current = element.style.overflow;
|
|
1911
1914
|
if (locked) {
|
|
1912
1915
|
element.style.overflow = "hidden";
|
|
1913
1916
|
}
|
|
1914
1917
|
}
|
|
1915
|
-
});
|
|
1918
|
+
}, [locked, element]);
|
|
1916
1919
|
const lock = useEvent(() => {
|
|
1917
|
-
const element = getTargetElement(target);
|
|
1918
1920
|
if (!element || locked) {
|
|
1919
1921
|
return;
|
|
1920
1922
|
}
|
|
1921
1923
|
if (isIOS) {
|
|
1922
1924
|
element.addEventListener("touchmove", preventDefault, { passive: false });
|
|
1923
1925
|
}
|
|
1924
|
-
element.style.overflow = "hidden";
|
|
1925
1926
|
setLocked(true);
|
|
1926
1927
|
});
|
|
1927
1928
|
const unlock = useEvent(() => {
|
|
1928
|
-
const element = getTargetElement(target);
|
|
1929
1929
|
if (!element || !locked) {
|
|
1930
1930
|
return;
|
|
1931
1931
|
}
|
|
@@ -2472,4 +2472,237 @@ var useOnceEffect = createOnceEffect(useEffect);
|
|
|
2472
2472
|
|
|
2473
2473
|
var useOnceLayoutEffect = createOnceEffect(useLayoutEffect);
|
|
2474
2474
|
|
|
2475
|
-
|
|
2475
|
+
function useReducedMotion(defaultState) {
|
|
2476
|
+
return useMediaQuery("(prefers-reduced-motion: reduce)", defaultState);
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
const setScrollParam = ({
|
|
2480
|
+
axis,
|
|
2481
|
+
parent,
|
|
2482
|
+
distance
|
|
2483
|
+
}) => {
|
|
2484
|
+
if (!parent && typeof document === "undefined") {
|
|
2485
|
+
return;
|
|
2486
|
+
}
|
|
2487
|
+
const method = axis === "y" ? "scrollTop" : "scrollLeft";
|
|
2488
|
+
if (parent) {
|
|
2489
|
+
parent[method] = distance;
|
|
2490
|
+
} else {
|
|
2491
|
+
const { body, documentElement } = document;
|
|
2492
|
+
body[method] = distance;
|
|
2493
|
+
documentElement[method] = distance;
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
const isScrollElement = (axis, node) => {
|
|
2497
|
+
if (!node) {
|
|
2498
|
+
return false;
|
|
2499
|
+
}
|
|
2500
|
+
const AXIS = axis === "x" ? "X" : "Y";
|
|
2501
|
+
return getComputedStyle(node)[`overflow${AXIS}`] === "auto" || getComputedStyle(node)[`overflow${AXIS}`] === "scroll";
|
|
2502
|
+
};
|
|
2503
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2504
|
+
const getScrollParent = (axis, node) => {
|
|
2505
|
+
if (!node || !node.parentElement) {
|
|
2506
|
+
return null;
|
|
2507
|
+
}
|
|
2508
|
+
if (cache.has(node)) {
|
|
2509
|
+
return cache.get(node) || null;
|
|
2510
|
+
}
|
|
2511
|
+
let parent = node.parentElement;
|
|
2512
|
+
while (parent && !isScrollElement(axis, parent)) {
|
|
2513
|
+
parent = parent.parentElement;
|
|
2514
|
+
}
|
|
2515
|
+
if (parent) {
|
|
2516
|
+
cache.set(node, parent);
|
|
2517
|
+
}
|
|
2518
|
+
return parent;
|
|
2519
|
+
};
|
|
2520
|
+
const getScrollStart = ({
|
|
2521
|
+
axis,
|
|
2522
|
+
parent
|
|
2523
|
+
}) => {
|
|
2524
|
+
if (!parent && typeof document === "undefined") {
|
|
2525
|
+
return 0;
|
|
2526
|
+
}
|
|
2527
|
+
const method = axis === "y" ? "scrollTop" : "scrollLeft";
|
|
2528
|
+
if (parent) {
|
|
2529
|
+
return parent[method];
|
|
2530
|
+
}
|
|
2531
|
+
const { body, documentElement } = document;
|
|
2532
|
+
return body[method] + documentElement[method];
|
|
2533
|
+
};
|
|
2534
|
+
|
|
2535
|
+
const easeInOutQuad = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
2536
|
+
|
|
2537
|
+
const getRelativePosition = ({
|
|
2538
|
+
axis,
|
|
2539
|
+
target,
|
|
2540
|
+
parent,
|
|
2541
|
+
alignment,
|
|
2542
|
+
offset,
|
|
2543
|
+
isList
|
|
2544
|
+
}) => {
|
|
2545
|
+
if (!target || !parent && typeof document === "undefined") {
|
|
2546
|
+
return 0;
|
|
2547
|
+
}
|
|
2548
|
+
const isCustomParent = !!parent;
|
|
2549
|
+
const parentElement = parent || document.body;
|
|
2550
|
+
const parentPosition = parentElement.getBoundingClientRect();
|
|
2551
|
+
const targetPosition = target.getBoundingClientRect();
|
|
2552
|
+
const getDiff = (property) => targetPosition[property] - parentPosition[property];
|
|
2553
|
+
if (axis === "y") {
|
|
2554
|
+
const diff = getDiff("top");
|
|
2555
|
+
if (diff === 0) {
|
|
2556
|
+
return 0;
|
|
2557
|
+
}
|
|
2558
|
+
if (alignment === "start") {
|
|
2559
|
+
const distance = diff - offset;
|
|
2560
|
+
const shouldScroll = distance <= targetPosition.height * (isList ? 0 : 1) || !isList;
|
|
2561
|
+
return shouldScroll ? distance : 0;
|
|
2562
|
+
}
|
|
2563
|
+
const parentHeight = isCustomParent ? parentPosition.height : window.innerHeight;
|
|
2564
|
+
if (alignment === "end") {
|
|
2565
|
+
const distance = diff + offset - parentHeight + targetPosition.height;
|
|
2566
|
+
const shouldScroll = distance >= -targetPosition.height * (isList ? 0 : 1) || !isList;
|
|
2567
|
+
return shouldScroll ? distance : 0;
|
|
2568
|
+
}
|
|
2569
|
+
if (alignment === "center") {
|
|
2570
|
+
return diff - parentHeight / 2 + targetPosition.height / 2;
|
|
2571
|
+
}
|
|
2572
|
+
return 0;
|
|
2573
|
+
}
|
|
2574
|
+
if (axis === "x") {
|
|
2575
|
+
const diff = getDiff("left");
|
|
2576
|
+
if (diff === 0) {
|
|
2577
|
+
return 0;
|
|
2578
|
+
}
|
|
2579
|
+
if (alignment === "start") {
|
|
2580
|
+
const distance = diff - offset;
|
|
2581
|
+
const shouldScroll = distance <= targetPosition.width || !isList;
|
|
2582
|
+
return shouldScroll ? distance : 0;
|
|
2583
|
+
}
|
|
2584
|
+
const parentWidth = isCustomParent ? parentPosition.width : window.innerWidth;
|
|
2585
|
+
if (alignment === "end") {
|
|
2586
|
+
const distance = diff + offset - parentWidth + targetPosition.width;
|
|
2587
|
+
const shouldScroll = distance >= -targetPosition.width || !isList;
|
|
2588
|
+
return shouldScroll ? distance : 0;
|
|
2589
|
+
}
|
|
2590
|
+
if (alignment === "center") {
|
|
2591
|
+
return diff - parentWidth / 2 + targetPosition.width / 2;
|
|
2592
|
+
}
|
|
2593
|
+
return 0;
|
|
2594
|
+
}
|
|
2595
|
+
return 0;
|
|
2596
|
+
};
|
|
2597
|
+
|
|
2598
|
+
function useScrollIntoView({
|
|
2599
|
+
duration = 1250,
|
|
2600
|
+
axis = "y",
|
|
2601
|
+
onScrollFinish,
|
|
2602
|
+
easing = easeInOutQuad,
|
|
2603
|
+
offset = 0,
|
|
2604
|
+
cancelable = true,
|
|
2605
|
+
isList = false,
|
|
2606
|
+
targetElement,
|
|
2607
|
+
scrollElement
|
|
2608
|
+
}) {
|
|
2609
|
+
const frameID = useRef(0);
|
|
2610
|
+
const startTime = useRef(0);
|
|
2611
|
+
const shouldStop = useRef(false);
|
|
2612
|
+
const reducedMotion = useReducedMotion(false);
|
|
2613
|
+
const cancel = () => {
|
|
2614
|
+
if (frameID.current) {
|
|
2615
|
+
cancelAnimationFrame(frameID.current);
|
|
2616
|
+
}
|
|
2617
|
+
};
|
|
2618
|
+
const scrollIntoView = useEvent(
|
|
2619
|
+
({ alignment = "start" } = {}) => {
|
|
2620
|
+
var _a;
|
|
2621
|
+
const element = getTargetElement(targetElement);
|
|
2622
|
+
const parent = getTargetElement(scrollElement) || getScrollParent(axis, element);
|
|
2623
|
+
shouldStop.current = false;
|
|
2624
|
+
if (frameID.current) {
|
|
2625
|
+
cancel();
|
|
2626
|
+
}
|
|
2627
|
+
const start = (_a = getScrollStart({ parent, axis })) != null ? _a : 0;
|
|
2628
|
+
const change = getRelativePosition({
|
|
2629
|
+
parent,
|
|
2630
|
+
target: element,
|
|
2631
|
+
axis,
|
|
2632
|
+
alignment,
|
|
2633
|
+
offset,
|
|
2634
|
+
isList
|
|
2635
|
+
}) - (parent ? 0 : start);
|
|
2636
|
+
const animateScroll = () => {
|
|
2637
|
+
if (startTime.current === 0) {
|
|
2638
|
+
startTime.current = performance.now();
|
|
2639
|
+
}
|
|
2640
|
+
const now = performance.now();
|
|
2641
|
+
const elapsed = now - startTime.current;
|
|
2642
|
+
const t = reducedMotion || duration === 0 ? 1 : elapsed / duration;
|
|
2643
|
+
const distance = start + change * easing(t);
|
|
2644
|
+
setScrollParam({
|
|
2645
|
+
parent,
|
|
2646
|
+
axis,
|
|
2647
|
+
distance
|
|
2648
|
+
});
|
|
2649
|
+
if (!shouldStop.current && t < 1) {
|
|
2650
|
+
frameID.current = requestAnimationFrame(animateScroll);
|
|
2651
|
+
} else {
|
|
2652
|
+
typeof onScrollFinish === "function" && onScrollFinish();
|
|
2653
|
+
startTime.current = 0;
|
|
2654
|
+
frameID.current = 0;
|
|
2655
|
+
cancel();
|
|
2656
|
+
}
|
|
2657
|
+
};
|
|
2658
|
+
animateScroll();
|
|
2659
|
+
}
|
|
2660
|
+
);
|
|
2661
|
+
const handleStop = () => {
|
|
2662
|
+
if (cancelable) {
|
|
2663
|
+
shouldStop.current = true;
|
|
2664
|
+
}
|
|
2665
|
+
};
|
|
2666
|
+
useEventListener("wheel", handleStop, null, { passive: true });
|
|
2667
|
+
useEventListener("touchmove", handleStop, null, { passive: true });
|
|
2668
|
+
useEffect(() => cancel, []);
|
|
2669
|
+
return {
|
|
2670
|
+
scrollIntoView,
|
|
2671
|
+
cancel
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
const useSticky = ({
|
|
2676
|
+
targetElement,
|
|
2677
|
+
scrollElement,
|
|
2678
|
+
axis = "y",
|
|
2679
|
+
nav = 0
|
|
2680
|
+
}) => {
|
|
2681
|
+
const [isSticky, setSticky] = useState(false);
|
|
2682
|
+
const element = getTargetElement(targetElement);
|
|
2683
|
+
const scrollParent = getTargetElement(scrollElement) || getScrollParent(axis, element);
|
|
2684
|
+
const { run: scrollHandler } = useThrottleFn(() => {
|
|
2685
|
+
if (!element) {
|
|
2686
|
+
return;
|
|
2687
|
+
}
|
|
2688
|
+
const rect = element.getBoundingClientRect();
|
|
2689
|
+
if (axis === "y") {
|
|
2690
|
+
setSticky((rect == null ? void 0 : rect.top) <= nav);
|
|
2691
|
+
} else {
|
|
2692
|
+
setSticky((rect == null ? void 0 : rect.left) <= nav);
|
|
2693
|
+
}
|
|
2694
|
+
}, 50);
|
|
2695
|
+
useEffect(() => {
|
|
2696
|
+
if (!element || !scrollParent) {
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
scrollParent.addEventListener("scroll", scrollHandler);
|
|
2700
|
+
scrollHandler();
|
|
2701
|
+
return () => {
|
|
2702
|
+
scrollParent.removeEventListener("scroll", scrollHandler);
|
|
2703
|
+
};
|
|
2704
|
+
}, [axis, element, scrollHandler, scrollParent]);
|
|
2705
|
+
return [isSticky, setSticky];
|
|
2706
|
+
};
|
|
2707
|
+
|
|
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 };
|