react-native-keyboard-controller 1.14.5 → 1.15.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/android/build.gradle +3 -2
- package/android/gradle.properties +1 -0
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +2 -2
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt +35 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt +18 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +5 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt +9 -6
- package/android/src/main/java/com/reactnativekeyboardcontroller/modules/KeyboardControllerModuleImpl.kt +13 -4
- package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +2 -2
- package/ios/KeyboardControllerModule.mm +3 -3
- package/ios/KeyboardControllerModuleImpl.swift +66 -0
- package/ios/events/KeyboardEventEmitterPayload.swift +23 -0
- package/ios/extensions/UIKeyboardAppearance.swift +21 -0
- package/ios/extensions/UIKeyboardType.swift +30 -0
- package/ios/observers/KeyboardMovementObserver.swift +4 -14
- package/ios/protocols/TextInput.swift +5 -1
- package/ios/traversal/ViewHierarchyNavigator.swift +4 -1
- package/jest/index.js +20 -15
- package/lib/commonjs/animated.js +6 -0
- package/lib/commonjs/animated.js.map +1 -1
- package/lib/commonjs/bindings.js +5 -3
- package/lib/commonjs/bindings.js.map +1 -1
- package/lib/commonjs/bindings.native.js +2 -8
- package/lib/commonjs/bindings.native.js.map +1 -1
- package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardStickyView/index.js +3 -2
- package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/index.js +14 -6
- package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/commonjs/hooks/index.js +3 -3
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useWindowDimensions/index.android.js +5 -0
- package/lib/commonjs/hooks/useWindowDimensions/index.android.js.map +1 -1
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal.js +2 -2
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/commonjs/module.js +45 -0
- package/lib/commonjs/module.js.map +1 -0
- package/lib/commonjs/specs/NativeKeyboardController.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/animated.js +6 -0
- package/lib/module/animated.js.map +1 -1
- package/lib/module/bindings.js +4 -2
- package/lib/module/bindings.js.map +1 -1
- package/lib/module/bindings.native.js +1 -7
- package/lib/module/bindings.native.js.map +1 -1
- package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/module/components/KeyboardStickyView/index.js +3 -2
- package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/index.js +12 -4
- package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/module/hooks/index.js +1 -1
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useWindowDimensions/index.android.js +5 -0
- package/lib/module/hooks/useWindowDimensions/index.android.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal.js +2 -2
- package/lib/module/internal.js.map +1 -1
- package/lib/module/module.js +39 -0
- package/lib/module/module.js.map +1 -0
- package/lib/module/specs/NativeKeyboardController.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/bindings.d.ts +2 -2
- package/lib/typescript/bindings.native.d.ts +1 -2
- package/lib/typescript/components/KeyboardAvoidingView/index.d.ts +14 -24
- package/lib/typescript/components/KeyboardStickyView/index.d.ts +4 -0
- package/lib/typescript/components/KeyboardToolbar/index.d.ts +2 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/module.d.ts +2 -0
- package/lib/typescript/specs/NativeKeyboardController.d.ts +1 -1
- package/lib/typescript/types.d.ts +14 -3
- package/package.json +1 -1
- package/src/animated.tsx +6 -0
- package/src/bindings.native.ts +1 -8
- package/src/bindings.ts +4 -2
- package/src/components/KeyboardAvoidingView/index.tsx +27 -11
- package/src/components/KeyboardStickyView/index.tsx +12 -3
- package/src/components/KeyboardToolbar/index.tsx +11 -4
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useWindowDimensions/index.android.ts +5 -0
- package/src/index.ts +1 -0
- package/src/internal.ts +2 -2
- package/src/module.ts +50 -0
- package/src/specs/NativeKeyboardController.ts +1 -1
- package/src/types.ts +16 -2
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
3
|
import type { ViewProps } from "react-native";
|
|
4
|
-
export type
|
|
5
|
-
/**
|
|
6
|
-
* Specify how to react to the presence of the keyboard.
|
|
7
|
-
*/
|
|
8
|
-
behavior?: "height" | "position" | "padding";
|
|
9
|
-
/**
|
|
10
|
-
* Style of the content container when `behavior` is 'position'.
|
|
11
|
-
*/
|
|
12
|
-
contentContainerStyle?: ViewProps["style"];
|
|
4
|
+
export type KeyboardAvoidingViewBaseProps = {
|
|
13
5
|
/**
|
|
14
6
|
* Controls whether this `KeyboardAvoidingView` instance should take effect.
|
|
15
7
|
* This is useful when more than one is on the screen. Defaults to true.
|
|
@@ -21,30 +13,28 @@ export type KeyboardAvoidingViewProps = {
|
|
|
21
13
|
*/
|
|
22
14
|
keyboardVerticalOffset?: number;
|
|
23
15
|
} & ViewProps;
|
|
24
|
-
|
|
25
|
-
* View that moves out of the way when the keyboard appears by automatically
|
|
26
|
-
* adjusting its height, position, or bottom padding.
|
|
27
|
-
*/
|
|
28
|
-
declare const KeyboardAvoidingView: React.ForwardRefExoticComponent<{
|
|
16
|
+
export type KeyboardAvoidingViewProps = KeyboardAvoidingViewBaseProps & ({
|
|
29
17
|
/**
|
|
30
18
|
* Specify how to react to the presence of the keyboard.
|
|
31
19
|
*/
|
|
32
|
-
behavior?: "
|
|
20
|
+
behavior?: "position";
|
|
33
21
|
/**
|
|
34
22
|
* Style of the content container when `behavior` is 'position'.
|
|
35
23
|
*/
|
|
36
24
|
contentContainerStyle?: ViewProps["style"];
|
|
25
|
+
} | {
|
|
37
26
|
/**
|
|
38
|
-
*
|
|
39
|
-
* This is useful when more than one is on the screen. Defaults to true.
|
|
27
|
+
* Specify how to react to the presence of the keyboard.
|
|
40
28
|
*/
|
|
41
|
-
|
|
29
|
+
behavior?: "height" | "padding";
|
|
42
30
|
/**
|
|
43
|
-
*
|
|
44
|
-
* may be non-zero in some cases. Defaults to 0.
|
|
31
|
+
* `contentContainerStyle` is not allowed for these behaviors.
|
|
45
32
|
*/
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
contentContainerStyle?: never;
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* View that moves out of the way when the keyboard appears by automatically
|
|
37
|
+
* adjusting its height, position, or bottom padding.
|
|
38
|
+
*/
|
|
39
|
+
declare const KeyboardAvoidingView: React.ForwardRefExoticComponent<React.PropsWithChildren<KeyboardAvoidingViewProps> & React.RefAttributes<View>>;
|
|
50
40
|
export default KeyboardAvoidingView;
|
|
@@ -14,6 +14,8 @@ export type KeyboardStickyViewProps = {
|
|
|
14
14
|
*/
|
|
15
15
|
opened?: number;
|
|
16
16
|
};
|
|
17
|
+
/** Controls whether this `KeyboardStickyView` instance should take effect. Default is `true` */
|
|
18
|
+
enabled?: boolean;
|
|
17
19
|
} & ViewProps;
|
|
18
20
|
declare const KeyboardStickyView: React.ForwardRefExoticComponent<{
|
|
19
21
|
/**
|
|
@@ -29,6 +31,8 @@ declare const KeyboardStickyView: React.ForwardRefExoticComponent<{
|
|
|
29
31
|
*/
|
|
30
32
|
opened?: number;
|
|
31
33
|
};
|
|
34
|
+
/** Controls whether this `KeyboardStickyView` instance should take effect. Default is `true` */
|
|
35
|
+
enabled?: boolean;
|
|
32
36
|
} & ViewProps & {
|
|
33
37
|
children?: React.ReactNode | undefined;
|
|
34
38
|
} & React.RefAttributes<View>>;
|
|
@@ -3,6 +3,7 @@ import Arrow from "./Arrow";
|
|
|
3
3
|
import Button from "./Button";
|
|
4
4
|
import { colors } from "./colors";
|
|
5
5
|
import type { HEX, KeyboardToolbarTheme } from "./types";
|
|
6
|
+
import type { KeyboardStickyViewProps } from "../KeyboardStickyView";
|
|
6
7
|
import type { ReactNode } from "react";
|
|
7
8
|
import type { GestureResponderEvent, ViewProps } from "react-native";
|
|
8
9
|
export type KeyboardToolbarProps = Omit<ViewProps, "style" | "testID" | "children"> & {
|
|
@@ -41,7 +42,7 @@ export type KeyboardToolbarProps = Omit<ViewProps, "style" | "testID" | "childre
|
|
|
41
42
|
* A value for container opacity in hexadecimal format (e.g. `ff`). Default value is `ff`.
|
|
42
43
|
*/
|
|
43
44
|
opacity?: HEX;
|
|
44
|
-
}
|
|
45
|
+
} & Pick<KeyboardStickyViewProps, "offset" | "enabled">;
|
|
45
46
|
/**
|
|
46
47
|
* `KeyboardToolbar` is a component that is shown above the keyboard with `Prev`/`Next` and
|
|
47
48
|
* `Done` buttons.
|
|
@@ -3,6 +3,7 @@ export * from "./animated";
|
|
|
3
3
|
export * from "./context";
|
|
4
4
|
export * from "./hooks";
|
|
5
5
|
export * from "./constants";
|
|
6
|
+
export * from "./module";
|
|
6
7
|
export * from "./types";
|
|
7
8
|
export { KeyboardAvoidingView, KeyboardStickyView, KeyboardAwareScrollView, KeyboardToolbar, DefaultKeyboardToolbarTheme, } from "./components";
|
|
8
9
|
export type { KeyboardAvoidingViewProps, KeyboardStickyViewProps, KeyboardAwareScrollViewProps, KeyboardToolbarProps, } from "./components";
|
|
@@ -3,7 +3,7 @@ export interface Spec extends TurboModule {
|
|
|
3
3
|
readonly getConstants: () => {};
|
|
4
4
|
setInputMode(mode: number): void;
|
|
5
5
|
setDefaultMode(): void;
|
|
6
|
-
dismiss(): void;
|
|
6
|
+
dismiss(keepFocus: boolean): void;
|
|
7
7
|
setFocusTo(direction: string): void;
|
|
8
8
|
addListener: (eventName: string) => void;
|
|
9
9
|
removeListeners: (count: number) => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropsWithChildren } from "react";
|
|
2
|
-
import type { EmitterSubscription, NativeSyntheticEvent, ViewProps } from "react-native";
|
|
2
|
+
import type { EmitterSubscription, NativeSyntheticEvent, TextInputProps, ViewProps } from "react-native";
|
|
3
3
|
export type NativeEvent = {
|
|
4
4
|
progress: number;
|
|
5
5
|
height: number;
|
|
@@ -78,22 +78,33 @@ export type OverKeyboardViewProps = PropsWithChildren<{
|
|
|
78
78
|
visible: boolean;
|
|
79
79
|
}>;
|
|
80
80
|
export type Direction = "next" | "prev" | "current";
|
|
81
|
+
export type DismissOptions = {
|
|
82
|
+
keepFocus: boolean;
|
|
83
|
+
};
|
|
81
84
|
export type KeyboardControllerModule = {
|
|
82
85
|
setDefaultMode: () => void;
|
|
83
86
|
setInputMode: (mode: number) => void;
|
|
84
|
-
dismiss: () => void
|
|
87
|
+
dismiss: (options?: DismissOptions) => Promise<void>;
|
|
85
88
|
setFocusTo: (direction: Direction) => void;
|
|
89
|
+
isVisible: () => boolean;
|
|
90
|
+
state: () => KeyboardEventData | null;
|
|
86
91
|
};
|
|
87
92
|
export type KeyboardControllerNativeModule = {
|
|
93
|
+
setDefaultMode: () => void;
|
|
94
|
+
setInputMode: (mode: number) => void;
|
|
95
|
+
dismiss: (keepFocus: boolean) => void;
|
|
96
|
+
setFocusTo: (direction: Direction) => void;
|
|
88
97
|
addListener: (eventName: string) => void;
|
|
89
98
|
removeListeners: (count: number) => void;
|
|
90
|
-
}
|
|
99
|
+
};
|
|
91
100
|
export type KeyboardControllerEvents = "keyboardWillShow" | "keyboardDidShow" | "keyboardWillHide" | "keyboardDidHide";
|
|
92
101
|
export type KeyboardEventData = {
|
|
93
102
|
height: number;
|
|
94
103
|
duration: number;
|
|
95
104
|
timestamp: number;
|
|
96
105
|
target: number;
|
|
106
|
+
type: NonNullable<TextInputProps["keyboardType"]>;
|
|
107
|
+
appearance: NonNullable<TextInputProps["keyboardAppearance"]>;
|
|
97
108
|
};
|
|
98
109
|
export type KeyboardEventsModule = {
|
|
99
110
|
addListener: (name: KeyboardControllerEvents, cb: (e: KeyboardEventData) => void) => EmitterSubscription;
|
package/package.json
CHANGED
package/src/animated.tsx
CHANGED
|
@@ -169,6 +169,11 @@ export const KeyboardProvider = ({
|
|
|
169
169
|
|
|
170
170
|
updateSharedValues(event, ["android", "ios"]);
|
|
171
171
|
},
|
|
172
|
+
onKeyboardMoveEnd: (event: NativeEvent) => {
|
|
173
|
+
"worklet";
|
|
174
|
+
|
|
175
|
+
updateSharedValues(event, ["android"]);
|
|
176
|
+
},
|
|
172
177
|
},
|
|
173
178
|
[],
|
|
174
179
|
);
|
|
@@ -213,6 +218,7 @@ export const KeyboardProvider = ({
|
|
|
213
218
|
onKeyboardMoveStart={OS === "ios" ? onKeyboardMove : undefined}
|
|
214
219
|
onKeyboardMove={OS === "android" ? onKeyboardMove : undefined}
|
|
215
220
|
onKeyboardMoveInteractive={onKeyboardMove}
|
|
221
|
+
onKeyboardMoveEnd={OS === "android" ? onKeyboardMove : undefined}
|
|
216
222
|
onFocusedInputLayoutChangedReanimated={inputLayoutHandler}
|
|
217
223
|
>
|
|
218
224
|
{children}
|
package/src/bindings.native.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { NativeEventEmitter, Platform } from "react-native";
|
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
FocusedInputEventsModule,
|
|
5
|
-
KeyboardControllerModule,
|
|
6
5
|
KeyboardControllerNativeModule,
|
|
7
6
|
KeyboardControllerProps,
|
|
8
7
|
KeyboardEventsModule,
|
|
@@ -40,13 +39,7 @@ export const KeyboardEvents: KeyboardEventsModule = {
|
|
|
40
39
|
addListener: (name, cb) =>
|
|
41
40
|
eventEmitter.addListener(KEYBOARD_CONTROLLER_NAMESPACE + name, cb),
|
|
42
41
|
};
|
|
43
|
-
|
|
44
|
-
setDefaultMode: KeyboardControllerNative.setDefaultMode,
|
|
45
|
-
setInputMode: KeyboardControllerNative.setInputMode,
|
|
46
|
-
setFocusTo: KeyboardControllerNative.setFocusTo,
|
|
47
|
-
// additional function is needed because of this https://github.com/kirillzyusko/react-native-keyboard-controller/issues/684
|
|
48
|
-
dismiss: () => KeyboardControllerNative.dismiss(),
|
|
49
|
-
};
|
|
42
|
+
|
|
50
43
|
/**
|
|
51
44
|
* This API is not documented, it's for internal usage only (for now), and is a subject to potential breaking changes in future.
|
|
52
45
|
* Use it with cautious.
|
package/src/bindings.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { View } from "react-native";
|
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
FocusedInputEventsModule,
|
|
5
|
-
|
|
5
|
+
KeyboardControllerNativeModule,
|
|
6
6
|
KeyboardControllerProps,
|
|
7
7
|
KeyboardEventsModule,
|
|
8
8
|
KeyboardGestureAreaProps,
|
|
@@ -13,11 +13,13 @@ import type { EmitterSubscription } from "react-native";
|
|
|
13
13
|
|
|
14
14
|
const NOOP = () => {};
|
|
15
15
|
|
|
16
|
-
export const
|
|
16
|
+
export const KeyboardControllerNative: KeyboardControllerNativeModule = {
|
|
17
17
|
setDefaultMode: NOOP,
|
|
18
18
|
setInputMode: NOOP,
|
|
19
19
|
dismiss: NOOP,
|
|
20
20
|
setFocusTo: NOOP,
|
|
21
|
+
addListener: NOOP,
|
|
22
|
+
removeListeners: NOOP,
|
|
21
23
|
};
|
|
22
24
|
export const KeyboardEvents: KeyboardEventsModule = {
|
|
23
25
|
addListener: () => ({ remove: NOOP } as EmitterSubscription),
|
|
@@ -14,17 +14,7 @@ import { useKeyboardAnimation } from "./hooks";
|
|
|
14
14
|
|
|
15
15
|
import type { LayoutRectangle, ViewProps } from "react-native";
|
|
16
16
|
|
|
17
|
-
export type
|
|
18
|
-
/**
|
|
19
|
-
* Specify how to react to the presence of the keyboard.
|
|
20
|
-
*/
|
|
21
|
-
behavior?: "height" | "position" | "padding";
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Style of the content container when `behavior` is 'position'.
|
|
25
|
-
*/
|
|
26
|
-
contentContainerStyle?: ViewProps["style"];
|
|
27
|
-
|
|
17
|
+
export type KeyboardAvoidingViewBaseProps = {
|
|
28
18
|
/**
|
|
29
19
|
* Controls whether this `KeyboardAvoidingView` instance should take effect.
|
|
30
20
|
* This is useful when more than one is on the screen. Defaults to true.
|
|
@@ -38,6 +28,32 @@ export type KeyboardAvoidingViewProps = {
|
|
|
38
28
|
keyboardVerticalOffset?: number;
|
|
39
29
|
} & ViewProps;
|
|
40
30
|
|
|
31
|
+
export type KeyboardAvoidingViewProps = KeyboardAvoidingViewBaseProps &
|
|
32
|
+
(
|
|
33
|
+
| {
|
|
34
|
+
/**
|
|
35
|
+
* Specify how to react to the presence of the keyboard.
|
|
36
|
+
*/
|
|
37
|
+
behavior?: "position";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Style of the content container when `behavior` is 'position'.
|
|
41
|
+
*/
|
|
42
|
+
contentContainerStyle?: ViewProps["style"];
|
|
43
|
+
}
|
|
44
|
+
| {
|
|
45
|
+
/**
|
|
46
|
+
* Specify how to react to the presence of the keyboard.
|
|
47
|
+
*/
|
|
48
|
+
behavior?: "height" | "padding";
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* `contentContainerStyle` is not allowed for these behaviors.
|
|
52
|
+
*/
|
|
53
|
+
contentContainerStyle?: never;
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
41
57
|
const defaultLayout: LayoutRectangle = {
|
|
42
58
|
x: 0,
|
|
43
59
|
y: 0,
|
|
@@ -22,6 +22,9 @@ export type KeyboardStickyViewProps = {
|
|
|
22
22
|
*/
|
|
23
23
|
opened?: number;
|
|
24
24
|
};
|
|
25
|
+
|
|
26
|
+
/** Controls whether this `KeyboardStickyView` instance should take effect. Default is `true` */
|
|
27
|
+
enabled?: boolean;
|
|
25
28
|
} & ViewProps;
|
|
26
29
|
|
|
27
30
|
const KeyboardStickyView = forwardRef<
|
|
@@ -29,7 +32,13 @@ const KeyboardStickyView = forwardRef<
|
|
|
29
32
|
React.PropsWithChildren<KeyboardStickyViewProps>
|
|
30
33
|
>(
|
|
31
34
|
(
|
|
32
|
-
{
|
|
35
|
+
{
|
|
36
|
+
children,
|
|
37
|
+
offset: { closed = 0, opened = 0 } = {},
|
|
38
|
+
style,
|
|
39
|
+
enabled = true,
|
|
40
|
+
...props
|
|
41
|
+
},
|
|
33
42
|
ref,
|
|
34
43
|
) => {
|
|
35
44
|
const { height, progress } = useReanimatedKeyboardAnimation();
|
|
@@ -38,9 +47,9 @@ const KeyboardStickyView = forwardRef<
|
|
|
38
47
|
const offset = interpolate(progress.value, [0, 1], [closed, opened]);
|
|
39
48
|
|
|
40
49
|
return {
|
|
41
|
-
transform: [{ translateY: height.value + offset }],
|
|
50
|
+
transform: [{ translateY: enabled ? height.value + offset : closed }],
|
|
42
51
|
};
|
|
43
|
-
}, [closed, opened]);
|
|
52
|
+
}, [closed, opened, enabled]);
|
|
44
53
|
|
|
45
54
|
const styles = useMemo(
|
|
46
55
|
() => [style, stickyViewStyle],
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
2
|
import { StyleSheet, Text, View } from "react-native";
|
|
3
3
|
|
|
4
|
-
import { FocusedInputEvents
|
|
4
|
+
import { FocusedInputEvents } from "../../bindings";
|
|
5
|
+
import { KeyboardController } from "../../module";
|
|
5
6
|
import useColorScheme from "../hooks/useColorScheme";
|
|
6
7
|
import KeyboardStickyView from "../KeyboardStickyView";
|
|
7
8
|
|
|
@@ -10,6 +11,7 @@ import Button from "./Button";
|
|
|
10
11
|
import { colors } from "./colors";
|
|
11
12
|
|
|
12
13
|
import type { HEX, KeyboardToolbarTheme } from "./types";
|
|
14
|
+
import type { KeyboardStickyViewProps } from "../KeyboardStickyView";
|
|
13
15
|
import type { ReactNode } from "react";
|
|
14
16
|
import type { GestureResponderEvent, ViewProps } from "react-native";
|
|
15
17
|
|
|
@@ -52,7 +54,7 @@ export type KeyboardToolbarProps = Omit<
|
|
|
52
54
|
* A value for container opacity in hexadecimal format (e.g. `ff`). Default value is `ff`.
|
|
53
55
|
*/
|
|
54
56
|
opacity?: HEX;
|
|
55
|
-
}
|
|
57
|
+
} & Pick<KeyboardStickyViewProps, "offset" | "enabled">;
|
|
56
58
|
|
|
57
59
|
const TEST_ID_KEYBOARD_TOOLBAR = "keyboard.toolbar";
|
|
58
60
|
const TEST_ID_KEYBOARD_TOOLBAR_PREVIOUS = `${TEST_ID_KEYBOARD_TOOLBAR}.previous`;
|
|
@@ -62,7 +64,6 @@ const TEST_ID_KEYBOARD_TOOLBAR_DONE = `${TEST_ID_KEYBOARD_TOOLBAR}.done`;
|
|
|
62
64
|
|
|
63
65
|
const KEYBOARD_TOOLBAR_HEIGHT = 42;
|
|
64
66
|
const DEFAULT_OPACITY: HEX = "FF";
|
|
65
|
-
const offset = { closed: KEYBOARD_TOOLBAR_HEIGHT };
|
|
66
67
|
|
|
67
68
|
/**
|
|
68
69
|
* `KeyboardToolbar` is a component that is shown above the keyboard with `Prev`/`Next` and
|
|
@@ -80,6 +81,8 @@ const KeyboardToolbar: React.FC<KeyboardToolbarProps> = ({
|
|
|
80
81
|
onDoneCallback,
|
|
81
82
|
blur = null,
|
|
82
83
|
opacity = DEFAULT_OPACITY,
|
|
84
|
+
offset: { closed = 0, opened = 0 } = {},
|
|
85
|
+
enabled = true,
|
|
83
86
|
...rest
|
|
84
87
|
}) => {
|
|
85
88
|
const colorScheme = useColorScheme();
|
|
@@ -110,6 +113,10 @@ const KeyboardToolbar: React.FC<KeyboardToolbarProps> = ({
|
|
|
110
113
|
],
|
|
111
114
|
[colorScheme, opacity, theme],
|
|
112
115
|
);
|
|
116
|
+
const offset = useMemo(
|
|
117
|
+
() => ({ closed: closed + KEYBOARD_TOOLBAR_HEIGHT, opened }),
|
|
118
|
+
[closed, opened],
|
|
119
|
+
);
|
|
113
120
|
const ButtonContainer = button || Button;
|
|
114
121
|
const IconContainer = icon || Arrow;
|
|
115
122
|
|
|
@@ -145,7 +152,7 @@ const KeyboardToolbar: React.FC<KeyboardToolbarProps> = ({
|
|
|
145
152
|
);
|
|
146
153
|
|
|
147
154
|
return (
|
|
148
|
-
<KeyboardStickyView offset={offset}>
|
|
155
|
+
<KeyboardStickyView enabled={enabled} offset={offset}>
|
|
149
156
|
<View {...rest} style={toolbarStyle} testID={TEST_ID_KEYBOARD_TOOLBAR}>
|
|
150
157
|
{blur}
|
|
151
158
|
{showArrows && (
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useEffect, useLayoutEffect } from "react";
|
|
2
2
|
|
|
3
|
-
import { KeyboardController } from "../bindings";
|
|
4
3
|
import { AndroidSoftInputModes } from "../constants";
|
|
5
4
|
import { useKeyboardContext } from "../context";
|
|
5
|
+
import { KeyboardController } from "../module";
|
|
6
6
|
|
|
7
7
|
import type { AnimatedContext, ReanimatedContext } from "../context";
|
|
8
8
|
import type { FocusedInputHandler, KeyboardHandler } from "../types";
|
|
@@ -24,6 +24,11 @@ export const useWindowDimensions = () => {
|
|
|
24
24
|
},
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
+
// we might have missed an update between reading a value in render and
|
|
28
|
+
// `addListener` in this handler, so we set it here. If there was
|
|
29
|
+
// no change, React will filter out this update as a no-op.
|
|
30
|
+
setDimensions(initialDimensions);
|
|
31
|
+
|
|
27
32
|
return () => {
|
|
28
33
|
subscription.remove();
|
|
29
34
|
};
|
package/src/index.ts
CHANGED
package/src/internal.ts
CHANGED
|
@@ -48,8 +48,8 @@ export function useEventHandlerRegistration<
|
|
|
48
48
|
if (viewTagRef.current) {
|
|
49
49
|
attachWorkletHandlers();
|
|
50
50
|
} else {
|
|
51
|
-
// view may not be mounted yet - defer registration
|
|
52
|
-
|
|
51
|
+
// view may not be mounted yet - defer registration until call-stack becomes empty
|
|
52
|
+
queueMicrotask(attachWorkletHandlers);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
return () => {
|
package/src/module.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { KeyboardControllerNative, KeyboardEvents } from "./bindings";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
DismissOptions,
|
|
5
|
+
KeyboardControllerModule,
|
|
6
|
+
KeyboardEventData,
|
|
7
|
+
} from "./types";
|
|
8
|
+
|
|
9
|
+
let isClosed = false;
|
|
10
|
+
let lastEvent: KeyboardEventData | null = null;
|
|
11
|
+
|
|
12
|
+
KeyboardEvents.addListener("keyboardDidHide", (e) => {
|
|
13
|
+
isClosed = true;
|
|
14
|
+
lastEvent = e;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
KeyboardEvents.addListener("keyboardDidShow", (e) => {
|
|
18
|
+
isClosed = false;
|
|
19
|
+
lastEvent = e;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const dismiss = async (
|
|
23
|
+
{ keepFocus }: DismissOptions = { keepFocus: false },
|
|
24
|
+
): Promise<void> => {
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
if (isClosed) {
|
|
27
|
+
resolve();
|
|
28
|
+
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const subscription = KeyboardEvents.addListener("keyboardDidHide", () => {
|
|
33
|
+
resolve(undefined);
|
|
34
|
+
subscription.remove();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
KeyboardControllerNative.dismiss(keepFocus);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const isVisible = () => !isClosed;
|
|
41
|
+
const state = () => lastEvent;
|
|
42
|
+
|
|
43
|
+
export const KeyboardController: KeyboardControllerModule = {
|
|
44
|
+
setDefaultMode: KeyboardControllerNative.setDefaultMode,
|
|
45
|
+
setInputMode: KeyboardControllerNative.setInputMode,
|
|
46
|
+
setFocusTo: KeyboardControllerNative.setFocusTo,
|
|
47
|
+
dismiss,
|
|
48
|
+
isVisible,
|
|
49
|
+
state,
|
|
50
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { PropsWithChildren } from "react";
|
|
|
2
2
|
import type {
|
|
3
3
|
EmitterSubscription,
|
|
4
4
|
NativeSyntheticEvent,
|
|
5
|
+
TextInputProps,
|
|
5
6
|
ViewProps,
|
|
6
7
|
} from "react-native";
|
|
7
8
|
|
|
@@ -114,19 +115,30 @@ export type OverKeyboardViewProps = PropsWithChildren<{
|
|
|
114
115
|
}>;
|
|
115
116
|
|
|
116
117
|
export type Direction = "next" | "prev" | "current";
|
|
118
|
+
export type DismissOptions = {
|
|
119
|
+
keepFocus: boolean;
|
|
120
|
+
};
|
|
117
121
|
export type KeyboardControllerModule = {
|
|
118
122
|
// android only
|
|
119
123
|
setDefaultMode: () => void;
|
|
120
124
|
setInputMode: (mode: number) => void;
|
|
121
125
|
// all platforms
|
|
122
|
-
dismiss: () => void
|
|
126
|
+
dismiss: (options?: DismissOptions) => Promise<void>;
|
|
123
127
|
setFocusTo: (direction: Direction) => void;
|
|
128
|
+
isVisible: () => boolean;
|
|
129
|
+
state: () => KeyboardEventData | null;
|
|
124
130
|
};
|
|
125
131
|
export type KeyboardControllerNativeModule = {
|
|
132
|
+
// android only
|
|
133
|
+
setDefaultMode: () => void;
|
|
134
|
+
setInputMode: (mode: number) => void;
|
|
135
|
+
// all platforms
|
|
136
|
+
dismiss: (keepFocus: boolean) => void;
|
|
137
|
+
setFocusTo: (direction: Direction) => void;
|
|
126
138
|
// native event module stuff
|
|
127
139
|
addListener: (eventName: string) => void;
|
|
128
140
|
removeListeners: (count: number) => void;
|
|
129
|
-
}
|
|
141
|
+
};
|
|
130
142
|
|
|
131
143
|
// Event module declarations
|
|
132
144
|
export type KeyboardControllerEvents =
|
|
@@ -139,6 +151,8 @@ export type KeyboardEventData = {
|
|
|
139
151
|
duration: number;
|
|
140
152
|
timestamp: number;
|
|
141
153
|
target: number;
|
|
154
|
+
type: NonNullable<TextInputProps["keyboardType"]>;
|
|
155
|
+
appearance: NonNullable<TextInputProps["keyboardAppearance"]>;
|
|
142
156
|
};
|
|
143
157
|
export type KeyboardEventsModule = {
|
|
144
158
|
addListener: (
|