react-native-keyboard-controller 1.8.0 → 1.9.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/README.md +2 -1
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/reactnativekeyboardcontroller/events/FocusedInputLayoutChangedEvent.kt +41 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt +9 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt +7 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/FocusedInputLayoutObserver.kt +93 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/{KeyboardAnimationCallback.kt → listeners/KeyboardAnimationCallback.kt} +86 -55
- package/android/src/main/java/com/reactnativekeyboardcontroller/managers/KeyboardControllerViewManagerImpl.kt +2 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +16 -8
- package/ios/Extensions.swift +7 -0
- package/ios/KeyboardController.xcodeproj/project.pbxproj +41 -7
- package/ios/events/FocusedInputLayoutChangedEvent.h +16 -0
- package/ios/events/FocusedInputLayoutChangedEvent.m +75 -0
- package/ios/observers/FocusedInputLayoutObserver.swift +136 -0
- package/ios/{KeyboardControllerView.mm → views/KeyboardControllerView.mm} +40 -4
- package/ios/{KeyboardControllerViewManager.mm → views/KeyboardControllerViewManager.mm} +3 -0
- package/ios/{KeyboardControllerViewManager.swift → views/KeyboardControllerViewManager.swift} +14 -0
- package/jest/index.js +16 -0
- package/lib/commonjs/animated.js +18 -4
- package/lib/commonjs/animated.js.map +1 -1
- package/lib/commonjs/bindings.js.map +1 -1
- 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.map +1 -1
- package/lib/commonjs/components/KeyboardStickyView/index.js +44 -0
- package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -0
- package/lib/commonjs/components/index.js +7 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/constants.js.map +1 -1
- package/lib/commonjs/context.js +6 -3
- package/lib/commonjs/context.js.map +1 -1
- package/lib/commonjs/hooks.js +8 -1
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/commonjs/index.js +8 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/commonjs/reanimated.js +5 -2
- package/lib/commonjs/reanimated.js.map +1 -1
- package/lib/commonjs/reanimated.native.js +18 -1
- package/lib/commonjs/reanimated.native.js.map +1 -1
- package/lib/commonjs/replicas.js +1 -1
- package/lib/commonjs/replicas.js.map +1 -1
- package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/NativeKeyboardController.js.map +1 -1
- package/lib/commonjs/specs/NativeStatusBarManagerCompat.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/animated.js +19 -5
- package/lib/module/animated.js.map +1 -1
- package/lib/module/bindings.js.map +1 -1
- package/lib/module/bindings.native.js +1 -1
- 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 +2 -2
- package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/module/components/KeyboardStickyView/index.js +35 -0
- package/lib/module/components/KeyboardStickyView/index.js.map +1 -0
- package/lib/module/components/index.js +1 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/constants.js.map +1 -1
- package/lib/module/context.js +6 -3
- package/lib/module/context.js.map +1 -1
- package/lib/module/hooks.js +7 -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.map +1 -1
- package/lib/module/reanimated.js +3 -1
- package/lib/module/reanimated.js.map +1 -1
- package/lib/module/reanimated.native.js +16 -0
- package/lib/module/reanimated.native.js.map +1 -1
- package/lib/module/replicas.js +2 -2
- package/lib/module/replicas.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/typescript/components/KeyboardAvoidingView/index.d.ts +2 -1
- package/lib/typescript/components/KeyboardStickyView/index.d.ts +20 -0
- package/lib/typescript/components/index.d.ts +1 -0
- package/lib/typescript/context.d.ts +3 -2
- package/lib/typescript/hooks.d.ts +5 -2
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/internal.d.ts +1 -1
- package/lib/typescript/reanimated.d.ts +2 -1
- package/lib/typescript/reanimated.native.d.ts +2 -1
- package/lib/typescript/specs/KeyboardControllerViewNativeComponent.d.ts +12 -0
- package/lib/typescript/types.d.ts +16 -0
- package/package.json +9 -28
- package/src/animated.tsx +30 -7
- package/src/bindings.native.ts +1 -1
- package/src/bindings.ts +3 -1
- package/src/components/KeyboardAvoidingView/hooks.ts +1 -0
- package/src/components/KeyboardAvoidingView/index.tsx +8 -10
- package/src/components/KeyboardStickyView/index.tsx +63 -0
- package/src/components/index.ts +1 -0
- package/src/constants.ts +2 -0
- package/src/context.ts +12 -5
- package/src/hooks.ts +10 -6
- package/src/index.ts +1 -1
- package/src/internal.ts +3 -1
- package/src/reanimated.native.ts +30 -1
- package/src/reanimated.ts +13 -2
- package/src/replicas.ts +2 -2
- package/src/specs/KeyboardControllerViewNativeComponent.ts +15 -1
- package/src/specs/KeyboardGestureAreaNativeComponent.ts +2 -1
- package/src/specs/NativeKeyboardController.ts +2 -1
- package/src/specs/NativeStatusBarManagerCompat.ts +2 -1
- package/src/types.ts +27 -1
- /package/ios/{KeyboardMoveEvent.h → events/KeyboardMoveEvent.h} +0 -0
- /package/ios/{KeyboardMoveEvent.m → events/KeyboardMoveEvent.m} +0 -0
- /package/ios/{KeyboardMovementObserver.swift → observers/KeyboardMovementObserver.swift} +0 -0
- /package/ios/{KeyboardControllerView.h → views/KeyboardControllerView.h} +0 -0
package/src/animated.tsx
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import { Animated, Platform, StyleSheet
|
|
2
|
+
import { Animated, Platform, StyleSheet } from 'react-native';
|
|
3
3
|
import Reanimated, { useSharedValue } from 'react-native-reanimated';
|
|
4
4
|
|
|
5
|
-
import { KeyboardAnimationContext, KeyboardContext } from './context';
|
|
6
|
-
import { useSharedHandlers, useAnimatedValue } from './internal';
|
|
7
5
|
import { KeyboardControllerView } from './bindings';
|
|
8
|
-
import {
|
|
6
|
+
import { KeyboardContext } from './context';
|
|
7
|
+
import { useAnimatedValue, useSharedHandlers } from './internal';
|
|
8
|
+
import { applyMonkeyPatch, revertMonkeyPatch } from './monkey-patch';
|
|
9
|
+
import {
|
|
10
|
+
useAnimatedKeyboardHandler,
|
|
11
|
+
useFocusedInputHandler,
|
|
12
|
+
} from './reanimated';
|
|
9
13
|
|
|
14
|
+
import type { KeyboardAnimationContext } from './context';
|
|
10
15
|
import type {
|
|
16
|
+
FocusedInputLayoutChangedEvent,
|
|
11
17
|
KeyboardControllerProps,
|
|
12
18
|
KeyboardHandler,
|
|
13
19
|
NativeEvent,
|
|
14
20
|
} from './types';
|
|
15
|
-
import {
|
|
21
|
+
import type { ViewStyle } from 'react-native';
|
|
16
22
|
|
|
17
23
|
const KeyboardControllerViewAnimated = Reanimated.createAnimatedComponent(
|
|
18
24
|
Animated.createAnimatedComponent(
|
|
@@ -77,6 +83,7 @@ export const KeyboardProvider = ({
|
|
|
77
83
|
// shared values
|
|
78
84
|
const progressSV = useSharedValue(0);
|
|
79
85
|
const heightSV = useSharedValue(0);
|
|
86
|
+
const layout = useSharedValue<FocusedInputLayoutChangedEvent | null>(null);
|
|
80
87
|
const { setHandlers, broadcast } = useSharedHandlers<KeyboardHandler>();
|
|
81
88
|
// memo
|
|
82
89
|
const context = useMemo<KeyboardAnimationContext>(
|
|
@@ -84,6 +91,7 @@ export const KeyboardProvider = ({
|
|
|
84
91
|
enabled,
|
|
85
92
|
animated: { progress: progress, height: Animated.multiply(height, -1) },
|
|
86
93
|
reanimated: { progress: progressSV, height: heightSV },
|
|
94
|
+
layout,
|
|
87
95
|
setHandlers,
|
|
88
96
|
setEnabled,
|
|
89
97
|
}),
|
|
@@ -120,7 +128,7 @@ export const KeyboardProvider = ({
|
|
|
120
128
|
heightSV.value = -event.height;
|
|
121
129
|
}
|
|
122
130
|
};
|
|
123
|
-
const
|
|
131
|
+
const keyboardHandler = useAnimatedKeyboardHandler(
|
|
124
132
|
{
|
|
125
133
|
onKeyboardMoveStart: (event: NativeEvent) => {
|
|
126
134
|
'worklet';
|
|
@@ -148,6 +156,20 @@ export const KeyboardProvider = ({
|
|
|
148
156
|
},
|
|
149
157
|
[]
|
|
150
158
|
);
|
|
159
|
+
const inputHandler = useFocusedInputHandler(
|
|
160
|
+
{
|
|
161
|
+
onFocusedInputLayoutChanged: (e) => {
|
|
162
|
+
'worklet';
|
|
163
|
+
|
|
164
|
+
if (e.target !== -1) {
|
|
165
|
+
layout.value = e;
|
|
166
|
+
} else {
|
|
167
|
+
layout.value = null;
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
[]
|
|
172
|
+
);
|
|
151
173
|
// effects
|
|
152
174
|
useEffect(() => {
|
|
153
175
|
if (enabled) {
|
|
@@ -161,10 +183,11 @@ export const KeyboardProvider = ({
|
|
|
161
183
|
<KeyboardContext.Provider value={context}>
|
|
162
184
|
<KeyboardControllerViewAnimated
|
|
163
185
|
enabled={enabled}
|
|
164
|
-
onKeyboardMoveReanimated={
|
|
186
|
+
onKeyboardMoveReanimated={keyboardHandler}
|
|
165
187
|
onKeyboardMoveStart={Platform.OS === 'ios' ? onKeyboardMove : undefined}
|
|
166
188
|
onKeyboardMove={Platform.OS === 'android' ? onKeyboardMove : undefined}
|
|
167
189
|
onKeyboardMoveInteractive={onKeyboardMove}
|
|
190
|
+
onFocusedInputLayoutChangedReanimated={inputHandler}
|
|
168
191
|
navigationBarTranslucent={navigationBarTranslucent}
|
|
169
192
|
statusBarTranslucent={statusBarTranslucent}
|
|
170
193
|
// @ts-expect-error https://github.com/software-mansion/react-native-reanimated/pull/4923
|
package/src/bindings.native.ts
CHANGED
package/src/bindings.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
|
|
2
3
|
import type {
|
|
3
4
|
KeyboardControllerModule,
|
|
4
5
|
KeyboardControllerProps,
|
|
5
6
|
KeyboardEventsModule,
|
|
6
7
|
KeyboardGestureAreaProps,
|
|
7
8
|
} from './types';
|
|
9
|
+
import type { EmitterSubscription } from 'react-native';
|
|
8
10
|
|
|
9
11
|
const NOOP = () => {};
|
|
10
12
|
export const KeyboardController: KeyboardControllerModule = {
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import React, { forwardRef, useCallback, useMemo } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
LayoutRectangle,
|
|
4
|
-
useWindowDimensions,
|
|
5
|
-
View,
|
|
6
|
-
ViewProps,
|
|
7
|
-
} from 'react-native';
|
|
2
|
+
import { View, useWindowDimensions } from 'react-native';
|
|
8
3
|
import Reanimated, {
|
|
9
|
-
useAnimatedStyle,
|
|
10
|
-
useWorkletCallback,
|
|
11
|
-
useSharedValue,
|
|
12
|
-
useDerivedValue,
|
|
13
4
|
interpolate,
|
|
14
5
|
runOnUI,
|
|
6
|
+
useAnimatedStyle,
|
|
7
|
+
useDerivedValue,
|
|
8
|
+
useSharedValue,
|
|
9
|
+
useWorkletCallback,
|
|
15
10
|
} from 'react-native-reanimated';
|
|
11
|
+
|
|
16
12
|
import { useKeyboardAnimation } from './hooks';
|
|
17
13
|
|
|
14
|
+
import type { LayoutRectangle, ViewProps } from 'react-native';
|
|
15
|
+
|
|
18
16
|
type Props = {
|
|
19
17
|
/**
|
|
20
18
|
* Specify how to react to the presence of the keyboard.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { forwardRef, useMemo } from 'react';
|
|
2
|
+
import Reanimated, {
|
|
3
|
+
interpolate,
|
|
4
|
+
useAnimatedStyle,
|
|
5
|
+
} from 'react-native-reanimated';
|
|
6
|
+
|
|
7
|
+
import { useReanimatedKeyboardAnimation } from '../../hooks';
|
|
8
|
+
|
|
9
|
+
import type { View, ViewProps } from 'react-native';
|
|
10
|
+
|
|
11
|
+
type KeyboardStickyViewProps = {
|
|
12
|
+
/**
|
|
13
|
+
* Specify additional offset to the view for given keyboard state.
|
|
14
|
+
*/
|
|
15
|
+
offset?: {
|
|
16
|
+
/**
|
|
17
|
+
* Adds additional `translateY` when keyboard is close. By default `0`.
|
|
18
|
+
*/
|
|
19
|
+
closed?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Adds additional `translateY` when keyboard is open. By default `0`.
|
|
22
|
+
*/
|
|
23
|
+
opened?: number;
|
|
24
|
+
};
|
|
25
|
+
} & ViewProps;
|
|
26
|
+
|
|
27
|
+
const KeyboardStickyView = forwardRef<
|
|
28
|
+
View,
|
|
29
|
+
React.PropsWithChildren<KeyboardStickyViewProps>
|
|
30
|
+
>(
|
|
31
|
+
(
|
|
32
|
+
{ children, offset: { closed = 0, opened = 0 } = {}, style, ...props },
|
|
33
|
+
ref
|
|
34
|
+
) => {
|
|
35
|
+
const { height, progress } = useReanimatedKeyboardAnimation();
|
|
36
|
+
|
|
37
|
+
const stickyViewStyle = useAnimatedStyle(() => {
|
|
38
|
+
const offset = interpolate(progress.value, [0, 1], [closed, opened]);
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
transform: [{ translateY: height.value + offset }],
|
|
42
|
+
};
|
|
43
|
+
}, [closed, opened]);
|
|
44
|
+
|
|
45
|
+
const styles = useMemo(
|
|
46
|
+
() => [style, stickyViewStyle],
|
|
47
|
+
[style, stickyViewStyle]
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Reanimated.View
|
|
52
|
+
// @ts-expect-error because `ref` from reanimated is not compatible with react-native
|
|
53
|
+
ref={ref}
|
|
54
|
+
style={styles}
|
|
55
|
+
{...props}
|
|
56
|
+
>
|
|
57
|
+
{children}
|
|
58
|
+
</Reanimated.View>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export default KeyboardStickyView;
|
package/src/components/index.ts
CHANGED
package/src/constants.ts
CHANGED
|
@@ -12,6 +12,8 @@ export enum AndroidSoftInputModes {
|
|
|
12
12
|
SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5,
|
|
13
13
|
SOFT_INPUT_STATE_HIDDEN = 2,
|
|
14
14
|
SOFT_INPUT_STATE_UNCHANGED = 1,
|
|
15
|
+
// temporarily disable this rule to avoid breaking changes.
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
15
17
|
SOFT_INPUT_STATE_UNSPECIFIED = 0,
|
|
16
18
|
SOFT_INPUT_STATE_VISIBLE = 4,
|
|
17
19
|
}
|
package/src/context.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
2
|
import { Animated } from 'react-native';
|
|
3
3
|
|
|
4
|
+
import type { FocusedInputLayoutChangedEvent, KeyboardHandlers } from './types';
|
|
5
|
+
import type React from 'react';
|
|
4
6
|
import type { SharedValue } from 'react-native-reanimated';
|
|
5
|
-
import type { KeyboardHandlers } from './types';
|
|
6
7
|
|
|
7
8
|
export type AnimatedContext = {
|
|
8
9
|
progress: Animated.Value;
|
|
@@ -16,16 +17,21 @@ export type KeyboardAnimationContext = {
|
|
|
16
17
|
enabled: boolean;
|
|
17
18
|
animated: AnimatedContext;
|
|
18
19
|
reanimated: ReanimatedContext;
|
|
20
|
+
layout: SharedValue<FocusedInputLayoutChangedEvent | null>;
|
|
19
21
|
setHandlers: (handlers: KeyboardHandlers) => void;
|
|
20
22
|
setEnabled: React.Dispatch<React.SetStateAction<boolean>>;
|
|
21
23
|
};
|
|
22
24
|
const NOOP = () => {};
|
|
23
|
-
const
|
|
24
|
-
value
|
|
25
|
+
const withSharedValue = <T>(value: T): SharedValue<T> => ({
|
|
26
|
+
value,
|
|
25
27
|
addListener: NOOP,
|
|
26
28
|
removeListener: NOOP,
|
|
27
29
|
modify: NOOP,
|
|
28
|
-
};
|
|
30
|
+
});
|
|
31
|
+
const DEFAULT_SHARED_VALUE = withSharedValue(0);
|
|
32
|
+
const DEFAULT_LAYOUT = withSharedValue<FocusedInputLayoutChangedEvent | null>(
|
|
33
|
+
null
|
|
34
|
+
);
|
|
29
35
|
const defaultContext: KeyboardAnimationContext = {
|
|
30
36
|
enabled: true,
|
|
31
37
|
animated: {
|
|
@@ -36,6 +42,7 @@ const defaultContext: KeyboardAnimationContext = {
|
|
|
36
42
|
progress: DEFAULT_SHARED_VALUE,
|
|
37
43
|
height: DEFAULT_SHARED_VALUE,
|
|
38
44
|
},
|
|
45
|
+
layout: DEFAULT_LAYOUT,
|
|
39
46
|
setHandlers: NOOP,
|
|
40
47
|
setEnabled: NOOP,
|
|
41
48
|
};
|
package/src/hooks.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
AnimatedContext,
|
|
5
|
-
ReanimatedContext,
|
|
6
|
-
useKeyboardContext,
|
|
7
|
-
} from './context';
|
|
8
3
|
import { KeyboardController } from './bindings';
|
|
9
4
|
import { AndroidSoftInputModes } from './constants';
|
|
5
|
+
import { useKeyboardContext } from './context';
|
|
10
6
|
import { uuid } from './utils';
|
|
11
7
|
|
|
8
|
+
import type { AnimatedContext, ReanimatedContext } from './context';
|
|
12
9
|
import type { KeyboardHandler } from './types';
|
|
10
|
+
import type { DependencyList } from 'react';
|
|
13
11
|
|
|
14
12
|
export const useResizeMode = () => {
|
|
15
13
|
useEffect(() => {
|
|
@@ -65,3 +63,9 @@ export function useKeyboardController() {
|
|
|
65
63
|
|
|
66
64
|
return { setEnabled: context.setEnabled, enabled: context.enabled };
|
|
67
65
|
}
|
|
66
|
+
|
|
67
|
+
export function useReanimatedFocusedInput() {
|
|
68
|
+
const context = useKeyboardContext();
|
|
69
|
+
|
|
70
|
+
return { input: context.layout };
|
|
71
|
+
}
|
package/src/index.ts
CHANGED
package/src/internal.ts
CHANGED
|
@@ -15,7 +15,9 @@ import type { Handlers, NativeEvent } from './types';
|
|
|
15
15
|
* onEvent2: () => {},
|
|
16
16
|
* }
|
|
17
17
|
*/
|
|
18
|
-
export function useSharedHandlers<
|
|
18
|
+
export function useSharedHandlers<
|
|
19
|
+
T extends Record<string, (event: NativeEvent) => void>
|
|
20
|
+
>() {
|
|
19
21
|
const handlers = useSharedValue<Handlers<T>>({});
|
|
20
22
|
const jsHandlers = useRef<Handlers<T>>({});
|
|
21
23
|
|
package/src/reanimated.native.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { useEvent, useHandler } from 'react-native-reanimated';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
EventWithName,
|
|
5
|
+
FocusedInputHandlerHook,
|
|
6
|
+
FocusedInputLayoutChangedEvent,
|
|
7
|
+
KeyboardHandlerHook,
|
|
8
|
+
NativeEvent,
|
|
9
|
+
} from './types';
|
|
4
10
|
|
|
5
11
|
export const useAnimatedKeyboardHandler: KeyboardHandlerHook<
|
|
6
12
|
Record<string, unknown>,
|
|
@@ -49,3 +55,26 @@ export const useAnimatedKeyboardHandler: KeyboardHandlerHook<
|
|
|
49
55
|
doDependenciesDiffer
|
|
50
56
|
);
|
|
51
57
|
};
|
|
58
|
+
|
|
59
|
+
export const useFocusedInputHandler: FocusedInputHandlerHook<
|
|
60
|
+
Record<string, unknown>,
|
|
61
|
+
EventWithName<FocusedInputLayoutChangedEvent>
|
|
62
|
+
> = (handlers, dependencies) => {
|
|
63
|
+
const { context, doDependenciesDiffer } = useHandler(handlers, dependencies);
|
|
64
|
+
|
|
65
|
+
return useEvent(
|
|
66
|
+
(event) => {
|
|
67
|
+
'worklet';
|
|
68
|
+
const { onFocusedInputLayoutChanged } = handlers;
|
|
69
|
+
|
|
70
|
+
if (
|
|
71
|
+
onFocusedInputLayoutChanged &&
|
|
72
|
+
event.eventName.endsWith('onFocusedInputLayoutChanged')
|
|
73
|
+
) {
|
|
74
|
+
onFocusedInputLayoutChanged(event, context);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
['onFocusedInputLayoutChanged'],
|
|
78
|
+
doDependenciesDiffer
|
|
79
|
+
);
|
|
80
|
+
};
|
package/src/reanimated.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
EventWithName,
|
|
3
|
+
FocusedInputHandlerHook,
|
|
4
|
+
FocusedInputLayoutChangedEvent,
|
|
5
|
+
KeyboardHandlerHook,
|
|
6
|
+
NativeEvent,
|
|
7
|
+
} from './types';
|
|
2
8
|
|
|
9
|
+
const NOOP = () => () => {};
|
|
3
10
|
export const useAnimatedKeyboardHandler: KeyboardHandlerHook<
|
|
4
11
|
Record<string, unknown>,
|
|
5
12
|
EventWithName<NativeEvent>
|
|
6
|
-
> =
|
|
13
|
+
> = NOOP;
|
|
14
|
+
export const useFocusedInputHandler: FocusedInputHandlerHook<
|
|
15
|
+
Record<string, unknown>,
|
|
16
|
+
EventWithName<FocusedInputLayoutChangedEvent>
|
|
17
|
+
> = NOOP;
|
package/src/replicas.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { Animated, Easing, Keyboard, Platform } from 'react-native';
|
|
3
3
|
import {
|
|
4
4
|
runOnUI,
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
useWorkletCallback,
|
|
9
9
|
withSpring,
|
|
10
10
|
} from 'react-native-reanimated';
|
|
11
|
-
import { useReanimatedKeyboardAnimation } from './hooks';
|
|
12
11
|
|
|
13
12
|
import { KeyboardController } from './bindings';
|
|
14
13
|
import { AndroidSoftInputModes } from './constants';
|
|
14
|
+
import { useReanimatedKeyboardAnimation } from './hooks';
|
|
15
15
|
|
|
16
16
|
const availableOSEventType = Platform.OS === 'ios' ? 'Will' : 'Did';
|
|
17
17
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
2
|
+
|
|
1
3
|
import type { HostComponent } from 'react-native';
|
|
2
4
|
import type { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes';
|
|
3
5
|
import type {
|
|
@@ -5,7 +7,6 @@ import type {
|
|
|
5
7
|
Double,
|
|
6
8
|
Int32,
|
|
7
9
|
} from 'react-native/Libraries/Types/CodegenTypes';
|
|
8
|
-
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
9
10
|
|
|
10
11
|
type KeyboardMoveEvent = Readonly<{
|
|
11
12
|
height: Double;
|
|
@@ -14,6 +15,18 @@ type KeyboardMoveEvent = Readonly<{
|
|
|
14
15
|
target: Int32;
|
|
15
16
|
}>;
|
|
16
17
|
|
|
18
|
+
type FocusedInputLayoutChangedEvent = Readonly<{
|
|
19
|
+
target: Int32;
|
|
20
|
+
layout: {
|
|
21
|
+
x: Double;
|
|
22
|
+
y: Double;
|
|
23
|
+
width: Double;
|
|
24
|
+
height: Double;
|
|
25
|
+
absoluteX: Double;
|
|
26
|
+
absoluteY: Double;
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
|
|
17
30
|
export interface NativeProps extends ViewProps {
|
|
18
31
|
// props
|
|
19
32
|
enabled?: boolean;
|
|
@@ -24,6 +37,7 @@ export interface NativeProps extends ViewProps {
|
|
|
24
37
|
onKeyboardMove?: DirectEventHandler<KeyboardMoveEvent>;
|
|
25
38
|
onKeyboardMoveEnd?: DirectEventHandler<KeyboardMoveEvent>;
|
|
26
39
|
onKeyboardMoveInteractive?: DirectEventHandler<KeyboardMoveEvent>;
|
|
40
|
+
onFocusedInputLayoutChanged?: DirectEventHandler<FocusedInputLayoutChangedEvent>;
|
|
27
41
|
}
|
|
28
42
|
|
|
29
43
|
export default codegenNativeComponent<NativeProps>(
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
2
|
+
|
|
1
3
|
import type { HostComponent } from 'react-native';
|
|
2
4
|
import type { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes';
|
|
3
5
|
import type { WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
|
|
4
|
-
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
5
6
|
|
|
6
7
|
export interface NativeProps extends ViewProps {
|
|
7
8
|
interpolator?: WithDefault<'linear' | 'ios', 'linear'>;
|
package/src/types.ts
CHANGED
|
@@ -11,6 +11,17 @@ export type NativeEvent = {
|
|
|
11
11
|
duration: number;
|
|
12
12
|
target: number;
|
|
13
13
|
};
|
|
14
|
+
export type FocusedInputLayoutChangedEvent = {
|
|
15
|
+
target: number;
|
|
16
|
+
layout: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
absoluteX: number;
|
|
22
|
+
absoluteY: number;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
14
25
|
export type EventWithName<T> = {
|
|
15
26
|
eventName: string;
|
|
16
27
|
} & T;
|
|
@@ -30,10 +41,16 @@ export type KeyboardControllerProps = {
|
|
|
30
41
|
onKeyboardMoveInteractive?: (
|
|
31
42
|
e: NativeSyntheticEvent<EventWithName<NativeEvent>>
|
|
32
43
|
) => void;
|
|
33
|
-
|
|
44
|
+
onFocusedInputLayoutChanged?: (
|
|
45
|
+
e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>
|
|
46
|
+
) => void;
|
|
47
|
+
// fake props used to activate reanimated bindings
|
|
34
48
|
onKeyboardMoveReanimated?: (
|
|
35
49
|
e: NativeSyntheticEvent<EventWithName<NativeEvent>>
|
|
36
50
|
) => void;
|
|
51
|
+
onFocusedInputLayoutChangedReanimated?: (
|
|
52
|
+
e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>
|
|
53
|
+
) => void;
|
|
37
54
|
statusBarTranslucent?: boolean;
|
|
38
55
|
navigationBarTranslucent?: boolean;
|
|
39
56
|
} & ViewProps;
|
|
@@ -91,6 +108,15 @@ export type KeyboardHandlerHook<TContext, Event> = (
|
|
|
91
108
|
},
|
|
92
109
|
dependencies?: unknown[]
|
|
93
110
|
) => (e: NativeSyntheticEvent<Event>) => void;
|
|
111
|
+
export type FocusedInputHandlerHook<TContext, Event> = (
|
|
112
|
+
handlers: {
|
|
113
|
+
onFocusedInputLayoutChanged?: (
|
|
114
|
+
e: FocusedInputLayoutChangedEvent,
|
|
115
|
+
context: TContext
|
|
116
|
+
) => void;
|
|
117
|
+
},
|
|
118
|
+
dependencies?: unknown[]
|
|
119
|
+
) => (e: NativeSyntheticEvent<Event>) => void;
|
|
94
120
|
|
|
95
121
|
// package types
|
|
96
122
|
export type Handlers<T> = Record<string, T | undefined>;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|