react-native-keyboard-controller 1.12.2 → 1.12.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.
Files changed (64) hide show
  1. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt +15 -1
  2. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +11 -2
  3. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/WindowDimensionListener.kt +57 -0
  4. package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +9 -9
  5. package/ios/traversal/KeyboardView.swift +5 -8
  6. package/jest/index.js +3 -1
  7. package/lib/commonjs/bindings.js +6 -1
  8. package/lib/commonjs/bindings.js.map +1 -1
  9. package/lib/commonjs/bindings.native.js +4 -1
  10. package/lib/commonjs/bindings.native.js.map +1 -1
  11. package/lib/commonjs/components/KeyboardAvoidingView/index.js +2 -1
  12. package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
  13. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +4 -3
  14. package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
  15. package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +3 -1
  16. package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
  17. package/lib/commonjs/components/KeyboardAwareScrollView/utils.js +11 -1
  18. package/lib/commonjs/components/KeyboardAwareScrollView/utils.js.map +1 -1
  19. package/lib/commonjs/{hooks.js → hooks/index.js} +27 -5
  20. package/lib/commonjs/hooks/index.js.map +1 -0
  21. package/lib/commonjs/hooks/useWindowDimensions/index.android.js +29 -0
  22. package/lib/commonjs/hooks/useWindowDimensions/index.android.js.map +1 -0
  23. package/lib/commonjs/hooks/useWindowDimensions/index.js +13 -0
  24. package/lib/commonjs/hooks/useWindowDimensions/index.js.map +1 -0
  25. package/lib/commonjs/types.js.map +1 -1
  26. package/lib/module/bindings.js +5 -0
  27. package/lib/module/bindings.js.map +1 -1
  28. package/lib/module/bindings.native.js +3 -0
  29. package/lib/module/bindings.native.js.map +1 -1
  30. package/lib/module/components/KeyboardAvoidingView/index.js +2 -1
  31. package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
  32. package/lib/module/components/KeyboardAwareScrollView/index.js +6 -5
  33. package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
  34. package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +3 -1
  35. package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
  36. package/lib/module/components/KeyboardAwareScrollView/utils.js +9 -0
  37. package/lib/module/components/KeyboardAwareScrollView/utils.js.map +1 -1
  38. package/lib/module/{hooks.js → hooks/index.js} +6 -5
  39. package/lib/module/hooks/index.js.map +1 -0
  40. package/lib/module/hooks/useWindowDimensions/index.android.js +22 -0
  41. package/lib/module/hooks/useWindowDimensions/index.android.js.map +1 -0
  42. package/lib/module/hooks/useWindowDimensions/index.js +2 -0
  43. package/lib/module/hooks/useWindowDimensions/index.js.map +1 -0
  44. package/lib/module/types.js.map +1 -1
  45. package/lib/typescript/bindings.d.ts +2 -1
  46. package/lib/typescript/bindings.native.d.ts +2 -1
  47. package/lib/typescript/components/KeyboardAwareScrollView/utils.d.ts +1 -0
  48. package/lib/typescript/{hooks.d.ts → hooks/index.d.ts} +4 -3
  49. package/lib/typescript/hooks/useWindowDimensions/index.android.d.ts +2 -0
  50. package/lib/typescript/hooks/useWindowDimensions/index.d.ts +1 -0
  51. package/lib/typescript/types.d.ts +8 -0
  52. package/package.json +2 -2
  53. package/src/bindings.native.ts +5 -0
  54. package/src/bindings.ts +4 -0
  55. package/src/components/KeyboardAvoidingView/index.tsx +3 -1
  56. package/src/components/KeyboardAwareScrollView/index.tsx +13 -4
  57. package/src/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.ts +2 -1
  58. package/src/components/KeyboardAwareScrollView/utils.ts +15 -0
  59. package/src/{hooks.ts → hooks/index.ts} +8 -6
  60. package/src/hooks/useWindowDimensions/index.android.ts +33 -0
  61. package/src/hooks/useWindowDimensions/index.ts +1 -0
  62. package/src/types.ts +11 -0
  63. package/lib/commonjs/hooks.js.map +0 -1
  64. package/lib/module/hooks.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type {\n EmitterSubscription,\n NativeSyntheticEvent,\n ViewProps,\n} from \"react-native\";\n\n// DirectEventHandler events declaration\nexport type NativeEvent = {\n progress: number;\n height: number;\n duration: number;\n target: number;\n};\nexport type FocusedInputLayoutChangedEvent = {\n target: number;\n parentScrollViewTarget: number;\n layout: {\n x: number;\n y: number;\n width: number;\n height: number;\n absoluteX: number;\n absoluteY: number;\n };\n};\nexport type FocusedInputTextChangedEvent = {\n text: string;\n};\nexport type FocusedInputSelectionChangedEvent = {\n target: number;\n selection: {\n start: {\n x: number;\n y: number;\n position: number;\n };\n end: {\n x: number;\n y: number;\n position: number;\n };\n };\n};\nexport type EventWithName<T> = {\n eventName: string;\n} & T;\n\n// native View/Module declarations\nexport type KeyboardControllerProps = {\n // callback props\n onKeyboardMoveStart?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMove?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMoveEnd?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMoveInteractive?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onFocusedInputLayoutChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>,\n ) => void;\n onFocusedInputTextChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputTextChangedEvent>>,\n ) => void;\n onFocusedInputSelectionChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputSelectionChangedEvent>>,\n ) => void;\n // fake props used to activate reanimated bindings\n onKeyboardMoveReanimated?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onFocusedInputLayoutChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>,\n ) => void;\n onFocusedInputTextChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputTextChangedEvent>>,\n ) => void;\n onFocusedInputSelectionChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputSelectionChangedEvent>>,\n ) => void;\n // props\n statusBarTranslucent?: boolean;\n navigationBarTranslucent?: boolean;\n enabled?: boolean;\n} & ViewProps;\n\nexport type KeyboardGestureAreaProps = {\n interpolator: \"ios\" | \"linear\";\n /**\n * Whether to allow to show a keyboard from dismissed state by swipe up.\n * Default to `false`.\n */\n showOnSwipeUp?: boolean;\n /**\n * Whether to allow to control a keyboard by gestures. The strategy how\n * it should be controlled is determined by `interpolator` property.\n * Defaults to `true`.\n */\n enableSwipeToDismiss?: boolean;\n} & ViewProps;\n\nexport type Direction = \"next\" | \"prev\" | \"current\";\nexport type KeyboardControllerModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: () => void;\n setFocusTo: (direction: Direction) => void;\n // native event module stuff\n addListener: (eventName: string) => void;\n removeListeners: (count: number) => void;\n};\n\n// Event module declarations\nexport type KeyboardControllerEvents =\n | \"keyboardWillShow\"\n | \"keyboardDidShow\"\n | \"keyboardWillHide\"\n | \"keyboardDidHide\";\nexport type KeyboardEventData = {\n height: number;\n duration: number;\n timestamp: number;\n target: number;\n};\nexport type KeyboardEventsModule = {\n addListener: (\n name: KeyboardControllerEvents,\n cb: (e: KeyboardEventData) => void,\n ) => EmitterSubscription;\n};\nexport type FocusedInputAvailableEvents = \"focusDidSet\";\nexport type FocusedInputEventData = {\n current: number;\n count: number;\n};\nexport type FocusedInputEventsModule = {\n addListener: (\n name: FocusedInputAvailableEvents,\n cb: (e: FocusedInputEventData) => void,\n ) => EmitterSubscription;\n};\n\n// reanimated hook declaration\nexport type KeyboardHandlerHook<TContext, Event> = (\n handlers: {\n onKeyboardMoveStart?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMove?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMoveEnd?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMoveInteractive?: (e: NativeEvent, context: TContext) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputLayoutHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputLayoutChanged?: (\n e: FocusedInputLayoutChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputTextHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputTextChanged?: (\n e: FocusedInputTextChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputSelectionHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputSelectionChanged?: (\n e: FocusedInputSelectionChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\n\n// package types\nexport type Handlers<T> = Record<string, T | undefined>;\nexport type KeyboardHandler = Partial<{\n onStart: (e: NativeEvent) => void;\n onMove: (e: NativeEvent) => void;\n onEnd: (e: NativeEvent) => void;\n onInteractive: (e: NativeEvent) => void;\n}>;\nexport type KeyboardHandlers = Handlers<KeyboardHandler>;\nexport type FocusedInputHandler = Partial<{\n onChangeText: (e: FocusedInputTextChangedEvent) => void;\n onSelectionChange: (e: FocusedInputSelectionChangedEvent) => void;\n}>;\nexport type FocusedInputHandlers = Handlers<FocusedInputHandler>;\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type {\n EmitterSubscription,\n NativeSyntheticEvent,\n ViewProps,\n} from \"react-native\";\n\n// DirectEventHandler events declaration\nexport type NativeEvent = {\n progress: number;\n height: number;\n duration: number;\n target: number;\n};\nexport type FocusedInputLayoutChangedEvent = {\n target: number;\n parentScrollViewTarget: number;\n layout: {\n x: number;\n y: number;\n width: number;\n height: number;\n absoluteX: number;\n absoluteY: number;\n };\n};\nexport type FocusedInputTextChangedEvent = {\n text: string;\n};\nexport type FocusedInputSelectionChangedEvent = {\n target: number;\n selection: {\n start: {\n x: number;\n y: number;\n position: number;\n };\n end: {\n x: number;\n y: number;\n position: number;\n };\n };\n};\nexport type EventWithName<T> = {\n eventName: string;\n} & T;\n\n// native View/Module declarations\nexport type KeyboardControllerProps = {\n // callback props\n onKeyboardMoveStart?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMove?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMoveEnd?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMoveInteractive?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onFocusedInputLayoutChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>,\n ) => void;\n onFocusedInputTextChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputTextChangedEvent>>,\n ) => void;\n onFocusedInputSelectionChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputSelectionChangedEvent>>,\n ) => void;\n // fake props used to activate reanimated bindings\n onKeyboardMoveReanimated?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onFocusedInputLayoutChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>,\n ) => void;\n onFocusedInputTextChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputTextChangedEvent>>,\n ) => void;\n onFocusedInputSelectionChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputSelectionChangedEvent>>,\n ) => void;\n // props\n statusBarTranslucent?: boolean;\n navigationBarTranslucent?: boolean;\n enabled?: boolean;\n} & ViewProps;\n\nexport type KeyboardGestureAreaProps = {\n interpolator: \"ios\" | \"linear\";\n /**\n * Whether to allow to show a keyboard from dismissed state by swipe up.\n * Default to `false`.\n */\n showOnSwipeUp?: boolean;\n /**\n * Whether to allow to control a keyboard by gestures. The strategy how\n * it should be controlled is determined by `interpolator` property.\n * Defaults to `true`.\n */\n enableSwipeToDismiss?: boolean;\n} & ViewProps;\n\nexport type Direction = \"next\" | \"prev\" | \"current\";\nexport type KeyboardControllerModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: () => void;\n setFocusTo: (direction: Direction) => void;\n // native event module stuff\n addListener: (eventName: string) => void;\n removeListeners: (count: number) => void;\n};\n\n// Event module declarations\nexport type KeyboardControllerEvents =\n | \"keyboardWillShow\"\n | \"keyboardDidShow\"\n | \"keyboardWillHide\"\n | \"keyboardDidHide\";\nexport type KeyboardEventData = {\n height: number;\n duration: number;\n timestamp: number;\n target: number;\n};\nexport type KeyboardEventsModule = {\n addListener: (\n name: KeyboardControllerEvents,\n cb: (e: KeyboardEventData) => void,\n ) => EmitterSubscription;\n};\nexport type FocusedInputAvailableEvents = \"focusDidSet\";\nexport type FocusedInputEventData = {\n current: number;\n count: number;\n};\nexport type FocusedInputEventsModule = {\n addListener: (\n name: FocusedInputAvailableEvents,\n cb: (e: FocusedInputEventData) => void,\n ) => EmitterSubscription;\n};\nexport type WindowDimensionsAvailableEvents = \"windowDidResize\";\nexport type WindowDimensionsEventData = {\n width: number;\n height: number;\n};\nexport type WindowDimensionsEventsModule = {\n addListener: (\n name: WindowDimensionsAvailableEvents,\n cb: (e: WindowDimensionsEventData) => void,\n ) => EmitterSubscription;\n};\n\n// reanimated hook declaration\nexport type KeyboardHandlerHook<TContext, Event> = (\n handlers: {\n onKeyboardMoveStart?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMove?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMoveEnd?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMoveInteractive?: (e: NativeEvent, context: TContext) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputLayoutHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputLayoutChanged?: (\n e: FocusedInputLayoutChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputTextHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputTextChanged?: (\n e: FocusedInputTextChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputSelectionHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputSelectionChanged?: (\n e: FocusedInputSelectionChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\n\n// package types\nexport type Handlers<T> = Record<string, T | undefined>;\nexport type KeyboardHandler = Partial<{\n onStart: (e: NativeEvent) => void;\n onMove: (e: NativeEvent) => void;\n onEnd: (e: NativeEvent) => void;\n onInteractive: (e: NativeEvent) => void;\n}>;\nexport type KeyboardHandlers = Handlers<KeyboardHandler>;\nexport type FocusedInputHandler = Partial<{\n onChangeText: (e: FocusedInputTextChangedEvent) => void;\n onSelectionChange: (e: FocusedInputSelectionChangedEvent) => void;\n}>;\nexport type FocusedInputHandlers = Handlers<FocusedInputHandler>;\n"],"mappings":"","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { FocusedInputEventsModule, KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps } from "./types";
2
+ import type { FocusedInputEventsModule, KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps, WindowDimensionsEventsModule } from "./types";
3
3
  export declare const KeyboardController: KeyboardControllerModule;
4
4
  export declare const KeyboardEvents: KeyboardEventsModule;
5
5
  /**
@@ -7,5 +7,6 @@ export declare const KeyboardEvents: KeyboardEventsModule;
7
7
  * Use it with cautious.
8
8
  */
9
9
  export declare const FocusedInputEvents: FocusedInputEventsModule;
10
+ export declare const WindowDimensionsEvents: WindowDimensionsEventsModule;
10
11
  export declare const KeyboardControllerView: import("react").FC<KeyboardControllerProps>;
11
12
  export declare const KeyboardGestureArea: import("react").FC<KeyboardGestureAreaProps>;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { FocusedInputEventsModule, KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps } from "./types";
2
+ import type { FocusedInputEventsModule, KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps, WindowDimensionsEventsModule } from "./types";
3
3
  export declare const KeyboardController: KeyboardControllerModule;
4
4
  export declare const KeyboardEvents: KeyboardEventsModule;
5
5
  /**
@@ -7,5 +7,6 @@ export declare const KeyboardEvents: KeyboardEventsModule;
7
7
  * Use it with cautious.
8
8
  */
9
9
  export declare const FocusedInputEvents: FocusedInputEventsModule;
10
+ export declare const WindowDimensionsEvents: WindowDimensionsEventsModule;
10
11
  export declare const KeyboardControllerView: React.FC<KeyboardControllerProps>;
11
12
  export declare const KeyboardGestureArea: React.FC<KeyboardGestureAreaProps>;
@@ -1 +1,2 @@
1
1
  export declare const debounce: <F extends (...args: Parameters<F>) => ReturnType<F>>(worklet: F, wait?: number) => (...args: Parameters<F>) => void | ReturnType<F>;
2
+ export declare const scrollDistanceWithRespectToSnapPoints: (defaultScrollValue: number, snapPoints?: number[]) => number;
@@ -1,5 +1,5 @@
1
- import type { AnimatedContext, ReanimatedContext } from "./context";
2
- import type { FocusedInputHandler, KeyboardHandler } from "./types";
1
+ import type { AnimatedContext, ReanimatedContext } from "../context";
2
+ import type { FocusedInputHandler, KeyboardHandler } from "../types";
3
3
  import type { DependencyList } from "react";
4
4
  export declare const useResizeMode: () => void;
5
5
  export declare const useKeyboardAnimation: () => AnimatedContext;
@@ -11,6 +11,7 @@ export declare function useKeyboardController(): {
11
11
  enabled: boolean;
12
12
  };
13
13
  export declare function useReanimatedFocusedInput(): {
14
- input: import("react-native-reanimated").SharedValue<import("./types").FocusedInputLayoutChangedEvent | null>;
14
+ input: import("react-native-reanimated").SharedValue<import("../types").FocusedInputLayoutChangedEvent | null>;
15
15
  };
16
16
  export declare function useFocusedInputHandler(handler?: FocusedInputHandler, deps?: DependencyList): void;
17
+ export * from "./useWindowDimensions";
@@ -0,0 +1,2 @@
1
+ import type { WindowDimensionsEventData } from "../../types";
2
+ export declare const useWindowDimensions: () => WindowDimensionsEventData;
@@ -0,0 +1 @@
1
+ export { useWindowDimensions } from "react-native";
@@ -95,6 +95,14 @@ export type FocusedInputEventData = {
95
95
  export type FocusedInputEventsModule = {
96
96
  addListener: (name: FocusedInputAvailableEvents, cb: (e: FocusedInputEventData) => void) => EmitterSubscription;
97
97
  };
98
+ export type WindowDimensionsAvailableEvents = "windowDidResize";
99
+ export type WindowDimensionsEventData = {
100
+ width: number;
101
+ height: number;
102
+ };
103
+ export type WindowDimensionsEventsModule = {
104
+ addListener: (name: WindowDimensionsAvailableEvents, cb: (e: WindowDimensionsEventData) => void) => EmitterSubscription;
105
+ };
98
106
  export type KeyboardHandlerHook<TContext, Event> = (handlers: {
99
107
  onKeyboardMoveStart?: (e: NativeEvent, context: TContext) => void;
100
108
  onKeyboardMove?: (e: NativeEvent, context: TContext) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-keyboard-controller",
3
- "version": "1.12.2",
3
+ "version": "1.12.4",
4
4
  "description": "Keyboard manager which works in identical way on both iOS and Android",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -90,7 +90,7 @@
90
90
  "react": "18.2.0",
91
91
  "react-native": "0.74.0",
92
92
  "react-native-builder-bob": "^0.18.0",
93
- "react-native-reanimated": "3.9.0",
93
+ "react-native-reanimated": "3.12.1",
94
94
  "release-it": "^14.2.2",
95
95
  "typescript": "5.0.4"
96
96
  },
@@ -6,6 +6,7 @@ import type {
6
6
  KeyboardControllerProps,
7
7
  KeyboardEventsModule,
8
8
  KeyboardGestureAreaProps,
9
+ WindowDimensionsEventsModule,
9
10
  } from "./types";
10
11
 
11
12
  const LINKING_ERROR =
@@ -44,6 +45,10 @@ export const FocusedInputEvents: FocusedInputEventsModule = {
44
45
  addListener: (name, cb) =>
45
46
  eventEmitter.addListener(KEYBOARD_CONTROLLER_NAMESPACE + name, cb),
46
47
  };
48
+ export const WindowDimensionsEvents: WindowDimensionsEventsModule = {
49
+ addListener: (name, cb) =>
50
+ eventEmitter.addListener(KEYBOARD_CONTROLLER_NAMESPACE + name, cb),
51
+ };
47
52
  export const KeyboardControllerView: React.FC<KeyboardControllerProps> =
48
53
  require("./specs/KeyboardControllerViewNativeComponent").default;
49
54
  export const KeyboardGestureArea: React.FC<KeyboardGestureAreaProps> =
package/src/bindings.ts CHANGED
@@ -6,6 +6,7 @@ import type {
6
6
  KeyboardControllerProps,
7
7
  KeyboardEventsModule,
8
8
  KeyboardGestureAreaProps,
9
+ WindowDimensionsEventsModule,
9
10
  } from "./types";
10
11
  import type { EmitterSubscription } from "react-native";
11
12
 
@@ -28,6 +29,9 @@ export const KeyboardEvents: KeyboardEventsModule = {
28
29
  export const FocusedInputEvents: FocusedInputEventsModule = {
29
30
  addListener: () => ({ remove: NOOP } as EmitterSubscription),
30
31
  };
32
+ export const WindowDimensionsEvents: WindowDimensionsEventsModule = {
33
+ addListener: () => ({ remove: NOOP } as EmitterSubscription),
34
+ };
31
35
  export const KeyboardControllerView =
32
36
  View as unknown as React.FC<KeyboardControllerProps>;
33
37
  export const KeyboardGestureArea =
@@ -1,5 +1,5 @@
1
1
  import React, { forwardRef, useCallback, useMemo } from "react";
2
- import { View, useWindowDimensions } from "react-native";
2
+ import { View } from "react-native";
3
3
  import Reanimated, {
4
4
  interpolate,
5
5
  runOnUI,
@@ -8,6 +8,8 @@ import Reanimated, {
8
8
  useSharedValue,
9
9
  } from "react-native-reanimated";
10
10
 
11
+ import { useWindowDimensions } from "react-native-keyboard-controller";
12
+
11
13
  import { useKeyboardAnimation } from "./hooks";
12
14
 
13
15
  import type { LayoutRectangle, ViewProps } from "react-native";
@@ -1,5 +1,5 @@
1
1
  import React, { forwardRef, useCallback, useMemo } from "react";
2
- import { findNodeHandle, useWindowDimensions } from "react-native";
2
+ import { findNodeHandle } from "react-native";
3
3
  import Reanimated, {
4
4
  interpolate,
5
5
  scrollTo,
@@ -12,10 +12,11 @@ import Reanimated, {
12
12
  import {
13
13
  useFocusedInputHandler,
14
14
  useReanimatedFocusedInput,
15
+ useWindowDimensions,
15
16
  } from "react-native-keyboard-controller";
16
17
 
17
18
  import { useSmoothKeyboardHandler } from "./useSmoothKeyboardHandler";
18
- import { debounce } from "./utils";
19
+ import { debounce, scrollDistanceWithRespectToSnapPoints } from "./utils";
19
20
 
20
21
  import type {
21
22
  LayoutChangeEvent,
@@ -154,10 +155,18 @@ const KeyboardAwareScrollView = forwardRef<
154
155
  const point = absoluteY + inputHeight;
155
156
 
156
157
  if (visibleRect - point <= bottomOffset) {
158
+ const relativeScrollTo =
159
+ keyboardHeight.value - (height - point) + bottomOffset;
157
160
  const interpolatedScrollTo = interpolate(
158
161
  e,
159
162
  [initialKeyboardSize.value, keyboardHeight.value],
160
- [0, keyboardHeight.value - (height - point) + bottomOffset],
163
+ [
164
+ 0,
165
+ scrollDistanceWithRespectToSnapPoints(
166
+ relativeScrollTo + scrollPosition.value,
167
+ rest.snapToOffsets,
168
+ ) - scrollPosition.value,
169
+ ],
161
170
  );
162
171
  const targetScrollY =
163
172
  Math.max(interpolatedScrollTo, 0) + scrollPosition.value;
@@ -180,7 +189,7 @@ const KeyboardAwareScrollView = forwardRef<
180
189
 
181
190
  return 0;
182
191
  },
183
- [bottomOffset, enabled],
192
+ [bottomOffset, enabled, rest.snapToOffsets],
184
193
  );
185
194
 
186
195
  const onChangeText = useCallback(() => {
@@ -68,7 +68,8 @@ export const useSmoothKeyboardHandler: typeof useKeyboardHandler = (
68
68
  persistedHeight.value = height.value;
69
69
  }
70
70
  },
71
- [handler],
71
+ // REA uses own version of `DependencyList` and it's not compatible with the same type from React
72
+ deps as unknown[],
72
73
  );
73
74
 
74
75
  useKeyboardHandler(
@@ -24,3 +24,18 @@ export const debounce = <F extends (...args: Parameters<F>) => ReturnType<F>>(
24
24
  return worklet(...args);
25
25
  };
26
26
  };
27
+
28
+ export const scrollDistanceWithRespectToSnapPoints = (
29
+ defaultScrollValue: number,
30
+ snapPoints?: number[],
31
+ ) => {
32
+ "worklet";
33
+
34
+ let snapPoint: number | undefined;
35
+
36
+ if (snapPoints) {
37
+ snapPoint = snapPoints.find((offset) => offset >= defaultScrollValue);
38
+ }
39
+
40
+ return snapPoint ?? defaultScrollValue;
41
+ };
@@ -1,12 +1,12 @@
1
1
  import { useEffect } from "react";
2
2
 
3
- import { KeyboardController } from "./bindings";
4
- import { AndroidSoftInputModes } from "./constants";
5
- import { useKeyboardContext } from "./context";
6
- import { uuid } from "./utils";
3
+ import { KeyboardController } from "../bindings";
4
+ import { AndroidSoftInputModes } from "../constants";
5
+ import { useKeyboardContext } from "../context";
6
+ import { uuid } from "../utils";
7
7
 
8
- import type { AnimatedContext, ReanimatedContext } from "./context";
9
- import type { FocusedInputHandler, KeyboardHandler } from "./types";
8
+ import type { AnimatedContext, ReanimatedContext } from "../context";
9
+ import type { FocusedInputHandler, KeyboardHandler } from "../types";
10
10
  import type { DependencyList } from "react";
11
11
 
12
12
  export const useResizeMode = () => {
@@ -86,3 +86,5 @@ export function useFocusedInputHandler(
86
86
  };
87
87
  }, deps);
88
88
  }
89
+
90
+ export * from "./useWindowDimensions";
@@ -0,0 +1,33 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ import { WindowDimensionsEvents } from "../../bindings";
4
+
5
+ import type { WindowDimensionsEventData } from "../../types";
6
+
7
+ let initialDimensions: WindowDimensionsEventData = {
8
+ width: 0,
9
+ height: 0,
10
+ };
11
+
12
+ WindowDimensionsEvents.addListener("windowDidResize", (e) => {
13
+ initialDimensions = e;
14
+ });
15
+
16
+ export const useWindowDimensions = () => {
17
+ const [dimensions, setDimensions] = useState(initialDimensions);
18
+
19
+ useEffect(() => {
20
+ const subscription = WindowDimensionsEvents.addListener(
21
+ "windowDidResize",
22
+ (e) => {
23
+ setDimensions(e);
24
+ },
25
+ );
26
+
27
+ return () => {
28
+ subscription.remove();
29
+ };
30
+ }, []);
31
+
32
+ return dimensions;
33
+ };
@@ -0,0 +1 @@
1
+ export { useWindowDimensions } from "react-native";
package/src/types.ts CHANGED
@@ -145,6 +145,17 @@ export type FocusedInputEventsModule = {
145
145
  cb: (e: FocusedInputEventData) => void,
146
146
  ) => EmitterSubscription;
147
147
  };
148
+ export type WindowDimensionsAvailableEvents = "windowDidResize";
149
+ export type WindowDimensionsEventData = {
150
+ width: number;
151
+ height: number;
152
+ };
153
+ export type WindowDimensionsEventsModule = {
154
+ addListener: (
155
+ name: WindowDimensionsAvailableEvents,
156
+ cb: (e: WindowDimensionsEventData) => void,
157
+ ) => EmitterSubscription;
158
+ };
148
159
 
149
160
  // reanimated hook declaration
150
161
  export type KeyboardHandlerHook<TContext, Event> = (
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","require","_bindings","_constants","_context","_utils","useResizeMode","useEffect","KeyboardController","setInputMode","AndroidSoftInputModes","SOFT_INPUT_ADJUST_RESIZE","setDefaultMode","exports","useKeyboardAnimation","context","useKeyboardContext","animated","useReanimatedKeyboardAnimation","reanimated","useGenericKeyboardHandler","handler","deps","key","uuid","setKeyboardHandlers","undefined","useKeyboardHandler","useKeyboardController","setEnabled","enabled","useReanimatedFocusedInput","input","layout","useFocusedInputHandler","setInputHandlers"],"sources":["hooks.ts"],"sourcesContent":["import { useEffect } from \"react\";\n\nimport { KeyboardController } from \"./bindings\";\nimport { AndroidSoftInputModes } from \"./constants\";\nimport { useKeyboardContext } from \"./context\";\nimport { uuid } from \"./utils\";\n\nimport type { AnimatedContext, ReanimatedContext } from \"./context\";\nimport type { FocusedInputHandler, KeyboardHandler } from \"./types\";\nimport type { DependencyList } from \"react\";\n\nexport const useResizeMode = () => {\n useEffect(() => {\n KeyboardController.setInputMode(\n AndroidSoftInputModes.SOFT_INPUT_ADJUST_RESIZE,\n );\n\n return () => KeyboardController.setDefaultMode();\n }, []);\n};\n\nexport const useKeyboardAnimation = (): AnimatedContext => {\n useResizeMode();\n const context = useKeyboardContext();\n\n return context.animated;\n};\n\nexport const useReanimatedKeyboardAnimation = (): ReanimatedContext => {\n useResizeMode();\n const context = useKeyboardContext();\n\n return context.reanimated;\n};\n\nexport function useGenericKeyboardHandler(\n handler: KeyboardHandler,\n deps?: DependencyList,\n) {\n const context = useKeyboardContext();\n\n useEffect(() => {\n const key = uuid();\n\n context.setKeyboardHandlers({ [key]: handler });\n\n return () => {\n context.setKeyboardHandlers({ [key]: undefined });\n };\n }, deps);\n}\n\nexport function useKeyboardHandler(\n handler: KeyboardHandler,\n deps?: DependencyList,\n) {\n useResizeMode();\n useGenericKeyboardHandler(handler, deps);\n}\n\nexport function useKeyboardController() {\n const context = useKeyboardContext();\n\n return { setEnabled: context.setEnabled, enabled: context.enabled };\n}\n\nexport function useReanimatedFocusedInput() {\n const context = useKeyboardContext();\n\n return { input: context.layout };\n}\n\nexport function useFocusedInputHandler(\n handler?: FocusedInputHandler,\n deps?: DependencyList,\n) {\n const context = useKeyboardContext();\n\n useEffect(() => {\n const key = uuid();\n\n context.setInputHandlers({ [key]: handler });\n\n return () => {\n context.setInputHandlers({ [key]: undefined });\n };\n }, deps);\n}\n"],"mappings":";;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,SAAA,GAAAD,OAAA;AACA,IAAAE,UAAA,GAAAF,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AACA,IAAAI,MAAA,GAAAJ,OAAA;AAMO,MAAMK,aAAa,GAAGA,CAAA,KAAM;EACjC,IAAAC,gBAAS,EAAC,MAAM;IACdC,4BAAkB,CAACC,YAAY,CAC7BC,gCAAqB,CAACC,wBACxB,CAAC;IAED,OAAO,MAAMH,4BAAkB,CAACI,cAAc,CAAC,CAAC;EAClD,CAAC,EAAE,EAAE,CAAC;AACR,CAAC;AAACC,OAAA,CAAAP,aAAA,GAAAA,aAAA;AAEK,MAAMQ,oBAAoB,GAAGA,CAAA,KAAuB;EACzDR,aAAa,CAAC,CAAC;EACf,MAAMS,OAAO,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAEpC,OAAOD,OAAO,CAACE,QAAQ;AACzB,CAAC;AAACJ,OAAA,CAAAC,oBAAA,GAAAA,oBAAA;AAEK,MAAMI,8BAA8B,GAAGA,CAAA,KAAyB;EACrEZ,aAAa,CAAC,CAAC;EACf,MAAMS,OAAO,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAEpC,OAAOD,OAAO,CAACI,UAAU;AAC3B,CAAC;AAACN,OAAA,CAAAK,8BAAA,GAAAA,8BAAA;AAEK,SAASE,yBAAyBA,CACvCC,OAAwB,EACxBC,IAAqB,EACrB;EACA,MAAMP,OAAO,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAEpC,IAAAT,gBAAS,EAAC,MAAM;IACd,MAAMgB,GAAG,GAAG,IAAAC,WAAI,EAAC,CAAC;IAElBT,OAAO,CAACU,mBAAmB,CAAC;MAAE,CAACF,GAAG,GAAGF;IAAQ,CAAC,CAAC;IAE/C,OAAO,MAAM;MACXN,OAAO,CAACU,mBAAmB,CAAC;QAAE,CAACF,GAAG,GAAGG;MAAU,CAAC,CAAC;IACnD,CAAC;EACH,CAAC,EAAEJ,IAAI,CAAC;AACV;AAEO,SAASK,kBAAkBA,CAChCN,OAAwB,EACxBC,IAAqB,EACrB;EACAhB,aAAa,CAAC,CAAC;EACfc,yBAAyB,CAACC,OAAO,EAAEC,IAAI,CAAC;AAC1C;AAEO,SAASM,qBAAqBA,CAAA,EAAG;EACtC,MAAMb,OAAO,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAEpC,OAAO;IAAEa,UAAU,EAAEd,OAAO,CAACc,UAAU;IAAEC,OAAO,EAAEf,OAAO,CAACe;EAAQ,CAAC;AACrE;AAEO,SAASC,yBAAyBA,CAAA,EAAG;EAC1C,MAAMhB,OAAO,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAEpC,OAAO;IAAEgB,KAAK,EAAEjB,OAAO,CAACkB;EAAO,CAAC;AAClC;AAEO,SAASC,sBAAsBA,CACpCb,OAA6B,EAC7BC,IAAqB,EACrB;EACA,MAAMP,OAAO,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAEpC,IAAAT,gBAAS,EAAC,MAAM;IACd,MAAMgB,GAAG,GAAG,IAAAC,WAAI,EAAC,CAAC;IAElBT,OAAO,CAACoB,gBAAgB,CAAC;MAAE,CAACZ,GAAG,GAAGF;IAAQ,CAAC,CAAC;IAE5C,OAAO,MAAM;MACXN,OAAO,CAACoB,gBAAgB,CAAC;QAAE,CAACZ,GAAG,GAAGG;MAAU,CAAC,CAAC;IAChD,CAAC;EACH,CAAC,EAAEJ,IAAI,CAAC;AACV","ignoreList":[]}
@@ -1 +0,0 @@
1
- {"version":3,"names":["useEffect","KeyboardController","AndroidSoftInputModes","useKeyboardContext","uuid","useResizeMode","setInputMode","SOFT_INPUT_ADJUST_RESIZE","setDefaultMode","useKeyboardAnimation","context","animated","useReanimatedKeyboardAnimation","reanimated","useGenericKeyboardHandler","handler","deps","key","setKeyboardHandlers","undefined","useKeyboardHandler","useKeyboardController","setEnabled","enabled","useReanimatedFocusedInput","input","layout","useFocusedInputHandler","setInputHandlers"],"sources":["hooks.ts"],"sourcesContent":["import { useEffect } from \"react\";\n\nimport { KeyboardController } from \"./bindings\";\nimport { AndroidSoftInputModes } from \"./constants\";\nimport { useKeyboardContext } from \"./context\";\nimport { uuid } from \"./utils\";\n\nimport type { AnimatedContext, ReanimatedContext } from \"./context\";\nimport type { FocusedInputHandler, KeyboardHandler } from \"./types\";\nimport type { DependencyList } from \"react\";\n\nexport const useResizeMode = () => {\n useEffect(() => {\n KeyboardController.setInputMode(\n AndroidSoftInputModes.SOFT_INPUT_ADJUST_RESIZE,\n );\n\n return () => KeyboardController.setDefaultMode();\n }, []);\n};\n\nexport const useKeyboardAnimation = (): AnimatedContext => {\n useResizeMode();\n const context = useKeyboardContext();\n\n return context.animated;\n};\n\nexport const useReanimatedKeyboardAnimation = (): ReanimatedContext => {\n useResizeMode();\n const context = useKeyboardContext();\n\n return context.reanimated;\n};\n\nexport function useGenericKeyboardHandler(\n handler: KeyboardHandler,\n deps?: DependencyList,\n) {\n const context = useKeyboardContext();\n\n useEffect(() => {\n const key = uuid();\n\n context.setKeyboardHandlers({ [key]: handler });\n\n return () => {\n context.setKeyboardHandlers({ [key]: undefined });\n };\n }, deps);\n}\n\nexport function useKeyboardHandler(\n handler: KeyboardHandler,\n deps?: DependencyList,\n) {\n useResizeMode();\n useGenericKeyboardHandler(handler, deps);\n}\n\nexport function useKeyboardController() {\n const context = useKeyboardContext();\n\n return { setEnabled: context.setEnabled, enabled: context.enabled };\n}\n\nexport function useReanimatedFocusedInput() {\n const context = useKeyboardContext();\n\n return { input: context.layout };\n}\n\nexport function useFocusedInputHandler(\n handler?: FocusedInputHandler,\n deps?: DependencyList,\n) {\n const context = useKeyboardContext();\n\n useEffect(() => {\n const key = uuid();\n\n context.setInputHandlers({ [key]: handler });\n\n return () => {\n context.setInputHandlers({ [key]: undefined });\n };\n }, deps);\n}\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AAEjC,SAASC,kBAAkB,QAAQ,YAAY;AAC/C,SAASC,qBAAqB,QAAQ,aAAa;AACnD,SAASC,kBAAkB,QAAQ,WAAW;AAC9C,SAASC,IAAI,QAAQ,SAAS;AAM9B,OAAO,MAAMC,aAAa,GAAGA,CAAA,KAAM;EACjCL,SAAS,CAAC,MAAM;IACdC,kBAAkB,CAACK,YAAY,CAC7BJ,qBAAqB,CAACK,wBACxB,CAAC;IAED,OAAO,MAAMN,kBAAkB,CAACO,cAAc,CAAC,CAAC;EAClD,CAAC,EAAE,EAAE,CAAC;AACR,CAAC;AAED,OAAO,MAAMC,oBAAoB,GAAGA,CAAA,KAAuB;EACzDJ,aAAa,CAAC,CAAC;EACf,MAAMK,OAAO,GAAGP,kBAAkB,CAAC,CAAC;EAEpC,OAAOO,OAAO,CAACC,QAAQ;AACzB,CAAC;AAED,OAAO,MAAMC,8BAA8B,GAAGA,CAAA,KAAyB;EACrEP,aAAa,CAAC,CAAC;EACf,MAAMK,OAAO,GAAGP,kBAAkB,CAAC,CAAC;EAEpC,OAAOO,OAAO,CAACG,UAAU;AAC3B,CAAC;AAED,OAAO,SAASC,yBAAyBA,CACvCC,OAAwB,EACxBC,IAAqB,EACrB;EACA,MAAMN,OAAO,GAAGP,kBAAkB,CAAC,CAAC;EAEpCH,SAAS,CAAC,MAAM;IACd,MAAMiB,GAAG,GAAGb,IAAI,CAAC,CAAC;IAElBM,OAAO,CAACQ,mBAAmB,CAAC;MAAE,CAACD,GAAG,GAAGF;IAAQ,CAAC,CAAC;IAE/C,OAAO,MAAM;MACXL,OAAO,CAACQ,mBAAmB,CAAC;QAAE,CAACD,GAAG,GAAGE;MAAU,CAAC,CAAC;IACnD,CAAC;EACH,CAAC,EAAEH,IAAI,CAAC;AACV;AAEA,OAAO,SAASI,kBAAkBA,CAChCL,OAAwB,EACxBC,IAAqB,EACrB;EACAX,aAAa,CAAC,CAAC;EACfS,yBAAyB,CAACC,OAAO,EAAEC,IAAI,CAAC;AAC1C;AAEA,OAAO,SAASK,qBAAqBA,CAAA,EAAG;EACtC,MAAMX,OAAO,GAAGP,kBAAkB,CAAC,CAAC;EAEpC,OAAO;IAAEmB,UAAU,EAAEZ,OAAO,CAACY,UAAU;IAAEC,OAAO,EAAEb,OAAO,CAACa;EAAQ,CAAC;AACrE;AAEA,OAAO,SAASC,yBAAyBA,CAAA,EAAG;EAC1C,MAAMd,OAAO,GAAGP,kBAAkB,CAAC,CAAC;EAEpC,OAAO;IAAEsB,KAAK,EAAEf,OAAO,CAACgB;EAAO,CAAC;AAClC;AAEA,OAAO,SAASC,sBAAsBA,CACpCZ,OAA6B,EAC7BC,IAAqB,EACrB;EACA,MAAMN,OAAO,GAAGP,kBAAkB,CAAC,CAAC;EAEpCH,SAAS,CAAC,MAAM;IACd,MAAMiB,GAAG,GAAGb,IAAI,CAAC,CAAC;IAElBM,OAAO,CAACkB,gBAAgB,CAAC;MAAE,CAACX,GAAG,GAAGF;IAAQ,CAAC,CAAC;IAE5C,OAAO,MAAM;MACXL,OAAO,CAACkB,gBAAgB,CAAC;QAAE,CAACX,GAAG,GAAGE;MAAU,CAAC,CAAC;IAChD,CAAC;EACH,CAAC,EAAEH,IAAI,CAAC;AACV","ignoreList":[]}