react-native-keyboard-controller 1.10.0 → 1.10.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.
Files changed (144) hide show
  1. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt +31 -1
  2. package/ios/.clang-format +30 -30
  3. package/ios/.swiftlint.yml +1 -1
  4. package/ios/observers/FocusedInputObserver.swift +1 -0
  5. package/ios/views/KeyboardControllerViewManager.swift +12 -2
  6. package/jest/index.js +14 -4
  7. package/lib/commonjs/animated.js +19 -19
  8. package/lib/commonjs/animated.js.map +1 -1
  9. package/lib/commonjs/bindings.js.map +1 -1
  10. package/lib/commonjs/bindings.native.js +6 -6
  11. package/lib/commonjs/bindings.native.js.map +1 -1
  12. package/lib/commonjs/components/KeyboardAvoidingView/hooks.js +19 -5
  13. package/lib/commonjs/components/KeyboardAvoidingView/hooks.js.map +1 -1
  14. package/lib/commonjs/components/KeyboardAvoidingView/index.js +12 -7
  15. package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
  16. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +10 -8
  17. package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
  18. package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +5 -5
  19. package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
  20. package/lib/commonjs/components/KeyboardAwareScrollView/utils.js +2 -2
  21. package/lib/commonjs/components/KeyboardAwareScrollView/utils.js.map +1 -1
  22. package/lib/commonjs/components/KeyboardStickyView/index.js +9 -5
  23. package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
  24. package/lib/commonjs/components/hooks/useKeyboardInterpolation.js +88 -0
  25. package/lib/commonjs/components/hooks/useKeyboardInterpolation.js.map +1 -0
  26. package/lib/commonjs/components/index.js.map +1 -1
  27. package/lib/commonjs/constants.js.map +1 -1
  28. package/lib/commonjs/context.js.map +1 -1
  29. package/lib/commonjs/hooks.js.map +1 -1
  30. package/lib/commonjs/index.js.map +1 -1
  31. package/lib/commonjs/internal.js +1 -1
  32. package/lib/commonjs/internal.js.map +1 -1
  33. package/lib/commonjs/monkey-patch.android.js +1 -1
  34. package/lib/commonjs/monkey-patch.android.js.map +1 -1
  35. package/lib/commonjs/monkey-patch.js.map +1 -1
  36. package/lib/commonjs/reanimated.js.map +1 -1
  37. package/lib/commonjs/reanimated.native.js +12 -12
  38. package/lib/commonjs/reanimated.native.js.map +1 -1
  39. package/lib/commonjs/replicas.js +5 -5
  40. package/lib/commonjs/replicas.js.map +1 -1
  41. package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js +1 -1
  42. package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
  43. package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js +2 -2
  44. package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
  45. package/lib/commonjs/specs/NativeKeyboardController.js +1 -1
  46. package/lib/commonjs/specs/NativeKeyboardController.js.map +1 -1
  47. package/lib/commonjs/specs/NativeStatusBarManagerCompat.js +1 -1
  48. package/lib/commonjs/specs/NativeStatusBarManagerCompat.js.map +1 -1
  49. package/lib/commonjs/types.js.map +1 -1
  50. package/lib/commonjs/utils.js.map +1 -1
  51. package/lib/module/animated.js +27 -27
  52. package/lib/module/animated.js.map +1 -1
  53. package/lib/module/bindings.js +1 -1
  54. package/lib/module/bindings.js.map +1 -1
  55. package/lib/module/bindings.native.js +7 -7
  56. package/lib/module/bindings.native.js.map +1 -1
  57. package/lib/module/components/KeyboardAvoidingView/hooks.js +19 -5
  58. package/lib/module/components/KeyboardAvoidingView/hooks.js.map +1 -1
  59. package/lib/module/components/KeyboardAvoidingView/index.js +15 -11
  60. package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
  61. package/lib/module/components/KeyboardAwareScrollView/index.js +16 -14
  62. package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
  63. package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +8 -8
  64. package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
  65. package/lib/module/components/KeyboardAwareScrollView/utils.js +2 -2
  66. package/lib/module/components/KeyboardAwareScrollView/utils.js.map +1 -1
  67. package/lib/module/components/KeyboardStickyView/index.js +9 -6
  68. package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
  69. package/lib/module/components/hooks/useKeyboardInterpolation.js +81 -0
  70. package/lib/module/components/hooks/useKeyboardInterpolation.js.map +1 -0
  71. package/lib/module/components/index.js +3 -3
  72. package/lib/module/components/index.js.map +1 -1
  73. package/lib/module/context.js +2 -2
  74. package/lib/module/context.js.map +1 -1
  75. package/lib/module/hooks.js +5 -5
  76. package/lib/module/hooks.js.map +1 -1
  77. package/lib/module/index.js +8 -8
  78. package/lib/module/index.js.map +1 -1
  79. package/lib/module/internal.js +4 -4
  80. package/lib/module/internal.js.map +1 -1
  81. package/lib/module/monkey-patch.android.js +2 -2
  82. package/lib/module/monkey-patch.android.js.map +1 -1
  83. package/lib/module/monkey-patch.js.map +1 -1
  84. package/lib/module/reanimated.js.map +1 -1
  85. package/lib/module/reanimated.native.js +13 -13
  86. package/lib/module/reanimated.native.js.map +1 -1
  87. package/lib/module/replicas.js +11 -11
  88. package/lib/module/replicas.js.map +1 -1
  89. package/lib/module/specs/KeyboardControllerViewNativeComponent.js +2 -2
  90. package/lib/module/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
  91. package/lib/module/specs/KeyboardGestureAreaNativeComponent.js +3 -3
  92. package/lib/module/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
  93. package/lib/module/specs/NativeKeyboardController.js +2 -2
  94. package/lib/module/specs/NativeKeyboardController.js.map +1 -1
  95. package/lib/module/specs/NativeStatusBarManagerCompat.js +2 -2
  96. package/lib/module/specs/NativeStatusBarManagerCompat.js.map +1 -1
  97. package/lib/module/types.js.map +1 -1
  98. package/lib/module/utils.js.map +1 -1
  99. package/lib/typescript/animated.d.ts +1 -1
  100. package/lib/typescript/bindings.d.ts +1 -1
  101. package/lib/typescript/bindings.native.d.ts +1 -1
  102. package/lib/typescript/components/KeyboardAvoidingView/index.d.ts +4 -4
  103. package/lib/typescript/components/KeyboardAwareScrollView/index.d.ts +2 -2
  104. package/lib/typescript/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.d.ts +1 -1
  105. package/lib/typescript/components/KeyboardStickyView/index.d.ts +2 -2
  106. package/lib/typescript/components/hooks/useKeyboardInterpolation.d.ts +20 -0
  107. package/lib/typescript/components/index.d.ts +3 -3
  108. package/lib/typescript/context.d.ts +4 -4
  109. package/lib/typescript/hooks.d.ts +3 -3
  110. package/lib/typescript/index.d.ts +8 -8
  111. package/lib/typescript/internal.d.ts +2 -2
  112. package/lib/typescript/reanimated.d.ts +1 -1
  113. package/lib/typescript/reanimated.native.d.ts +1 -1
  114. package/lib/typescript/replicas.d.ts +1 -1
  115. package/lib/typescript/specs/KeyboardControllerViewNativeComponent.d.ts +3 -3
  116. package/lib/typescript/specs/KeyboardGestureAreaNativeComponent.d.ts +4 -4
  117. package/lib/typescript/specs/NativeKeyboardController.d.ts +1 -1
  118. package/lib/typescript/specs/NativeStatusBarManagerCompat.d.ts +1 -1
  119. package/lib/typescript/types.d.ts +3 -3
  120. package/package.json +8 -10
  121. package/src/animated.tsx +39 -39
  122. package/src/bindings.native.ts +11 -11
  123. package/src/bindings.ts +3 -3
  124. package/src/components/KeyboardAvoidingView/hooks.ts +20 -6
  125. package/src/components/KeyboardAvoidingView/index.tsx +25 -24
  126. package/src/components/KeyboardAwareScrollView/index.tsx +29 -25
  127. package/src/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.ts +13 -13
  128. package/src/components/KeyboardAwareScrollView/utils.ts +3 -3
  129. package/src/components/KeyboardStickyView/index.tsx +12 -12
  130. package/src/components/hooks/useKeyboardInterpolation.ts +108 -0
  131. package/src/components/index.ts +3 -3
  132. package/src/context.ts +7 -7
  133. package/src/hooks.ts +12 -12
  134. package/src/index.ts +8 -8
  135. package/src/internal.ts +9 -9
  136. package/src/monkey-patch.android.ts +2 -2
  137. package/src/reanimated.native.ts +20 -20
  138. package/src/reanimated.ts +1 -1
  139. package/src/replicas.ts +16 -16
  140. package/src/specs/KeyboardControllerViewNativeComponent.ts +5 -5
  141. package/src/specs/KeyboardGestureAreaNativeComponent.ts +7 -7
  142. package/src/specs/NativeKeyboardController.ts +3 -3
  143. package/src/specs/NativeStatusBarManagerCompat.ts +3 -3
  144. package/src/types.ts +21 -21
@@ -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 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 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 // 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 // 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 KeyboardControllerModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: () => 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};\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;\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}>;\nexport type FocusedInputHandlers = Handlers<FocusedInputHandler>;\n"],"mappings":""}
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 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 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 // 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 // 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 KeyboardControllerModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: () => 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};\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;\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}>;\nexport type FocusedInputHandlers = Handlers<FocusedInputHandler>;\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":["uuid","Math","random","toString","slice"],"sources":["utils.ts"],"sourcesContent":["export const uuid = () => Math.random().toString(36).slice(-6);\n"],"mappings":"AAAA,OAAO,MAAMA,IAAI,GAAG,MAAMC,IAAI,CAACC,MAAM,EAAE,CAACC,QAAQ,CAAC,EAAE,CAAC,CAACC,KAAK,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"names":["uuid","Math","random","toString","slice"],"sources":["utils.ts"],"sourcesContent":["export const uuid = () => Math.random().toString(36).slice(-6);\n"],"mappings":"AAAA,OAAO,MAAMA,IAAI,GAAGA,CAAA,KAAMC,IAAI,CAACC,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC,CAACC,KAAK,CAAC,CAAC,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
  type KeyboardProviderProps = {
3
3
  children: React.ReactNode;
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps } from './types';
2
+ import type { KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps } from "./types";
3
3
  export declare const KeyboardController: KeyboardControllerModule;
4
4
  export declare const KeyboardEvents: KeyboardEventsModule;
5
5
  export declare const KeyboardControllerView: import("react").FC<KeyboardControllerProps>;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps } from './types';
2
+ import type { KeyboardControllerModule, KeyboardControllerProps, KeyboardEventsModule, KeyboardGestureAreaProps } from "./types";
3
3
  export declare const KeyboardController: KeyboardControllerModule;
4
4
  export declare const KeyboardEvents: KeyboardEventsModule;
5
5
  export declare const KeyboardControllerView: React.FC<KeyboardControllerProps>;
@@ -1,6 +1,6 @@
1
- import React from 'react';
2
- import { View } from 'react-native';
3
- import type { ViewProps } from 'react-native';
1
+ import React from "react";
2
+ import { View } from "react-native";
3
+ import type { ViewProps } from "react-native";
4
4
  /**
5
5
  * View that moves out of the way when the keyboard appears by automatically
6
6
  * adjusting its height, position, or bottom padding.
@@ -13,7 +13,7 @@ declare const KeyboardAvoidingView: React.ForwardRefExoticComponent<{
13
13
  /**
14
14
  * Style of the content container when `behavior` is 'position'.
15
15
  */
16
- contentContainerStyle?: ViewProps['style'];
16
+ contentContainerStyle?: ViewProps["style"];
17
17
  /**
18
18
  * Controls whether this `KeyboardAvoidingView` instance should take effect.
19
19
  * This is useful when more than one is on the screen. Defaults to true.
@@ -1,5 +1,5 @@
1
- import type { FC } from 'react';
2
- import type { ScrollViewProps } from 'react-native';
1
+ import type { FC } from "react";
2
+ import type { ScrollViewProps } from "react-native";
3
3
  type KeyboardAwareScrollViewProps = {
4
4
  bottomOffset?: number;
5
5
  } & ScrollViewProps;
@@ -1,4 +1,4 @@
1
- import { useKeyboardHandler } from 'react-native-keyboard-controller';
1
+ import { useKeyboardHandler } from "react-native-keyboard-controller";
2
2
  /**
3
3
  * Hook that uses default transitions for iOS and Android > 11, and uses
4
4
  * custom interpolation on Android < 11 to achieve more smooth animation
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
- import type { View, ViewProps } from 'react-native';
1
+ import React from "react";
2
+ import type { View, ViewProps } from "react-native";
3
3
  declare const KeyboardStickyView: React.ForwardRefExoticComponent<{
4
4
  /**
5
5
  * Specify additional offset to the view for given keyboard state.
@@ -0,0 +1,20 @@
1
+ type KeyboardInterpolationOutput = [number, number];
2
+ /**
3
+ * Hook that can be used for interpolation keyboard movement. The main concern is the thing
4
+ * when keyboard is opened and gets resized on Android. Let's say we are interpolating from
5
+ * closed to open [0, 200] and we want to interpolate it to [0, 230] (to achieve nice parallax effect).
6
+ * Then let's say keyboard changes its height to 220 (and we want to interpolate the value to 250, +30
7
+ * to keyboard height). If we interpolate based on `progress` value, then we will have a jump on first frame:
8
+ * the last interpolated position was 230, now we will interpolate to 250, but first frame will be calculated
9
+ * as 200 / 220 * 250 = 227 (and last interpolated position was 230) so we will have a jump.
10
+ *
11
+ * This hook handles it, and when keyboard changes its size it does an interpolation as:
12
+ * [200, 220] -> [230, 250], i. e. we preserve last interpolated value and use it as initial value for interpolation
13
+ * and because of that we will not have a jump and animation will start from the last frame and will be smooth.
14
+ *
15
+ * @see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/315
16
+ */
17
+ declare const useKeyboardInterpolation: () => {
18
+ interpolate: (keyboardPosition: number, output: KeyboardInterpolationOutput) => number;
19
+ };
20
+ export default useKeyboardInterpolation;
@@ -1,3 +1,3 @@
1
- export { default as KeyboardAvoidingView } from './KeyboardAvoidingView';
2
- export { default as KeyboardStickyView } from './KeyboardStickyView';
3
- export { default as KeyboardAwareScrollView } from './KeyboardAwareScrollView';
1
+ export { default as KeyboardAvoidingView } from "./KeyboardAvoidingView";
2
+ export { default as KeyboardStickyView } from "./KeyboardStickyView";
3
+ export { default as KeyboardAwareScrollView } from "./KeyboardAwareScrollView";
@@ -1,7 +1,7 @@
1
- import { Animated } from 'react-native';
2
- import type { FocusedInputHandlers, FocusedInputLayoutChangedEvent, KeyboardHandlers } from './types';
3
- import type React from 'react';
4
- import type { SharedValue } from 'react-native-reanimated';
1
+ import { Animated } from "react-native";
2
+ import type { FocusedInputHandlers, FocusedInputLayoutChangedEvent, KeyboardHandlers } from "./types";
3
+ import type React from "react";
4
+ import type { SharedValue } from "react-native-reanimated";
5
5
  export type AnimatedContext = {
6
6
  progress: Animated.Value;
7
7
  height: Animated.AnimatedMultiplication<number>;
@@ -1,6 +1,6 @@
1
- import type { AnimatedContext, ReanimatedContext } from './context';
2
- import type { FocusedInputHandler, KeyboardHandler } from './types';
3
- import type { DependencyList } from 'react';
1
+ import type { AnimatedContext, ReanimatedContext } from "./context";
2
+ import type { FocusedInputHandler, KeyboardHandler } from "./types";
3
+ import type { DependencyList } from "react";
4
4
  export declare const useResizeMode: () => void;
5
5
  export declare const useKeyboardAnimation: () => AnimatedContext;
6
6
  export declare const useReanimatedKeyboardAnimation: () => ReanimatedContext;
@@ -1,8 +1,8 @@
1
- export * from './bindings';
2
- export * from './animated';
3
- export * from './replicas';
4
- export * from './context';
5
- export * from './hooks';
6
- export * from './constants';
7
- export * from './types';
8
- export { KeyboardAvoidingView, KeyboardStickyView, KeyboardAwareScrollView, } from './components';
1
+ export * from "./bindings";
2
+ export * from "./animated";
3
+ export * from "./replicas";
4
+ export * from "./context";
5
+ export * from "./hooks";
6
+ export * from "./constants";
7
+ export * from "./types";
8
+ export { KeyboardAvoidingView, KeyboardStickyView, KeyboardAwareScrollView, } from "./components";
@@ -1,5 +1,5 @@
1
- import { Animated } from 'react-native';
2
- import type { Handlers } from './types';
1
+ import { Animated } from "react-native";
2
+ import type { Handlers } from "./types";
3
3
  type UntypedHandler = Record<string, (event: never) => void>;
4
4
  type SharedHandlersReturnType<T extends UntypedHandler> = [
5
5
  (handler: Handlers<T>) => void,
@@ -1,4 +1,4 @@
1
- import type { EventWithName, FocusedInputLayoutChangedEvent, FocusedInputLayoutHandlerHook, FocusedInputTextChangedEvent, FocusedInputTextHandlerHook, KeyboardHandlerHook, NativeEvent } from './types';
1
+ import type { EventWithName, FocusedInputLayoutChangedEvent, FocusedInputLayoutHandlerHook, FocusedInputTextChangedEvent, FocusedInputTextHandlerHook, KeyboardHandlerHook, NativeEvent } from "./types";
2
2
  export declare const useAnimatedKeyboardHandler: KeyboardHandlerHook<Record<string, unknown>, EventWithName<NativeEvent>>;
3
3
  export declare const useFocusedInputLayoutHandler: FocusedInputLayoutHandlerHook<Record<string, unknown>, EventWithName<FocusedInputLayoutChangedEvent>>;
4
4
  export declare const useFocusedInputTextHandler: FocusedInputTextHandlerHook<Record<string, unknown>, EventWithName<FocusedInputTextChangedEvent>>;
@@ -1,4 +1,4 @@
1
- import type { EventWithName, FocusedInputLayoutChangedEvent, FocusedInputLayoutHandlerHook, FocusedInputTextChangedEvent, FocusedInputTextHandlerHook, KeyboardHandlerHook, NativeEvent } from './types';
1
+ import type { EventWithName, FocusedInputLayoutChangedEvent, FocusedInputLayoutHandlerHook, FocusedInputTextChangedEvent, FocusedInputTextHandlerHook, KeyboardHandlerHook, NativeEvent } from "./types";
2
2
  export declare const useAnimatedKeyboardHandler: KeyboardHandlerHook<Record<string, unknown>, EventWithName<NativeEvent>>;
3
3
  export declare const useFocusedInputLayoutHandler: FocusedInputLayoutHandlerHook<Record<string, unknown>, EventWithName<FocusedInputLayoutChangedEvent>>;
4
4
  export declare const useFocusedInputTextHandler: FocusedInputTextHandlerHook<Record<string, unknown>, EventWithName<FocusedInputTextChangedEvent>>;
@@ -1,4 +1,4 @@
1
- import { Animated } from 'react-native';
1
+ import { Animated } from "react-native";
2
2
  export declare const defaultAndroidEasing: import("react-native").EasingFunction;
3
3
  type KeyboardAnimation = {
4
4
  progress: Animated.Value;
@@ -1,6 +1,6 @@
1
- import type { HostComponent } from 'react-native';
2
- import type { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes';
3
- import type { DirectEventHandler, Double, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
1
+ import type { HostComponent } from "react-native";
2
+ import type { ViewProps } from "react-native/Libraries/Components/View/ViewPropTypes";
3
+ import type { DirectEventHandler, Double, Int32 } from "react-native/Libraries/Types/CodegenTypes";
4
4
  type KeyboardMoveEvent = Readonly<{
5
5
  height: Double;
6
6
  progress: Double;
@@ -1,8 +1,8 @@
1
- import type { HostComponent } from 'react-native';
2
- import type { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes';
3
- import type { WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
1
+ import type { HostComponent } from "react-native";
2
+ import type { ViewProps } from "react-native/Libraries/Components/View/ViewPropTypes";
3
+ import type { WithDefault } from "react-native/Libraries/Types/CodegenTypes";
4
4
  export interface NativeProps extends ViewProps {
5
- interpolator?: WithDefault<'linear' | 'ios', 'linear'>;
5
+ interpolator?: WithDefault<"linear" | "ios", "linear">;
6
6
  showOnSwipeUp?: boolean;
7
7
  enableSwipeToDismiss?: boolean;
8
8
  }
@@ -1,4 +1,4 @@
1
- import type { TurboModule } from 'react-native';
1
+ import type { TurboModule } from "react-native";
2
2
  export interface Spec extends TurboModule {
3
3
  readonly getConstants: () => {};
4
4
  setInputMode(mode: number): void;
@@ -1,4 +1,4 @@
1
- import type { TurboModule } from 'react-native';
1
+ import type { TurboModule } from "react-native";
2
2
  export interface Spec extends TurboModule {
3
3
  readonly getConstants: () => {};
4
4
  setHidden(hidden: boolean): void;
@@ -1,4 +1,4 @@
1
- import type { EmitterSubscription, NativeSyntheticEvent, ViewProps } from 'react-native';
1
+ import type { EmitterSubscription, NativeSyntheticEvent, ViewProps } from "react-native";
2
2
  export type NativeEvent = {
3
3
  progress: number;
4
4
  height: number;
@@ -37,7 +37,7 @@ export type KeyboardControllerProps = {
37
37
  enabled?: boolean;
38
38
  } & ViewProps;
39
39
  export type KeyboardGestureAreaProps = {
40
- interpolator: 'ios' | 'linear';
40
+ interpolator: "ios" | "linear";
41
41
  /**
42
42
  * Whether to allow to show a keyboard from dismissed state by swipe up.
43
43
  * Default to `false`.
@@ -57,7 +57,7 @@ export type KeyboardControllerModule = {
57
57
  addListener: (eventName: string) => void;
58
58
  removeListeners: (count: number) => void;
59
59
  };
60
- export type KeyboardControllerEvents = 'keyboardWillShow' | 'keyboardDidShow' | 'keyboardWillHide' | 'keyboardDidHide';
60
+ export type KeyboardControllerEvents = "keyboardWillShow" | "keyboardDidShow" | "keyboardWillHide" | "keyboardDidHide";
61
61
  export type KeyboardEventData = {
62
62
  height: number;
63
63
  duration: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-keyboard-controller",
3
- "version": "1.10.0",
3
+ "version": "1.10.2",
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",
@@ -27,6 +27,7 @@
27
27
  "!**/__mocks__"
28
28
  ],
29
29
  "scripts": {
30
+ "format": "prettier '**/*' --ignore-unknown --write",
30
31
  "test": "jest",
31
32
  "typescript": "tsc --noEmit --project tsconfig.build.json",
32
33
  "lint": "eslint --quiet \"**/*.{js,ts,tsx}\"",
@@ -62,7 +63,7 @@
62
63
  },
63
64
  "devDependencies": {
64
65
  "@commitlint/config-conventional": "^11.0.0",
65
- "@react-native/eslint-config": "^0.72.2",
66
+ "@react-native/eslint-config": "^0.74.0",
66
67
  "@release-it/conventional-changelog": "^2.0.0",
67
68
  "@types/jest": "^29.2.1",
68
69
  "@types/react": "^18.0.24",
@@ -71,15 +72,15 @@
71
72
  "clang-format": "^1.8.0",
72
73
  "commitlint": "^11.0.0",
73
74
  "eslint": "^8.19.0",
74
- "eslint-config-prettier": "^7.0.0",
75
+ "eslint-config-prettier": "^8.5.0",
75
76
  "eslint-import-resolver-typescript": "^3.6.1",
76
77
  "eslint-plugin-import": "^2.28.1",
77
- "eslint-plugin-jest": "^27.4.2",
78
- "eslint-plugin-prettier": "^3.1.3",
78
+ "eslint-plugin-jest": "^26.5.3",
79
+ "eslint-plugin-prettier": "^4.2.1",
79
80
  "husky": "^6.0.0",
80
81
  "jest": "^29.2.1",
81
82
  "pod-install": "^0.1.0",
82
- "prettier": "^2.4.1",
83
+ "prettier": "^2.8.8",
83
84
  "react": "18.2.0",
84
85
  "react-native": "0.72.4",
85
86
  "react-native-builder-bob": "^0.18.0",
@@ -123,10 +124,7 @@
123
124
  },
124
125
  "prettier": {
125
126
  "quoteProps": "consistent",
126
- "singleQuote": true,
127
- "tabWidth": 2,
128
- "trailingComma": "es5",
129
- "useTabs": false
127
+ "trailingComma": "all"
130
128
  },
131
129
  "react-native-builder-bob": {
132
130
  "source": "src",
package/src/animated.tsx CHANGED
@@ -1,31 +1,31 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
2
- import { Animated, Platform, StyleSheet } from 'react-native';
3
- import Reanimated, { useSharedValue } from 'react-native-reanimated';
1
+ import React, { useEffect, useMemo, useState } from "react";
2
+ import { Animated, Platform, StyleSheet } from "react-native";
3
+ import Reanimated, { useSharedValue } from "react-native-reanimated";
4
4
 
5
- import { KeyboardControllerView } from './bindings';
6
- import { KeyboardContext } from './context';
7
- import { useAnimatedValue, useSharedHandlers } from './internal';
8
- import { applyMonkeyPatch, revertMonkeyPatch } from './monkey-patch';
5
+ import { KeyboardControllerView } from "./bindings";
6
+ import { KeyboardContext } from "./context";
7
+ import { useAnimatedValue, useSharedHandlers } from "./internal";
8
+ import { applyMonkeyPatch, revertMonkeyPatch } from "./monkey-patch";
9
9
  import {
10
10
  useAnimatedKeyboardHandler,
11
11
  useFocusedInputLayoutHandler,
12
12
  useFocusedInputTextHandler,
13
- } from './reanimated';
13
+ } from "./reanimated";
14
14
 
15
- import type { KeyboardAnimationContext } from './context';
15
+ import type { KeyboardAnimationContext } from "./context";
16
16
  import type {
17
17
  FocusedInputHandler,
18
18
  FocusedInputLayoutChangedEvent,
19
19
  KeyboardControllerProps,
20
20
  KeyboardHandler,
21
21
  NativeEvent,
22
- } from './types';
23
- import type { ViewStyle } from 'react-native';
22
+ } from "./types";
23
+ import type { ViewStyle } from "react-native";
24
24
 
25
25
  const KeyboardControllerViewAnimated = Reanimated.createAnimatedComponent(
26
26
  Animated.createAnimatedComponent(
27
- KeyboardControllerView
28
- ) as React.FC<KeyboardControllerProps>
27
+ KeyboardControllerView,
28
+ ) as React.FC<KeyboardControllerProps>,
29
29
  );
30
30
 
31
31
  type Styles = {
@@ -38,8 +38,8 @@ const styles = StyleSheet.create<Styles>({
38
38
  flex: 1,
39
39
  },
40
40
  hidden: {
41
- display: 'none',
42
- position: 'absolute',
41
+ display: "none",
42
+ position: "absolute",
43
43
  },
44
44
  });
45
45
 
@@ -102,14 +102,14 @@ export const KeyboardProvider = ({
102
102
  setInputHandlers,
103
103
  setEnabled,
104
104
  }),
105
- [enabled]
105
+ [enabled],
106
106
  );
107
107
  const style = useMemo(
108
108
  () => [
109
109
  styles.hidden,
110
110
  { transform: [{ translateX: height }, { translateY: progress }] },
111
111
  ],
112
- []
112
+ [],
113
113
  );
114
114
  const onKeyboardMove = useMemo(
115
115
  () =>
@@ -122,13 +122,13 @@ export const KeyboardProvider = ({
122
122
  },
123
123
  },
124
124
  ],
125
- { useNativeDriver: true }
125
+ { useNativeDriver: true },
126
126
  ),
127
- []
127
+ [],
128
128
  );
129
129
  // handlers
130
130
  const updateSharedValues = (event: NativeEvent, platforms: string[]) => {
131
- 'worklet';
131
+ "worklet";
132
132
 
133
133
  if (platforms.includes(Platform.OS)) {
134
134
  progressSV.value = event.progress;
@@ -138,35 +138,35 @@ export const KeyboardProvider = ({
138
138
  const keyboardHandler = useAnimatedKeyboardHandler(
139
139
  {
140
140
  onKeyboardMoveStart: (event: NativeEvent) => {
141
- 'worklet';
141
+ "worklet";
142
142
 
143
- broadcastKeyboardEvents('onStart', event);
144
- updateSharedValues(event, ['ios']);
143
+ broadcastKeyboardEvents("onStart", event);
144
+ updateSharedValues(event, ["ios"]);
145
145
  },
146
146
  onKeyboardMove: (event: NativeEvent) => {
147
- 'worklet';
147
+ "worklet";
148
148
 
149
- broadcastKeyboardEvents('onMove', event);
150
- updateSharedValues(event, ['android']);
149
+ broadcastKeyboardEvents("onMove", event);
150
+ updateSharedValues(event, ["android"]);
151
151
  },
152
152
  onKeyboardMoveEnd: (event: NativeEvent) => {
153
- 'worklet';
153
+ "worklet";
154
154
 
155
- broadcastKeyboardEvents('onEnd', event);
155
+ broadcastKeyboardEvents("onEnd", event);
156
156
  },
157
157
  onKeyboardMoveInteractive: (event: NativeEvent) => {
158
- 'worklet';
158
+ "worklet";
159
159
 
160
- updateSharedValues(event, ['android', 'ios']);
161
- broadcastKeyboardEvents('onInteractive', event);
160
+ updateSharedValues(event, ["android", "ios"]);
161
+ broadcastKeyboardEvents("onInteractive", event);
162
162
  },
163
163
  },
164
- []
164
+ [],
165
165
  );
166
166
  const inputLayoutHandler = useFocusedInputLayoutHandler(
167
167
  {
168
168
  onFocusedInputLayoutChanged: (e) => {
169
- 'worklet';
169
+ "worklet";
170
170
 
171
171
  if (e.target !== -1) {
172
172
  layout.value = e;
@@ -175,17 +175,17 @@ export const KeyboardProvider = ({
175
175
  }
176
176
  },
177
177
  },
178
- []
178
+ [],
179
179
  );
180
180
  const inputTextHandler = useFocusedInputTextHandler(
181
181
  {
182
182
  onFocusedInputTextChanged: (e) => {
183
- 'worklet';
183
+ "worklet";
184
184
 
185
- broadcastInputEvents('onChangeText', e);
185
+ broadcastInputEvents("onChangeText", e);
186
186
  },
187
187
  },
188
- []
188
+ [],
189
189
  );
190
190
  // effects
191
191
  useEffect(() => {
@@ -201,8 +201,8 @@ export const KeyboardProvider = ({
201
201
  <KeyboardControllerViewAnimated
202
202
  enabled={enabled}
203
203
  onKeyboardMoveReanimated={keyboardHandler}
204
- onKeyboardMoveStart={Platform.OS === 'ios' ? onKeyboardMove : undefined}
205
- onKeyboardMove={Platform.OS === 'android' ? onKeyboardMove : undefined}
204
+ onKeyboardMoveStart={Platform.OS === "ios" ? onKeyboardMove : undefined}
205
+ onKeyboardMove={Platform.OS === "android" ? onKeyboardMove : undefined}
206
206
  onKeyboardMoveInteractive={onKeyboardMove}
207
207
  onFocusedInputLayoutChangedReanimated={inputLayoutHandler}
208
208
  onFocusedInputTextChangedReanimated={inputTextHandler}
@@ -1,20 +1,20 @@
1
- import { NativeEventEmitter, Platform } from 'react-native';
1
+ import { NativeEventEmitter, Platform } from "react-native";
2
2
 
3
3
  import type {
4
4
  KeyboardControllerModule,
5
5
  KeyboardControllerProps,
6
6
  KeyboardEventsModule,
7
7
  KeyboardGestureAreaProps,
8
- } from './types';
8
+ } from "./types";
9
9
 
10
10
  const LINKING_ERROR =
11
11
  `The package 'react-native-keyboard-controller' doesn't seem to be linked. Make sure: \n\n` +
12
- Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
13
- '- You rebuilt the app after installing the package\n' +
14
- '- You are not using Expo Go\n';
12
+ Platform.select({ ios: "- You have run 'pod install'\n", default: "" }) +
13
+ "- You rebuilt the app after installing the package\n" +
14
+ "- You are not using Expo Go\n";
15
15
 
16
16
  const RCTKeyboardController =
17
- require('./specs/NativeKeyboardController').default;
17
+ require("./specs/NativeKeyboardController").default;
18
18
  export const KeyboardController = (
19
19
  RCTKeyboardController
20
20
  ? RCTKeyboardController
@@ -24,7 +24,7 @@ export const KeyboardController = (
24
24
  get() {
25
25
  throw new Error(LINKING_ERROR);
26
26
  },
27
- }
27
+ },
28
28
  )
29
29
  ) as KeyboardControllerModule;
30
30
 
@@ -32,11 +32,11 @@ const eventEmitter = new NativeEventEmitter(KeyboardController);
32
32
 
33
33
  export const KeyboardEvents: KeyboardEventsModule = {
34
34
  addListener: (name, cb) =>
35
- eventEmitter.addListener('KeyboardController::' + name, cb),
35
+ eventEmitter.addListener("KeyboardController::" + name, cb),
36
36
  };
37
37
  export const KeyboardControllerView: React.FC<KeyboardControllerProps> =
38
- require('./specs/KeyboardControllerViewNativeComponent').default;
38
+ require("./specs/KeyboardControllerViewNativeComponent").default;
39
39
  export const KeyboardGestureArea: React.FC<KeyboardGestureAreaProps> =
40
- Platform.OS === 'android' && Platform.Version >= 30
41
- ? require('./specs/KeyboardGestureAreaNativeComponent').default
40
+ Platform.OS === "android" && Platform.Version >= 30
41
+ ? require("./specs/KeyboardGestureAreaNativeComponent").default
42
42
  : ({ children }: KeyboardGestureAreaProps) => children;
package/src/bindings.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { View } from 'react-native';
1
+ import { View } from "react-native";
2
2
 
3
3
  import type {
4
4
  KeyboardControllerModule,
5
5
  KeyboardControllerProps,
6
6
  KeyboardEventsModule,
7
7
  KeyboardGestureAreaProps,
8
- } from './types';
9
- import type { EmitterSubscription } from 'react-native';
8
+ } from "./types";
9
+ import type { EmitterSubscription } from "react-native";
10
10
 
11
11
  const NOOP = () => {};
12
12
  export const KeyboardController: KeyboardControllerModule = {
@@ -1,6 +1,6 @@
1
- import { useSharedValue } from 'react-native-reanimated';
1
+ import { useSharedValue } from "react-native-reanimated";
2
2
 
3
- import { useKeyboardHandler } from '../../hooks';
3
+ import { useKeyboardHandler } from "react-native-keyboard-controller";
4
4
 
5
5
  export const useKeyboardAnimation = () => {
6
6
  const heightWhenOpened = useSharedValue(0);
@@ -11,7 +11,7 @@ export const useKeyboardAnimation = () => {
11
11
  useKeyboardHandler(
12
12
  {
13
13
  onStart: (e) => {
14
- 'worklet';
14
+ "worklet";
15
15
 
16
16
  if (e.height > 0) {
17
17
  isClosed.value = false;
@@ -19,18 +19,32 @@ export const useKeyboardAnimation = () => {
19
19
  }
20
20
  },
21
21
  onMove: (e) => {
22
- 'worklet';
22
+ "worklet";
23
23
 
24
24
  progress.value = e.progress;
25
25
  height.value = e.height;
26
26
  },
27
27
  onEnd: (e) => {
28
- 'worklet';
28
+ "worklet";
29
29
 
30
30
  isClosed.value = e.height === 0;
31
+
32
+ // `height` update happens in `onMove` handler
33
+ // in `onEnd` we need to update only if `onMove`
34
+ // wasn't called (i. e. duration === 0)
35
+ //
36
+ // we can not call this code without condition below
37
+ // because in some corner cases (iOS with `secureTextEntry`)
38
+ // `onEnd` can be emitted before `onMove` and in this case
39
+ // it may lead to choppy/glitchy/jumpy UI
40
+ // see https://github.com/kirillzyusko/react-native-keyboard-controller/issues/327
41
+ if (e.duration === 0) {
42
+ progress.value = e.progress;
43
+ height.value = e.height;
44
+ }
31
45
  },
32
46
  },
33
- []
47
+ [],
34
48
  );
35
49
 
36
50
  return { height, progress, heightWhenOpened, isClosed };