react-simplikit 0.0.52 → 0.1.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 +106 -0
- package/README.md +36 -26
- 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/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/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/usePreservedReference/usePreservedReference.cjs +1 -0
- package/dist/hooks/usePreservedReference/usePreservedReference.mjs +1 -0
- package/dist/hooks/usePrevious/usePrevious.cjs +1 -0
- package/dist/hooks/usePrevious/usePrevious.mjs +1 -0
- package/dist/hooks/useRefEffect/useRefEffect.cjs +1 -0
- package/dist/hooks/useRefEffect/useRefEffect.mjs +1 -0
- package/dist/hooks/useStorageState/useStorageState.cjs +1 -0
- package/dist/hooks/useStorageState/useStorageState.mjs +1 -0
- package/dist/hooks/useThrottledCallback/useThrottledCallback.cjs +9 -1
- package/dist/hooks/useThrottledCallback/useThrottledCallback.mjs +9 -1
- 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 +73 -0
- package/dist/mobile/hooks/usePageVisibility/usePageVisibility.d.cts +62 -0
- package/dist/mobile/hooks/usePageVisibility/usePageVisibility.d.mts +62 -0
- package/dist/mobile/hooks/usePageVisibility/usePageVisibility.mjs +73 -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/package.json +22 -8
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/mobile/utils/isServer/isServer.ts
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* `isServer` is a utility function that checks if the code is running on the server.
|
|
6
|
+
* It returns `true` in SSR (Server-Side Rendering) environments where `window` is undefined,
|
|
7
|
+
* and `false` in client-side environments.
|
|
8
|
+
*
|
|
9
|
+
* @returns {boolean} `true` if running in a server environment (SSR), `false` otherwise.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* if (isServer()) {
|
|
13
|
+
* // SSR-safe code
|
|
14
|
+
* return null;
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* // Client-only code
|
|
18
|
+
* window.addEventListener('resize', handleResize);
|
|
19
|
+
*/
|
|
20
|
+
function isServer() {
|
|
21
|
+
return typeof window === "undefined";
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
exports.isServer = isServer;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/utils/isServer/isServer.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* `isServer` is a utility function that checks if the code is running on the server.
|
|
6
|
+
* It returns `true` in SSR (Server-Side Rendering) environments where `window` is undefined,
|
|
7
|
+
* and `false` in client-side environments.
|
|
8
|
+
*
|
|
9
|
+
* @returns {boolean} `true` if running in a server environment (SSR), `false` otherwise.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* if (isServer()) {
|
|
13
|
+
* // SSR-safe code
|
|
14
|
+
* return null;
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* // Client-only code
|
|
18
|
+
* window.addEventListener('resize', handleResize);
|
|
19
|
+
*/
|
|
20
|
+
declare function isServer(): boolean;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { isServer };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/utils/isServer/isServer.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* `isServer` is a utility function that checks if the code is running on the server.
|
|
6
|
+
* It returns `true` in SSR (Server-Side Rendering) environments where `window` is undefined,
|
|
7
|
+
* and `false` in client-side environments.
|
|
8
|
+
*
|
|
9
|
+
* @returns {boolean} `true` if running in a server environment (SSR), `false` otherwise.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* if (isServer()) {
|
|
13
|
+
* // SSR-safe code
|
|
14
|
+
* return null;
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* // Client-only code
|
|
18
|
+
* window.addEventListener('resize', handleResize);
|
|
19
|
+
*/
|
|
20
|
+
declare function isServer(): boolean;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { isServer };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/mobile/utils/isServer/isServer.ts
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* `isServer` is a utility function that checks if the code is running on the server.
|
|
6
|
+
* It returns `true` in SSR (Server-Side Rendering) environments where `window` is undefined,
|
|
7
|
+
* and `false` in client-side environments.
|
|
8
|
+
*
|
|
9
|
+
* @returns {boolean} `true` if running in a server environment (SSR), `false` otherwise.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* if (isServer()) {
|
|
13
|
+
* // SSR-safe code
|
|
14
|
+
* return null;
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* // Client-only code
|
|
18
|
+
* window.addEventListener('resize', handleResize);
|
|
19
|
+
*/
|
|
20
|
+
function isServer() {
|
|
21
|
+
return typeof window === "undefined";
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { isServer };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_isServer = require("../isServer/isServer.cjs");
|
|
3
|
+
const require_getKeyboardHeight = require("../getKeyboardHeight/getKeyboardHeight.cjs");
|
|
4
|
+
//#region src/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.ts
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* `subscribeKeyboardHeight` is a utility function that subscribes to changes in the on-screen keyboard height.
|
|
8
|
+
*
|
|
9
|
+
* The provided callback is invoked whenever the keyboard height may change,
|
|
10
|
+
* including when the keyboard appears, disappears, or changes size.
|
|
11
|
+
*
|
|
12
|
+
* Internally, this function listens to both `resize` and `scroll` events
|
|
13
|
+
* on the Visual Viewport:
|
|
14
|
+
* - `resize`: triggered when the visual viewport height changes
|
|
15
|
+
* - `scroll`: triggered when the visual viewport offset changes
|
|
16
|
+
* (important for iOS where the viewport can shift without resizing)
|
|
17
|
+
*
|
|
18
|
+
* Performance optimizations:
|
|
19
|
+
* - Throttled by default (16ms, ~60fps) to prevent excessive callback invocations
|
|
20
|
+
* - Skips callback when height hasn't changed (deduplication)
|
|
21
|
+
*
|
|
22
|
+
* @param {SubscribeKeyboardHeightOptions} options - Configuration options
|
|
23
|
+
* @param {(height: number) => void} options.callback - A function that will be called with the updated keyboard height in pixels.
|
|
24
|
+
* @param {boolean} [options.immediate=false] - If true, the callback will be invoked immediately with the current keyboard height.
|
|
25
|
+
* @param {number} [options.throttleMs=16] - Throttle interval in milliseconds.
|
|
26
|
+
*
|
|
27
|
+
* @returns {SubscribeKeyboardHeightResult} An object containing the unsubscribe function.
|
|
28
|
+
* - unsubscribe `() => void` - Unsubscribes all listeners and stops receiving keyboard height updates.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const { unsubscribe } = subscribeKeyboardHeight({
|
|
32
|
+
* callback: (height) => {
|
|
33
|
+
* footer.style.paddingBottom = `${height}px`;
|
|
34
|
+
* },
|
|
35
|
+
* immediate: true,
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Later, when cleanup is needed
|
|
39
|
+
* unsubscribe();
|
|
40
|
+
*/
|
|
41
|
+
function subscribeKeyboardHeight({ callback, immediate = false, throttleMs = 16 }) {
|
|
42
|
+
if (require_isServer.isServer()) return { unsubscribe: () => {} };
|
|
43
|
+
const visualViewport = window.visualViewport;
|
|
44
|
+
if (!visualViewport) return { unsubscribe: () => {} };
|
|
45
|
+
let lastHeight = null;
|
|
46
|
+
let throttleTimer = null;
|
|
47
|
+
const handler = () => {
|
|
48
|
+
if (throttleTimer != null) return;
|
|
49
|
+
const currentHeight = require_getKeyboardHeight.getKeyboardHeight();
|
|
50
|
+
if (lastHeight === currentHeight) return;
|
|
51
|
+
lastHeight = currentHeight;
|
|
52
|
+
callback(currentHeight);
|
|
53
|
+
throttleTimer = setTimeout(() => {
|
|
54
|
+
throttleTimer = null;
|
|
55
|
+
}, throttleMs);
|
|
56
|
+
};
|
|
57
|
+
if (immediate) {
|
|
58
|
+
const currentHeight = require_getKeyboardHeight.getKeyboardHeight();
|
|
59
|
+
lastHeight = currentHeight;
|
|
60
|
+
callback(currentHeight);
|
|
61
|
+
}
|
|
62
|
+
visualViewport.addEventListener("resize", handler);
|
|
63
|
+
visualViewport.addEventListener("scroll", handler);
|
|
64
|
+
return { unsubscribe: () => {
|
|
65
|
+
visualViewport.removeEventListener("resize", handler);
|
|
66
|
+
visualViewport.removeEventListener("scroll", handler);
|
|
67
|
+
if (throttleTimer != null) clearTimeout(throttleTimer);
|
|
68
|
+
} };
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
exports.subscribeKeyboardHeight = subscribeKeyboardHeight;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.d.ts
|
|
3
|
+
type SubscribeKeyboardHeightOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* A function that will be called with the updated keyboard height in pixels.
|
|
6
|
+
*/
|
|
7
|
+
callback: (height: number) => void;
|
|
8
|
+
/**
|
|
9
|
+
* If true, the callback will be invoked immediately with the current keyboard height.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
immediate?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Throttle interval in milliseconds.
|
|
15
|
+
* Events within this interval will be ignored to improve performance.
|
|
16
|
+
* @default 16 (~60fps)
|
|
17
|
+
*/
|
|
18
|
+
throttleMs?: number;
|
|
19
|
+
};
|
|
20
|
+
type SubscribeKeyboardHeightResult = {
|
|
21
|
+
/**
|
|
22
|
+
* Unsubscribes all listeners and stops receiving keyboard height updates.
|
|
23
|
+
*/
|
|
24
|
+
unsubscribe: () => void;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* @description
|
|
28
|
+
* `subscribeKeyboardHeight` is a utility function that subscribes to changes in the on-screen keyboard height.
|
|
29
|
+
*
|
|
30
|
+
* The provided callback is invoked whenever the keyboard height may change,
|
|
31
|
+
* including when the keyboard appears, disappears, or changes size.
|
|
32
|
+
*
|
|
33
|
+
* Internally, this function listens to both `resize` and `scroll` events
|
|
34
|
+
* on the Visual Viewport:
|
|
35
|
+
* - `resize`: triggered when the visual viewport height changes
|
|
36
|
+
* - `scroll`: triggered when the visual viewport offset changes
|
|
37
|
+
* (important for iOS where the viewport can shift without resizing)
|
|
38
|
+
*
|
|
39
|
+
* Performance optimizations:
|
|
40
|
+
* - Throttled by default (16ms, ~60fps) to prevent excessive callback invocations
|
|
41
|
+
* - Skips callback when height hasn't changed (deduplication)
|
|
42
|
+
*
|
|
43
|
+
* @param {SubscribeKeyboardHeightOptions} options - Configuration options
|
|
44
|
+
* @param {(height: number) => void} options.callback - A function that will be called with the updated keyboard height in pixels.
|
|
45
|
+
* @param {boolean} [options.immediate=false] - If true, the callback will be invoked immediately with the current keyboard height.
|
|
46
|
+
* @param {number} [options.throttleMs=16] - Throttle interval in milliseconds.
|
|
47
|
+
*
|
|
48
|
+
* @returns {SubscribeKeyboardHeightResult} An object containing the unsubscribe function.
|
|
49
|
+
* - unsubscribe `() => void` - Unsubscribes all listeners and stops receiving keyboard height updates.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const { unsubscribe } = subscribeKeyboardHeight({
|
|
53
|
+
* callback: (height) => {
|
|
54
|
+
* footer.style.paddingBottom = `${height}px`;
|
|
55
|
+
* },
|
|
56
|
+
* immediate: true,
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* // Later, when cleanup is needed
|
|
60
|
+
* unsubscribe();
|
|
61
|
+
*/
|
|
62
|
+
declare function subscribeKeyboardHeight({ callback, immediate, throttleMs }: SubscribeKeyboardHeightOptions): SubscribeKeyboardHeightResult;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { subscribeKeyboardHeight };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.d.ts
|
|
3
|
+
type SubscribeKeyboardHeightOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* A function that will be called with the updated keyboard height in pixels.
|
|
6
|
+
*/
|
|
7
|
+
callback: (height: number) => void;
|
|
8
|
+
/**
|
|
9
|
+
* If true, the callback will be invoked immediately with the current keyboard height.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
immediate?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Throttle interval in milliseconds.
|
|
15
|
+
* Events within this interval will be ignored to improve performance.
|
|
16
|
+
* @default 16 (~60fps)
|
|
17
|
+
*/
|
|
18
|
+
throttleMs?: number;
|
|
19
|
+
};
|
|
20
|
+
type SubscribeKeyboardHeightResult = {
|
|
21
|
+
/**
|
|
22
|
+
* Unsubscribes all listeners and stops receiving keyboard height updates.
|
|
23
|
+
*/
|
|
24
|
+
unsubscribe: () => void;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* @description
|
|
28
|
+
* `subscribeKeyboardHeight` is a utility function that subscribes to changes in the on-screen keyboard height.
|
|
29
|
+
*
|
|
30
|
+
* The provided callback is invoked whenever the keyboard height may change,
|
|
31
|
+
* including when the keyboard appears, disappears, or changes size.
|
|
32
|
+
*
|
|
33
|
+
* Internally, this function listens to both `resize` and `scroll` events
|
|
34
|
+
* on the Visual Viewport:
|
|
35
|
+
* - `resize`: triggered when the visual viewport height changes
|
|
36
|
+
* - `scroll`: triggered when the visual viewport offset changes
|
|
37
|
+
* (important for iOS where the viewport can shift without resizing)
|
|
38
|
+
*
|
|
39
|
+
* Performance optimizations:
|
|
40
|
+
* - Throttled by default (16ms, ~60fps) to prevent excessive callback invocations
|
|
41
|
+
* - Skips callback when height hasn't changed (deduplication)
|
|
42
|
+
*
|
|
43
|
+
* @param {SubscribeKeyboardHeightOptions} options - Configuration options
|
|
44
|
+
* @param {(height: number) => void} options.callback - A function that will be called with the updated keyboard height in pixels.
|
|
45
|
+
* @param {boolean} [options.immediate=false] - If true, the callback will be invoked immediately with the current keyboard height.
|
|
46
|
+
* @param {number} [options.throttleMs=16] - Throttle interval in milliseconds.
|
|
47
|
+
*
|
|
48
|
+
* @returns {SubscribeKeyboardHeightResult} An object containing the unsubscribe function.
|
|
49
|
+
* - unsubscribe `() => void` - Unsubscribes all listeners and stops receiving keyboard height updates.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const { unsubscribe } = subscribeKeyboardHeight({
|
|
53
|
+
* callback: (height) => {
|
|
54
|
+
* footer.style.paddingBottom = `${height}px`;
|
|
55
|
+
* },
|
|
56
|
+
* immediate: true,
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* // Later, when cleanup is needed
|
|
60
|
+
* unsubscribe();
|
|
61
|
+
*/
|
|
62
|
+
declare function subscribeKeyboardHeight({ callback, immediate, throttleMs }: SubscribeKeyboardHeightOptions): SubscribeKeyboardHeightResult;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { subscribeKeyboardHeight };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { isServer } from "../isServer/isServer.mjs";
|
|
3
|
+
import { getKeyboardHeight } from "../getKeyboardHeight/getKeyboardHeight.mjs";
|
|
4
|
+
//#region src/mobile/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.ts
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* `subscribeKeyboardHeight` is a utility function that subscribes to changes in the on-screen keyboard height.
|
|
8
|
+
*
|
|
9
|
+
* The provided callback is invoked whenever the keyboard height may change,
|
|
10
|
+
* including when the keyboard appears, disappears, or changes size.
|
|
11
|
+
*
|
|
12
|
+
* Internally, this function listens to both `resize` and `scroll` events
|
|
13
|
+
* on the Visual Viewport:
|
|
14
|
+
* - `resize`: triggered when the visual viewport height changes
|
|
15
|
+
* - `scroll`: triggered when the visual viewport offset changes
|
|
16
|
+
* (important for iOS where the viewport can shift without resizing)
|
|
17
|
+
*
|
|
18
|
+
* Performance optimizations:
|
|
19
|
+
* - Throttled by default (16ms, ~60fps) to prevent excessive callback invocations
|
|
20
|
+
* - Skips callback when height hasn't changed (deduplication)
|
|
21
|
+
*
|
|
22
|
+
* @param {SubscribeKeyboardHeightOptions} options - Configuration options
|
|
23
|
+
* @param {(height: number) => void} options.callback - A function that will be called with the updated keyboard height in pixels.
|
|
24
|
+
* @param {boolean} [options.immediate=false] - If true, the callback will be invoked immediately with the current keyboard height.
|
|
25
|
+
* @param {number} [options.throttleMs=16] - Throttle interval in milliseconds.
|
|
26
|
+
*
|
|
27
|
+
* @returns {SubscribeKeyboardHeightResult} An object containing the unsubscribe function.
|
|
28
|
+
* - unsubscribe `() => void` - Unsubscribes all listeners and stops receiving keyboard height updates.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const { unsubscribe } = subscribeKeyboardHeight({
|
|
32
|
+
* callback: (height) => {
|
|
33
|
+
* footer.style.paddingBottom = `${height}px`;
|
|
34
|
+
* },
|
|
35
|
+
* immediate: true,
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Later, when cleanup is needed
|
|
39
|
+
* unsubscribe();
|
|
40
|
+
*/
|
|
41
|
+
function subscribeKeyboardHeight({ callback, immediate = false, throttleMs = 16 }) {
|
|
42
|
+
if (isServer()) return { unsubscribe: () => {} };
|
|
43
|
+
const visualViewport = window.visualViewport;
|
|
44
|
+
if (!visualViewport) return { unsubscribe: () => {} };
|
|
45
|
+
let lastHeight = null;
|
|
46
|
+
let throttleTimer = null;
|
|
47
|
+
const handler = () => {
|
|
48
|
+
if (throttleTimer != null) return;
|
|
49
|
+
const currentHeight = getKeyboardHeight();
|
|
50
|
+
if (lastHeight === currentHeight) return;
|
|
51
|
+
lastHeight = currentHeight;
|
|
52
|
+
callback(currentHeight);
|
|
53
|
+
throttleTimer = setTimeout(() => {
|
|
54
|
+
throttleTimer = null;
|
|
55
|
+
}, throttleMs);
|
|
56
|
+
};
|
|
57
|
+
if (immediate) {
|
|
58
|
+
const currentHeight = getKeyboardHeight();
|
|
59
|
+
lastHeight = currentHeight;
|
|
60
|
+
callback(currentHeight);
|
|
61
|
+
}
|
|
62
|
+
visualViewport.addEventListener("resize", handler);
|
|
63
|
+
visualViewport.addEventListener("scroll", handler);
|
|
64
|
+
return { unsubscribe: () => {
|
|
65
|
+
visualViewport.removeEventListener("resize", handler);
|
|
66
|
+
visualViewport.removeEventListener("scroll", handler);
|
|
67
|
+
if (throttleTimer != null) clearTimeout(throttleTimer);
|
|
68
|
+
} };
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { subscribeKeyboardHeight };
|
|
@@ -32,6 +32,7 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
32
32
|
function buildContext(contextName, defaultContextValues) {
|
|
33
33
|
const Context = (0, react.createContext)(defaultContextValues ?? void 0);
|
|
34
34
|
function Provider({ children, ...contextValues }) {
|
|
35
|
+
"use no memo";
|
|
35
36
|
const value = (0, react.useMemo)(() => Object.keys(contextValues).length > 0 ? contextValues : null, [...Object.values(contextValues)]);
|
|
36
37
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Context.Provider, {
|
|
37
38
|
value,
|
|
@@ -32,6 +32,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
32
32
|
function buildContext(contextName, defaultContextValues) {
|
|
33
33
|
const Context = createContext(defaultContextValues ?? void 0);
|
|
34
34
|
function Provider({ children, ...contextValues }) {
|
|
35
|
+
"use no memo";
|
|
35
36
|
const value = useMemo(() => Object.keys(contextValues).length > 0 ? contextValues : null, [...Object.values(contextValues)]);
|
|
36
37
|
return /* @__PURE__ */ jsx(Context.Provider, {
|
|
37
38
|
value,
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-simplikit",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React hooks, components and utilities — SSR-safe, zero dependencies, mobile web included",
|
|
4
5
|
"main": "./dist/index.cjs",
|
|
5
6
|
"module": "./dist/index.mjs",
|
|
6
7
|
"types": "./dist/index.d.cts",
|
|
@@ -20,14 +21,22 @@
|
|
|
20
21
|
"type": "module",
|
|
21
22
|
"sideEffects": false,
|
|
22
23
|
"keywords": [
|
|
23
|
-
"react"
|
|
24
|
+
"react",
|
|
25
|
+
"react-hooks",
|
|
26
|
+
"hooks",
|
|
27
|
+
"components",
|
|
28
|
+
"utils",
|
|
29
|
+
"typescript",
|
|
30
|
+
"ssr",
|
|
31
|
+
"zero-dependency",
|
|
32
|
+
"mobile-web"
|
|
24
33
|
],
|
|
25
34
|
"homepage": "https://react-simplikit.slash.page",
|
|
26
35
|
"bugs": "https://github.com/toss/react-simplikit/issues",
|
|
27
36
|
"repository": {
|
|
28
37
|
"type": "git",
|
|
29
38
|
"url": "git+https://github.com/toss/react-simplikit.git",
|
|
30
|
-
"directory": "packages/
|
|
39
|
+
"directory": "packages/react-simplikit"
|
|
31
40
|
},
|
|
32
41
|
"license": "MIT",
|
|
33
42
|
"files": [
|
|
@@ -40,14 +49,18 @@
|
|
|
40
49
|
"typecheck": "tsc --noEmit",
|
|
41
50
|
"test": "vitest run",
|
|
42
51
|
"test:watch": "vitest",
|
|
43
|
-
"test:coverage": "vitest run --coverage"
|
|
52
|
+
"test:coverage": "vitest run --coverage",
|
|
53
|
+
"test:compiled": "vitest run -c vitest.compiled.config.ts"
|
|
44
54
|
},
|
|
45
55
|
"publishConfig": {
|
|
46
56
|
"access": "public"
|
|
47
57
|
},
|
|
48
58
|
"devDependencies": {
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
59
|
+
"@babel/core": "^7.29.0",
|
|
60
|
+
"@babel/preset-react": "^7.27.0",
|
|
61
|
+
"@babel/preset-typescript": "^7.28.0",
|
|
62
|
+
"@changesets/changelog-github": "^1.0.0",
|
|
63
|
+
"@changesets/cli": "^3.0.1",
|
|
51
64
|
"@eslint/js": "^9.16.0",
|
|
52
65
|
"@testing-library/dom": "^10.4.0",
|
|
53
66
|
"@testing-library/jest-dom": "^6.6.3",
|
|
@@ -57,6 +70,7 @@
|
|
|
57
70
|
"@types/react": "^19.0.0",
|
|
58
71
|
"@types/react-dom": "^19.0.0",
|
|
59
72
|
"@vitest/coverage-v8": "^2.1.8",
|
|
73
|
+
"babel-plugin-react-compiler": "1.0.0",
|
|
60
74
|
"commander": "^13.1.0",
|
|
61
75
|
"comment-parser": "^1.4.1",
|
|
62
76
|
"corepack": "^0.30.0",
|
|
@@ -66,7 +80,7 @@
|
|
|
66
80
|
"eslint-plugin-import": "^2.31.0",
|
|
67
81
|
"eslint-plugin-prettier": "^5.2.1",
|
|
68
82
|
"eslint-plugin-react": "^7.37.2",
|
|
69
|
-
"eslint-plugin-react-hooks": "^
|
|
83
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
70
84
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
71
85
|
"eslint-plugin-unused-imports": "^4.1.4",
|
|
72
86
|
"fast-glob": "^3.3.3",
|
|
@@ -92,4 +106,4 @@
|
|
|
92
106
|
"peerDependencies": {
|
|
93
107
|
"react": "*"
|
|
94
108
|
}
|
|
95
|
-
}
|
|
109
|
+
}
|