react-native-keyboard-controller 1.11.2 → 1.11.4
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/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +52 -60
- package/ios/KeyboardController.xcodeproj/project.pbxproj +4 -0
- package/ios/observers/KeyboardMovementObserver.swift +1 -25
- package/ios/traversal/KeyboardView.swift +36 -0
- package/lib/commonjs/animated.js +14 -12
- package/lib/commonjs/animated.js.map +1 -1
- package/lib/commonjs/bindings.js +5 -10
- package/lib/commonjs/bindings.js.map +1 -1
- package/lib/commonjs/bindings.native.js +7 -15
- package/lib/commonjs/bindings.native.js.map +1 -1
- package/lib/commonjs/components/KeyboardAvoidingView/hooks.js.map +1 -1
- package/lib/commonjs/components/KeyboardAvoidingView/index.js +16 -23
- package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js +17 -19
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +7 -7
- package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/utils.js +3 -4
- package/lib/commonjs/components/KeyboardAwareScrollView/utils.js.map +1 -1
- package/lib/commonjs/components/KeyboardStickyView/index.js +15 -21
- package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/Arrow.js +8 -10
- package/lib/commonjs/components/KeyboardToolbar/Arrow.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/Button.js +23 -26
- package/lib/commonjs/components/KeyboardToolbar/Button.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/colors.js +1 -2
- package/lib/commonjs/components/KeyboardToolbar/colors.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/colors.native.js +1 -2
- package/lib/commonjs/components/KeyboardToolbar/colors.native.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/index.js +13 -14
- package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/types.js.map +1 -1
- package/lib/commonjs/components/hooks/useColorScheme.js +1 -2
- package/lib/commonjs/components/hooks/useColorScheme.js.map +1 -1
- package/lib/commonjs/components/index.js +2 -8
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/constants.js +3 -4
- package/lib/commonjs/constants.js.map +1 -1
- package/lib/commonjs/context.js +1 -2
- package/lib/commonjs/context.js.map +1 -1
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/commonjs/index.js +1 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal.js +1 -1
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/commonjs/monkey-patch.android.js +38 -26
- package/lib/commonjs/monkey-patch.android.js.map +1 -1
- package/lib/commonjs/monkey-patch.js +2 -4
- package/lib/commonjs/monkey-patch.js.map +1 -1
- package/lib/commonjs/reanimated.js +3 -6
- package/lib/commonjs/reanimated.js.map +1 -1
- package/lib/commonjs/reanimated.native.js.map +1 -1
- package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js +1 -2
- package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js +1 -2
- package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/NativeKeyboardController.js +1 -2
- package/lib/commonjs/specs/NativeKeyboardController.js.map +1 -1
- package/lib/commonjs/specs/NativeStatusBarManagerCompat.js +1 -2
- package/lib/commonjs/specs/NativeStatusBarManagerCompat.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/module/animated.js +12 -10
- package/lib/module/animated.js.map +1 -1
- package/lib/module/bindings.js.map +1 -1
- package/lib/module/bindings.native.js +3 -6
- package/lib/module/bindings.native.js.map +1 -1
- package/lib/module/components/KeyboardAvoidingView/hooks.js.map +1 -1
- package/lib/module/components/KeyboardAvoidingView/index.js +14 -19
- package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/index.js +15 -16
- package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +7 -7
- package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/utils.js +3 -4
- package/lib/module/components/KeyboardAwareScrollView/utils.js.map +1 -1
- package/lib/module/components/KeyboardStickyView/index.js +13 -17
- package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/Arrow.js +5 -6
- package/lib/module/components/KeyboardToolbar/Arrow.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/Button.js +20 -22
- package/lib/module/components/KeyboardToolbar/Button.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/colors.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/colors.native.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/index.js +10 -10
- package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/types.js.map +1 -1
- package/lib/module/components/hooks/useColorScheme.js.map +1 -1
- package/lib/module/components/index.js +1 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/constants.js +3 -3
- package/lib/module/constants.js.map +1 -1
- package/lib/module/context.js.map +1 -1
- package/lib/module/hooks.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal.js +1 -1
- package/lib/module/internal.js.map +1 -1
- package/lib/module/monkey-patch.android.js +36 -24
- package/lib/module/monkey-patch.android.js.map +1 -1
- package/lib/module/monkey-patch.js.map +1 -1
- package/lib/module/reanimated.js.map +1 -1
- package/lib/module/reanimated.native.js.map +1 -1
- package/lib/module/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
- package/lib/module/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
- package/lib/module/specs/NativeKeyboardController.js.map +1 -1
- package/lib/module/specs/NativeStatusBarManagerCompat.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/animated.d.ts +1 -1
- package/lib/typescript/components/KeyboardToolbar/Button.d.ts +1 -1
- package/lib/typescript/components/KeyboardToolbar/index.d.ts +5 -0
- package/lib/typescript/components/index.d.ts +2 -1
- package/lib/typescript/index.d.ts +2 -1
- package/package.json +7 -7
- package/src/animated.tsx +7 -3
- package/src/components/KeyboardAvoidingView/index.tsx +7 -8
- package/src/components/KeyboardAwareScrollView/index.tsx +4 -4
- package/src/components/KeyboardStickyView/index.tsx +6 -6
- package/src/components/KeyboardToolbar/index.tsx +38 -20
- package/src/components/index.ts +1 -1
- package/src/index.ts +1 -1
- package/src/monkey-patch.android.ts +31 -26
- package/lib/commonjs/components/hooks/useKeyboardInterpolation.js +0 -89
- package/lib/commonjs/components/hooks/useKeyboardInterpolation.js.map +0 -1
- package/lib/module/components/hooks/useKeyboardInterpolation.js +0 -82
- package/lib/module/components/hooks/useKeyboardInterpolation.js.map +0 -1
- package/lib/typescript/components/hooks/useKeyboardInterpolation.d.ts +0 -20
- package/src/components/hooks/useKeyboardInterpolation.ts +0 -109
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef, useCallback, useMemo } from "react";
|
|
2
|
-
import { useWindowDimensions } from "react-native";
|
|
2
|
+
import { findNodeHandle, useWindowDimensions } from "react-native";
|
|
3
3
|
import Reanimated, {
|
|
4
4
|
interpolate,
|
|
5
5
|
scrollTo,
|
|
@@ -121,8 +121,8 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
121
121
|
scrollViewAnimatedRef(assignedRef);
|
|
122
122
|
}, []);
|
|
123
123
|
const onScrollViewLayout = useCallback(
|
|
124
|
-
(e: LayoutChangeEvent
|
|
125
|
-
scrollViewTarget.value =
|
|
124
|
+
(e: LayoutChangeEvent) => {
|
|
125
|
+
scrollViewTarget.value = findNodeHandle(scrollViewAnimatedRef.current);
|
|
126
126
|
|
|
127
127
|
onLayout?.(e);
|
|
128
128
|
},
|
|
@@ -319,8 +319,8 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
319
319
|
<Reanimated.ScrollView
|
|
320
320
|
ref={onRef}
|
|
321
321
|
{...rest}
|
|
322
|
-
// @ts-expect-error https://github.com/facebook/react-native/pull/42785
|
|
323
322
|
onLayout={onScrollViewLayout}
|
|
323
|
+
// @ts-expect-error `onScrollReanimated` is a fake prop needed for reanimated to intercept scroll events
|
|
324
324
|
onScrollReanimated={onScroll}
|
|
325
325
|
scrollEventThrottle={16}
|
|
326
326
|
>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React, { forwardRef, useMemo } from "react";
|
|
2
|
-
import Reanimated, {
|
|
2
|
+
import Reanimated, {
|
|
3
|
+
interpolate,
|
|
4
|
+
useAnimatedStyle,
|
|
5
|
+
} from "react-native-reanimated";
|
|
3
6
|
|
|
4
7
|
import { useReanimatedKeyboardAnimation } from "react-native-keyboard-controller";
|
|
5
8
|
|
|
6
|
-
import useKeyboardInterpolation from "../hooks/useKeyboardInterpolation";
|
|
7
|
-
|
|
8
9
|
import type { View, ViewProps } from "react-native";
|
|
9
10
|
|
|
10
11
|
type KeyboardStickyViewProps = {
|
|
@@ -31,11 +32,10 @@ const KeyboardStickyView = forwardRef<
|
|
|
31
32
|
{ children, offset: { closed = 0, opened = 0 } = {}, style, ...props },
|
|
32
33
|
ref,
|
|
33
34
|
) => {
|
|
34
|
-
const { height } = useReanimatedKeyboardAnimation();
|
|
35
|
-
const { interpolate } = useKeyboardInterpolation();
|
|
35
|
+
const { height, progress } = useReanimatedKeyboardAnimation();
|
|
36
36
|
|
|
37
37
|
const stickyViewStyle = useAnimatedStyle(() => {
|
|
38
|
-
const offset = interpolate(
|
|
38
|
+
const offset = interpolate(progress.value, [0, 1], [closed, opened]);
|
|
39
39
|
|
|
40
40
|
return {
|
|
41
41
|
transform: [{ translateY: height.value + offset }],
|
|
@@ -27,6 +27,11 @@ export type KeyboardToolbarProps = {
|
|
|
27
27
|
button?: typeof Button;
|
|
28
28
|
/** Custom icon component used to display next/prev buttons. */
|
|
29
29
|
icon?: typeof Arrow;
|
|
30
|
+
/**
|
|
31
|
+
* Whether to show next and previous buttons. Can be useful to set it to `false` if you have only one input
|
|
32
|
+
* and want to show only `Done` button. Default to `true`.
|
|
33
|
+
*/
|
|
34
|
+
showArrows?: boolean;
|
|
30
35
|
};
|
|
31
36
|
const TEST_ID_KEYBOARD_TOOLBAR = "keyboard.toolbar";
|
|
32
37
|
const TEST_ID_KEYBOARD_TOOLBAR_PREVIOUS = `${TEST_ID_KEYBOARD_TOOLBAR}.previous`;
|
|
@@ -51,6 +56,7 @@ const KeyboardToolbar: React.FC<KeyboardToolbarProps> = ({
|
|
|
51
56
|
doneText,
|
|
52
57
|
button,
|
|
53
58
|
icon,
|
|
59
|
+
showArrows = true,
|
|
54
60
|
}) => {
|
|
55
61
|
const colorScheme = useColorScheme();
|
|
56
62
|
const [inputs, setInputs] = useState({
|
|
@@ -86,26 +92,38 @@ const KeyboardToolbar: React.FC<KeyboardToolbarProps> = ({
|
|
|
86
92
|
return (
|
|
87
93
|
<KeyboardStickyView offset={offset}>
|
|
88
94
|
<View style={toolbarStyle} testID={TEST_ID_KEYBOARD_TOOLBAR}>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
{showArrows && (
|
|
96
|
+
<>
|
|
97
|
+
<ButtonContainer
|
|
98
|
+
accessibilityLabel="Previous"
|
|
99
|
+
accessibilityHint="Will move focus to previous field"
|
|
100
|
+
disabled={isPrevDisabled}
|
|
101
|
+
onPress={goToPrevField}
|
|
102
|
+
testID={TEST_ID_KEYBOARD_TOOLBAR_PREVIOUS}
|
|
103
|
+
theme={theme}
|
|
104
|
+
>
|
|
105
|
+
<IconContainer
|
|
106
|
+
disabled={isPrevDisabled}
|
|
107
|
+
type="prev"
|
|
108
|
+
theme={theme}
|
|
109
|
+
/>
|
|
110
|
+
</ButtonContainer>
|
|
111
|
+
<ButtonContainer
|
|
112
|
+
accessibilityLabel="Next"
|
|
113
|
+
accessibilityHint="Will move focus to next field"
|
|
114
|
+
disabled={isNextDisabled}
|
|
115
|
+
onPress={goToNextField}
|
|
116
|
+
testID={TEST_ID_KEYBOARD_TOOLBAR_NEXT}
|
|
117
|
+
theme={theme}
|
|
118
|
+
>
|
|
119
|
+
<IconContainer
|
|
120
|
+
disabled={isNextDisabled}
|
|
121
|
+
type="next"
|
|
122
|
+
theme={theme}
|
|
123
|
+
/>
|
|
124
|
+
</ButtonContainer>
|
|
125
|
+
</>
|
|
126
|
+
)}
|
|
109
127
|
|
|
110
128
|
<View style={styles.flex} testID={TEST_ID_KEYBOARD_TOOLBAR_CONTENT}>
|
|
111
129
|
{content}
|
package/src/components/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,39 +1,44 @@
|
|
|
1
1
|
// @ts-expect-error because there is no corresponding type definition
|
|
2
2
|
import * as NativeAndroidManager from "react-native/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid";
|
|
3
3
|
|
|
4
|
-
const DefaultNativeAndroidManager = NativeAndroidManager.default;
|
|
5
|
-
const getConstants = NativeAndroidManager.default.getConstants;
|
|
6
4
|
const RCTStatusBarManagerCompat =
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
7
6
|
require("./specs/NativeStatusBarManagerCompat").default;
|
|
8
7
|
|
|
8
|
+
// Copy original default manager to keep its original state and methods
|
|
9
|
+
const OriginalNativeAndroidManager = { ...NativeAndroidManager.default };
|
|
10
|
+
|
|
11
|
+
// Create a new object that modifies the necessary methods
|
|
9
12
|
// On Android < 11 RN uses legacy API which breaks EdgeToEdge mode in RN, so
|
|
10
13
|
// in order to use library on all available platforms we have to monkey patch
|
|
11
14
|
// default RN implementation and use modern `WindowInsetsControllerCompat`.
|
|
12
|
-
|
|
13
|
-
NativeAndroidManager.default
|
|
14
|
-
|
|
15
|
-
setColor(color
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
const ModifiedNativeAndroidManager = {
|
|
16
|
+
...NativeAndroidManager.default, // Spread original properties to keep existing functionality
|
|
17
|
+
setColor: (color: number, animated: boolean): void => {
|
|
18
|
+
RCTStatusBarManagerCompat.setColor(color, animated);
|
|
19
|
+
},
|
|
20
|
+
setTranslucent: (translucent: boolean): void => {
|
|
21
|
+
RCTStatusBarManagerCompat.setTranslucent(translucent);
|
|
22
|
+
},
|
|
23
|
+
/**
|
|
24
|
+
* - statusBarStyles can be:
|
|
25
|
+
* - 'default'
|
|
26
|
+
* - 'dark-content'
|
|
27
|
+
*/
|
|
28
|
+
setStyle: (statusBarStyle?: string): void => {
|
|
29
|
+
RCTStatusBarManagerCompat.setStyle(statusBarStyle);
|
|
30
|
+
},
|
|
31
|
+
setHidden: (hidden: boolean): void => {
|
|
32
|
+
RCTStatusBarManagerCompat.setHidden(hidden);
|
|
33
|
+
},
|
|
34
|
+
};
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
};
|
|
36
|
+
// Define a function to apply the monkey patch
|
|
37
|
+
export const applyMonkeyPatch = () => {
|
|
38
|
+
Object.assign(NativeAndroidManager.default, ModifiedNativeAndroidManager);
|
|
36
39
|
};
|
|
40
|
+
|
|
41
|
+
// Define a function to revert changes back to the original state
|
|
37
42
|
export const revertMonkeyPatch = () => {
|
|
38
|
-
NativeAndroidManager.default
|
|
43
|
+
Object.assign(NativeAndroidManager.default, OriginalNativeAndroidManager);
|
|
39
44
|
};
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _reactNative = require("react-native");
|
|
8
|
-
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
|
-
var _reactNativeKeyboardController = require("react-native-keyboard-controller");
|
|
10
|
-
/**
|
|
11
|
-
* Hook that can be used for interpolation keyboard movement. The main concern is the thing
|
|
12
|
-
* when keyboard is opened and gets resized on Android. Let's say we are interpolating from
|
|
13
|
-
* closed to open [0, 200] and we want to interpolate it to [0, 230] (to achieve nice parallax effect).
|
|
14
|
-
* Then let's say keyboard changes its height to 220 (and we want to interpolate the value to 250, +30
|
|
15
|
-
* to keyboard height). If we interpolate based on `progress` value, then we will have a jump on first frame:
|
|
16
|
-
* the last interpolated position was 230, now we will interpolate to 250, but first frame will be calculated
|
|
17
|
-
* as 200 / 220 * 250 = 227 (and last interpolated position was 230) so we will have a jump.
|
|
18
|
-
*
|
|
19
|
-
* This hook handles it, and when keyboard changes its size it does an interpolation as:
|
|
20
|
-
* [200, 220] -> [230, 250], i. e. we preserve last interpolated value and use it as initial value for interpolation
|
|
21
|
-
* and because of that we will not have a jump and animation will start from the last frame and will be smooth.
|
|
22
|
-
*
|
|
23
|
-
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/315
|
|
24
|
-
*/
|
|
25
|
-
const useKeyboardInterpolation = () => {
|
|
26
|
-
// keyboard heights
|
|
27
|
-
const nextKeyboardHeight = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
28
|
-
const prevKeyboardHeight = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
29
|
-
// save latest interpolated position
|
|
30
|
-
const lastInterpolation = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
31
|
-
// boolean flag indicating which output range should be used
|
|
32
|
-
const shouldUseInternalInterpolation = (0, _reactNativeReanimated.useSharedValue)(false);
|
|
33
|
-
const interpolate = (keyboardPosition, output) => {
|
|
34
|
-
"worklet";
|
|
35
|
-
|
|
36
|
-
// on iOS it's safe to interpolate between 0 and `fullKeyboardSize` because when
|
|
37
|
-
// keyboard resized we will not have intermediate values and transition will be instant
|
|
38
|
-
// see: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/327
|
|
39
|
-
if (_reactNative.Platform.OS === "ios") {
|
|
40
|
-
return (0, _reactNativeReanimated.interpolate)(keyboardPosition, [0, nextKeyboardHeight.value], output);
|
|
41
|
-
}
|
|
42
|
-
const interpolation = (0, _reactNativeReanimated.interpolate)(keyboardPosition, [prevKeyboardHeight.value, nextKeyboardHeight.value], shouldUseInternalInterpolation.value ? [lastInterpolation.value, output[1]] : output);
|
|
43
|
-
lastInterpolation.value = interpolation;
|
|
44
|
-
return interpolation;
|
|
45
|
-
};
|
|
46
|
-
(0, _reactNativeKeyboardController.useKeyboardHandler)({
|
|
47
|
-
onStart: e => {
|
|
48
|
-
"worklet";
|
|
49
|
-
|
|
50
|
-
const keyboardWillBeHidden = e.height === 0;
|
|
51
|
-
|
|
52
|
-
// keyboard will be hidden
|
|
53
|
-
if (keyboardWillBeHidden) {
|
|
54
|
-
shouldUseInternalInterpolation.value = false;
|
|
55
|
-
prevKeyboardHeight.value = 0;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// keyboard will change its size
|
|
59
|
-
if (
|
|
60
|
-
// keyboard is shown on screen
|
|
61
|
-
nextKeyboardHeight.value !== 0 &&
|
|
62
|
-
// it really changes size (handles iOS case when after interactive keyboard gets shown again)
|
|
63
|
-
nextKeyboardHeight.value !== e.height &&
|
|
64
|
-
// keyboard is not hiding
|
|
65
|
-
!keyboardWillBeHidden) {
|
|
66
|
-
prevKeyboardHeight.value = nextKeyboardHeight.value;
|
|
67
|
-
shouldUseInternalInterpolation.value = true;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// keyboard will show or change size
|
|
71
|
-
if (!keyboardWillBeHidden) {
|
|
72
|
-
nextKeyboardHeight.value = e.height;
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
onEnd: e => {
|
|
76
|
-
"worklet";
|
|
77
|
-
|
|
78
|
-
// handles case show -> resize -> hide -> show
|
|
79
|
-
// here we reset value to 0 when keyboard is hidden
|
|
80
|
-
nextKeyboardHeight.value = e.height;
|
|
81
|
-
}
|
|
82
|
-
}, []);
|
|
83
|
-
return {
|
|
84
|
-
interpolate
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
var _default = useKeyboardInterpolation;
|
|
88
|
-
exports.default = _default;
|
|
89
|
-
//# sourceMappingURL=useKeyboardInterpolation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_reactNativeReanimated","_reactNativeKeyboardController","useKeyboardInterpolation","nextKeyboardHeight","useSharedValue","prevKeyboardHeight","lastInterpolation","shouldUseInternalInterpolation","interpolate","keyboardPosition","output","Platform","OS","interpolateREA","value","interpolation","useKeyboardHandler","onStart","e","keyboardWillBeHidden","height","onEnd","_default","exports","default"],"sources":["useKeyboardInterpolation.ts"],"sourcesContent":["import { Platform } from \"react-native\";\nimport {\n interpolate as interpolateREA,\n useSharedValue,\n} from \"react-native-reanimated\";\n\nimport { useKeyboardHandler } from \"react-native-keyboard-controller\";\n\ntype KeyboardInterpolationOutput = [number, number];\n\n/**\n * Hook that can be used for interpolation keyboard movement. The main concern is the thing\n * when keyboard is opened and gets resized on Android. Let's say we are interpolating from\n * closed to open [0, 200] and we want to interpolate it to [0, 230] (to achieve nice parallax effect).\n * Then let's say keyboard changes its height to 220 (and we want to interpolate the value to 250, +30\n * to keyboard height). If we interpolate based on `progress` value, then we will have a jump on first frame:\n * the last interpolated position was 230, now we will interpolate to 250, but first frame will be calculated\n * as 200 / 220 * 250 = 227 (and last interpolated position was 230) so we will have a jump.\n *\n * This hook handles it, and when keyboard changes its size it does an interpolation as:\n * [200, 220] -> [230, 250], i. e. we preserve last interpolated value and use it as initial value for interpolation\n * and because of that we will not have a jump and animation will start from the last frame and will be smooth.\n *\n * @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/315\n */\nconst useKeyboardInterpolation = () => {\n // keyboard heights\n const nextKeyboardHeight = useSharedValue(0);\n const prevKeyboardHeight = useSharedValue(0);\n // save latest interpolated position\n const lastInterpolation = useSharedValue(0);\n // boolean flag indicating which output range should be used\n const shouldUseInternalInterpolation = useSharedValue(false);\n\n const interpolate = (\n keyboardPosition: number,\n output: KeyboardInterpolationOutput,\n ) => {\n \"worklet\";\n\n // on iOS it's safe to interpolate between 0 and `fullKeyboardSize` because when\n // keyboard resized we will not have intermediate values and transition will be instant\n // see: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/327\n if (Platform.OS === \"ios\") {\n return interpolateREA(\n keyboardPosition,\n [0, nextKeyboardHeight.value],\n output,\n );\n }\n\n const interpolation = interpolateREA(\n keyboardPosition,\n [prevKeyboardHeight.value, nextKeyboardHeight.value],\n shouldUseInternalInterpolation.value\n ? [lastInterpolation.value, output[1]]\n : output,\n );\n lastInterpolation.value = interpolation;\n\n return interpolation;\n };\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n const keyboardWillBeHidden = e.height === 0;\n\n // keyboard will be hidden\n if (keyboardWillBeHidden) {\n shouldUseInternalInterpolation.value = false;\n prevKeyboardHeight.value = 0;\n }\n\n // keyboard will change its size\n if (\n // keyboard is shown on screen\n nextKeyboardHeight.value !== 0 &&\n // it really changes size (handles iOS case when after interactive keyboard gets shown again)\n nextKeyboardHeight.value !== e.height &&\n // keyboard is not hiding\n !keyboardWillBeHidden\n ) {\n prevKeyboardHeight.value = nextKeyboardHeight.value;\n shouldUseInternalInterpolation.value = true;\n }\n\n // keyboard will show or change size\n if (!keyboardWillBeHidden) {\n nextKeyboardHeight.value = e.height;\n }\n },\n onEnd: (e) => {\n \"worklet\";\n\n // handles case show -> resize -> hide -> show\n // here we reset value to 0 when keyboard is hidden\n nextKeyboardHeight.value = e.height;\n },\n },\n [],\n );\n\n return { interpolate };\n};\n\nexport default useKeyboardInterpolation;\n"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAKA,IAAAE,8BAAA,GAAAF,OAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMG,wBAAwB,GAAGA,CAAA,KAAM;EACrC;EACA,MAAMC,kBAAkB,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EAC5C,MAAMC,kBAAkB,GAAG,IAAAD,qCAAc,EAAC,CAAC,CAAC;EAC5C;EACA,MAAME,iBAAiB,GAAG,IAAAF,qCAAc,EAAC,CAAC,CAAC;EAC3C;EACA,MAAMG,8BAA8B,GAAG,IAAAH,qCAAc,EAAC,KAAK,CAAC;EAE5D,MAAMI,WAAW,GAAGA,CAClBC,gBAAwB,EACxBC,MAAmC,KAChC;IACH,SAAS;;IAET;IACA;IACA;IACA,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzB,OAAO,IAAAC,kCAAc,EACnBJ,gBAAgB,EAChB,CAAC,CAAC,EAAEN,kBAAkB,CAACW,KAAK,CAAC,EAC7BJ,MACF,CAAC;IACH;IAEA,MAAMK,aAAa,GAAG,IAAAF,kCAAc,EAClCJ,gBAAgB,EAChB,CAACJ,kBAAkB,CAACS,KAAK,EAAEX,kBAAkB,CAACW,KAAK,CAAC,EACpDP,8BAA8B,CAACO,KAAK,GAChC,CAACR,iBAAiB,CAACQ,KAAK,EAAEJ,MAAM,CAAC,CAAC,CAAC,CAAC,GACpCA,MACN,CAAC;IACDJ,iBAAiB,CAACQ,KAAK,GAAGC,aAAa;IAEvC,OAAOA,aAAa;EACtB,CAAC;EAED,IAAAC,iDAAkB,EAChB;IACEC,OAAO,EAAGC,CAAC,IAAK;MACd,SAAS;;MAET,MAAMC,oBAAoB,GAAGD,CAAC,CAACE,MAAM,KAAK,CAAC;;MAE3C;MACA,IAAID,oBAAoB,EAAE;QACxBZ,8BAA8B,CAACO,KAAK,GAAG,KAAK;QAC5CT,kBAAkB,CAACS,KAAK,GAAG,CAAC;MAC9B;;MAEA;MACA;MACE;MACAX,kBAAkB,CAACW,KAAK,KAAK,CAAC;MAC9B;MACAX,kBAAkB,CAACW,KAAK,KAAKI,CAAC,CAACE,MAAM;MACrC;MACA,CAACD,oBAAoB,EACrB;QACAd,kBAAkB,CAACS,KAAK,GAAGX,kBAAkB,CAACW,KAAK;QACnDP,8BAA8B,CAACO,KAAK,GAAG,IAAI;MAC7C;;MAEA;MACA,IAAI,CAACK,oBAAoB,EAAE;QACzBhB,kBAAkB,CAACW,KAAK,GAAGI,CAAC,CAACE,MAAM;MACrC;IACF,CAAC;IACDC,KAAK,EAAGH,CAAC,IAAK;MACZ,SAAS;;MAET;MACA;MACAf,kBAAkB,CAACW,KAAK,GAAGI,CAAC,CAACE,MAAM;IACrC;EACF,CAAC,EACD,EACF,CAAC;EAED,OAAO;IAAEZ;EAAY,CAAC;AACxB,CAAC;AAAC,IAAAc,QAAA,GAEapB,wBAAwB;AAAAqB,OAAA,CAAAC,OAAA,GAAAF,QAAA"}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { Platform } from "react-native";
|
|
2
|
-
import { interpolate as interpolateREA, useSharedValue } from "react-native-reanimated";
|
|
3
|
-
import { useKeyboardHandler } from "react-native-keyboard-controller";
|
|
4
|
-
/**
|
|
5
|
-
* Hook that can be used for interpolation keyboard movement. The main concern is the thing
|
|
6
|
-
* when keyboard is opened and gets resized on Android. Let's say we are interpolating from
|
|
7
|
-
* closed to open [0, 200] and we want to interpolate it to [0, 230] (to achieve nice parallax effect).
|
|
8
|
-
* Then let's say keyboard changes its height to 220 (and we want to interpolate the value to 250, +30
|
|
9
|
-
* to keyboard height). If we interpolate based on `progress` value, then we will have a jump on first frame:
|
|
10
|
-
* the last interpolated position was 230, now we will interpolate to 250, but first frame will be calculated
|
|
11
|
-
* as 200 / 220 * 250 = 227 (and last interpolated position was 230) so we will have a jump.
|
|
12
|
-
*
|
|
13
|
-
* This hook handles it, and when keyboard changes its size it does an interpolation as:
|
|
14
|
-
* [200, 220] -> [230, 250], i. e. we preserve last interpolated value and use it as initial value for interpolation
|
|
15
|
-
* and because of that we will not have a jump and animation will start from the last frame and will be smooth.
|
|
16
|
-
*
|
|
17
|
-
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/315
|
|
18
|
-
*/
|
|
19
|
-
const useKeyboardInterpolation = () => {
|
|
20
|
-
// keyboard heights
|
|
21
|
-
const nextKeyboardHeight = useSharedValue(0);
|
|
22
|
-
const prevKeyboardHeight = useSharedValue(0);
|
|
23
|
-
// save latest interpolated position
|
|
24
|
-
const lastInterpolation = useSharedValue(0);
|
|
25
|
-
// boolean flag indicating which output range should be used
|
|
26
|
-
const shouldUseInternalInterpolation = useSharedValue(false);
|
|
27
|
-
const interpolate = (keyboardPosition, output) => {
|
|
28
|
-
"worklet";
|
|
29
|
-
|
|
30
|
-
// on iOS it's safe to interpolate between 0 and `fullKeyboardSize` because when
|
|
31
|
-
// keyboard resized we will not have intermediate values and transition will be instant
|
|
32
|
-
// see: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/327
|
|
33
|
-
if (Platform.OS === "ios") {
|
|
34
|
-
return interpolateREA(keyboardPosition, [0, nextKeyboardHeight.value], output);
|
|
35
|
-
}
|
|
36
|
-
const interpolation = interpolateREA(keyboardPosition, [prevKeyboardHeight.value, nextKeyboardHeight.value], shouldUseInternalInterpolation.value ? [lastInterpolation.value, output[1]] : output);
|
|
37
|
-
lastInterpolation.value = interpolation;
|
|
38
|
-
return interpolation;
|
|
39
|
-
};
|
|
40
|
-
useKeyboardHandler({
|
|
41
|
-
onStart: e => {
|
|
42
|
-
"worklet";
|
|
43
|
-
|
|
44
|
-
const keyboardWillBeHidden = e.height === 0;
|
|
45
|
-
|
|
46
|
-
// keyboard will be hidden
|
|
47
|
-
if (keyboardWillBeHidden) {
|
|
48
|
-
shouldUseInternalInterpolation.value = false;
|
|
49
|
-
prevKeyboardHeight.value = 0;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// keyboard will change its size
|
|
53
|
-
if (
|
|
54
|
-
// keyboard is shown on screen
|
|
55
|
-
nextKeyboardHeight.value !== 0 &&
|
|
56
|
-
// it really changes size (handles iOS case when after interactive keyboard gets shown again)
|
|
57
|
-
nextKeyboardHeight.value !== e.height &&
|
|
58
|
-
// keyboard is not hiding
|
|
59
|
-
!keyboardWillBeHidden) {
|
|
60
|
-
prevKeyboardHeight.value = nextKeyboardHeight.value;
|
|
61
|
-
shouldUseInternalInterpolation.value = true;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// keyboard will show or change size
|
|
65
|
-
if (!keyboardWillBeHidden) {
|
|
66
|
-
nextKeyboardHeight.value = e.height;
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
onEnd: e => {
|
|
70
|
-
"worklet";
|
|
71
|
-
|
|
72
|
-
// handles case show -> resize -> hide -> show
|
|
73
|
-
// here we reset value to 0 when keyboard is hidden
|
|
74
|
-
nextKeyboardHeight.value = e.height;
|
|
75
|
-
}
|
|
76
|
-
}, []);
|
|
77
|
-
return {
|
|
78
|
-
interpolate
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
export default useKeyboardInterpolation;
|
|
82
|
-
//# sourceMappingURL=useKeyboardInterpolation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","interpolate","interpolateREA","useSharedValue","useKeyboardHandler","useKeyboardInterpolation","nextKeyboardHeight","prevKeyboardHeight","lastInterpolation","shouldUseInternalInterpolation","keyboardPosition","output","OS","value","interpolation","onStart","e","keyboardWillBeHidden","height","onEnd"],"sources":["useKeyboardInterpolation.ts"],"sourcesContent":["import { Platform } from \"react-native\";\nimport {\n interpolate as interpolateREA,\n useSharedValue,\n} from \"react-native-reanimated\";\n\nimport { useKeyboardHandler } from \"react-native-keyboard-controller\";\n\ntype KeyboardInterpolationOutput = [number, number];\n\n/**\n * Hook that can be used for interpolation keyboard movement. The main concern is the thing\n * when keyboard is opened and gets resized on Android. Let's say we are interpolating from\n * closed to open [0, 200] and we want to interpolate it to [0, 230] (to achieve nice parallax effect).\n * Then let's say keyboard changes its height to 220 (and we want to interpolate the value to 250, +30\n * to keyboard height). If we interpolate based on `progress` value, then we will have a jump on first frame:\n * the last interpolated position was 230, now we will interpolate to 250, but first frame will be calculated\n * as 200 / 220 * 250 = 227 (and last interpolated position was 230) so we will have a jump.\n *\n * This hook handles it, and when keyboard changes its size it does an interpolation as:\n * [200, 220] -> [230, 250], i. e. we preserve last interpolated value and use it as initial value for interpolation\n * and because of that we will not have a jump and animation will start from the last frame and will be smooth.\n *\n * @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/315\n */\nconst useKeyboardInterpolation = () => {\n // keyboard heights\n const nextKeyboardHeight = useSharedValue(0);\n const prevKeyboardHeight = useSharedValue(0);\n // save latest interpolated position\n const lastInterpolation = useSharedValue(0);\n // boolean flag indicating which output range should be used\n const shouldUseInternalInterpolation = useSharedValue(false);\n\n const interpolate = (\n keyboardPosition: number,\n output: KeyboardInterpolationOutput,\n ) => {\n \"worklet\";\n\n // on iOS it's safe to interpolate between 0 and `fullKeyboardSize` because when\n // keyboard resized we will not have intermediate values and transition will be instant\n // see: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/327\n if (Platform.OS === \"ios\") {\n return interpolateREA(\n keyboardPosition,\n [0, nextKeyboardHeight.value],\n output,\n );\n }\n\n const interpolation = interpolateREA(\n keyboardPosition,\n [prevKeyboardHeight.value, nextKeyboardHeight.value],\n shouldUseInternalInterpolation.value\n ? [lastInterpolation.value, output[1]]\n : output,\n );\n lastInterpolation.value = interpolation;\n\n return interpolation;\n };\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n const keyboardWillBeHidden = e.height === 0;\n\n // keyboard will be hidden\n if (keyboardWillBeHidden) {\n shouldUseInternalInterpolation.value = false;\n prevKeyboardHeight.value = 0;\n }\n\n // keyboard will change its size\n if (\n // keyboard is shown on screen\n nextKeyboardHeight.value !== 0 &&\n // it really changes size (handles iOS case when after interactive keyboard gets shown again)\n nextKeyboardHeight.value !== e.height &&\n // keyboard is not hiding\n !keyboardWillBeHidden\n ) {\n prevKeyboardHeight.value = nextKeyboardHeight.value;\n shouldUseInternalInterpolation.value = true;\n }\n\n // keyboard will show or change size\n if (!keyboardWillBeHidden) {\n nextKeyboardHeight.value = e.height;\n }\n },\n onEnd: (e) => {\n \"worklet\";\n\n // handles case show -> resize -> hide -> show\n // here we reset value to 0 when keyboard is hidden\n nextKeyboardHeight.value = e.height;\n },\n },\n [],\n );\n\n return { interpolate };\n};\n\nexport default useKeyboardInterpolation;\n"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SACEC,WAAW,IAAIC,cAAc,EAC7BC,cAAc,QACT,yBAAyB;AAEhC,SAASC,kBAAkB,QAAQ,kCAAkC;AAIrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,wBAAwB,GAAGA,CAAA,KAAM;EACrC;EACA,MAAMC,kBAAkB,GAAGH,cAAc,CAAC,CAAC,CAAC;EAC5C,MAAMI,kBAAkB,GAAGJ,cAAc,CAAC,CAAC,CAAC;EAC5C;EACA,MAAMK,iBAAiB,GAAGL,cAAc,CAAC,CAAC,CAAC;EAC3C;EACA,MAAMM,8BAA8B,GAAGN,cAAc,CAAC,KAAK,CAAC;EAE5D,MAAMF,WAAW,GAAGA,CAClBS,gBAAwB,EACxBC,MAAmC,KAChC;IACH,SAAS;;IAET;IACA;IACA;IACA,IAAIX,QAAQ,CAACY,EAAE,KAAK,KAAK,EAAE;MACzB,OAAOV,cAAc,CACnBQ,gBAAgB,EAChB,CAAC,CAAC,EAAEJ,kBAAkB,CAACO,KAAK,CAAC,EAC7BF,MACF,CAAC;IACH;IAEA,MAAMG,aAAa,GAAGZ,cAAc,CAClCQ,gBAAgB,EAChB,CAACH,kBAAkB,CAACM,KAAK,EAAEP,kBAAkB,CAACO,KAAK,CAAC,EACpDJ,8BAA8B,CAACI,KAAK,GAChC,CAACL,iBAAiB,CAACK,KAAK,EAAEF,MAAM,CAAC,CAAC,CAAC,CAAC,GACpCA,MACN,CAAC;IACDH,iBAAiB,CAACK,KAAK,GAAGC,aAAa;IAEvC,OAAOA,aAAa;EACtB,CAAC;EAEDV,kBAAkB,CAChB;IACEW,OAAO,EAAGC,CAAC,IAAK;MACd,SAAS;;MAET,MAAMC,oBAAoB,GAAGD,CAAC,CAACE,MAAM,KAAK,CAAC;;MAE3C;MACA,IAAID,oBAAoB,EAAE;QACxBR,8BAA8B,CAACI,KAAK,GAAG,KAAK;QAC5CN,kBAAkB,CAACM,KAAK,GAAG,CAAC;MAC9B;;MAEA;MACA;MACE;MACAP,kBAAkB,CAACO,KAAK,KAAK,CAAC;MAC9B;MACAP,kBAAkB,CAACO,KAAK,KAAKG,CAAC,CAACE,MAAM;MACrC;MACA,CAACD,oBAAoB,EACrB;QACAV,kBAAkB,CAACM,KAAK,GAAGP,kBAAkB,CAACO,KAAK;QACnDJ,8BAA8B,CAACI,KAAK,GAAG,IAAI;MAC7C;;MAEA;MACA,IAAI,CAACI,oBAAoB,EAAE;QACzBX,kBAAkB,CAACO,KAAK,GAAGG,CAAC,CAACE,MAAM;MACrC;IACF,CAAC;IACDC,KAAK,EAAGH,CAAC,IAAK;MACZ,SAAS;;MAET;MACA;MACAV,kBAAkB,CAACO,KAAK,GAAGG,CAAC,CAACE,MAAM;IACrC;EACF,CAAC,EACD,EACF,CAAC;EAED,OAAO;IAAEjB;EAAY,CAAC;AACxB,CAAC;AAED,eAAeI,wBAAwB"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
type KeyboardInterpolationOutput = [number, number];
|
|
2
|
-
/**
|
|
3
|
-
* Hook that can be used for interpolation keyboard movement. The main concern is the thing
|
|
4
|
-
* when keyboard is opened and gets resized on Android. Let's say we are interpolating from
|
|
5
|
-
* closed to open [0, 200] and we want to interpolate it to [0, 230] (to achieve nice parallax effect).
|
|
6
|
-
* Then let's say keyboard changes its height to 220 (and we want to interpolate the value to 250, +30
|
|
7
|
-
* to keyboard height). If we interpolate based on `progress` value, then we will have a jump on first frame:
|
|
8
|
-
* the last interpolated position was 230, now we will interpolate to 250, but first frame will be calculated
|
|
9
|
-
* as 200 / 220 * 250 = 227 (and last interpolated position was 230) so we will have a jump.
|
|
10
|
-
*
|
|
11
|
-
* This hook handles it, and when keyboard changes its size it does an interpolation as:
|
|
12
|
-
* [200, 220] -> [230, 250], i. e. we preserve last interpolated value and use it as initial value for interpolation
|
|
13
|
-
* and because of that we will not have a jump and animation will start from the last frame and will be smooth.
|
|
14
|
-
*
|
|
15
|
-
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/315
|
|
16
|
-
*/
|
|
17
|
-
declare const useKeyboardInterpolation: () => {
|
|
18
|
-
interpolate: (keyboardPosition: number, output: KeyboardInterpolationOutput) => number;
|
|
19
|
-
};
|
|
20
|
-
export default useKeyboardInterpolation;
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { Platform } from "react-native";
|
|
2
|
-
import {
|
|
3
|
-
interpolate as interpolateREA,
|
|
4
|
-
useSharedValue,
|
|
5
|
-
} from "react-native-reanimated";
|
|
6
|
-
|
|
7
|
-
import { useKeyboardHandler } from "react-native-keyboard-controller";
|
|
8
|
-
|
|
9
|
-
type KeyboardInterpolationOutput = [number, number];
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Hook that can be used for interpolation keyboard movement. The main concern is the thing
|
|
13
|
-
* when keyboard is opened and gets resized on Android. Let's say we are interpolating from
|
|
14
|
-
* closed to open [0, 200] and we want to interpolate it to [0, 230] (to achieve nice parallax effect).
|
|
15
|
-
* Then let's say keyboard changes its height to 220 (and we want to interpolate the value to 250, +30
|
|
16
|
-
* to keyboard height). If we interpolate based on `progress` value, then we will have a jump on first frame:
|
|
17
|
-
* the last interpolated position was 230, now we will interpolate to 250, but first frame will be calculated
|
|
18
|
-
* as 200 / 220 * 250 = 227 (and last interpolated position was 230) so we will have a jump.
|
|
19
|
-
*
|
|
20
|
-
* This hook handles it, and when keyboard changes its size it does an interpolation as:
|
|
21
|
-
* [200, 220] -> [230, 250], i. e. we preserve last interpolated value and use it as initial value for interpolation
|
|
22
|
-
* and because of that we will not have a jump and animation will start from the last frame and will be smooth.
|
|
23
|
-
*
|
|
24
|
-
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/315
|
|
25
|
-
*/
|
|
26
|
-
const useKeyboardInterpolation = () => {
|
|
27
|
-
// keyboard heights
|
|
28
|
-
const nextKeyboardHeight = useSharedValue(0);
|
|
29
|
-
const prevKeyboardHeight = useSharedValue(0);
|
|
30
|
-
// save latest interpolated position
|
|
31
|
-
const lastInterpolation = useSharedValue(0);
|
|
32
|
-
// boolean flag indicating which output range should be used
|
|
33
|
-
const shouldUseInternalInterpolation = useSharedValue(false);
|
|
34
|
-
|
|
35
|
-
const interpolate = (
|
|
36
|
-
keyboardPosition: number,
|
|
37
|
-
output: KeyboardInterpolationOutput,
|
|
38
|
-
) => {
|
|
39
|
-
"worklet";
|
|
40
|
-
|
|
41
|
-
// on iOS it's safe to interpolate between 0 and `fullKeyboardSize` because when
|
|
42
|
-
// keyboard resized we will not have intermediate values and transition will be instant
|
|
43
|
-
// see: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/327
|
|
44
|
-
if (Platform.OS === "ios") {
|
|
45
|
-
return interpolateREA(
|
|
46
|
-
keyboardPosition,
|
|
47
|
-
[0, nextKeyboardHeight.value],
|
|
48
|
-
output,
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const interpolation = interpolateREA(
|
|
53
|
-
keyboardPosition,
|
|
54
|
-
[prevKeyboardHeight.value, nextKeyboardHeight.value],
|
|
55
|
-
shouldUseInternalInterpolation.value
|
|
56
|
-
? [lastInterpolation.value, output[1]]
|
|
57
|
-
: output,
|
|
58
|
-
);
|
|
59
|
-
lastInterpolation.value = interpolation;
|
|
60
|
-
|
|
61
|
-
return interpolation;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
useKeyboardHandler(
|
|
65
|
-
{
|
|
66
|
-
onStart: (e) => {
|
|
67
|
-
"worklet";
|
|
68
|
-
|
|
69
|
-
const keyboardWillBeHidden = e.height === 0;
|
|
70
|
-
|
|
71
|
-
// keyboard will be hidden
|
|
72
|
-
if (keyboardWillBeHidden) {
|
|
73
|
-
shouldUseInternalInterpolation.value = false;
|
|
74
|
-
prevKeyboardHeight.value = 0;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// keyboard will change its size
|
|
78
|
-
if (
|
|
79
|
-
// keyboard is shown on screen
|
|
80
|
-
nextKeyboardHeight.value !== 0 &&
|
|
81
|
-
// it really changes size (handles iOS case when after interactive keyboard gets shown again)
|
|
82
|
-
nextKeyboardHeight.value !== e.height &&
|
|
83
|
-
// keyboard is not hiding
|
|
84
|
-
!keyboardWillBeHidden
|
|
85
|
-
) {
|
|
86
|
-
prevKeyboardHeight.value = nextKeyboardHeight.value;
|
|
87
|
-
shouldUseInternalInterpolation.value = true;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// keyboard will show or change size
|
|
91
|
-
if (!keyboardWillBeHidden) {
|
|
92
|
-
nextKeyboardHeight.value = e.height;
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
onEnd: (e) => {
|
|
96
|
-
"worklet";
|
|
97
|
-
|
|
98
|
-
// handles case show -> resize -> hide -> show
|
|
99
|
-
// here we reset value to 0 when keyboard is hidden
|
|
100
|
-
nextKeyboardHeight.value = e.height;
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
[],
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
return { interpolate };
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
export default useKeyboardInterpolation;
|