react-native-keyboard-controller 1.17.0 → 1.17.2
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/README.md +24 -23
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt +49 -15
- package/ios/delegates/KCTextInputCompositeDelegate.swift +16 -1
- package/ios/observers/FocusedInputObserver.swift +3 -1
- package/lib/commonjs/animated.js +23 -7
- package/lib/commonjs/animated.js.map +1 -1
- package/lib/commonjs/bindings.js +19 -0
- package/lib/commonjs/bindings.js.map +1 -1
- package/lib/commonjs/components/KeyboardAvoidingView/index.js +11 -2
- package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js +54 -39
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +17 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
- package/lib/commonjs/components/KeyboardStickyView/index.js +13 -0
- package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/index.js +31 -22
- package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/commonjs/context.js +16 -0
- package/lib/commonjs/context.js.map +1 -1
- package/lib/commonjs/hooks/index.js +164 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useKeyboardState/index.js +21 -0
- package/lib/commonjs/hooks/useKeyboardState/index.js.map +1 -1
- package/lib/commonjs/internal.js +23 -1
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/commonjs/module.js +4 -0
- package/lib/commonjs/module.js.map +1 -1
- package/lib/commonjs/monkey-patch.android.js +0 -5
- package/lib/commonjs/monkey-patch.android.js.map +1 -1
- package/lib/commonjs/{types.js → types/hooks.js} +1 -1
- package/lib/commonjs/types/hooks.js.map +1 -0
- package/lib/commonjs/types/index.js +50 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/types/internal.js +6 -0
- package/lib/commonjs/types/internal.js.map +1 -0
- package/lib/commonjs/types/module.js +6 -0
- package/lib/commonjs/types/module.js.map +1 -0
- package/lib/commonjs/types/views.js +6 -0
- package/lib/commonjs/types/views.js.map +1 -0
- package/lib/commonjs/utils/findNodeHandle/index.js +9 -0
- package/lib/commonjs/utils/findNodeHandle/index.js.map +1 -0
- package/lib/commonjs/utils/findNodeHandle/index.native.js +13 -0
- package/lib/commonjs/utils/findNodeHandle/index.native.js.map +1 -0
- package/lib/commonjs/views/OverKeyboardView/index.js +18 -4
- package/lib/commonjs/views/OverKeyboardView/index.js.map +1 -1
- package/lib/module/animated.js +23 -7
- package/lib/module/animated.js.map +1 -1
- package/lib/module/bindings.js +19 -0
- package/lib/module/bindings.js.map +1 -1
- package/lib/module/components/KeyboardAvoidingView/index.js +11 -2
- package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/index.js +53 -38
- package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +17 -1
- package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
- package/lib/module/components/KeyboardStickyView/index.js +13 -0
- package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/index.js +31 -22
- package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/module/context.js +16 -0
- package/lib/module/context.js.map +1 -1
- package/lib/module/hooks/index.js +164 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useKeyboardState/index.js +21 -0
- package/lib/module/hooks/useKeyboardState/index.js.map +1 -1
- package/lib/module/internal.js +23 -1
- package/lib/module/internal.js.map +1 -1
- package/lib/module/module.js +4 -0
- package/lib/module/module.js.map +1 -1
- package/lib/module/monkey-patch.android.js +0 -5
- package/lib/module/monkey-patch.android.js.map +1 -1
- package/lib/module/types/hooks.js +2 -0
- package/lib/module/types/hooks.js.map +1 -0
- package/lib/module/types/index.js +5 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/internal.js +2 -0
- package/lib/module/types/internal.js.map +1 -0
- package/lib/module/types/module.js +2 -0
- package/lib/module/types/module.js.map +1 -0
- package/lib/module/types/views.js +2 -0
- package/lib/module/types/views.js.map +1 -0
- package/lib/module/utils/findNodeHandle/index.js +2 -0
- package/lib/module/utils/findNodeHandle/index.js.map +1 -0
- package/lib/module/utils/findNodeHandle/index.native.js +3 -0
- package/lib/module/utils/findNodeHandle/index.native.js.map +1 -0
- package/lib/module/views/OverKeyboardView/index.js +18 -4
- package/lib/module/views/OverKeyboardView/index.js.map +1 -1
- package/lib/typescript/animated.d.ts +20 -6
- package/lib/typescript/bindings.d.ts +19 -0
- package/lib/typescript/components/KeyboardAvoidingView/index.d.ts +11 -2
- package/lib/typescript/components/KeyboardAwareScrollView/index.d.ts +23 -6
- package/lib/typescript/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.d.ts +17 -1
- package/lib/typescript/components/KeyboardStickyView/index.d.ts +15 -2
- package/lib/typescript/components/KeyboardToolbar/index.d.ts +13 -2
- package/lib/typescript/context.d.ts +32 -0
- package/lib/typescript/hooks/index.d.ts +157 -0
- package/lib/typescript/hooks/useKeyboardState/index.d.ts +20 -0
- package/lib/typescript/internal.d.ts +23 -1
- package/lib/typescript/module.d.ts +3 -0
- package/lib/typescript/{types.d.ts → types/hooks.d.ts} +72 -78
- package/lib/typescript/types/index.d.ts +4 -0
- package/lib/typescript/types/internal.d.ts +17 -0
- package/lib/typescript/types/module.d.ts +91 -0
- package/lib/typescript/types/views.d.ts +45 -0
- package/lib/typescript/utils/findNodeHandle/index.d.ts +4 -0
- package/lib/typescript/utils/findNodeHandle/index.native.d.ts +2 -0
- package/lib/typescript/views/OverKeyboardView/index.d.ts +14 -1
- package/package.json +2 -1
- package/src/animated.tsx +27 -12
- package/src/bindings.ts +19 -0
- package/src/components/KeyboardAvoidingView/index.tsx +11 -2
- package/src/components/KeyboardAwareScrollView/index.tsx +56 -41
- package/src/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.ts +17 -1
- package/src/components/KeyboardStickyView/index.tsx +14 -1
- package/src/components/KeyboardToolbar/index.tsx +31 -19
- package/src/context.ts +33 -0
- package/src/hooks/index.ts +157 -0
- package/src/hooks/useKeyboardState/index.ts +20 -0
- package/src/internal.ts +23 -1
- package/src/module.ts +3 -0
- package/src/monkey-patch.android.ts +3 -6
- package/src/{types.ts → types/hooks.ts} +72 -105
- package/src/types/index.ts +4 -0
- package/src/types/internal.ts +24 -0
- package/src/types/module.ts +105 -0
- package/src/types/views.ts +46 -0
- package/src/utils/findNodeHandle/index.native.ts +3 -0
- package/src/utils/findNodeHandle/index.ts +6 -0
- package/src/views/OverKeyboardView/index.tsx +15 -4
- package/lib/commonjs/types.js.map +0 -1
- package/lib/module/types.js +0 -2
- package/lib/module/types.js.map +0 -1
package/src/animated.tsx
CHANGED
|
@@ -56,29 +56,29 @@ type KeyboardProviderProps = {
|
|
|
56
56
|
* or `StatusBar` component from `react-native`, you can ignore it.
|
|
57
57
|
* Defaults to `false`.
|
|
58
58
|
*
|
|
59
|
-
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/14
|
|
60
59
|
* @platform android
|
|
60
|
+
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/14
|
|
61
61
|
*/
|
|
62
62
|
statusBarTranslucent?: boolean;
|
|
63
63
|
/**
|
|
64
64
|
* Set the value to `true`, if you use translucent navigation bar on Android.
|
|
65
65
|
* Defaults to `false`.
|
|
66
66
|
*
|
|
67
|
-
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/119
|
|
68
67
|
* @platform android
|
|
68
|
+
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/119
|
|
69
69
|
*/
|
|
70
70
|
navigationBarTranslucent?: boolean;
|
|
71
71
|
/**
|
|
72
72
|
* A boolean property indicating whether to keep edge-to-edge mode always enabled (even when you disable the module).
|
|
73
73
|
* Defaults to `false`.
|
|
74
74
|
*
|
|
75
|
-
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/592
|
|
76
75
|
* @platform android
|
|
76
|
+
* @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/592
|
|
77
77
|
*/
|
|
78
78
|
preserveEdgeToEdge?: boolean;
|
|
79
79
|
/**
|
|
80
|
-
* A boolean prop indicating whether the module is enabled. It indicate only initial state
|
|
81
|
-
*
|
|
80
|
+
* A boolean prop indicating whether the module is enabled. It indicate only initial state
|
|
81
|
+
* (if you try to change this prop after component mount it will not have any effect).
|
|
82
82
|
* To change the property in runtime use `useKeyboardController` hook and `setEnabled` method.
|
|
83
83
|
* Defaults to `true`.
|
|
84
84
|
*/
|
|
@@ -89,13 +89,28 @@ type KeyboardProviderProps = {
|
|
|
89
89
|
// see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/393 and https://github.com/kirillzyusko/react-native-keyboard-controller/issues/294 for more details
|
|
90
90
|
const OS = Platform.OS;
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
92
|
+
/**
|
|
93
|
+
* A component that wrap your app. Under the hood it works with {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller-view|KeyboardControllerView} to receive events during keyboard movements,
|
|
94
|
+
* maps these events to `Animated`/`Reanimated` values and store them in context.
|
|
95
|
+
*
|
|
96
|
+
* @param props - Provider props, such as `statusBarTranslucent`, `navigationBarTranslucent`, etc.
|
|
97
|
+
* @returns A component that should be mounted in root of your App layout.
|
|
98
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-provider|Documentation} page for more details.
|
|
99
|
+
* @example
|
|
100
|
+
* ```tsx
|
|
101
|
+
* <KeyboardProvider>
|
|
102
|
+
* <NavigationContainer />
|
|
103
|
+
* </KeyboardProvider>
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export const KeyboardProvider = (props: KeyboardProviderProps) => {
|
|
107
|
+
const {
|
|
108
|
+
children,
|
|
109
|
+
statusBarTranslucent,
|
|
110
|
+
navigationBarTranslucent,
|
|
111
|
+
preserveEdgeToEdge,
|
|
112
|
+
enabled: initiallyEnabled = true,
|
|
113
|
+
} = props;
|
|
99
114
|
// ref
|
|
100
115
|
const viewTagRef = useRef<React.Component<KeyboardControllerProps>>(null);
|
|
101
116
|
// state
|
package/src/bindings.ts
CHANGED
|
@@ -21,6 +21,15 @@ export const KeyboardControllerNative: KeyboardControllerNativeModule = {
|
|
|
21
21
|
addListener: NOOP,
|
|
22
22
|
removeListeners: NOOP,
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* An event emitter that provides a way to subscribe to next keyboard events:
|
|
26
|
+
* - `keyboardWillShow`;
|
|
27
|
+
* - `keyboardDidShow`;
|
|
28
|
+
* - `keyboardWillHide`;
|
|
29
|
+
* - `keyboardDidHide`.
|
|
30
|
+
*
|
|
31
|
+
* Use `addListener` function to add your event listener for a specific keyboard event.
|
|
32
|
+
*/
|
|
24
33
|
export const KeyboardEvents: KeyboardEventsModule = {
|
|
25
34
|
addListener: () => ({ remove: NOOP } as EmitterSubscription),
|
|
26
35
|
};
|
|
@@ -34,8 +43,18 @@ export const FocusedInputEvents: FocusedInputEventsModule = {
|
|
|
34
43
|
export const WindowDimensionsEvents: WindowDimensionsEventsModule = {
|
|
35
44
|
addListener: () => ({ remove: NOOP } as EmitterSubscription),
|
|
36
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* A view that sends events whenever keyboard or focused events are happening.
|
|
48
|
+
*
|
|
49
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller-view|Documentation} page for more details.
|
|
50
|
+
*/
|
|
37
51
|
export const KeyboardControllerView =
|
|
38
52
|
View as unknown as React.FC<KeyboardControllerProps>;
|
|
53
|
+
/**
|
|
54
|
+
* A view that defines a region on the screen, where gestures will control the keyboard position.
|
|
55
|
+
*
|
|
56
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-gesture-area|Documentation} page for more details.
|
|
57
|
+
*/
|
|
39
58
|
export const KeyboardGestureArea =
|
|
40
59
|
View as unknown as React.FC<KeyboardGestureAreaProps>;
|
|
41
60
|
export const RCTOverKeyboardView =
|
|
@@ -62,8 +62,17 @@ const defaultLayout: LayoutRectangle = {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
|
-
* View that
|
|
66
|
-
*
|
|
65
|
+
* A View component that automatically adjusts its height, position, or bottom padding
|
|
66
|
+
* when the keyboard appears to ensure that the content remains visible.
|
|
67
|
+
*
|
|
68
|
+
* @returns A View component that adjusts to keyboard visibility.
|
|
69
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-avoiding-view|Documentation} page for more details.
|
|
70
|
+
* @example
|
|
71
|
+
* ```tsx
|
|
72
|
+
* <KeyboardAvoidingView behavior="padding">
|
|
73
|
+
* <TextInput />
|
|
74
|
+
* </KeyboardAvoidingView>
|
|
75
|
+
* ```
|
|
67
76
|
*/
|
|
68
77
|
const KeyboardAvoidingView = forwardRef<
|
|
69
78
|
View,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { forwardRef, useCallback, useMemo } from "react";
|
|
2
|
-
import { findNodeHandle } from "react-native";
|
|
3
2
|
import Reanimated, {
|
|
4
3
|
interpolate,
|
|
5
4
|
scrollTo,
|
|
@@ -15,6 +14,7 @@ import {
|
|
|
15
14
|
useReanimatedFocusedInput,
|
|
16
15
|
useWindowDimensions,
|
|
17
16
|
} from "../../hooks";
|
|
17
|
+
import { findNodeHandle } from "../../utils/findNodeHandle";
|
|
18
18
|
|
|
19
19
|
import { useSmoothKeyboardHandler } from "./useSmoothKeyboardHandler";
|
|
20
20
|
import { debounce, scrollDistanceWithRespectToSnapPoints } from "./utils";
|
|
@@ -35,51 +35,66 @@ export type KeyboardAwareScrollViewProps = {
|
|
|
35
35
|
bottomOffset?: number;
|
|
36
36
|
/** Prevents automatic scrolling of the `ScrollView` when the keyboard gets hidden, maintaining the current screen position. Default is `false`. */
|
|
37
37
|
disableScrollOnKeyboardHide?: boolean;
|
|
38
|
-
/** Controls whether this `KeyboardAwareScrollView` instance should take effect. Default is `true
|
|
38
|
+
/** Controls whether this `KeyboardAwareScrollView` instance should take effect. Default is `true`. */
|
|
39
39
|
enabled?: boolean;
|
|
40
|
-
/** Adjusting the bottom spacing of KeyboardAwareScrollView. Default is `0
|
|
40
|
+
/** Adjusting the bottom spacing of KeyboardAwareScrollView. Default is `0`. */
|
|
41
41
|
extraKeyboardSpace?: number;
|
|
42
|
-
/** Custom component for `ScrollView`. Default is `ScrollView
|
|
42
|
+
/** Custom component for `ScrollView`. Default is `ScrollView`. */
|
|
43
43
|
ScrollViewComponent?: React.ComponentType<ScrollViewProps>;
|
|
44
44
|
} & ScrollViewProps;
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
// Everything begins from `onStart` handler. This handler is called every time,
|
|
47
|
+
// when keyboard changes its size or when focused `TextInput` was changed. In
|
|
48
|
+
// this handler we are calculating/memoizing values which later will be used
|
|
49
|
+
// during layout movement. For that we calculate:
|
|
50
|
+
// - layout of focused field (`layout`) - to understand whether there will be overlap
|
|
51
|
+
// - initial keyboard size (`initialKeyboardSize`) - used in scroll interpolation
|
|
52
|
+
// - future keyboard height (`keyboardHeight`) - used in scroll interpolation
|
|
53
|
+
// - current scroll position (`scrollPosition`) - used to scroll from this point
|
|
54
|
+
//
|
|
55
|
+
// Once we've calculated all necessary variables - we can actually start to use them.
|
|
56
|
+
// It happens in `onMove` handler - this function simply calls `maybeScroll` with
|
|
57
|
+
// current keyboard frame height. This functions makes the smooth transition.
|
|
58
|
+
//
|
|
59
|
+
// When the transition has finished we go to `onEnd` handler. In this handler
|
|
60
|
+
// we verify, that the current field is not overlapped within a keyboard frame.
|
|
61
|
+
// For full `onStart`/`onMove`/`onEnd` flow it may look like a redundant thing,
|
|
62
|
+
// however there could be some cases, when `onMove` is not called:
|
|
63
|
+
// - on iOS when TextInput was changed - keyboard transition is instant
|
|
64
|
+
// - on Android when TextInput was changed and keyboard size wasn't changed
|
|
65
|
+
// So `onEnd` handler handle the case, when `onMove` wasn't triggered.
|
|
66
|
+
//
|
|
67
|
+
// ====================================================================================================================+
|
|
68
|
+
// -----------------------------------------------------Flow chart-----------------------------------------------------+
|
|
69
|
+
// ====================================================================================================================+
|
|
70
|
+
//
|
|
71
|
+
// +============================+ +============================+ +==================================+
|
|
72
|
+
// + User Press on TextInput + => + Keyboard starts showing + => + As keyboard moves frame by frame + =>
|
|
73
|
+
// + + + (run `onStart`) + + `onMove` is getting called +
|
|
74
|
+
// +============================+ +============================+ +==================================+
|
|
75
|
+
//
|
|
76
|
+
// +============================+ +============================+ +=====================================+
|
|
77
|
+
// + Keyboard is shown and we + => + User moved focus to + => + Only `onStart`/`onEnd` maybe called +
|
|
78
|
+
// + call `onEnd` handler + + another `TextInput` + + (without involving `onMove`) +
|
|
79
|
+
// +============================+ +============================+ +=====================================+
|
|
80
|
+
//
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* A ScrollView component that automatically handles keyboard appearance and disappearance
|
|
84
|
+
* by adjusting its content position to ensure the focused input remains visible.
|
|
55
85
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* current keyboard frame height. This functions makes the smooth transition.
|
|
59
|
-
*
|
|
60
|
-
* When the transition has finished we go to `onEnd` handler. In this handler
|
|
61
|
-
* we verify, that the current field is not overlapped within a keyboard frame.
|
|
62
|
-
* For full `onStart`/`onMove`/`onEnd` flow it may look like a redundant thing,
|
|
63
|
-
* however there could be some cases, when `onMove` is not called:
|
|
64
|
-
* - on iOS when TextInput was changed - keyboard transition is instant
|
|
65
|
-
* - on Android when TextInput was changed and keyboard size wasn't changed
|
|
66
|
-
* So `onEnd` handler handle the case, when `onMove` wasn't triggered.
|
|
67
|
-
*
|
|
68
|
-
* ====================================================================================================================+
|
|
69
|
-
* -----------------------------------------------------Flow chart-----------------------------------------------------+
|
|
70
|
-
* ====================================================================================================================+
|
|
71
|
-
*
|
|
72
|
-
* +============================+ +============================+ +==================================+
|
|
73
|
-
* + User Press on TextInput + => + Keyboard starts showing + => + As keyboard moves frame by frame + =>
|
|
74
|
-
* + + + (run `onStart`) + + `onMove` is getting called +
|
|
75
|
-
* +============================+ +============================+ +==================================+
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* +============================+ +============================+ +=====================================+
|
|
79
|
-
* + Keyboard is shown and we + => + User moved focus to + => + Only `onStart`/`onEnd` maybe called +
|
|
80
|
-
* + call `onEnd` handler + + another `TextInput` + + (without involving `onMove`) +
|
|
81
|
-
* +============================+ +============================+ +=====================================+
|
|
86
|
+
* The component uses a sophisticated animation system to smoothly handle keyboard transitions
|
|
87
|
+
* and maintain proper scroll position during keyboard interactions.
|
|
82
88
|
*
|
|
89
|
+
* @returns A ScrollView component that handles keyboard interactions.
|
|
90
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-aware-scroll-view|Documentation} page for more details.
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* <KeyboardAwareScrollView bottomOffset={20}>
|
|
94
|
+
* <TextInput placeholder="Enter text" />
|
|
95
|
+
* <TextInput placeholder="Another input" />
|
|
96
|
+
* </KeyboardAwareScrollView>
|
|
97
|
+
* ```
|
|
83
98
|
*/
|
|
84
99
|
const KeyboardAwareScrollView = forwardRef<
|
|
85
100
|
ScrollView,
|
|
@@ -133,7 +148,7 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
133
148
|
);
|
|
134
149
|
|
|
135
150
|
/**
|
|
136
|
-
* Function that will scroll a ScrollView as keyboard gets moving
|
|
151
|
+
* Function that will scroll a ScrollView as keyboard gets moving.
|
|
137
152
|
*/
|
|
138
153
|
const maybeScroll = useCallback(
|
|
139
154
|
(e: number, animated: boolean = false) => {
|
|
@@ -383,7 +398,7 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
383
398
|
onLayout={onScrollViewLayout}
|
|
384
399
|
>
|
|
385
400
|
{children}
|
|
386
|
-
<Reanimated.View style={view} />
|
|
401
|
+
{enabled && <Reanimated.View style={view} />}
|
|
387
402
|
</ScrollViewComponent>
|
|
388
403
|
);
|
|
389
404
|
},
|
|
@@ -28,7 +28,23 @@ const TELEGRAM_ANDROID_TIMING_CONFIG = {
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Hook that uses default transitions for iOS and Android > 11, and uses
|
|
31
|
-
* custom interpolation on Android < 11 to achieve more smooth animation
|
|
31
|
+
* custom interpolation on Android < 11 to achieve more smooth animation.
|
|
32
|
+
*
|
|
33
|
+
* @param handler - Object containing keyboard event handlers.
|
|
34
|
+
* @param [deps] - Dependencies array for the effect.
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* useSmoothKeyboardHandler(
|
|
38
|
+
* {
|
|
39
|
+
* onStart: (e) => {
|
|
40
|
+
* "worklet";
|
|
41
|
+
*
|
|
42
|
+
* // your handler for keyboard start
|
|
43
|
+
* },
|
|
44
|
+
* },
|
|
45
|
+
* [],
|
|
46
|
+
* );
|
|
47
|
+
* ```
|
|
32
48
|
*/
|
|
33
49
|
export const useSmoothKeyboardHandler: typeof useKeyboardHandler = (
|
|
34
50
|
handler,
|
|
@@ -20,10 +20,23 @@ export type KeyboardStickyViewProps = {
|
|
|
20
20
|
opened?: number;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
/** Controls whether this `KeyboardStickyView` instance should take effect. Default is `true
|
|
23
|
+
/** Controls whether this `KeyboardStickyView` instance should take effect. Default is `true`. */
|
|
24
24
|
enabled?: boolean;
|
|
25
25
|
} & ViewProps;
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* A View component that sticks to the keyboard and moves with it when it appears or disappears.
|
|
29
|
+
* The view can be configured with custom offsets for both closed and open keyboard states.
|
|
30
|
+
*
|
|
31
|
+
* @returns An animated View component that sticks to the keyboard.
|
|
32
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-sticky-view|Documentation} page for more details.
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* <KeyboardStickyView offset={{ closed: 0, opened: 20 }}>
|
|
36
|
+
* <Button title="Submit" />
|
|
37
|
+
* </KeyboardStickyView>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
27
40
|
const KeyboardStickyView = forwardRef<
|
|
28
41
|
View,
|
|
29
42
|
React.PropsWithChildren<KeyboardStickyViewProps>
|
|
@@ -59,6 +59,9 @@ export type KeyboardToolbarProps = Omit<
|
|
|
59
59
|
* A value for container opacity in hexadecimal format (e.g. `ff`). Default value is `ff`.
|
|
60
60
|
*/
|
|
61
61
|
opacity?: HEX;
|
|
62
|
+
/**
|
|
63
|
+
* A object containing `left`/`right` properties. Used to specify proper container padding in landscape mode.
|
|
64
|
+
*/
|
|
62
65
|
insets?: SafeAreaInsets;
|
|
63
66
|
} & Pick<KeyboardStickyViewProps, "offset" | "enabled">;
|
|
64
67
|
|
|
@@ -72,26 +75,35 @@ const KEYBOARD_TOOLBAR_HEIGHT = 42;
|
|
|
72
75
|
const DEFAULT_OPACITY: HEX = "FF";
|
|
73
76
|
|
|
74
77
|
/**
|
|
75
|
-
* `KeyboardToolbar` is a component that is shown above the keyboard with `Prev`/`Next` and
|
|
76
|
-
* `Done`
|
|
78
|
+
* `KeyboardToolbar` is a component that is shown above the keyboard with `Prev`/`Next` buttons from left and
|
|
79
|
+
* `Done` button from the right (to dismiss the keyboard). Allows to add customizable content (yours UI elements) in the middle.
|
|
80
|
+
*
|
|
81
|
+
* @param props - Component props.
|
|
82
|
+
* @returns A component that is shown above the keyboard with `Prev`/`Next` and `Done` buttons.
|
|
83
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-toolbar|Documentation} page for more details.
|
|
84
|
+
* @example
|
|
85
|
+
* ```tsx
|
|
86
|
+
* <KeyboardToolbar doneText="Close" />
|
|
87
|
+
* ```
|
|
77
88
|
*/
|
|
78
|
-
const KeyboardToolbar: React.FC<KeyboardToolbarProps> = ({
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
const KeyboardToolbar: React.FC<KeyboardToolbarProps> = (props) => {
|
|
90
|
+
const {
|
|
91
|
+
content,
|
|
92
|
+
theme = colors,
|
|
93
|
+
doneText = "Done",
|
|
94
|
+
button,
|
|
95
|
+
icon,
|
|
96
|
+
showArrows = true,
|
|
97
|
+
onNextCallback,
|
|
98
|
+
onPrevCallback,
|
|
99
|
+
onDoneCallback,
|
|
100
|
+
blur = null,
|
|
101
|
+
opacity = DEFAULT_OPACITY,
|
|
102
|
+
offset: { closed = 0, opened = 0 } = {},
|
|
103
|
+
enabled = true,
|
|
104
|
+
insets,
|
|
105
|
+
...rest
|
|
106
|
+
} = props;
|
|
95
107
|
const colorScheme = useColorScheme();
|
|
96
108
|
const [inputs, setInputs] = useState({
|
|
97
109
|
current: 0,
|
package/src/context.ts
CHANGED
|
@@ -10,20 +10,37 @@ import type React from "react";
|
|
|
10
10
|
import type { SharedValue } from "react-native-reanimated";
|
|
11
11
|
|
|
12
12
|
export type AnimatedContext = {
|
|
13
|
+
/**
|
|
14
|
+
* A value between `0` and `1` indicating keyboard position, where `0` means keyboard is closed and `1` means keyboard is fully visible.
|
|
15
|
+
* Represented as `Animated.Value`.
|
|
16
|
+
*/
|
|
13
17
|
progress: Animated.Value;
|
|
18
|
+
/** Height of the keyboard. Represented as `Animated.Value`. */
|
|
14
19
|
height: Animated.AnimatedMultiplication<number>;
|
|
15
20
|
};
|
|
16
21
|
export type ReanimatedContext = {
|
|
22
|
+
/**
|
|
23
|
+
* A value between `0` and `1` indicating keyboard position, where `0` means keyboard is closed and `1` means keyboard is fully visible.
|
|
24
|
+
* Represented as `SharedValue`.
|
|
25
|
+
*/
|
|
17
26
|
progress: SharedValue<number>;
|
|
27
|
+
/** Height of the keyboard. Represented as `SharedValue`. */
|
|
18
28
|
height: SharedValue<number>;
|
|
19
29
|
};
|
|
20
30
|
export type KeyboardAnimationContext = {
|
|
31
|
+
/** Whether KeyboardController library is active or not. */
|
|
21
32
|
enabled: boolean;
|
|
33
|
+
/** Object that stores animated values that reflect the keyboard’s current position and movement. */
|
|
22
34
|
animated: AnimatedContext;
|
|
35
|
+
/** Object that stores reanimated values that reflect the keyboard’s current position and movement. */
|
|
23
36
|
reanimated: ReanimatedContext;
|
|
37
|
+
/** Layout of the focused `TextInput` represented as `SharedValue`. */
|
|
24
38
|
layout: SharedValue<FocusedInputLayoutChangedEvent | null>;
|
|
39
|
+
/** Method for setting workletized keyboard handlers. */
|
|
25
40
|
setKeyboardHandlers: (handlers: KeyboardHandler) => () => void;
|
|
41
|
+
/** Method for setting workletized handlers for tracking focused input events. */
|
|
26
42
|
setInputHandlers: (handlers: FocusedInputHandler) => () => void;
|
|
43
|
+
/** Method to enable/disable KeyboardController library. */
|
|
27
44
|
setEnabled: React.Dispatch<React.SetStateAction<boolean>>;
|
|
28
45
|
};
|
|
29
46
|
const NOOP = () => {};
|
|
@@ -57,6 +74,22 @@ const defaultContext: KeyboardAnimationContext = {
|
|
|
57
74
|
};
|
|
58
75
|
|
|
59
76
|
export const KeyboardContext = createContext(defaultContext);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* A hook that returns a reference to {@link KeyboardAnimationContext} object.
|
|
80
|
+
*
|
|
81
|
+
* @returns Object {@link KeyboardAnimationContext|containing} keyboard-controller context.
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const context = useKeyboardContext();
|
|
85
|
+
*
|
|
86
|
+
* useLayoutEffect(() => {
|
|
87
|
+
* const cleanup = context.setInputHandlers(handler);
|
|
88
|
+
*
|
|
89
|
+
* return () => cleanup();
|
|
90
|
+
* }, deps);
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
60
93
|
export const useKeyboardContext = () => {
|
|
61
94
|
const context = useContext(KeyboardContext);
|
|
62
95
|
|
package/src/hooks/index.ts
CHANGED
|
@@ -8,6 +8,20 @@ import type { AnimatedContext, ReanimatedContext } from "../context";
|
|
|
8
8
|
import type { FocusedInputHandler, KeyboardHandler } from "../types";
|
|
9
9
|
import type { DependencyList } from "react";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Hook that sets the Android soft input mode to adjust resize on mount and
|
|
13
|
+
* restores default mode on unmount. This ensures the keyboard behavior is consistent
|
|
14
|
+
* on all Android versions.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller#setinputmode-|Documentation} page for more details.
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* function MyComponent() {
|
|
20
|
+
* useResizeMode();
|
|
21
|
+
* return <View />;
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
11
25
|
export const useResizeMode = () => {
|
|
12
26
|
useEffect(() => {
|
|
13
27
|
KeyboardController.setInputMode(
|
|
@@ -18,6 +32,20 @@ export const useResizeMode = () => {
|
|
|
18
32
|
}, []);
|
|
19
33
|
};
|
|
20
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Hook that provides animated (`height`/`progress`) values for tracking keyboard movement.
|
|
37
|
+
* Automatically sets the resize mode for Android.
|
|
38
|
+
*
|
|
39
|
+
* @returns Object {@link AnimatedContext|containing} animated values for keyboard movement.
|
|
40
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/keyboard/use-keyboard-animation|Documentation} page for more details.
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* function MyComponent() {
|
|
44
|
+
* const { height, progress } = useKeyboardAnimation();
|
|
45
|
+
* return <Animated.View style={{ transform: [{ translateY: height }] }} />;
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
21
49
|
export const useKeyboardAnimation = (): AnimatedContext => {
|
|
22
50
|
useResizeMode();
|
|
23
51
|
const context = useKeyboardContext();
|
|
@@ -25,6 +53,20 @@ export const useKeyboardAnimation = (): AnimatedContext => {
|
|
|
25
53
|
return context.animated;
|
|
26
54
|
};
|
|
27
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Hook that provides reanimated (`height`/`progress`) values for tracking keyboard movement.
|
|
58
|
+
* Automatically sets the resize mode for Android.
|
|
59
|
+
*
|
|
60
|
+
* @returns Object {@link ReanimatedContext|containing} reanimated values for keyboard movement.
|
|
61
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/keyboard/use-reanimated-keyboard-animation|Documentation} page for more details.
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* function MyComponent() {
|
|
65
|
+
* const { height, progress } = useReanimatedKeyboardAnimation();
|
|
66
|
+
* return <Reanimated.View style={{ transform: [{ translateY: height }] }} />;
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
28
70
|
export const useReanimatedKeyboardAnimation = (): ReanimatedContext => {
|
|
29
71
|
useResizeMode();
|
|
30
72
|
const context = useKeyboardContext();
|
|
@@ -32,6 +74,37 @@ export const useReanimatedKeyboardAnimation = (): ReanimatedContext => {
|
|
|
32
74
|
return context.reanimated;
|
|
33
75
|
};
|
|
34
76
|
|
|
77
|
+
/**
|
|
78
|
+
* An alternative to {@link useKeyboardHandler} that doesn't set resize mode on mount. If your
|
|
79
|
+
* app already uses `adjustResize`, then you can use this hook instead of `useKeyboardHandler`.
|
|
80
|
+
*
|
|
81
|
+
* @param handler - Object containing keyboard event handlers.
|
|
82
|
+
* @param [deps] - Dependencies array for the effect.
|
|
83
|
+
* @example
|
|
84
|
+
* ```tsx
|
|
85
|
+
* function MyComponent() {
|
|
86
|
+
* const height = useSharedValue(0);
|
|
87
|
+
* const progress = useSharedValue(0);
|
|
88
|
+
*
|
|
89
|
+
* useGenericKeyboardHandler({
|
|
90
|
+
* onMove: (e) => {
|
|
91
|
+
* "worklet";
|
|
92
|
+
*
|
|
93
|
+
* height.value = e.height;
|
|
94
|
+
* progress.value = e.progress;
|
|
95
|
+
* },
|
|
96
|
+
* onEnd: (e) => {
|
|
97
|
+
* "worklet";
|
|
98
|
+
*
|
|
99
|
+
* height.value = e.height;
|
|
100
|
+
* progress.value = e.progress;
|
|
101
|
+
* },
|
|
102
|
+
* }, []);
|
|
103
|
+
*
|
|
104
|
+
* return <Reanimated.View style={{ height: height }] }} />;
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
35
108
|
export function useGenericKeyboardHandler(
|
|
36
109
|
handler: KeyboardHandler,
|
|
37
110
|
deps?: DependencyList,
|
|
@@ -45,6 +118,37 @@ export function useGenericKeyboardHandler(
|
|
|
45
118
|
}, deps);
|
|
46
119
|
}
|
|
47
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Hook that gives an access to each aspect of keyboard movement with workletized `onStart`/`onMove`/`onInteractive`/`onEnd` handlers.
|
|
123
|
+
*
|
|
124
|
+
* @param handler - Object containing keyboard event handlers.
|
|
125
|
+
* @param [deps] - Dependencies array for the effect.
|
|
126
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/keyboard/use-keyboard-handler|Documentation} page for more details.
|
|
127
|
+
* @example
|
|
128
|
+
* ```tsx
|
|
129
|
+
* function MyComponent() {
|
|
130
|
+
* const height = useSharedValue(0);
|
|
131
|
+
* const progress = useSharedValue(0);
|
|
132
|
+
*
|
|
133
|
+
* useKeyboardHandler({
|
|
134
|
+
* onMove: (e) => {
|
|
135
|
+
* "worklet";
|
|
136
|
+
*
|
|
137
|
+
* height.value = e.height;
|
|
138
|
+
* progress.value = e.progress;
|
|
139
|
+
* },
|
|
140
|
+
* onEnd: (e) => {
|
|
141
|
+
* "worklet";
|
|
142
|
+
*
|
|
143
|
+
* height.value = e.height;
|
|
144
|
+
* progress.value = e.progress;
|
|
145
|
+
* },
|
|
146
|
+
* }, []);
|
|
147
|
+
*
|
|
148
|
+
* return <Reanimated.View style={{ height: height }] }} />;
|
|
149
|
+
* }
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
48
152
|
export function useKeyboardHandler(
|
|
49
153
|
handler: KeyboardHandler,
|
|
50
154
|
deps?: DependencyList,
|
|
@@ -53,18 +157,71 @@ export function useKeyboardHandler(
|
|
|
53
157
|
useGenericKeyboardHandler(handler, deps);
|
|
54
158
|
}
|
|
55
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Hook for controlling keyboard controller module.
|
|
162
|
+
* Allows to disable/enable it and check the actual state (whether it's enabled or not).
|
|
163
|
+
* When disabled it fallbacks to default android keyboard handling and stops tracking all
|
|
164
|
+
* the events that are exposed from this library.
|
|
165
|
+
*
|
|
166
|
+
* @property {Function} setEnabled - Function to enable/disable keyboard handling.
|
|
167
|
+
* @property {boolean} enabled - Current enabled state.
|
|
168
|
+
* @returns Object containing keyboard control functions and state.
|
|
169
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/module/use-keyboard-controller|Documentation} page for more details.
|
|
170
|
+
* @example
|
|
171
|
+
* ```tsx
|
|
172
|
+
* function MyComponent() {
|
|
173
|
+
* const { setEnabled, enabled } = useKeyboardController();
|
|
174
|
+
* return (
|
|
175
|
+
* <Button
|
|
176
|
+
* title={enabled ? 'Disable' : 'Enable'}
|
|
177
|
+
* onPress={() => setEnabled(!enabled)}
|
|
178
|
+
* />
|
|
179
|
+
* );
|
|
180
|
+
* }
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
56
183
|
export function useKeyboardController() {
|
|
57
184
|
const context = useKeyboardContext();
|
|
58
185
|
|
|
59
186
|
return { setEnabled: context.setEnabled, enabled: context.enabled };
|
|
60
187
|
}
|
|
61
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Hook that provides access to the layout of the currently focused input.
|
|
191
|
+
*
|
|
192
|
+
* @returns Object containing reanimated values for focused input.
|
|
193
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/input/use-reanimated-focused-input|Documentation} page for more details.
|
|
194
|
+
* @example
|
|
195
|
+
* ```tsx
|
|
196
|
+
* function MyComponent() {
|
|
197
|
+
* const { input } = useReanimatedFocusedInput();
|
|
198
|
+
* return <Reanimated.View style={{ height: input.value?.layout.height }} />;
|
|
199
|
+
* }
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
62
202
|
export function useReanimatedFocusedInput() {
|
|
63
203
|
const context = useKeyboardContext();
|
|
64
204
|
|
|
65
205
|
return { input: context.layout };
|
|
66
206
|
}
|
|
67
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Hook for handling focused input events, such as changes of selection, text etc.
|
|
210
|
+
*
|
|
211
|
+
* @param handler - Object containing focused input event handlers.
|
|
212
|
+
* @param [deps] - Dependencies array for the effect.
|
|
213
|
+
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/input/use-focused-input-handler|Documentation} page for more details.
|
|
214
|
+
* @example
|
|
215
|
+
* ```tsx
|
|
216
|
+
* function MyComponent() {
|
|
217
|
+
* useFocusedInputHandler({
|
|
218
|
+
* onChangeText: (e) => console.log('Text changed:', e.text),
|
|
219
|
+
* onSelectionChange: (e) => console.log('Selection changed:', e.selection)
|
|
220
|
+
* });
|
|
221
|
+
* return <View />;
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
68
225
|
export function useFocusedInputHandler(
|
|
69
226
|
handler: FocusedInputHandler,
|
|
70
227
|
deps?: DependencyList,
|