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.
Files changed (153) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +2 -42
  3. package/dist/hooks/useAsyncEffect/useAsyncEffect.cjs +1 -0
  4. package/dist/hooks/useAsyncEffect/useAsyncEffect.mjs +1 -0
  5. package/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.cjs +1 -0
  6. package/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.mjs +1 -0
  7. package/dist/hooks/useConditionalEffect/useConditionalEffect.cjs +1 -0
  8. package/dist/hooks/useConditionalEffect/useConditionalEffect.mjs +1 -0
  9. package/dist/hooks/useDebouncedCallback/useDebouncedCallback.cjs +24 -6
  10. package/dist/hooks/useDebouncedCallback/useDebouncedCallback.d.cts +17 -7
  11. package/dist/hooks/useDebouncedCallback/useDebouncedCallback.d.mts +17 -7
  12. package/dist/hooks/useDebouncedCallback/useDebouncedCallback.mjs +24 -6
  13. package/dist/hooks/useDoubleClick/useDoubleClick.cjs +0 -4
  14. package/dist/hooks/useDoubleClick/useDoubleClick.d.cts +0 -4
  15. package/dist/hooks/useDoubleClick/useDoubleClick.d.mts +0 -4
  16. package/dist/hooks/useDoubleClick/useDoubleClick.mjs +0 -4
  17. package/dist/hooks/useGeolocation/useGeolocation.cjs +0 -4
  18. package/dist/hooks/useGeolocation/useGeolocation.d.cts +0 -4
  19. package/dist/hooks/useGeolocation/useGeolocation.d.mts +0 -4
  20. package/dist/hooks/useGeolocation/useGeolocation.mjs +0 -4
  21. package/dist/hooks/useImpressionRef/useImpressionRef.cjs +7 -5
  22. package/dist/hooks/useImpressionRef/useImpressionRef.d.cts +0 -4
  23. package/dist/hooks/useImpressionRef/useImpressionRef.d.mts +0 -4
  24. package/dist/hooks/useImpressionRef/useImpressionRef.mjs +7 -5
  25. package/dist/hooks/useInputState/useInputState.cjs +9 -3
  26. package/dist/hooks/useInputState/useInputState.d.cts +11 -4
  27. package/dist/hooks/useInputState/useInputState.d.mts +11 -4
  28. package/dist/hooks/useInputState/useInputState.mjs +9 -3
  29. package/dist/hooks/useIntersectionObserver/useIntersectionObserver.cjs +1 -5
  30. package/dist/hooks/useIntersectionObserver/useIntersectionObserver.d.cts +1 -5
  31. package/dist/hooks/useIntersectionObserver/useIntersectionObserver.d.mts +1 -5
  32. package/dist/hooks/useIntersectionObserver/useIntersectionObserver.mjs +1 -5
  33. package/dist/hooks/useList/useList.cjs +11 -8
  34. package/dist/hooks/useList/useList.d.cts +12 -9
  35. package/dist/hooks/useList/useList.d.mts +12 -9
  36. package/dist/hooks/useList/useList.mjs +11 -8
  37. package/dist/hooks/useLoading/useLoading.cjs +3 -5
  38. package/dist/hooks/useLoading/useLoading.d.cts +2 -5
  39. package/dist/hooks/useLoading/useLoading.d.mts +2 -5
  40. package/dist/hooks/useLoading/useLoading.mjs +3 -5
  41. package/dist/hooks/useLongPress/useLongPress.cjs +0 -4
  42. package/dist/hooks/useLongPress/useLongPress.d.cts +0 -4
  43. package/dist/hooks/useLongPress/useLongPress.d.mts +0 -4
  44. package/dist/hooks/useLongPress/useLongPress.mjs +0 -4
  45. package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.cjs +0 -4
  46. package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.d.cts +0 -4
  47. package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.d.mts +0 -4
  48. package/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.mjs +0 -4
  49. package/dist/hooks/usePreservedReference/usePreservedReference.cjs +1 -0
  50. package/dist/hooks/usePreservedReference/usePreservedReference.mjs +1 -0
  51. package/dist/hooks/useRefEffect/useRefEffect.cjs +1 -0
  52. package/dist/hooks/useRefEffect/useRefEffect.mjs +1 -0
  53. package/dist/hooks/useSet/useSet.cjs +11 -2
  54. package/dist/hooks/useSet/useSet.d.cts +11 -2
  55. package/dist/hooks/useSet/useSet.d.mts +11 -2
  56. package/dist/hooks/useSet/useSet.mjs +11 -2
  57. package/dist/hooks/useStorageState/useStorageState.cjs +1 -0
  58. package/dist/hooks/useStorageState/useStorageState.d.cts +0 -4
  59. package/dist/hooks/useStorageState/useStorageState.d.mts +0 -4
  60. package/dist/hooks/useStorageState/useStorageState.mjs +1 -0
  61. package/dist/hooks/useThrottledCallback/useThrottledCallback.cjs +16 -9
  62. package/dist/hooks/useThrottledCallback/useThrottledCallback.d.cts +18 -11
  63. package/dist/hooks/useThrottledCallback/useThrottledCallback.d.mts +18 -11
  64. package/dist/hooks/useThrottledCallback/useThrottledCallback.mjs +16 -9
  65. package/dist/hooks/useVisibilityEvent/useVisibilityEvent.cjs +2 -4
  66. package/dist/hooks/useVisibilityEvent/useVisibilityEvent.d.cts +2 -4
  67. package/dist/hooks/useVisibilityEvent/useVisibilityEvent.d.mts +2 -4
  68. package/dist/hooks/useVisibilityEvent/useVisibilityEvent.mjs +2 -4
  69. package/dist/index.cjs +34 -0
  70. package/dist/index.d.cts +19 -1
  71. package/dist/index.d.mts +19 -1
  72. package/dist/index.mjs +18 -1
  73. package/dist/mobile/hooks/useAvoidKeyboard/index.d.cts +3 -0
  74. package/dist/mobile/hooks/useAvoidKeyboard/index.d.mts +3 -0
  75. package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.cjs +75 -0
  76. package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.d.cts +89 -0
  77. package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.d.mts +89 -0
  78. package/dist/mobile/hooks/useAvoidKeyboard/useAvoidKeyboard.mjs +75 -0
  79. package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.cjs +47 -0
  80. package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.d.cts +37 -0
  81. package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.d.mts +37 -0
  82. package/dist/mobile/hooks/useBodyScrollLock/useBodyScrollLock.mjs +47 -0
  83. package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.cjs +41 -0
  84. package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.d.cts +41 -0
  85. package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.d.mts +41 -0
  86. package/dist/mobile/hooks/useKeyboardHeight/useKeyboardHeight.mjs +41 -0
  87. package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.cjs +88 -0
  88. package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.d.cts +77 -0
  89. package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.d.mts +77 -0
  90. package/dist/mobile/hooks/useNetworkStatus/useNetworkStatus.mjs +88 -0
  91. package/dist/mobile/hooks/usePageVisibility/usePageVisibility.cjs +75 -0
  92. package/dist/mobile/hooks/usePageVisibility/usePageVisibility.d.cts +64 -0
  93. package/dist/mobile/hooks/usePageVisibility/usePageVisibility.d.mts +64 -0
  94. package/dist/mobile/hooks/usePageVisibility/usePageVisibility.mjs +75 -0
  95. package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.cjs +74 -0
  96. package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.d.cts +55 -0
  97. package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.d.mts +55 -0
  98. package/dist/mobile/hooks/useSafeAreaInset/useSafeAreaInset.mjs +74 -0
  99. package/dist/mobile/hooks/useScrollDirection/useScrollDirection.cjs +79 -0
  100. package/dist/mobile/hooks/useScrollDirection/useScrollDirection.d.cts +40 -0
  101. package/dist/mobile/hooks/useScrollDirection/useScrollDirection.d.mts +40 -0
  102. package/dist/mobile/hooks/useScrollDirection/useScrollDirection.mjs +79 -0
  103. package/dist/mobile/hooks/useVisualViewport/useVisualViewport.cjs +77 -0
  104. package/dist/mobile/hooks/useVisualViewport/useVisualViewport.d.cts +89 -0
  105. package/dist/mobile/hooks/useVisualViewport/useVisualViewport.d.mts +89 -0
  106. package/dist/mobile/hooks/useVisualViewport/useVisualViewport.mjs +77 -0
  107. package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.cjs +55 -0
  108. package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.d.cts +22 -0
  109. package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.d.mts +22 -0
  110. package/dist/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.mjs +55 -0
  111. package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.cjs +49 -0
  112. package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.d.cts +23 -0
  113. package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.d.mts +23 -0
  114. package/dist/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.mjs +49 -0
  115. package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.cjs +35 -0
  116. package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.d.cts +28 -0
  117. package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.d.mts +28 -0
  118. package/dist/mobile/utils/getKeyboardHeight/getKeyboardHeight.mjs +35 -0
  119. package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.cjs +58 -0
  120. package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.d.cts +44 -0
  121. package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.d.mts +44 -0
  122. package/dist/mobile/utils/getSafeAreaInset/getSafeAreaInset.mjs +58 -0
  123. package/dist/mobile/utils/isAndroid/isAndroid.cjs +32 -0
  124. package/dist/mobile/utils/isAndroid/isAndroid.d.cts +27 -0
  125. package/dist/mobile/utils/isAndroid/isAndroid.d.mts +27 -0
  126. package/dist/mobile/utils/isAndroid/isAndroid.mjs +32 -0
  127. package/dist/mobile/utils/isIOS/isIOS.cjs +37 -0
  128. package/dist/mobile/utils/isIOS/isIOS.d.cts +30 -0
  129. package/dist/mobile/utils/isIOS/isIOS.d.mts +30 -0
  130. package/dist/mobile/utils/isIOS/isIOS.mjs +37 -0
  131. package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.cjs +28 -0
  132. package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.d.cts +25 -0
  133. package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.d.mts +25 -0
  134. package/dist/mobile/utils/isKeyboardVisible/isKeyboardVisible.mjs +28 -0
  135. package/dist/mobile/utils/isServer/isServer.cjs +24 -0
  136. package/dist/mobile/utils/isServer/isServer.d.cts +22 -0
  137. package/dist/mobile/utils/isServer/isServer.d.mts +22 -0
  138. package/dist/mobile/utils/isServer/isServer.mjs +24 -0
  139. package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.cjs +71 -0
  140. package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.d.cts +64 -0
  141. package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.d.mts +64 -0
  142. package/dist/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.mjs +71 -0
  143. package/dist/utils/buildContext/buildContext.cjs +1 -0
  144. package/dist/utils/buildContext/buildContext.mjs +1 -0
  145. package/dist/utils/mergeProps/mergeProps.cjs +1 -1
  146. package/dist/utils/mergeProps/mergeProps.d.cts +1 -1
  147. package/dist/utils/mergeProps/mergeProps.d.mts +1 -1
  148. package/dist/utils/mergeProps/mergeProps.mjs +1 -1
  149. package/dist/utils/mergeRefs/mergeRefs.cjs +1 -1
  150. package/dist/utils/mergeRefs/mergeRefs.d.cts +1 -1
  151. package/dist/utils/mergeRefs/mergeRefs.d.mts +1 -1
  152. package/dist/utils/mergeRefs/mergeRefs.mjs +1 -1
  153. package/package.json +22 -10
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import { isServer } from "../../utils/isServer/isServer.mjs";
3
+ import { startTransition, useCallback, useEffect, useState } from "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 = isServer() ? null : window.visualViewport;
51
+ const [viewport, setViewport] = useState(() => visualViewport != null ? getVisualViewportState(visualViewport) : null);
52
+ const updateViewportState = useCallback(() => {
53
+ startTransition(() => {
54
+ setViewport(window.visualViewport != null ? getVisualViewportState(window.visualViewport) : null);
55
+ });
56
+ }, []);
57
+ 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
+ export { useVisualViewport };
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ const require_isServer = require("../isServer/isServer.cjs");
3
+ //#region src/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.ts
4
+ /**
5
+ * Data attribute key for storing scroll position
6
+ */
7
+ const SCROLL_POSITION_ATTR = "data-simplikit-scroll-y";
8
+ /**
9
+ * @description
10
+ * `disableBodyScrollLock` is a utility function that unlocks the body scroll.
11
+ * It restores the scroll locked by `enableBodyScrollLock` and returns to the saved scroll position.
12
+ *
13
+ * Safe to call in SSR environment (no-op on server).
14
+ * Safe to call even if not locked (no-op).
15
+ *
16
+ * @returns {void}
17
+ *
18
+ * @example
19
+ * // When modal opens
20
+ * enableBodyScrollLock();
21
+ *
22
+ * // When modal closes
23
+ * disableBodyScrollLock();
24
+ */
25
+ function disableBodyScrollLock() {
26
+ if (require_isServer.isServer()) return;
27
+ const savedScrollY = document.body.getAttribute(SCROLL_POSITION_ATTR);
28
+ if (savedScrollY == null) return;
29
+ removeScrollLockStyles();
30
+ restoreScrollPosition(savedScrollY);
31
+ clearSavedScrollPosition();
32
+ }
33
+ function removeScrollLockStyles() {
34
+ const { body } = document;
35
+ body.style.removeProperty("overflow");
36
+ body.style.removeProperty("position");
37
+ body.style.removeProperty("top");
38
+ body.style.removeProperty("left");
39
+ body.style.removeProperty("right");
40
+ body.style.removeProperty("bottom");
41
+ }
42
+ function restoreScrollPosition(savedScrollY) {
43
+ const scrollY = Number(savedScrollY);
44
+ if (Number.isNaN(scrollY)) {
45
+ console.warn("[react-simplikit] Invalid scroll position, defaulting to 0");
46
+ window.scrollTo(0, 0);
47
+ return;
48
+ }
49
+ window.scrollTo(0, scrollY);
50
+ }
51
+ function clearSavedScrollPosition() {
52
+ document.body.removeAttribute(SCROLL_POSITION_ATTR);
53
+ }
54
+ //#endregion
55
+ exports.disableBodyScrollLock = disableBodyScrollLock;
@@ -0,0 +1,22 @@
1
+
2
+ //#region src/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.d.ts
3
+ /**
4
+ * @description
5
+ * `disableBodyScrollLock` is a utility function that unlocks the body scroll.
6
+ * It restores the scroll locked by `enableBodyScrollLock` and returns to the saved scroll position.
7
+ *
8
+ * Safe to call in SSR environment (no-op on server).
9
+ * Safe to call even if not locked (no-op).
10
+ *
11
+ * @returns {void}
12
+ *
13
+ * @example
14
+ * // When modal opens
15
+ * enableBodyScrollLock();
16
+ *
17
+ * // When modal closes
18
+ * disableBodyScrollLock();
19
+ */
20
+ declare function disableBodyScrollLock(): void;
21
+ //#endregion
22
+ export { disableBodyScrollLock };
@@ -0,0 +1,22 @@
1
+
2
+ //#region src/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.d.ts
3
+ /**
4
+ * @description
5
+ * `disableBodyScrollLock` is a utility function that unlocks the body scroll.
6
+ * It restores the scroll locked by `enableBodyScrollLock` and returns to the saved scroll position.
7
+ *
8
+ * Safe to call in SSR environment (no-op on server).
9
+ * Safe to call even if not locked (no-op).
10
+ *
11
+ * @returns {void}
12
+ *
13
+ * @example
14
+ * // When modal opens
15
+ * enableBodyScrollLock();
16
+ *
17
+ * // When modal closes
18
+ * disableBodyScrollLock();
19
+ */
20
+ declare function disableBodyScrollLock(): void;
21
+ //#endregion
22
+ export { disableBodyScrollLock };
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { isServer } from "../isServer/isServer.mjs";
3
+ //#region src/mobile/utils/disableBodyScrollLock/disableBodyScrollLock.ts
4
+ /**
5
+ * Data attribute key for storing scroll position
6
+ */
7
+ const SCROLL_POSITION_ATTR = "data-simplikit-scroll-y";
8
+ /**
9
+ * @description
10
+ * `disableBodyScrollLock` is a utility function that unlocks the body scroll.
11
+ * It restores the scroll locked by `enableBodyScrollLock` and returns to the saved scroll position.
12
+ *
13
+ * Safe to call in SSR environment (no-op on server).
14
+ * Safe to call even if not locked (no-op).
15
+ *
16
+ * @returns {void}
17
+ *
18
+ * @example
19
+ * // When modal opens
20
+ * enableBodyScrollLock();
21
+ *
22
+ * // When modal closes
23
+ * disableBodyScrollLock();
24
+ */
25
+ function disableBodyScrollLock() {
26
+ if (isServer()) return;
27
+ const savedScrollY = document.body.getAttribute(SCROLL_POSITION_ATTR);
28
+ if (savedScrollY == null) return;
29
+ removeScrollLockStyles();
30
+ restoreScrollPosition(savedScrollY);
31
+ clearSavedScrollPosition();
32
+ }
33
+ function removeScrollLockStyles() {
34
+ const { body } = document;
35
+ body.style.removeProperty("overflow");
36
+ body.style.removeProperty("position");
37
+ body.style.removeProperty("top");
38
+ body.style.removeProperty("left");
39
+ body.style.removeProperty("right");
40
+ body.style.removeProperty("bottom");
41
+ }
42
+ function restoreScrollPosition(savedScrollY) {
43
+ const scrollY = Number(savedScrollY);
44
+ if (Number.isNaN(scrollY)) {
45
+ console.warn("[react-simplikit] Invalid scroll position, defaulting to 0");
46
+ window.scrollTo(0, 0);
47
+ return;
48
+ }
49
+ window.scrollTo(0, scrollY);
50
+ }
51
+ function clearSavedScrollPosition() {
52
+ document.body.removeAttribute(SCROLL_POSITION_ATTR);
53
+ }
54
+ //#endregion
55
+ export { disableBodyScrollLock };
@@ -0,0 +1,49 @@
1
+ "use client";
2
+ const require_isServer = require("../isServer/isServer.cjs");
3
+ //#region src/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.ts
4
+ /**
5
+ * Data attribute key for storing scroll position
6
+ */
7
+ const SCROLL_POSITION_ATTR = "data-simplikit-scroll-y";
8
+ /**
9
+ * @description
10
+ * `enableBodyScrollLock` is a utility function that locks the body scroll.
11
+ * It prevents the body from scrolling by applying fixed positioning.
12
+ * This is useful when opening modals, drawers, or other overlay components.
13
+ *
14
+ * Safe to call in SSR environment (no-op on server).
15
+ * Calling multiple times has no effect until unlocked.
16
+ *
17
+ * @returns {void}
18
+ *
19
+ * @example
20
+ * // When modal opens
21
+ * enableBodyScrollLock();
22
+ *
23
+ * // When modal closes
24
+ * disableBodyScrollLock();
25
+ */
26
+ function enableBodyScrollLock() {
27
+ if (require_isServer.isServer()) return;
28
+ if (isBodyScrollLocked()) return;
29
+ const scrollY = window.scrollY;
30
+ saveScrollPosition(scrollY);
31
+ applyScrollLockStyles(scrollY);
32
+ }
33
+ function isBodyScrollLocked() {
34
+ return document.body.getAttribute(SCROLL_POSITION_ATTR) != null;
35
+ }
36
+ function saveScrollPosition(scrollY) {
37
+ document.body.setAttribute(SCROLL_POSITION_ATTR, scrollY.toString());
38
+ }
39
+ function applyScrollLockStyles(scrollY) {
40
+ const { body } = document;
41
+ body.style.overflow = "hidden";
42
+ body.style.position = "fixed";
43
+ body.style.top = `-${scrollY}px`;
44
+ body.style.left = "0px";
45
+ body.style.right = "0px";
46
+ body.style.bottom = "0px";
47
+ }
48
+ //#endregion
49
+ exports.enableBodyScrollLock = enableBodyScrollLock;
@@ -0,0 +1,23 @@
1
+
2
+ //#region src/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.d.ts
3
+ /**
4
+ * @description
5
+ * `enableBodyScrollLock` is a utility function that locks the body scroll.
6
+ * It prevents the body from scrolling by applying fixed positioning.
7
+ * This is useful when opening modals, drawers, or other overlay components.
8
+ *
9
+ * Safe to call in SSR environment (no-op on server).
10
+ * Calling multiple times has no effect until unlocked.
11
+ *
12
+ * @returns {void}
13
+ *
14
+ * @example
15
+ * // When modal opens
16
+ * enableBodyScrollLock();
17
+ *
18
+ * // When modal closes
19
+ * disableBodyScrollLock();
20
+ */
21
+ declare function enableBodyScrollLock(): void;
22
+ //#endregion
23
+ export { enableBodyScrollLock };
@@ -0,0 +1,23 @@
1
+
2
+ //#region src/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.d.ts
3
+ /**
4
+ * @description
5
+ * `enableBodyScrollLock` is a utility function that locks the body scroll.
6
+ * It prevents the body from scrolling by applying fixed positioning.
7
+ * This is useful when opening modals, drawers, or other overlay components.
8
+ *
9
+ * Safe to call in SSR environment (no-op on server).
10
+ * Calling multiple times has no effect until unlocked.
11
+ *
12
+ * @returns {void}
13
+ *
14
+ * @example
15
+ * // When modal opens
16
+ * enableBodyScrollLock();
17
+ *
18
+ * // When modal closes
19
+ * disableBodyScrollLock();
20
+ */
21
+ declare function enableBodyScrollLock(): void;
22
+ //#endregion
23
+ export { enableBodyScrollLock };
@@ -0,0 +1,49 @@
1
+ "use client";
2
+ import { isServer } from "../isServer/isServer.mjs";
3
+ //#region src/mobile/utils/enableBodyScrollLock/enableBodyScrollLock.ts
4
+ /**
5
+ * Data attribute key for storing scroll position
6
+ */
7
+ const SCROLL_POSITION_ATTR = "data-simplikit-scroll-y";
8
+ /**
9
+ * @description
10
+ * `enableBodyScrollLock` is a utility function that locks the body scroll.
11
+ * It prevents the body from scrolling by applying fixed positioning.
12
+ * This is useful when opening modals, drawers, or other overlay components.
13
+ *
14
+ * Safe to call in SSR environment (no-op on server).
15
+ * Calling multiple times has no effect until unlocked.
16
+ *
17
+ * @returns {void}
18
+ *
19
+ * @example
20
+ * // When modal opens
21
+ * enableBodyScrollLock();
22
+ *
23
+ * // When modal closes
24
+ * disableBodyScrollLock();
25
+ */
26
+ function enableBodyScrollLock() {
27
+ if (isServer()) return;
28
+ if (isBodyScrollLocked()) return;
29
+ const scrollY = window.scrollY;
30
+ saveScrollPosition(scrollY);
31
+ applyScrollLockStyles(scrollY);
32
+ }
33
+ function isBodyScrollLocked() {
34
+ return document.body.getAttribute(SCROLL_POSITION_ATTR) != null;
35
+ }
36
+ function saveScrollPosition(scrollY) {
37
+ document.body.setAttribute(SCROLL_POSITION_ATTR, scrollY.toString());
38
+ }
39
+ function applyScrollLockStyles(scrollY) {
40
+ const { body } = document;
41
+ body.style.overflow = "hidden";
42
+ body.style.position = "fixed";
43
+ body.style.top = `-${scrollY}px`;
44
+ body.style.left = "0px";
45
+ body.style.right = "0px";
46
+ body.style.bottom = "0px";
47
+ }
48
+ //#endregion
49
+ export { enableBodyScrollLock };
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ const require_isServer = require("../isServer/isServer.cjs");
3
+ //#region src/mobile/utils/getKeyboardHeight/getKeyboardHeight.ts
4
+ /**
5
+ * @description
6
+ * `getKeyboardHeight` is a utility function that returns the current on-screen keyboard height in pixels.
7
+ *
8
+ * This function uses the Visual Viewport API to calculate the keyboard height.
9
+ * It assumes a modern environment where Visual Viewport is supported
10
+ * (Safari / WKWebView 14+, Chrome / Android WebView 80+).
11
+ *
12
+ * The keyboard height is computed as:
13
+ * `window.innerHeight - visualViewport.height - visualViewport.offsetTop`
14
+ *
15
+ * The subtraction of `offsetTop` is required to correctly handle iOS behavior
16
+ * where the visual viewport may shift vertically when the keyboard appears.
17
+ *
18
+ * @returns {number} The keyboard height in pixels. Returns 0 if the keyboard is not visible.
19
+ *
20
+ * @example
21
+ * const height = getKeyboardHeight();
22
+ *
23
+ * if (height > 0) {
24
+ * footer.style.paddingBottom = `${height}px`;
25
+ * }
26
+ */
27
+ function getKeyboardHeight() {
28
+ if (require_isServer.isServer()) return 0;
29
+ const visualViewport = window.visualViewport;
30
+ if (visualViewport == null) return 0;
31
+ const height = window.innerHeight - visualViewport.height - visualViewport.offsetTop;
32
+ return Math.max(0, height);
33
+ }
34
+ //#endregion
35
+ exports.getKeyboardHeight = getKeyboardHeight;
@@ -0,0 +1,28 @@
1
+
2
+ //#region src/mobile/utils/getKeyboardHeight/getKeyboardHeight.d.ts
3
+ /**
4
+ * @description
5
+ * `getKeyboardHeight` is a utility function that returns the current on-screen keyboard height in pixels.
6
+ *
7
+ * This function uses the Visual Viewport API to calculate the keyboard height.
8
+ * It assumes a modern environment where Visual Viewport is supported
9
+ * (Safari / WKWebView 14+, Chrome / Android WebView 80+).
10
+ *
11
+ * The keyboard height is computed as:
12
+ * `window.innerHeight - visualViewport.height - visualViewport.offsetTop`
13
+ *
14
+ * The subtraction of `offsetTop` is required to correctly handle iOS behavior
15
+ * where the visual viewport may shift vertically when the keyboard appears.
16
+ *
17
+ * @returns {number} The keyboard height in pixels. Returns 0 if the keyboard is not visible.
18
+ *
19
+ * @example
20
+ * const height = getKeyboardHeight();
21
+ *
22
+ * if (height > 0) {
23
+ * footer.style.paddingBottom = `${height}px`;
24
+ * }
25
+ */
26
+ declare function getKeyboardHeight(): number;
27
+ //#endregion
28
+ export { getKeyboardHeight };
@@ -0,0 +1,28 @@
1
+
2
+ //#region src/mobile/utils/getKeyboardHeight/getKeyboardHeight.d.ts
3
+ /**
4
+ * @description
5
+ * `getKeyboardHeight` is a utility function that returns the current on-screen keyboard height in pixels.
6
+ *
7
+ * This function uses the Visual Viewport API to calculate the keyboard height.
8
+ * It assumes a modern environment where Visual Viewport is supported
9
+ * (Safari / WKWebView 14+, Chrome / Android WebView 80+).
10
+ *
11
+ * The keyboard height is computed as:
12
+ * `window.innerHeight - visualViewport.height - visualViewport.offsetTop`
13
+ *
14
+ * The subtraction of `offsetTop` is required to correctly handle iOS behavior
15
+ * where the visual viewport may shift vertically when the keyboard appears.
16
+ *
17
+ * @returns {number} The keyboard height in pixels. Returns 0 if the keyboard is not visible.
18
+ *
19
+ * @example
20
+ * const height = getKeyboardHeight();
21
+ *
22
+ * if (height > 0) {
23
+ * footer.style.paddingBottom = `${height}px`;
24
+ * }
25
+ */
26
+ declare function getKeyboardHeight(): number;
27
+ //#endregion
28
+ export { getKeyboardHeight };
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { isServer } from "../isServer/isServer.mjs";
3
+ //#region src/mobile/utils/getKeyboardHeight/getKeyboardHeight.ts
4
+ /**
5
+ * @description
6
+ * `getKeyboardHeight` is a utility function that returns the current on-screen keyboard height in pixels.
7
+ *
8
+ * This function uses the Visual Viewport API to calculate the keyboard height.
9
+ * It assumes a modern environment where Visual Viewport is supported
10
+ * (Safari / WKWebView 14+, Chrome / Android WebView 80+).
11
+ *
12
+ * The keyboard height is computed as:
13
+ * `window.innerHeight - visualViewport.height - visualViewport.offsetTop`
14
+ *
15
+ * The subtraction of `offsetTop` is required to correctly handle iOS behavior
16
+ * where the visual viewport may shift vertically when the keyboard appears.
17
+ *
18
+ * @returns {number} The keyboard height in pixels. Returns 0 if the keyboard is not visible.
19
+ *
20
+ * @example
21
+ * const height = getKeyboardHeight();
22
+ *
23
+ * if (height > 0) {
24
+ * footer.style.paddingBottom = `${height}px`;
25
+ * }
26
+ */
27
+ function getKeyboardHeight() {
28
+ if (isServer()) return 0;
29
+ const visualViewport = window.visualViewport;
30
+ if (visualViewport == null) return 0;
31
+ const height = window.innerHeight - visualViewport.height - visualViewport.offsetTop;
32
+ return Math.max(0, height);
33
+ }
34
+ //#endregion
35
+ export { getKeyboardHeight };
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ const require_isServer = require("../isServer/isServer.cjs");
3
+ //#region src/mobile/utils/getSafeAreaInset/getSafeAreaInset.ts
4
+ /**
5
+ * @description
6
+ * `getSafeAreaInset` is a utility function that returns all safe area insets in pixels as an object.
7
+ *
8
+ * This function reads the CSS `env(safe-area-inset-*)` values by creating
9
+ * a temporary DOM element and reading its computed style.
10
+ *
11
+ * Safe area insets account for device-specific UI elements:
12
+ * - **top**: Notch, Dynamic Island, or status bar
13
+ * - **bottom**: Home indicator on Face ID devices
14
+ * - **left/right**: Rounded corners in landscape mode
15
+ *
16
+ * Typical values (iPhone with Face ID, portrait mode):
17
+ * - top: 47-59px (notch/Dynamic Island)
18
+ * - bottom: 34px (home indicator)
19
+ * - left/right: 0px
20
+ *
21
+ * @returns {SafeAreaInset} Object containing safe area insets for all four sides, or all 0 if not available.
22
+ * - top `number` - Top safe area inset in pixels;
23
+ * - bottom `number` - Bottom safe area inset in pixels;
24
+ * - left `number` - Left safe area inset in pixels;
25
+ * - right `number` - Right safe area inset in pixels;
26
+ *
27
+ * @example
28
+ * const { top, bottom, left, right } = getSafeAreaInset();
29
+ *
30
+ * header.style.paddingTop = `${top}px`;
31
+ * footer.style.paddingBottom = `${bottom}px`;
32
+ */
33
+ function getSafeAreaInset() {
34
+ if (require_isServer.isServer()) return {
35
+ top: 0,
36
+ bottom: 0,
37
+ left: 0,
38
+ right: 0
39
+ };
40
+ const div = document.createElement("div");
41
+ div.style.position = "fixed";
42
+ div.style.setProperty("padding-top", "env(safe-area-inset-top)");
43
+ div.style.setProperty("padding-bottom", "env(safe-area-inset-bottom)");
44
+ div.style.setProperty("padding-left", "env(safe-area-inset-left)");
45
+ div.style.setProperty("padding-right", "env(safe-area-inset-right)");
46
+ document.body.appendChild(div);
47
+ const computedStyle = window.getComputedStyle(div);
48
+ const inset = {
49
+ top: parseFloat(computedStyle.getPropertyValue("padding-top")) || 0,
50
+ bottom: parseFloat(computedStyle.getPropertyValue("padding-bottom")) || 0,
51
+ left: parseFloat(computedStyle.getPropertyValue("padding-left")) || 0,
52
+ right: parseFloat(computedStyle.getPropertyValue("padding-right")) || 0
53
+ };
54
+ document.body.removeChild(div);
55
+ return inset;
56
+ }
57
+ //#endregion
58
+ exports.getSafeAreaInset = getSafeAreaInset;
@@ -0,0 +1,44 @@
1
+
2
+ //#region src/mobile/utils/getSafeAreaInset/getSafeAreaInset.d.ts
3
+ type SafeAreaInset = {
4
+ /** Top safe area inset in pixels (notch, Dynamic Island, or status bar) */
5
+ top: number;
6
+ /** Bottom safe area inset in pixels (home indicator on Face ID devices) */
7
+ bottom: number;
8
+ /** Left safe area inset in pixels (rounded corners in landscape mode) */
9
+ left: number;
10
+ /** Right safe area inset in pixels (rounded corners in landscape mode) */
11
+ right: number;
12
+ };
13
+ /**
14
+ * @description
15
+ * `getSafeAreaInset` is a utility function that returns all safe area insets in pixels as an object.
16
+ *
17
+ * This function reads the CSS `env(safe-area-inset-*)` values by creating
18
+ * a temporary DOM element and reading its computed style.
19
+ *
20
+ * Safe area insets account for device-specific UI elements:
21
+ * - **top**: Notch, Dynamic Island, or status bar
22
+ * - **bottom**: Home indicator on Face ID devices
23
+ * - **left/right**: Rounded corners in landscape mode
24
+ *
25
+ * Typical values (iPhone with Face ID, portrait mode):
26
+ * - top: 47-59px (notch/Dynamic Island)
27
+ * - bottom: 34px (home indicator)
28
+ * - left/right: 0px
29
+ *
30
+ * @returns {SafeAreaInset} Object containing safe area insets for all four sides, or all 0 if not available.
31
+ * - top `number` - Top safe area inset in pixels;
32
+ * - bottom `number` - Bottom safe area inset in pixels;
33
+ * - left `number` - Left safe area inset in pixels;
34
+ * - right `number` - Right safe area inset in pixels;
35
+ *
36
+ * @example
37
+ * const { top, bottom, left, right } = getSafeAreaInset();
38
+ *
39
+ * header.style.paddingTop = `${top}px`;
40
+ * footer.style.paddingBottom = `${bottom}px`;
41
+ */
42
+ declare function getSafeAreaInset(): SafeAreaInset;
43
+ //#endregion
44
+ export { SafeAreaInset, getSafeAreaInset };
@@ -0,0 +1,44 @@
1
+
2
+ //#region src/mobile/utils/getSafeAreaInset/getSafeAreaInset.d.ts
3
+ type SafeAreaInset = {
4
+ /** Top safe area inset in pixels (notch, Dynamic Island, or status bar) */
5
+ top: number;
6
+ /** Bottom safe area inset in pixels (home indicator on Face ID devices) */
7
+ bottom: number;
8
+ /** Left safe area inset in pixels (rounded corners in landscape mode) */
9
+ left: number;
10
+ /** Right safe area inset in pixels (rounded corners in landscape mode) */
11
+ right: number;
12
+ };
13
+ /**
14
+ * @description
15
+ * `getSafeAreaInset` is a utility function that returns all safe area insets in pixels as an object.
16
+ *
17
+ * This function reads the CSS `env(safe-area-inset-*)` values by creating
18
+ * a temporary DOM element and reading its computed style.
19
+ *
20
+ * Safe area insets account for device-specific UI elements:
21
+ * - **top**: Notch, Dynamic Island, or status bar
22
+ * - **bottom**: Home indicator on Face ID devices
23
+ * - **left/right**: Rounded corners in landscape mode
24
+ *
25
+ * Typical values (iPhone with Face ID, portrait mode):
26
+ * - top: 47-59px (notch/Dynamic Island)
27
+ * - bottom: 34px (home indicator)
28
+ * - left/right: 0px
29
+ *
30
+ * @returns {SafeAreaInset} Object containing safe area insets for all four sides, or all 0 if not available.
31
+ * - top `number` - Top safe area inset in pixels;
32
+ * - bottom `number` - Bottom safe area inset in pixels;
33
+ * - left `number` - Left safe area inset in pixels;
34
+ * - right `number` - Right safe area inset in pixels;
35
+ *
36
+ * @example
37
+ * const { top, bottom, left, right } = getSafeAreaInset();
38
+ *
39
+ * header.style.paddingTop = `${top}px`;
40
+ * footer.style.paddingBottom = `${bottom}px`;
41
+ */
42
+ declare function getSafeAreaInset(): SafeAreaInset;
43
+ //#endregion
44
+ export { SafeAreaInset, getSafeAreaInset };