react-simplikit 0.0.53 → 0.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/CHANGELOG.md +126 -0
- package/README.md +2 -42
- package/dist/hooks/useAsyncEffect/useAsyncEffect.cjs +1 -0
- package/dist/hooks/useAsyncEffect/useAsyncEffect.mjs +1 -0
- package/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.cjs +1 -0
- package/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.mjs +1 -0
- package/dist/hooks/useConditionalEffect/useConditionalEffect.cjs +1 -0
- package/dist/hooks/useConditionalEffect/useConditionalEffect.mjs +1 -0
- package/dist/hooks/useDebouncedCallback/useDebouncedCallback.cjs +24 -6
- package/dist/hooks/useDebouncedCallback/useDebouncedCallback.d.cts +17 -7
- package/dist/hooks/useDebouncedCallback/useDebouncedCallback.d.mts +17 -7
- package/dist/hooks/useDebouncedCallback/useDebouncedCallback.mjs +24 -6
- package/dist/hooks/useDoubleClick/useDoubleClick.cjs +0 -4
- package/dist/hooks/useDoubleClick/useDoubleClick.d.cts +0 -4
- package/dist/hooks/useDoubleClick/useDoubleClick.d.mts +0 -4
- package/dist/hooks/useDoubleClick/useDoubleClick.mjs +0 -4
- package/dist/hooks/useGeolocation/useGeolocation.cjs +0 -4
- package/dist/hooks/useGeolocation/useGeolocation.d.cts +0 -4
- package/dist/hooks/useGeolocation/useGeolocation.d.mts +0 -4
- package/dist/hooks/useGeolocation/useGeolocation.mjs +0 -4
- package/dist/hooks/useImpressionRef/useImpressionRef.cjs +7 -5
- package/dist/hooks/useImpressionRef/useImpressionRef.d.cts +0 -4
- package/dist/hooks/useImpressionRef/useImpressionRef.d.mts +0 -4
- package/dist/hooks/useImpressionRef/useImpressionRef.mjs +7 -5
- package/dist/hooks/useInputState/useInputState.cjs +9 -3
- package/dist/hooks/useInputState/useInputState.d.cts +11 -4
- package/dist/hooks/useInputState/useInputState.d.mts +11 -4
- package/dist/hooks/useInputState/useInputState.mjs +9 -3
- package/dist/hooks/useIntersectionObserver/useIntersectionObserver.cjs +1 -5
- package/dist/hooks/useIntersectionObserver/useIntersectionObserver.d.cts +1 -5
- package/dist/hooks/useIntersectionObserver/useIntersectionObserver.d.mts +1 -5
- package/dist/hooks/useIntersectionObserver/useIntersectionObserver.mjs +1 -5
- package/dist/hooks/useList/useList.cjs +11 -8
- package/dist/hooks/useList/useList.d.cts +12 -9
- package/dist/hooks/useList/useList.d.mts +12 -9
- package/dist/hooks/useList/useList.mjs +11 -8
- package/dist/hooks/useLoading/useLoading.cjs +3 -5
- package/dist/hooks/useLoading/useLoading.d.cts +2 -5
- package/dist/hooks/useLoading/useLoading.d.mts +2 -5
- package/dist/hooks/useLoading/useLoading.mjs +3 -5
- package/dist/hooks/useLongPress/useLongPress.cjs +0 -4
- package/dist/hooks/useLongPress/useLongPress.d.cts +0 -4
- package/dist/hooks/useLongPress/useLongPress.d.mts +0 -4
- package/dist/hooks/useLongPress/useLongPress.mjs +0 -4
- package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.cjs +0 -4
- package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.d.cts +0 -4
- package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.d.mts +0 -4
- package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.mjs +0 -4
- package/dist/hooks/usePreservedReference/usePreservedReference.cjs +1 -0
- package/dist/hooks/usePreservedReference/usePreservedReference.mjs +1 -0
- package/dist/hooks/useRefEffect/useRefEffect.cjs +1 -0
- package/dist/hooks/useRefEffect/useRefEffect.mjs +1 -0
- package/dist/hooks/useSet/useSet.cjs +11 -2
- package/dist/hooks/useSet/useSet.d.cts +11 -2
- package/dist/hooks/useSet/useSet.d.mts +11 -2
- package/dist/hooks/useSet/useSet.mjs +11 -2
- package/dist/hooks/useStorageState/useStorageState.cjs +1 -0
- package/dist/hooks/useStorageState/useStorageState.d.cts +0 -4
- package/dist/hooks/useStorageState/useStorageState.d.mts +0 -4
- package/dist/hooks/useStorageState/useStorageState.mjs +1 -0
- package/dist/hooks/useThrottledCallback/useThrottledCallback.cjs +16 -9
- package/dist/hooks/useThrottledCallback/useThrottledCallback.d.cts +18 -11
- package/dist/hooks/useThrottledCallback/useThrottledCallback.d.mts +18 -11
- package/dist/hooks/useThrottledCallback/useThrottledCallback.mjs +16 -9
- package/dist/hooks/useVisibilityEvent/useVisibilityEvent.cjs +2 -4
- package/dist/hooks/useVisibilityEvent/useVisibilityEvent.d.cts +2 -4
- package/dist/hooks/useVisibilityEvent/useVisibilityEvent.d.mts +2 -4
- package/dist/hooks/useVisibilityEvent/useVisibilityEvent.mjs +2 -4
- package/dist/index.cjs +34 -0
- package/dist/index.d.cts +19 -1
- package/dist/index.d.mts +19 -1
- package/dist/index.mjs +18 -1
- package/dist/mobile/hooks/useAvoidKeyboard/index.d.cts +3 -0
- package/dist/mobile/hooks/useAvoidKeyboard/index.d.mts +3 -0
- package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.cjs +75 -0
- package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.d.cts +89 -0
- package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.d.mts +89 -0
- package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.mjs +75 -0
- package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.cjs +47 -0
- package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.d.cts +37 -0
- package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.d.mts +37 -0
- package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.mjs +47 -0
- package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.cjs +41 -0
- package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.d.cts +41 -0
- package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.d.mts +41 -0
- package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.mjs +41 -0
- package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.cjs +88 -0
- package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.d.cts +77 -0
- package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.d.mts +77 -0
- package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.mjs +88 -0
- package/dist/mobile/hooks/usePageVisibility/usePageVisibility.cjs +75 -0
- package/dist/mobile/hooks/usePageVisibility/usePageVisibility.d.cts +64 -0
- package/dist/mobile/hooks/usePageVisibility/usePageVisibility.d.mts +64 -0
- package/dist/mobile/hooks/usePageVisibility/usePageVisibility.mjs +75 -0
- package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.cjs +74 -0
- package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.d.cts +55 -0
- package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.d.mts +55 -0
- package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.mjs +74 -0
- package/dist/mobile/hooks/useScrollDirection/useScrollDirection.cjs +79 -0
- package/dist/mobile/hooks/useScrollDirection/useScrollDirection.d.cts +40 -0
- package/dist/mobile/hooks/useScrollDirection/useScrollDirection.d.mts +40 -0
- package/dist/mobile/hooks/useScrollDirection/useScrollDirection.mjs +79 -0
- package/dist/mobile/hooks/useVisualViewport/useVisualViewport.cjs +77 -0
- package/dist/mobile/hooks/useVisualViewport/useVisualViewport.d.cts +89 -0
- package/dist/mobile/hooks/useVisualViewport/useVisualViewport.d.mts +89 -0
- package/dist/mobile/hooks/useVisualViewport/useVisualViewport.mjs +77 -0
- package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.cjs +55 -0
- package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.d.cts +22 -0
- package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.d.mts +22 -0
- package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.mjs +55 -0
- package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.cjs +49 -0
- package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.d.cts +23 -0
- package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.d.mts +23 -0
- package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.mjs +49 -0
- package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.cjs +35 -0
- package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.d.cts +28 -0
- package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.d.mts +28 -0
- package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.mjs +35 -0
- package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.cjs +58 -0
- package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.d.cts +44 -0
- package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.d.mts +44 -0
- package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.mjs +58 -0
- package/dist/mobile/utils/isAndroid/isAndroid.cjs +32 -0
- package/dist/mobile/utils/isAndroid/isAndroid.d.cts +27 -0
- package/dist/mobile/utils/isAndroid/isAndroid.d.mts +27 -0
- package/dist/mobile/utils/isAndroid/isAndroid.mjs +32 -0
- package/dist/mobile/utils/isIOS/isIOS.cjs +37 -0
- package/dist/mobile/utils/isIOS/isIOS.d.cts +30 -0
- package/dist/mobile/utils/isIOS/isIOS.d.mts +30 -0
- package/dist/mobile/utils/isIOS/isIOS.mjs +37 -0
- package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.cjs +28 -0
- package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.d.cts +25 -0
- package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.d.mts +25 -0
- package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.mjs +28 -0
- package/dist/mobile/utils/isServer/isServer.cjs +24 -0
- package/dist/mobile/utils/isServer/isServer.d.cts +22 -0
- package/dist/mobile/utils/isServer/isServer.d.mts +22 -0
- package/dist/mobile/utils/isServer/isServer.mjs +24 -0
- package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.cjs +71 -0
- package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.d.cts +64 -0
- package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.d.mts +64 -0
- package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.mjs +71 -0
- package/dist/utils/buildContext/buildContext.cjs +1 -0
- package/dist/utils/buildContext/buildContext.mjs +1 -0
- package/dist/utils/mergeProps/mergeProps.cjs +1 -1
- package/dist/utils/mergeProps/mergeProps.d.cts +1 -1
- package/dist/utils/mergeProps/mergeProps.d.mts +1 -1
- package/dist/utils/mergeProps/mergeProps.mjs +1 -1
- package/dist/utils/mergeRefs/mergeRefs.cjs +1 -1
- package/dist/utils/mergeRefs/mergeRefs.d.cts +1 -1
- package/dist/utils/mergeRefs/mergeRefs.d.mts +1 -1
- package/dist/utils/mergeRefs/mergeRefs.mjs +1 -1
- package/package.json +22 -10
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
import { SafeAreaInset } from "../../utils/getSafeAreaInset/getSafeAreaInset.mjs";
|
|
3
|
+
//#region src/mobile/hooks/useSafeAreaInset/useSafeAreaInset.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* `useSafeAreaInset` is a React hook that tracks safe area inset changes.
|
|
7
|
+
* It returns the safe area insets that automatically update when the screen
|
|
8
|
+
* orientation changes (e.g., portrait to landscape).
|
|
9
|
+
*
|
|
10
|
+
* Safe area insets account for device-specific UI elements:
|
|
11
|
+
* - **top**: Notch, Dynamic Island, or status bar
|
|
12
|
+
* - **bottom**: Home indicator on Face ID devices
|
|
13
|
+
* - **left/right**: Rounded corners in landscape mode
|
|
14
|
+
*
|
|
15
|
+
* @returns {SafeAreaInset} An object containing safe area insets for all four sides.
|
|
16
|
+
* - top `number` - Top safe area inset in pixels. Accounts for the notch, Dynamic Island, or status bar;
|
|
17
|
+
* - bottom `number` - Bottom safe area inset in pixels. Accounts for the home indicator on Face ID devices;
|
|
18
|
+
* - left `number` - Left safe area inset in pixels. Accounts for rounded corners in landscape mode;
|
|
19
|
+
* - right `number` - Right safe area inset in pixels. Accounts for rounded corners in landscape mode;
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* function MyComponent() {
|
|
23
|
+
* const safeArea = useSafeAreaInset();
|
|
24
|
+
*
|
|
25
|
+
* return (
|
|
26
|
+
* <div style={{
|
|
27
|
+
* paddingTop: safeArea.top,
|
|
28
|
+
* paddingBottom: safeArea.bottom,
|
|
29
|
+
* paddingLeft: safeArea.left,
|
|
30
|
+
* paddingRight: safeArea.right,
|
|
31
|
+
* }}>
|
|
32
|
+
* Content that respects safe areas
|
|
33
|
+
* </div>
|
|
34
|
+
* );
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Automatically updates when screen rotates
|
|
39
|
+
* function RotationAwareHeader() {
|
|
40
|
+
* const { top, left, right } = useSafeAreaInset();
|
|
41
|
+
*
|
|
42
|
+
* return (
|
|
43
|
+
* <header style={{
|
|
44
|
+
* paddingTop: top,
|
|
45
|
+
* paddingLeft: left,
|
|
46
|
+
* paddingRight: right,
|
|
47
|
+
* }}>
|
|
48
|
+
* Header content
|
|
49
|
+
* </header>
|
|
50
|
+
* );
|
|
51
|
+
* }
|
|
52
|
+
*/
|
|
53
|
+
declare function useSafeAreaInset(): SafeAreaInset;
|
|
54
|
+
//#endregion
|
|
55
|
+
export { useSafeAreaInset };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { isServer } from "../../utils/isServer/isServer.mjs";
|
|
3
|
+
import { getSafeAreaInset } from "../../utils/getSafeAreaInset/getSafeAreaInset.mjs";
|
|
4
|
+
import { startTransition, useCallback, useEffect, useState } from "react";
|
|
5
|
+
//#region src/mobile/hooks/useSafeAreaInset/useSafeAreaInset.ts
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* `useSafeAreaInset` is a React hook that tracks safe area inset changes.
|
|
9
|
+
* It returns the safe area insets that automatically update when the screen
|
|
10
|
+
* orientation changes (e.g., portrait to landscape).
|
|
11
|
+
*
|
|
12
|
+
* Safe area insets account for device-specific UI elements:
|
|
13
|
+
* - **top**: Notch, Dynamic Island, or status bar
|
|
14
|
+
* - **bottom**: Home indicator on Face ID devices
|
|
15
|
+
* - **left/right**: Rounded corners in landscape mode
|
|
16
|
+
*
|
|
17
|
+
* @returns {SafeAreaInset} An object containing safe area insets for all four sides.
|
|
18
|
+
* - top `number` - Top safe area inset in pixels. Accounts for the notch, Dynamic Island, or status bar;
|
|
19
|
+
* - bottom `number` - Bottom safe area inset in pixels. Accounts for the home indicator on Face ID devices;
|
|
20
|
+
* - left `number` - Left safe area inset in pixels. Accounts for rounded corners in landscape mode;
|
|
21
|
+
* - right `number` - Right safe area inset in pixels. Accounts for rounded corners in landscape mode;
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* function MyComponent() {
|
|
25
|
+
* const safeArea = useSafeAreaInset();
|
|
26
|
+
*
|
|
27
|
+
* return (
|
|
28
|
+
* <div style={{
|
|
29
|
+
* paddingTop: safeArea.top,
|
|
30
|
+
* paddingBottom: safeArea.bottom,
|
|
31
|
+
* paddingLeft: safeArea.left,
|
|
32
|
+
* paddingRight: safeArea.right,
|
|
33
|
+
* }}>
|
|
34
|
+
* Content that respects safe areas
|
|
35
|
+
* </div>
|
|
36
|
+
* );
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Automatically updates when screen rotates
|
|
41
|
+
* function RotationAwareHeader() {
|
|
42
|
+
* const { top, left, right } = useSafeAreaInset();
|
|
43
|
+
*
|
|
44
|
+
* return (
|
|
45
|
+
* <header style={{
|
|
46
|
+
* paddingTop: top,
|
|
47
|
+
* paddingLeft: left,
|
|
48
|
+
* paddingRight: right,
|
|
49
|
+
* }}>
|
|
50
|
+
* Header content
|
|
51
|
+
* </header>
|
|
52
|
+
* );
|
|
53
|
+
* }
|
|
54
|
+
*/
|
|
55
|
+
function useSafeAreaInset() {
|
|
56
|
+
const [inset, setInset] = useState(() => getSafeAreaInset());
|
|
57
|
+
const updateInset = useCallback(() => {
|
|
58
|
+
startTransition(() => {
|
|
59
|
+
setInset(getSafeAreaInset());
|
|
60
|
+
});
|
|
61
|
+
}, []);
|
|
62
|
+
useEffect(function handleOrientationChange() {
|
|
63
|
+
if (isServer()) return;
|
|
64
|
+
window.addEventListener("resize", updateInset);
|
|
65
|
+
window.addEventListener("orientationchange", updateInset);
|
|
66
|
+
return function cleanup() {
|
|
67
|
+
window.removeEventListener("resize", updateInset);
|
|
68
|
+
window.removeEventListener("orientationchange", updateInset);
|
|
69
|
+
};
|
|
70
|
+
}, [updateInset]);
|
|
71
|
+
return inset;
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { useSafeAreaInset };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_isServer = require("../../utils/isServer/isServer.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
//#region src/mobile/hooks/useScrollDirection/useScrollDirection.ts
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* `useScrollDirection` is a React hook that detects scroll direction.
|
|
8
|
+
* It returns scroll direction (up/down) and current scroll position.
|
|
9
|
+
* Throttled by default (50ms) for performance.
|
|
10
|
+
*
|
|
11
|
+
* @param {UseScrollDirectionOptions} [options] - Configuration options.
|
|
12
|
+
* @param {number} [options.throttleMs=50] - Throttle interval in milliseconds.
|
|
13
|
+
* @returns {ScrollDirectionState} Scroll direction state: `direction` (`'up' | 'down' | null`) and `position` (px).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* function Header() {
|
|
17
|
+
* const { direction, position } = useScrollDirection();
|
|
18
|
+
*
|
|
19
|
+
* // Hide header on scroll down
|
|
20
|
+
* const isHidden = direction === 'down' && position > 100;
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <header className={isHidden ? 'hidden' : 'visible'}>
|
|
24
|
+
* My Header
|
|
25
|
+
* </header>
|
|
26
|
+
* );
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
29
|
+
function useScrollDirection(options = {}) {
|
|
30
|
+
const { throttleMs = 50 } = options;
|
|
31
|
+
const [scrollInfo, setScrollInfo] = (0, react.useState)({
|
|
32
|
+
direction: null,
|
|
33
|
+
position: require_isServer.isServer() ? 0 : window.scrollY
|
|
34
|
+
});
|
|
35
|
+
const lastScrollYRef = (0, react.useRef)(require_isServer.isServer() ? 0 : window.scrollY);
|
|
36
|
+
const throttleTimerRef = (0, react.useRef)(null);
|
|
37
|
+
const updateScrollDirection = (0, react.useCallback)(({ currentScrollY, lastScrollY }) => {
|
|
38
|
+
if (currentScrollY > lastScrollY) {
|
|
39
|
+
setScrollInfo({
|
|
40
|
+
direction: "down",
|
|
41
|
+
position: currentScrollY
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (currentScrollY < lastScrollY) {
|
|
46
|
+
setScrollInfo({
|
|
47
|
+
direction: "up",
|
|
48
|
+
position: currentScrollY
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}, []);
|
|
53
|
+
const startThrottle = (0, react.useCallback)(() => {
|
|
54
|
+
throttleTimerRef.current = setTimeout(function clearThrottle() {
|
|
55
|
+
throttleTimerRef.current = null;
|
|
56
|
+
}, throttleMs);
|
|
57
|
+
}, [throttleMs]);
|
|
58
|
+
(0, react.useEffect)(function handleScrollDirectionChange() {
|
|
59
|
+
function handleScroll() {
|
|
60
|
+
if (throttleTimerRef.current != null) return;
|
|
61
|
+
const currentScrollY = window.scrollY;
|
|
62
|
+
const lastScrollY = lastScrollYRef.current;
|
|
63
|
+
lastScrollYRef.current = currentScrollY;
|
|
64
|
+
startThrottle();
|
|
65
|
+
updateScrollDirection({
|
|
66
|
+
currentScrollY,
|
|
67
|
+
lastScrollY
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
window.addEventListener("scroll", handleScroll, { passive: true });
|
|
71
|
+
return function cleanup() {
|
|
72
|
+
window.removeEventListener("scroll", handleScroll);
|
|
73
|
+
if (throttleTimerRef.current != null) clearTimeout(throttleTimerRef.current);
|
|
74
|
+
};
|
|
75
|
+
}, [startThrottle, updateScrollDirection]);
|
|
76
|
+
return scrollInfo;
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
exports.useScrollDirection = useScrollDirection;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/hooks/useScrollDirection/useScrollDirection.d.ts
|
|
3
|
+
type ScrollDirection = 'up' | 'down' | null;
|
|
4
|
+
type ScrollDirectionState = {
|
|
5
|
+
/** Current scroll direction */
|
|
6
|
+
direction: ScrollDirection;
|
|
7
|
+
/** Current scroll Y position (px) */
|
|
8
|
+
position: number;
|
|
9
|
+
};
|
|
10
|
+
type UseScrollDirectionOptions = {
|
|
11
|
+
/** Throttle interval (ms) - default: 50ms */
|
|
12
|
+
throttleMs?: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* @description
|
|
16
|
+
* `useScrollDirection` is a React hook that detects scroll direction.
|
|
17
|
+
* It returns scroll direction (up/down) and current scroll position.
|
|
18
|
+
* Throttled by default (50ms) for performance.
|
|
19
|
+
*
|
|
20
|
+
* @param {UseScrollDirectionOptions} [options] - Configuration options.
|
|
21
|
+
* @param {number} [options.throttleMs=50] - Throttle interval in milliseconds.
|
|
22
|
+
* @returns {ScrollDirectionState} Scroll direction state: `direction` (`'up' | 'down' | null`) and `position` (px).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* function Header() {
|
|
26
|
+
* const { direction, position } = useScrollDirection();
|
|
27
|
+
*
|
|
28
|
+
* // Hide header on scroll down
|
|
29
|
+
* const isHidden = direction === 'down' && position > 100;
|
|
30
|
+
*
|
|
31
|
+
* return (
|
|
32
|
+
* <header className={isHidden ? 'hidden' : 'visible'}>
|
|
33
|
+
* My Header
|
|
34
|
+
* </header>
|
|
35
|
+
* );
|
|
36
|
+
* }
|
|
37
|
+
*/
|
|
38
|
+
declare function useScrollDirection(options?: UseScrollDirectionOptions): ScrollDirectionState;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { useScrollDirection };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/hooks/useScrollDirection/useScrollDirection.d.ts
|
|
3
|
+
type ScrollDirection = 'up' | 'down' | null;
|
|
4
|
+
type ScrollDirectionState = {
|
|
5
|
+
/** Current scroll direction */
|
|
6
|
+
direction: ScrollDirection;
|
|
7
|
+
/** Current scroll Y position (px) */
|
|
8
|
+
position: number;
|
|
9
|
+
};
|
|
10
|
+
type UseScrollDirectionOptions = {
|
|
11
|
+
/** Throttle interval (ms) - default: 50ms */
|
|
12
|
+
throttleMs?: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* @description
|
|
16
|
+
* `useScrollDirection` is a React hook that detects scroll direction.
|
|
17
|
+
* It returns scroll direction (up/down) and current scroll position.
|
|
18
|
+
* Throttled by default (50ms) for performance.
|
|
19
|
+
*
|
|
20
|
+
* @param {UseScrollDirectionOptions} [options] - Configuration options.
|
|
21
|
+
* @param {number} [options.throttleMs=50] - Throttle interval in milliseconds.
|
|
22
|
+
* @returns {ScrollDirectionState} Scroll direction state: `direction` (`'up' | 'down' | null`) and `position` (px).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* function Header() {
|
|
26
|
+
* const { direction, position } = useScrollDirection();
|
|
27
|
+
*
|
|
28
|
+
* // Hide header on scroll down
|
|
29
|
+
* const isHidden = direction === 'down' && position > 100;
|
|
30
|
+
*
|
|
31
|
+
* return (
|
|
32
|
+
* <header className={isHidden ? 'hidden' : 'visible'}>
|
|
33
|
+
* My Header
|
|
34
|
+
* </header>
|
|
35
|
+
* );
|
|
36
|
+
* }
|
|
37
|
+
*/
|
|
38
|
+
declare function useScrollDirection(options?: UseScrollDirectionOptions): ScrollDirectionState;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { useScrollDirection };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { isServer } from "../../utils/isServer/isServer.mjs";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
//#region src/mobile/hooks/useScrollDirection/useScrollDirection.ts
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* `useScrollDirection` is a React hook that detects scroll direction.
|
|
8
|
+
* It returns scroll direction (up/down) and current scroll position.
|
|
9
|
+
* Throttled by default (50ms) for performance.
|
|
10
|
+
*
|
|
11
|
+
* @param {UseScrollDirectionOptions} [options] - Configuration options.
|
|
12
|
+
* @param {number} [options.throttleMs=50] - Throttle interval in milliseconds.
|
|
13
|
+
* @returns {ScrollDirectionState} Scroll direction state: `direction` (`'up' | 'down' | null`) and `position` (px).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* function Header() {
|
|
17
|
+
* const { direction, position } = useScrollDirection();
|
|
18
|
+
*
|
|
19
|
+
* // Hide header on scroll down
|
|
20
|
+
* const isHidden = direction === 'down' && position > 100;
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <header className={isHidden ? 'hidden' : 'visible'}>
|
|
24
|
+
* My Header
|
|
25
|
+
* </header>
|
|
26
|
+
* );
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
29
|
+
function useScrollDirection(options = {}) {
|
|
30
|
+
const { throttleMs = 50 } = options;
|
|
31
|
+
const [scrollInfo, setScrollInfo] = useState({
|
|
32
|
+
direction: null,
|
|
33
|
+
position: isServer() ? 0 : window.scrollY
|
|
34
|
+
});
|
|
35
|
+
const lastScrollYRef = useRef(isServer() ? 0 : window.scrollY);
|
|
36
|
+
const throttleTimerRef = useRef(null);
|
|
37
|
+
const updateScrollDirection = useCallback(({ currentScrollY, lastScrollY }) => {
|
|
38
|
+
if (currentScrollY > lastScrollY) {
|
|
39
|
+
setScrollInfo({
|
|
40
|
+
direction: "down",
|
|
41
|
+
position: currentScrollY
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (currentScrollY < lastScrollY) {
|
|
46
|
+
setScrollInfo({
|
|
47
|
+
direction: "up",
|
|
48
|
+
position: currentScrollY
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}, []);
|
|
53
|
+
const startThrottle = useCallback(() => {
|
|
54
|
+
throttleTimerRef.current = setTimeout(function clearThrottle() {
|
|
55
|
+
throttleTimerRef.current = null;
|
|
56
|
+
}, throttleMs);
|
|
57
|
+
}, [throttleMs]);
|
|
58
|
+
useEffect(function handleScrollDirectionChange() {
|
|
59
|
+
function handleScroll() {
|
|
60
|
+
if (throttleTimerRef.current != null) return;
|
|
61
|
+
const currentScrollY = window.scrollY;
|
|
62
|
+
const lastScrollY = lastScrollYRef.current;
|
|
63
|
+
lastScrollYRef.current = currentScrollY;
|
|
64
|
+
startThrottle();
|
|
65
|
+
updateScrollDirection({
|
|
66
|
+
currentScrollY,
|
|
67
|
+
lastScrollY
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
window.addEventListener("scroll", handleScroll, { passive: true });
|
|
71
|
+
return function cleanup() {
|
|
72
|
+
window.removeEventListener("scroll", handleScroll);
|
|
73
|
+
if (throttleTimerRef.current != null) clearTimeout(throttleTimerRef.current);
|
|
74
|
+
};
|
|
75
|
+
}, [startThrottle, updateScrollDirection]);
|
|
76
|
+
return scrollInfo;
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
export { useScrollDirection };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_isServer = require("../../utils/isServer/isServer.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
//#region src/mobile/hooks/useVisualViewport/useVisualViewport.ts
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* `useVisualViewport` is a React hook that tracks Visual Viewport changes.
|
|
8
|
+
* It returns the actual visible area in mobile WebView, which changes when
|
|
9
|
+
* the keyboard appears or the user zooms/scrolls.
|
|
10
|
+
*
|
|
11
|
+
* **Important:** `viewport` is `null` on SSR or in browsers that don't support Visual Viewport API.
|
|
12
|
+
* Always check for null before accessing viewport properties.
|
|
13
|
+
*
|
|
14
|
+
* **Tip:** If you only need keyboard height, use `useKeyboardHeight()` instead
|
|
15
|
+
* for a simpler API.
|
|
16
|
+
*
|
|
17
|
+
* @returns {{ viewport: VisualViewportState | null }} An object containing the Visual Viewport state.
|
|
18
|
+
* - viewport `VisualViewportState | null` - Visual Viewport state object, or `null` if not supported (SSR or browsers without the Visual Viewport API);
|
|
19
|
+
* - viewport.width `number` - Viewport width in pixels;
|
|
20
|
+
* - viewport.height `number` - Viewport height in pixels;
|
|
21
|
+
* - viewport.offsetLeft `number` - Viewport left offset in pixels from the layout viewport. Typically 0 unless horizontal scrolling or panning occurs;
|
|
22
|
+
* - viewport.offsetTop `number` - Viewport top offset in pixels from the layout viewport. Becomes negative on iOS when the keyboard appears, so use `-offsetTop` for the keyboard height. Typically remains 0 on Android;
|
|
23
|
+
* - viewport.scale `number` - Pinch-zoom scaling factor. 1.0 means no zoom, greater than 1.0 means zoomed in;
|
|
24
|
+
*
|
|
25
|
+
* @see {@link useKeyboardHeight} - Simpler hook for keyboard height only
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* function CustomLayout() {
|
|
29
|
+
* const { viewport } = useVisualViewport();
|
|
30
|
+
*
|
|
31
|
+
* // Always check for null first
|
|
32
|
+
* if (!viewport) {
|
|
33
|
+
* return <div>Visual Viewport not supported</div>;
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* const { width, height, offsetTop, scale } = viewport;
|
|
37
|
+
*
|
|
38
|
+
* // Hide floating UI when user zooms in
|
|
39
|
+
* const showFloatingUI = scale <= 1.3;
|
|
40
|
+
*
|
|
41
|
+
* return (
|
|
42
|
+
* <div style={{ height }}>
|
|
43
|
+
* {showFloatingUI && <FloatingButton />}
|
|
44
|
+
* Viewport-aware content
|
|
45
|
+
* </div>
|
|
46
|
+
* );
|
|
47
|
+
* }
|
|
48
|
+
*/
|
|
49
|
+
function useVisualViewport() {
|
|
50
|
+
const visualViewport = require_isServer.isServer() ? null : window.visualViewport;
|
|
51
|
+
const [viewport, setViewport] = (0, react.useState)(() => visualViewport != null ? getVisualViewportState(visualViewport) : null);
|
|
52
|
+
const updateViewportState = (0, react.useCallback)(() => {
|
|
53
|
+
(0, react.startTransition)(() => {
|
|
54
|
+
setViewport(window.visualViewport != null ? getVisualViewportState(window.visualViewport) : null);
|
|
55
|
+
});
|
|
56
|
+
}, []);
|
|
57
|
+
(0, react.useEffect)(function handleVisualViewportChange() {
|
|
58
|
+
window.visualViewport?.addEventListener("resize", updateViewportState);
|
|
59
|
+
window.visualViewport?.addEventListener("scroll", updateViewportState);
|
|
60
|
+
return function cleanup() {
|
|
61
|
+
window.visualViewport?.removeEventListener("resize", updateViewportState);
|
|
62
|
+
window.visualViewport?.removeEventListener("scroll", updateViewportState);
|
|
63
|
+
};
|
|
64
|
+
}, [updateViewportState]);
|
|
65
|
+
return { viewport };
|
|
66
|
+
}
|
|
67
|
+
function getVisualViewportState(visualViewport) {
|
|
68
|
+
return {
|
|
69
|
+
width: visualViewport.width,
|
|
70
|
+
height: visualViewport.height,
|
|
71
|
+
offsetLeft: visualViewport.offsetLeft,
|
|
72
|
+
offsetTop: visualViewport.offsetTop,
|
|
73
|
+
scale: visualViewport.scale
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
exports.useVisualViewport = useVisualViewport;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/hooks/useVisualViewport/useVisualViewport.d.ts
|
|
3
|
+
type VisualViewportState = {
|
|
4
|
+
/** Viewport width (px) */
|
|
5
|
+
width: number;
|
|
6
|
+
/** Viewport height (px) */
|
|
7
|
+
height: number;
|
|
8
|
+
/**
|
|
9
|
+
* Viewport left offset (px) from the layout viewport
|
|
10
|
+
*
|
|
11
|
+
* Typically 0 unless horizontal scrolling or panning occurs
|
|
12
|
+
*/
|
|
13
|
+
offsetLeft: number;
|
|
14
|
+
/**
|
|
15
|
+
* Viewport top offset (px) from the layout viewport
|
|
16
|
+
*
|
|
17
|
+
* On iOS: Becomes negative when keyboard appears (e.g., -300px means 300px keyboard height)
|
|
18
|
+
* On Android: Typically remains 0
|
|
19
|
+
*
|
|
20
|
+
* Use `-offsetTop` to get accurate keyboard height on iOS
|
|
21
|
+
*/
|
|
22
|
+
offsetTop: number;
|
|
23
|
+
/**
|
|
24
|
+
* Pinch-zoom scaling factor
|
|
25
|
+
*
|
|
26
|
+
* - 1.0 = no zoom (default)
|
|
27
|
+
* - > 1.0 = zoomed in
|
|
28
|
+
* - < 1.0 = zoomed out (rare, depends on viewport settings)
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* const { viewport } = useVisualViewport();
|
|
33
|
+
* if (viewport && viewport.scale > 1.3) {
|
|
34
|
+
* // Hide floating UI when user zooms in
|
|
35
|
+
* setShowFloatingButton(false);
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
scale: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* @description
|
|
43
|
+
* `useVisualViewport` is a React hook that tracks Visual Viewport changes.
|
|
44
|
+
* It returns the actual visible area in mobile WebView, which changes when
|
|
45
|
+
* the keyboard appears or the user zooms/scrolls.
|
|
46
|
+
*
|
|
47
|
+
* **Important:** `viewport` is `null` on SSR or in browsers that don't support Visual Viewport API.
|
|
48
|
+
* Always check for null before accessing viewport properties.
|
|
49
|
+
*
|
|
50
|
+
* **Tip:** If you only need keyboard height, use `useKeyboardHeight()` instead
|
|
51
|
+
* for a simpler API.
|
|
52
|
+
*
|
|
53
|
+
* @returns {{ viewport: VisualViewportState | null }} An object containing the Visual Viewport state.
|
|
54
|
+
* - viewport `VisualViewportState | null` - Visual Viewport state object, or `null` if not supported (SSR or browsers without the Visual Viewport API);
|
|
55
|
+
* - viewport.width `number` - Viewport width in pixels;
|
|
56
|
+
* - viewport.height `number` - Viewport height in pixels;
|
|
57
|
+
* - viewport.offsetLeft `number` - Viewport left offset in pixels from the layout viewport. Typically 0 unless horizontal scrolling or panning occurs;
|
|
58
|
+
* - viewport.offsetTop `number` - Viewport top offset in pixels from the layout viewport. Becomes negative on iOS when the keyboard appears, so use `-offsetTop` for the keyboard height. Typically remains 0 on Android;
|
|
59
|
+
* - viewport.scale `number` - Pinch-zoom scaling factor. 1.0 means no zoom, greater than 1.0 means zoomed in;
|
|
60
|
+
*
|
|
61
|
+
* @see {@link useKeyboardHeight} - Simpler hook for keyboard height only
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* function CustomLayout() {
|
|
65
|
+
* const { viewport } = useVisualViewport();
|
|
66
|
+
*
|
|
67
|
+
* // Always check for null first
|
|
68
|
+
* if (!viewport) {
|
|
69
|
+
* return <div>Visual Viewport not supported</div>;
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* const { width, height, offsetTop, scale } = viewport;
|
|
73
|
+
*
|
|
74
|
+
* // Hide floating UI when user zooms in
|
|
75
|
+
* const showFloatingUI = scale <= 1.3;
|
|
76
|
+
*
|
|
77
|
+
* return (
|
|
78
|
+
* <div style={{ height }}>
|
|
79
|
+
* {showFloatingUI && <FloatingButton />}
|
|
80
|
+
* Viewport-aware content
|
|
81
|
+
* </div>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
*/
|
|
85
|
+
declare function useVisualViewport(): {
|
|
86
|
+
viewport: VisualViewportState | null;
|
|
87
|
+
};
|
|
88
|
+
//#endregion
|
|
89
|
+
export { useVisualViewport };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/hooks/useVisualViewport/useVisualViewport.d.ts
|
|
3
|
+
type VisualViewportState = {
|
|
4
|
+
/** Viewport width (px) */
|
|
5
|
+
width: number;
|
|
6
|
+
/** Viewport height (px) */
|
|
7
|
+
height: number;
|
|
8
|
+
/**
|
|
9
|
+
* Viewport left offset (px) from the layout viewport
|
|
10
|
+
*
|
|
11
|
+
* Typically 0 unless horizontal scrolling or panning occurs
|
|
12
|
+
*/
|
|
13
|
+
offsetLeft: number;
|
|
14
|
+
/**
|
|
15
|
+
* Viewport top offset (px) from the layout viewport
|
|
16
|
+
*
|
|
17
|
+
* On iOS: Becomes negative when keyboard appears (e.g., -300px means 300px keyboard height)
|
|
18
|
+
* On Android: Typically remains 0
|
|
19
|
+
*
|
|
20
|
+
* Use `-offsetTop` to get accurate keyboard height on iOS
|
|
21
|
+
*/
|
|
22
|
+
offsetTop: number;
|
|
23
|
+
/**
|
|
24
|
+
* Pinch-zoom scaling factor
|
|
25
|
+
*
|
|
26
|
+
* - 1.0 = no zoom (default)
|
|
27
|
+
* - > 1.0 = zoomed in
|
|
28
|
+
* - < 1.0 = zoomed out (rare, depends on viewport settings)
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* const { viewport } = useVisualViewport();
|
|
33
|
+
* if (viewport && viewport.scale > 1.3) {
|
|
34
|
+
* // Hide floating UI when user zooms in
|
|
35
|
+
* setShowFloatingButton(false);
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
scale: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* @description
|
|
43
|
+
* `useVisualViewport` is a React hook that tracks Visual Viewport changes.
|
|
44
|
+
* It returns the actual visible area in mobile WebView, which changes when
|
|
45
|
+
* the keyboard appears or the user zooms/scrolls.
|
|
46
|
+
*
|
|
47
|
+
* **Important:** `viewport` is `null` on SSR or in browsers that don't support Visual Viewport API.
|
|
48
|
+
* Always check for null before accessing viewport properties.
|
|
49
|
+
*
|
|
50
|
+
* **Tip:** If you only need keyboard height, use `useKeyboardHeight()` instead
|
|
51
|
+
* for a simpler API.
|
|
52
|
+
*
|
|
53
|
+
* @returns {{ viewport: VisualViewportState | null }} An object containing the Visual Viewport state.
|
|
54
|
+
* - viewport `VisualViewportState | null` - Visual Viewport state object, or `null` if not supported (SSR or browsers without the Visual Viewport API);
|
|
55
|
+
* - viewport.width `number` - Viewport width in pixels;
|
|
56
|
+
* - viewport.height `number` - Viewport height in pixels;
|
|
57
|
+
* - viewport.offsetLeft `number` - Viewport left offset in pixels from the layout viewport. Typically 0 unless horizontal scrolling or panning occurs;
|
|
58
|
+
* - viewport.offsetTop `number` - Viewport top offset in pixels from the layout viewport. Becomes negative on iOS when the keyboard appears, so use `-offsetTop` for the keyboard height. Typically remains 0 on Android;
|
|
59
|
+
* - viewport.scale `number` - Pinch-zoom scaling factor. 1.0 means no zoom, greater than 1.0 means zoomed in;
|
|
60
|
+
*
|
|
61
|
+
* @see {@link useKeyboardHeight} - Simpler hook for keyboard height only
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* function CustomLayout() {
|
|
65
|
+
* const { viewport } = useVisualViewport();
|
|
66
|
+
*
|
|
67
|
+
* // Always check for null first
|
|
68
|
+
* if (!viewport) {
|
|
69
|
+
* return <div>Visual Viewport not supported</div>;
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* const { width, height, offsetTop, scale } = viewport;
|
|
73
|
+
*
|
|
74
|
+
* // Hide floating UI when user zooms in
|
|
75
|
+
* const showFloatingUI = scale <= 1.3;
|
|
76
|
+
*
|
|
77
|
+
* return (
|
|
78
|
+
* <div style={{ height }}>
|
|
79
|
+
* {showFloatingUI && <FloatingButton />}
|
|
80
|
+
* Viewport-aware content
|
|
81
|
+
* </div>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
*/
|
|
85
|
+
declare function useVisualViewport(): {
|
|
86
|
+
viewport: VisualViewportState | null;
|
|
87
|
+
};
|
|
88
|
+
//#endregion
|
|
89
|
+
export { useVisualViewport };
|