react-native-keyboard-controller 1.16.8 → 1.17.1

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 (110) hide show
  1. package/README.md +2 -8
  2. package/android/src/fabric/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt +11 -0
  3. package/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt +55 -4
  4. package/android/src/main/jni/CMakeLists.txt +85 -0
  5. package/android/src/main/jni/reactnativekeyboardcontroller.h +23 -0
  6. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewComponentDescriptor.h +21 -0
  7. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.cpp +7 -0
  8. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.h +23 -0
  9. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewState.h +21 -0
  10. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaComponentDescriptor.h +20 -0
  11. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.cpp +7 -0
  12. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.h +23 -0
  13. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaState.h +21 -0
  14. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewComponentDescriptor.h +31 -0
  15. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.cpp +7 -0
  16. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.h +23 -0
  17. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.cpp +12 -0
  18. package/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.h +43 -0
  19. package/ios/KeyboardController-Bridging-Header.h +0 -1
  20. package/ios/delegates/KCTextInputCompositeDelegate.swift +16 -1
  21. package/ios/objc/{RCTUITextView+DelegateManager.h → UITextView+DelegateManager.h} +2 -4
  22. package/ios/objc/{RCTUITextView+DelegateManager.m → UITextView+DelegateManager.m} +3 -3
  23. package/ios/observers/FocusedInputObserver.swift +5 -3
  24. package/ios/views/KeyboardControllerView.mm +1 -1
  25. package/ios/views/KeyboardGestureAreaManager.mm +1 -1
  26. package/ios/views/OverKeyboardViewManager.mm +1 -1
  27. package/jest/index.js +14 -1
  28. package/lib/commonjs/components/KeyboardAvoidingView/index.js +2 -2
  29. package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
  30. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +3 -3
  31. package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
  32. package/lib/commonjs/components/KeyboardStickyView/index.js +12 -12
  33. package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
  34. package/lib/commonjs/hooks/index.js +12 -0
  35. package/lib/commonjs/hooks/index.js.map +1 -1
  36. package/lib/commonjs/hooks/useKeyboardState/index.js +34 -0
  37. package/lib/commonjs/hooks/useKeyboardState/index.js.map +1 -0
  38. package/lib/commonjs/internal.js +2 -1
  39. package/lib/commonjs/internal.js.map +1 -1
  40. package/lib/commonjs/module.js +11 -4
  41. package/lib/commonjs/module.js.map +1 -1
  42. package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js +3 -1
  43. package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
  44. package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js +3 -1
  45. package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
  46. package/lib/commonjs/specs/OverKeyboardViewNativeComponent.js +3 -1
  47. package/lib/commonjs/specs/OverKeyboardViewNativeComponent.js.map +1 -1
  48. package/lib/commonjs/types.js.map +1 -1
  49. package/lib/commonjs/utils/findNodeHandle/index.js +9 -0
  50. package/lib/commonjs/utils/findNodeHandle/index.js.map +1 -0
  51. package/lib/commonjs/utils/findNodeHandle/index.native.js +13 -0
  52. package/lib/commonjs/utils/findNodeHandle/index.native.js.map +1 -0
  53. package/lib/commonjs/views/OverKeyboardView/index.js +10 -4
  54. package/lib/commonjs/views/OverKeyboardView/index.js.map +1 -1
  55. package/lib/module/components/KeyboardAvoidingView/index.js +2 -2
  56. package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
  57. package/lib/module/components/KeyboardAwareScrollView/index.js +2 -2
  58. package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
  59. package/lib/module/components/KeyboardStickyView/index.js +13 -13
  60. package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
  61. package/lib/module/hooks/index.js +1 -0
  62. package/lib/module/hooks/index.js.map +1 -1
  63. package/lib/module/hooks/useKeyboardState/index.js +27 -0
  64. package/lib/module/hooks/useKeyboardState/index.js.map +1 -0
  65. package/lib/module/internal.js +2 -1
  66. package/lib/module/internal.js.map +1 -1
  67. package/lib/module/module.js +11 -4
  68. package/lib/module/module.js.map +1 -1
  69. package/lib/module/specs/KeyboardControllerViewNativeComponent.js +3 -1
  70. package/lib/module/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
  71. package/lib/module/specs/KeyboardGestureAreaNativeComponent.js +3 -1
  72. package/lib/module/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
  73. package/lib/module/specs/OverKeyboardViewNativeComponent.js +3 -1
  74. package/lib/module/specs/OverKeyboardViewNativeComponent.js.map +1 -1
  75. package/lib/module/types.js.map +1 -1
  76. package/lib/module/utils/findNodeHandle/index.js +2 -0
  77. package/lib/module/utils/findNodeHandle/index.js.map +1 -0
  78. package/lib/module/utils/findNodeHandle/index.native.js +3 -0
  79. package/lib/module/utils/findNodeHandle/index.native.js.map +1 -0
  80. package/lib/module/views/OverKeyboardView/index.js +10 -4
  81. package/lib/module/views/OverKeyboardView/index.js.map +1 -1
  82. package/lib/typescript/hooks/index.d.ts +1 -0
  83. package/lib/typescript/hooks/useKeyboardState/index.d.ts +2 -0
  84. package/lib/typescript/internal.d.ts +2 -1
  85. package/lib/typescript/types.d.ts +4 -1
  86. package/lib/typescript/utils/findNodeHandle/index.d.ts +4 -0
  87. package/lib/typescript/utils/findNodeHandle/index.native.d.ts +2 -0
  88. package/package.json +4 -1
  89. package/react-native-keyboard-controller.podspec +8 -0
  90. package/react-native.config.js +14 -0
  91. package/src/components/KeyboardAvoidingView/index.tsx +14 -7
  92. package/src/components/KeyboardAwareScrollView/index.tsx +2 -2
  93. package/src/components/KeyboardStickyView/index.tsx +18 -17
  94. package/src/hooks/index.ts +1 -0
  95. package/src/hooks/useKeyboardState/index.ts +38 -0
  96. package/src/internal.ts +2 -1
  97. package/src/module.ts +11 -4
  98. package/src/specs/KeyboardControllerViewNativeComponent.ts +3 -3
  99. package/src/specs/KeyboardGestureAreaNativeComponent.ts +3 -3
  100. package/src/specs/OverKeyboardViewNativeComponent.ts +3 -3
  101. package/src/types.ts +4 -1
  102. package/src/utils/findNodeHandle/index.native.ts +3 -0
  103. package/src/utils/findNodeHandle/index.ts +6 -0
  104. package/src/views/OverKeyboardView/index.tsx +11 -4
  105. package/lib/commonjs/architecture.js +0 -8
  106. package/lib/commonjs/architecture.js.map +0 -1
  107. package/lib/module/architecture.js +0 -2
  108. package/lib/module/architecture.js.map +0 -1
  109. package/lib/typescript/architecture.d.ts +0 -1
  110. package/src/architecture.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"names":["codegenNativeComponent"],"sources":["KeyboardControllerViewNativeComponent.ts"],"sourcesContent":["import codegenNativeComponent from \"react-native/Libraries/Utilities/codegenNativeComponent\";\n\nimport type { HostComponent } from \"react-native\";\nimport type { ViewProps } from \"react-native/Libraries/Components/View/ViewPropTypes\";\nimport type {\n DirectEventHandler,\n Double,\n Int32,\n} from \"react-native/Libraries/Types/CodegenTypes\";\n\ntype KeyboardMoveEvent = Readonly<{\n height: Double;\n progress: Double;\n duration: Int32;\n target: Int32;\n}>;\n\ntype FocusedInputLayoutChangedEvent = Readonly<{\n target: Int32;\n parentScrollViewTarget: Int32;\n layout: {\n x: Double;\n y: Double;\n width: Double;\n height: Double;\n absoluteX: Double;\n absoluteY: Double;\n };\n}>;\n\ntype FocusedInputTextChangedEvent = Readonly<{\n text: string;\n}>;\n\ntype FocusedInputSelectionChangedEvent = Readonly<{\n target: Int32;\n selection: {\n start: {\n x: Double;\n y: Double;\n position: Int32;\n };\n end: {\n x: Double;\n y: Double;\n position: Int32;\n };\n };\n}>;\n\nexport interface NativeProps extends ViewProps {\n // props\n enabled?: boolean;\n statusBarTranslucent?: boolean;\n navigationBarTranslucent?: boolean;\n preserveEdgeToEdge?: boolean;\n // callbacks\n /// keyboard\n onKeyboardMoveStart?: DirectEventHandler<KeyboardMoveEvent>;\n onKeyboardMove?: DirectEventHandler<KeyboardMoveEvent>;\n onKeyboardMoveEnd?: DirectEventHandler<KeyboardMoveEvent>;\n onKeyboardMoveInteractive?: DirectEventHandler<KeyboardMoveEvent>;\n /// focused input\n onFocusedInputLayoutChanged?: DirectEventHandler<FocusedInputLayoutChangedEvent>;\n onFocusedInputTextChanged?: DirectEventHandler<FocusedInputTextChangedEvent>;\n onFocusedInputSelectionChanged?: DirectEventHandler<FocusedInputSelectionChangedEvent>;\n}\n\nexport default codegenNativeComponent<NativeProps>(\n \"KeyboardControllerView\",\n) as HostComponent<NativeProps>;\n"],"mappings":"AAAA,OAAOA,sBAAsB,MAAM,yDAAyD;AAoE5F,eAAeA,sBAAsB,CACnC,wBACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["codegenNativeComponent","interfaceOnly"],"sources":["KeyboardControllerViewNativeComponent.ts"],"sourcesContent":["import codegenNativeComponent from \"react-native/Libraries/Utilities/codegenNativeComponent\";\n\nimport type { HostComponent } from \"react-native\";\nimport type { ViewProps } from \"react-native/Libraries/Components/View/ViewPropTypes\";\nimport type {\n DirectEventHandler,\n Double,\n Int32,\n} from \"react-native/Libraries/Types/CodegenTypes\";\n\ntype KeyboardMoveEvent = Readonly<{\n height: Double;\n progress: Double;\n duration: Int32;\n target: Int32;\n}>;\n\ntype FocusedInputLayoutChangedEvent = Readonly<{\n target: Int32;\n parentScrollViewTarget: Int32;\n layout: {\n x: Double;\n y: Double;\n width: Double;\n height: Double;\n absoluteX: Double;\n absoluteY: Double;\n };\n}>;\n\ntype FocusedInputTextChangedEvent = Readonly<{\n text: string;\n}>;\n\ntype FocusedInputSelectionChangedEvent = Readonly<{\n target: Int32;\n selection: {\n start: {\n x: Double;\n y: Double;\n position: Int32;\n };\n end: {\n x: Double;\n y: Double;\n position: Int32;\n };\n };\n}>;\n\nexport interface NativeProps extends ViewProps {\n // props\n enabled?: boolean;\n statusBarTranslucent?: boolean;\n navigationBarTranslucent?: boolean;\n preserveEdgeToEdge?: boolean;\n // callbacks\n /// keyboard\n onKeyboardMoveStart?: DirectEventHandler<KeyboardMoveEvent>;\n onKeyboardMove?: DirectEventHandler<KeyboardMoveEvent>;\n onKeyboardMoveEnd?: DirectEventHandler<KeyboardMoveEvent>;\n onKeyboardMoveInteractive?: DirectEventHandler<KeyboardMoveEvent>;\n /// focused input\n onFocusedInputLayoutChanged?: DirectEventHandler<FocusedInputLayoutChangedEvent>;\n onFocusedInputTextChanged?: DirectEventHandler<FocusedInputTextChangedEvent>;\n onFocusedInputSelectionChanged?: DirectEventHandler<FocusedInputSelectionChangedEvent>;\n}\n\nexport default codegenNativeComponent<NativeProps>(\"KeyboardControllerView\", {\n interfaceOnly: true,\n}) as HostComponent<NativeProps>;\n"],"mappings":"AAAA,OAAOA,sBAAsB,MAAM,yDAAyD;AAoE5F,eAAeA,sBAAsB,CAAc,wBAAwB,EAAE;EAC3EC,aAAa,EAAE;AACjB,CAAC,CAAC","ignoreList":[]}
@@ -1,3 +1,5 @@
1
1
  import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
2
- export default codegenNativeComponent("KeyboardGestureArea");
2
+ export default codegenNativeComponent("KeyboardGestureArea", {
3
+ interfaceOnly: true
4
+ });
3
5
  //# sourceMappingURL=KeyboardGestureAreaNativeComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["codegenNativeComponent"],"sources":["KeyboardGestureAreaNativeComponent.ts"],"sourcesContent":["import codegenNativeComponent from \"react-native/Libraries/Utilities/codegenNativeComponent\";\n\nimport type { HostComponent } from \"react-native\";\nimport type { ViewProps } from \"react-native/Libraries/Components/View/ViewPropTypes\";\nimport type {\n Double,\n WithDefault,\n} from \"react-native/Libraries/Types/CodegenTypes\";\n\nexport interface NativeProps extends ViewProps {\n interpolator?: WithDefault<\"linear\" | \"ios\", \"linear\">;\n showOnSwipeUp?: boolean;\n enableSwipeToDismiss?: boolean;\n offset?: Double;\n textInputNativeID?: string;\n}\n\nexport default codegenNativeComponent<NativeProps>(\n \"KeyboardGestureArea\",\n) as HostComponent<NativeProps>;\n"],"mappings":"AAAA,OAAOA,sBAAsB,MAAM,yDAAyD;AAiB5F,eAAeA,sBAAsB,CACnC,qBACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["codegenNativeComponent","interfaceOnly"],"sources":["KeyboardGestureAreaNativeComponent.ts"],"sourcesContent":["import codegenNativeComponent from \"react-native/Libraries/Utilities/codegenNativeComponent\";\n\nimport type { HostComponent } from \"react-native\";\nimport type { ViewProps } from \"react-native/Libraries/Components/View/ViewPropTypes\";\nimport type {\n Double,\n WithDefault,\n} from \"react-native/Libraries/Types/CodegenTypes\";\n\nexport interface NativeProps extends ViewProps {\n interpolator?: WithDefault<\"linear\" | \"ios\", \"linear\">;\n showOnSwipeUp?: boolean;\n enableSwipeToDismiss?: boolean;\n offset?: Double;\n textInputNativeID?: string;\n}\n\nexport default codegenNativeComponent<NativeProps>(\"KeyboardGestureArea\", {\n interfaceOnly: true,\n}) as HostComponent<NativeProps>;\n"],"mappings":"AAAA,OAAOA,sBAAsB,MAAM,yDAAyD;AAiB5F,eAAeA,sBAAsB,CAAc,qBAAqB,EAAE;EACxEC,aAAa,EAAE;AACjB,CAAC,CAAC","ignoreList":[]}
@@ -1,3 +1,5 @@
1
1
  import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
2
- export default codegenNativeComponent("OverKeyboardView");
2
+ export default codegenNativeComponent("OverKeyboardView", {
3
+ interfaceOnly: true
4
+ });
3
5
  //# sourceMappingURL=OverKeyboardViewNativeComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["codegenNativeComponent"],"sources":["OverKeyboardViewNativeComponent.ts"],"sourcesContent":["import codegenNativeComponent from \"react-native/Libraries/Utilities/codegenNativeComponent\";\n\nimport type { HostComponent } from \"react-native\";\nimport type { ViewProps } from \"react-native/Libraries/Components/View/ViewPropTypes\";\n\nexport interface NativeProps extends ViewProps {\n visible?: boolean;\n}\n\nexport default codegenNativeComponent<NativeProps>(\n \"OverKeyboardView\",\n) as HostComponent<NativeProps>;\n"],"mappings":"AAAA,OAAOA,sBAAsB,MAAM,yDAAyD;AAS5F,eAAeA,sBAAsB,CACnC,kBACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["codegenNativeComponent","interfaceOnly"],"sources":["OverKeyboardViewNativeComponent.ts"],"sourcesContent":["import codegenNativeComponent from \"react-native/Libraries/Utilities/codegenNativeComponent\";\n\nimport type { HostComponent } from \"react-native\";\nimport type { ViewProps } from \"react-native/Libraries/Components/View/ViewPropTypes\";\n\nexport interface NativeProps extends ViewProps {\n visible?: boolean;\n}\n\nexport default codegenNativeComponent<NativeProps>(\"OverKeyboardView\", {\n interfaceOnly: true,\n}) as HostComponent<NativeProps>;\n"],"mappings":"AAAA,OAAOA,sBAAsB,MAAM,yDAAyD;AAS5F,eAAeA,sBAAsB,CAAc,kBAAkB,EAAE;EACrEC,aAAa,EAAE;AACjB,CAAC,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { PropsWithChildren } from \"react\";\nimport type {\n EmitterSubscription,\n NativeSyntheticEvent,\n TextInputProps,\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 //ref prop\n ref?: React.Ref<React.Component<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 preserveEdgeToEdge?: 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 /**\n * Extra distance to the keyboard.\n */\n offset?: number;\n /**\n * A corresponding `nativeID` value from the corresponding `TextInput`.\n */\n textInputNativeID?: string;\n} & ViewProps;\nexport type OverKeyboardViewProps = PropsWithChildren<{\n visible: boolean;\n}>;\n\nexport type Direction = \"next\" | \"prev\" | \"current\";\nexport type DismissOptions = {\n keepFocus: boolean;\n};\nexport type KeyboardControllerModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: (options?: DismissOptions) => Promise<void>;\n setFocusTo: (direction: Direction) => void;\n isVisible: () => boolean;\n state: () => KeyboardEventData | null;\n};\nexport type KeyboardControllerNativeModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: (keepFocus: boolean) => 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 type: NonNullable<TextInputProps[\"keyboardType\"]>;\n appearance: NonNullable<TextInputProps[\"keyboardAppearance\"]>;\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
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { PropsWithChildren } from \"react\";\nimport type {\n EmitterSubscription,\n NativeSyntheticEvent,\n TextInputProps,\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 //ref prop\n ref?: React.Ref<React.Component<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 preserveEdgeToEdge?: 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 /**\n * Extra distance to the keyboard.\n */\n offset?: number;\n /**\n * A corresponding `nativeID` value from the corresponding `TextInput`.\n */\n textInputNativeID?: string;\n} & ViewProps;\nexport type OverKeyboardViewProps = PropsWithChildren<{\n visible: boolean;\n}>;\n\nexport type Direction = \"next\" | \"prev\" | \"current\";\nexport type DismissOptions = {\n keepFocus: boolean;\n};\nexport type KeyboardControllerModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: (options?: DismissOptions) => Promise<void>;\n setFocusTo: (direction: Direction) => void;\n isVisible: () => boolean;\n state: () => KeyboardEventData;\n};\nexport type KeyboardControllerNativeModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: (keepFocus: boolean) => 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 type: NonNullable<TextInputProps[\"keyboardType\"]>;\n appearance: NonNullable<TextInputProps[\"keyboardAppearance\"]>;\n};\nexport type KeyboardState = {\n isVisible: boolean;\n} & KeyboardEventData;\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":[]}
@@ -0,0 +1,2 @@
1
+ export const findNodeHandle = componentOrHandle => componentOrHandle;
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["findNodeHandle","componentOrHandle"],"sources":["index.ts"],"sourcesContent":["import type { findNodeHandle as findNodeHandleRN } from \"react-native\";\n\ntype FindNodeHandleRN = typeof findNodeHandleRN;\n\nexport const findNodeHandle: FindNodeHandleRN = (componentOrHandle) =>\n componentOrHandle as number | null;\n"],"mappings":"AAIA,OAAO,MAAMA,cAAgC,GAAIC,iBAAiB,IAChEA,iBAAkC","ignoreList":[]}
@@ -0,0 +1,3 @@
1
+ import { findNodeHandle } from "react-native";
2
+ export { findNodeHandle };
3
+ //# sourceMappingURL=index.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["findNodeHandle"],"sources":["index.native.ts"],"sourcesContent":["import { findNodeHandle } from \"react-native\";\n\nexport { findNodeHandle };\n"],"mappings":"AAAA,SAASA,cAAc,QAAQ,cAAc;AAE7C,SAASA,cAAc","ignoreList":[]}
@@ -1,6 +1,5 @@
1
1
  import React, { useMemo } from "react";
2
2
  import { Platform, StyleSheet, View } from "react-native";
3
- import { IS_FABRIC } from "../../architecture";
4
3
  import { RCTOverKeyboardView } from "../../bindings";
5
4
  import { useWindowDimensions } from "../../hooks";
6
5
  const OverKeyboardView = ({
@@ -17,18 +16,25 @@ const OverKeyboardView = ({
17
16
  }), [height, width]);
18
17
  const style = useMemo(() => [styles.absolute,
19
18
  // On iOS - stretch view to full window dimensions to make yoga work
20
- // On Android Fabric we temporarily use the same approach
21
- Platform.OS === "ios" || IS_FABRIC ? inner : undefined], [inner]);
19
+ Platform.OS === "ios" ? inner : undefined,
20
+ // On Android - we are laid out by ShadowNode, so just stretch to full container
21
+ Platform.OS === "android" ? styles.stretch : undefined], [inner]);
22
22
  return /*#__PURE__*/React.createElement(RCTOverKeyboardView, {
23
23
  visible: visible
24
24
  }, /*#__PURE__*/React.createElement(View, {
25
25
  collapsable: false,
26
26
  style: style
27
- }, children));
27
+ }, visible && children));
28
28
  };
29
29
  const styles = StyleSheet.create({
30
30
  absolute: {
31
31
  position: "absolute"
32
+ },
33
+ stretch: {
34
+ top: 0,
35
+ bottom: 0,
36
+ left: 0,
37
+ right: 0
32
38
  }
33
39
  });
34
40
  export default OverKeyboardView;
@@ -1 +1 @@
1
- {"version":3,"names":["React","useMemo","Platform","StyleSheet","View","IS_FABRIC","RCTOverKeyboardView","useWindowDimensions","OverKeyboardView","children","visible","height","width","inner","style","styles","absolute","OS","undefined","createElement","collapsable","create","position"],"sources":["index.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { Platform, StyleSheet, View } from \"react-native\";\n\nimport { IS_FABRIC } from \"../../architecture\";\nimport { RCTOverKeyboardView } from \"../../bindings\";\nimport { useWindowDimensions } from \"../../hooks\";\n\nimport type { OverKeyboardViewProps } from \"../../types\";\nimport type { PropsWithChildren } from \"react\";\n\nconst OverKeyboardView = ({\n children,\n visible,\n}: PropsWithChildren<OverKeyboardViewProps>) => {\n const { height, width } = useWindowDimensions();\n const inner = useMemo(() => ({ height, width }), [height, width]);\n const style = useMemo(\n () => [\n styles.absolute,\n // On iOS - stretch view to full window dimensions to make yoga work\n // On Android Fabric we temporarily use the same approach\n Platform.OS === \"ios\" || IS_FABRIC ? inner : undefined,\n ],\n [inner],\n );\n\n return (\n <RCTOverKeyboardView visible={visible}>\n {/* `OverKeyboardView` should always have a single child */}\n <View collapsable={false} style={style}>\n {children}\n </View>\n </RCTOverKeyboardView>\n );\n};\n\nconst styles = StyleSheet.create({\n absolute: {\n position: \"absolute\",\n },\n});\n\nexport default OverKeyboardView;\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,OAAO,QAAQ,OAAO;AACtC,SAASC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAEzD,SAASC,SAAS,QAAQ,oBAAoB;AAC9C,SAASC,mBAAmB,QAAQ,gBAAgB;AACpD,SAASC,mBAAmB,QAAQ,aAAa;AAKjD,MAAMC,gBAAgB,GAAGA,CAAC;EACxBC,QAAQ;EACRC;AACwC,CAAC,KAAK;EAC9C,MAAM;IAAEC,MAAM;IAAEC;EAAM,CAAC,GAAGL,mBAAmB,CAAC,CAAC;EAC/C,MAAMM,KAAK,GAAGZ,OAAO,CAAC,OAAO;IAAEU,MAAM;IAAEC;EAAM,CAAC,CAAC,EAAE,CAACD,MAAM,EAAEC,KAAK,CAAC,CAAC;EACjE,MAAME,KAAK,GAAGb,OAAO,CACnB,MAAM,CACJc,MAAM,CAACC,QAAQ;EACf;EACA;EACAd,QAAQ,CAACe,EAAE,KAAK,KAAK,IAAIZ,SAAS,GAAGQ,KAAK,GAAGK,SAAS,CACvD,EACD,CAACL,KAAK,CACR,CAAC;EAED,oBACEb,KAAA,CAAAmB,aAAA,CAACb,mBAAmB;IAACI,OAAO,EAAEA;EAAQ,gBAEpCV,KAAA,CAAAmB,aAAA,CAACf,IAAI;IAACgB,WAAW,EAAE,KAAM;IAACN,KAAK,EAAEA;EAAM,GACpCL,QACG,CACa,CAAC;AAE1B,CAAC;AAED,MAAMM,MAAM,GAAGZ,UAAU,CAACkB,MAAM,CAAC;EAC/BL,QAAQ,EAAE;IACRM,QAAQ,EAAE;EACZ;AACF,CAAC,CAAC;AAEF,eAAed,gBAAgB","ignoreList":[]}
1
+ {"version":3,"names":["React","useMemo","Platform","StyleSheet","View","RCTOverKeyboardView","useWindowDimensions","OverKeyboardView","children","visible","height","width","inner","style","styles","absolute","OS","undefined","stretch","createElement","collapsable","create","position","top","bottom","left","right"],"sources":["index.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { Platform, StyleSheet, View } from \"react-native\";\n\nimport { RCTOverKeyboardView } from \"../../bindings\";\nimport { useWindowDimensions } from \"../../hooks\";\n\nimport type { OverKeyboardViewProps } from \"../../types\";\nimport type { PropsWithChildren } from \"react\";\n\nconst OverKeyboardView = ({\n children,\n visible,\n}: PropsWithChildren<OverKeyboardViewProps>) => {\n const { height, width } = useWindowDimensions();\n const inner = useMemo(() => ({ height, width }), [height, width]);\n const style = useMemo(\n () => [\n styles.absolute,\n // On iOS - stretch view to full window dimensions to make yoga work\n Platform.OS === \"ios\" ? inner : undefined,\n // On Android - we are laid out by ShadowNode, so just stretch to full container\n Platform.OS === \"android\" ? styles.stretch : undefined,\n ],\n [inner],\n );\n\n return (\n <RCTOverKeyboardView visible={visible}>\n {/* `OverKeyboardView` should always have a single child */}\n <View collapsable={false} style={style}>\n {/* Match RN behavior and trigger mount/unmount when visibility changes */}\n {visible && children}\n </View>\n </RCTOverKeyboardView>\n );\n};\n\nconst styles = StyleSheet.create({\n absolute: {\n position: \"absolute\",\n },\n stretch: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n});\n\nexport default OverKeyboardView;\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,OAAO,QAAQ,OAAO;AACtC,SAASC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAEzD,SAASC,mBAAmB,QAAQ,gBAAgB;AACpD,SAASC,mBAAmB,QAAQ,aAAa;AAKjD,MAAMC,gBAAgB,GAAGA,CAAC;EACxBC,QAAQ;EACRC;AACwC,CAAC,KAAK;EAC9C,MAAM;IAAEC,MAAM;IAAEC;EAAM,CAAC,GAAGL,mBAAmB,CAAC,CAAC;EAC/C,MAAMM,KAAK,GAAGX,OAAO,CAAC,OAAO;IAAES,MAAM;IAAEC;EAAM,CAAC,CAAC,EAAE,CAACD,MAAM,EAAEC,KAAK,CAAC,CAAC;EACjE,MAAME,KAAK,GAAGZ,OAAO,CACnB,MAAM,CACJa,MAAM,CAACC,QAAQ;EACf;EACAb,QAAQ,CAACc,EAAE,KAAK,KAAK,GAAGJ,KAAK,GAAGK,SAAS;EACzC;EACAf,QAAQ,CAACc,EAAE,KAAK,SAAS,GAAGF,MAAM,CAACI,OAAO,GAAGD,SAAS,CACvD,EACD,CAACL,KAAK,CACR,CAAC;EAED,oBACEZ,KAAA,CAAAmB,aAAA,CAACd,mBAAmB;IAACI,OAAO,EAAEA;EAAQ,gBAEpCT,KAAA,CAAAmB,aAAA,CAACf,IAAI;IAACgB,WAAW,EAAE,KAAM;IAACP,KAAK,EAAEA;EAAM,GAEpCJ,OAAO,IAAID,QACR,CACa,CAAC;AAE1B,CAAC;AAED,MAAMM,MAAM,GAAGX,UAAU,CAACkB,MAAM,CAAC;EAC/BN,QAAQ,EAAE;IACRO,QAAQ,EAAE;EACZ,CAAC;EACDJ,OAAO,EAAE;IACPK,GAAG,EAAE,CAAC;IACNC,MAAM,EAAE,CAAC;IACTC,IAAI,EAAE,CAAC;IACPC,KAAK,EAAE;EACT;AACF,CAAC,CAAC;AAEF,eAAenB,gBAAgB","ignoreList":[]}
@@ -15,3 +15,4 @@ export declare function useReanimatedFocusedInput(): {
15
15
  };
16
16
  export declare function useFocusedInputHandler(handler: FocusedInputHandler, deps?: DependencyList): void;
17
17
  export * from "./useWindowDimensions";
18
+ export * from "./useKeyboardState";
@@ -0,0 +1,2 @@
1
+ import type { KeyboardState } from "../../types";
2
+ export declare const useKeyboardState: () => KeyboardState;
@@ -1,4 +1,5 @@
1
- import { Animated, findNodeHandle } from "react-native";
1
+ import { Animated } from "react-native";
2
+ import { findNodeHandle } from "./utils/findNodeHandle";
2
3
  type EventHandler = (event: never) => void;
3
4
  type ComponentOrHandle = Parameters<typeof findNodeHandle>[0];
4
5
  export declare function useEventHandlerRegistration<H extends Partial<Record<string, EventHandler>>>(map: Map<keyof H, string>, viewTagRef: React.MutableRefObject<ComponentOrHandle>): (handler: H) => () => void;
@@ -92,7 +92,7 @@ export type KeyboardControllerModule = {
92
92
  dismiss: (options?: DismissOptions) => Promise<void>;
93
93
  setFocusTo: (direction: Direction) => void;
94
94
  isVisible: () => boolean;
95
- state: () => KeyboardEventData | null;
95
+ state: () => KeyboardEventData;
96
96
  };
97
97
  export type KeyboardControllerNativeModule = {
98
98
  setDefaultMode: () => void;
@@ -111,6 +111,9 @@ export type KeyboardEventData = {
111
111
  type: NonNullable<TextInputProps["keyboardType"]>;
112
112
  appearance: NonNullable<TextInputProps["keyboardAppearance"]>;
113
113
  };
114
+ export type KeyboardState = {
115
+ isVisible: boolean;
116
+ } & KeyboardEventData;
114
117
  export type KeyboardEventsModule = {
115
118
  addListener: (name: KeyboardControllerEvents, cb: (e: KeyboardEventData) => void) => EmitterSubscription;
116
119
  };
@@ -0,0 +1,4 @@
1
+ import type { findNodeHandle as findNodeHandleRN } from "react-native";
2
+ type FindNodeHandleRN = typeof findNodeHandleRN;
3
+ export declare const findNodeHandle: FindNodeHandleRN;
4
+ export {};
@@ -0,0 +1,2 @@
1
+ import { findNodeHandle } from "react-native";
2
+ export { findNodeHandle };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-keyboard-controller",
3
- "version": "1.16.8",
3
+ "version": "1.17.1",
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",
@@ -12,10 +12,13 @@
12
12
  "lib",
13
13
  "android",
14
14
  "ios",
15
+ "common",
15
16
  "cpp",
16
17
  "react-native-keyboard-controller.podspec",
18
+ "react-native.config.js",
17
19
  "jest",
18
20
  "!lib/typescript/example",
21
+ "!android/detekt.yml",
19
22
  "!android/build",
20
23
  "!android/src/test",
21
24
  "!android/.gradle",
@@ -58,4 +58,12 @@ Pod::Spec.new do |s|
58
58
  s.dependency "ReactCommon/turbomodule/core"
59
59
  end
60
60
  end
61
+ if new_arch_enabled
62
+ s.subspec "common" do |ss|
63
+ ss.source_files = ["common/cpp/**/*.{cpp,h}"]
64
+ ss.header_dir = "react/renderer/components/reactnativekeyboardcontroller"
65
+ ss.private_header_files = "common/cpp/**/*.{h}"
66
+ ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\"" }
67
+ end
68
+ end
61
69
  end
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ componentDescriptors: [
6
+ "KeyboardControllerViewComponentDescriptor",
7
+ "KeyboardGestureAreaComponentDescriptor",
8
+ "OverKeyboardViewComponentDescriptor",
9
+ ],
10
+ cmakeListsPath: "../android/src/main/jni/CMakeLists.txt",
11
+ },
12
+ },
13
+ },
14
+ };
@@ -106,14 +106,21 @@ const KeyboardAvoidingView = forwardRef<
106
106
  [relativeKeyboardHeight],
107
107
  );
108
108
 
109
- const onLayoutWorklet = useCallback((layout: LayoutRectangle) => {
110
- "worklet";
109
+ const onLayoutWorklet = useCallback(
110
+ (layout: LayoutRectangle) => {
111
+ "worklet";
111
112
 
112
- if (keyboard.isClosed.value || initialFrame.value === null) {
113
- // eslint-disable-next-line react-compiler/react-compiler
114
- initialFrame.value = layout;
115
- }
116
- }, []);
113
+ if (
114
+ keyboard.isClosed.value ||
115
+ initialFrame.value === null ||
116
+ behavior !== "height"
117
+ ) {
118
+ // eslint-disable-next-line react-compiler/react-compiler
119
+ initialFrame.value = layout;
120
+ }
121
+ },
122
+ [behavior],
123
+ );
117
124
  const onLayout = useCallback<NonNullable<ViewProps["onLayout"]>>(
118
125
  (e) => {
119
126
  runOnUI(onLayoutWorklet)(e.nativeEvent.layout);
@@ -1,5 +1,4 @@
1
1
  import React, { forwardRef, useCallback, useMemo } from "react";
2
- import { findNodeHandle } from "react-native";
3
2
  import Reanimated, {
4
3
  interpolate,
5
4
  scrollTo,
@@ -15,6 +14,7 @@ import {
15
14
  useReanimatedFocusedInput,
16
15
  useWindowDimensions,
17
16
  } from "../../hooks";
17
+ import { findNodeHandle } from "../../utils/findNodeHandle";
18
18
 
19
19
  import { useSmoothKeyboardHandler } from "./useSmoothKeyboardHandler";
20
20
  import { debounce, scrollDistanceWithRespectToSnapPoints } from "./utils";
@@ -383,7 +383,7 @@ const KeyboardAwareScrollView = forwardRef<
383
383
  onLayout={onScrollViewLayout}
384
384
  >
385
385
  {children}
386
- <Reanimated.View style={view} />
386
+ {enabled && <Reanimated.View style={view} />}
387
387
  </ScrollViewComponent>
388
388
  );
389
389
  },
@@ -1,10 +1,7 @@
1
1
  import React, { forwardRef, useMemo } from "react";
2
- import Reanimated, {
3
- interpolate,
4
- useAnimatedStyle,
5
- } from "react-native-reanimated";
2
+ import { Animated } from "react-native";
6
3
 
7
- import { useReanimatedKeyboardAnimation } from "../../hooks";
4
+ import { useKeyboardAnimation } from "../../hooks";
8
5
 
9
6
  import type { View, ViewProps } from "react-native";
10
7
 
@@ -41,25 +38,29 @@ const KeyboardStickyView = forwardRef<
41
38
  },
42
39
  ref,
43
40
  ) => {
44
- const { height, progress } = useReanimatedKeyboardAnimation();
41
+ const { height, progress } = useKeyboardAnimation();
45
42
 
46
- const stickyViewStyle = useAnimatedStyle(() => {
47
- const offset = interpolate(progress.value, [0, 1], [closed, opened]);
48
-
49
- return {
50
- transform: [{ translateY: enabled ? height.value + offset : closed }],
51
- };
52
- }, [closed, opened, enabled]);
43
+ const offset = progress.interpolate({
44
+ inputRange: [0, 1],
45
+ outputRange: [closed, opened],
46
+ });
53
47
 
54
48
  const styles = useMemo(
55
- () => [style, stickyViewStyle],
56
- [style, stickyViewStyle],
49
+ () => [
50
+ {
51
+ transform: [
52
+ { translateY: enabled ? Animated.add(height, offset) : closed },
53
+ ],
54
+ },
55
+ style,
56
+ ],
57
+ [closed, enabled, height, offset, style],
57
58
  );
58
59
 
59
60
  return (
60
- <Reanimated.View ref={ref} style={styles} {...props}>
61
+ <Animated.View ref={ref} style={styles} {...props}>
61
62
  {children}
62
- </Reanimated.View>
63
+ </Animated.View>
63
64
  );
64
65
  },
65
66
  );
@@ -79,3 +79,4 @@ export function useFocusedInputHandler(
79
79
  }
80
80
 
81
81
  export * from "./useWindowDimensions";
82
+ export * from "./useKeyboardState";
@@ -0,0 +1,38 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ import { KeyboardEvents } from "../../bindings";
4
+ import { KeyboardController } from "../../module";
5
+
6
+ import type { KeyboardState } from "../../types";
7
+
8
+ const EVENTS = ["keyboardDidShow", "keyboardDidHide"] as const;
9
+
10
+ const getLatestState = () => ({
11
+ ...KeyboardController.state(),
12
+ isVisible: KeyboardController.isVisible(),
13
+ });
14
+
15
+ export const useKeyboardState = (): KeyboardState => {
16
+ const [state, setState] = useState(getLatestState);
17
+
18
+ useEffect(() => {
19
+ const subscriptions = EVENTS.map((event) =>
20
+ KeyboardEvents.addListener(event, () =>
21
+ // state will be updated by global listener first,
22
+ // so we simply read it and don't derive data from the event
23
+ setState(getLatestState),
24
+ ),
25
+ );
26
+
27
+ // we might have missed an update between reading a value in render and
28
+ // `addListener` in this handler, so we set it here. If there was
29
+ // no change, React will filter out this update as a no-op.
30
+ setState(getLatestState);
31
+
32
+ return () => {
33
+ subscriptions.forEach((subscription) => subscription.remove());
34
+ };
35
+ }, []);
36
+
37
+ return state;
38
+ };
package/src/internal.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { useRef } from "react";
2
- import { Animated, findNodeHandle } from "react-native";
2
+ import { Animated } from "react-native";
3
3
 
4
4
  import { registerEventHandler, unregisterEventHandler } from "./event-handler";
5
+ import { findNodeHandle } from "./utils/findNodeHandle";
5
6
 
6
7
  type EventHandler = (event: never) => void;
7
8
  type ComponentOrHandle = Parameters<typeof findNodeHandle>[0];
package/src/module.ts CHANGED
@@ -7,16 +7,23 @@ import type {
7
7
  } from "./types";
8
8
 
9
9
  let isClosed = true;
10
- let lastEvent: KeyboardEventData | null = null;
10
+ let lastState: KeyboardEventData = {
11
+ height: 0,
12
+ duration: 0,
13
+ timestamp: new Date().getTime(),
14
+ target: -1,
15
+ type: "default",
16
+ appearance: "default",
17
+ };
11
18
 
12
19
  KeyboardEvents.addListener("keyboardDidHide", (e) => {
13
20
  isClosed = true;
14
- lastEvent = e;
21
+ lastState = e;
15
22
  });
16
23
 
17
24
  KeyboardEvents.addListener("keyboardDidShow", (e) => {
18
25
  isClosed = false;
19
- lastEvent = e;
26
+ lastState = e;
20
27
  });
21
28
 
22
29
  const dismiss = async (options?: DismissOptions): Promise<void> => {
@@ -38,7 +45,7 @@ const dismiss = async (options?: DismissOptions): Promise<void> => {
38
45
  });
39
46
  };
40
47
  const isVisible = () => !isClosed;
41
- const state = () => lastEvent;
48
+ const state = () => lastState;
42
49
 
43
50
  export const KeyboardController: KeyboardControllerModule = {
44
51
  setDefaultMode: KeyboardControllerNative.setDefaultMode,
@@ -66,6 +66,6 @@ export interface NativeProps extends ViewProps {
66
66
  onFocusedInputSelectionChanged?: DirectEventHandler<FocusedInputSelectionChangedEvent>;
67
67
  }
68
68
 
69
- export default codegenNativeComponent<NativeProps>(
70
- "KeyboardControllerView",
71
- ) as HostComponent<NativeProps>;
69
+ export default codegenNativeComponent<NativeProps>("KeyboardControllerView", {
70
+ interfaceOnly: true,
71
+ }) as HostComponent<NativeProps>;
@@ -15,6 +15,6 @@ export interface NativeProps extends ViewProps {
15
15
  textInputNativeID?: string;
16
16
  }
17
17
 
18
- export default codegenNativeComponent<NativeProps>(
19
- "KeyboardGestureArea",
20
- ) as HostComponent<NativeProps>;
18
+ export default codegenNativeComponent<NativeProps>("KeyboardGestureArea", {
19
+ interfaceOnly: true,
20
+ }) as HostComponent<NativeProps>;
@@ -7,6 +7,6 @@ export interface NativeProps extends ViewProps {
7
7
  visible?: boolean;
8
8
  }
9
9
 
10
- export default codegenNativeComponent<NativeProps>(
11
- "OverKeyboardView",
12
- ) as HostComponent<NativeProps>;
10
+ export default codegenNativeComponent<NativeProps>("OverKeyboardView", {
11
+ interfaceOnly: true,
12
+ }) as HostComponent<NativeProps>;
package/src/types.ts CHANGED
@@ -131,7 +131,7 @@ export type KeyboardControllerModule = {
131
131
  dismiss: (options?: DismissOptions) => Promise<void>;
132
132
  setFocusTo: (direction: Direction) => void;
133
133
  isVisible: () => boolean;
134
- state: () => KeyboardEventData | null;
134
+ state: () => KeyboardEventData;
135
135
  };
136
136
  export type KeyboardControllerNativeModule = {
137
137
  // android only
@@ -159,6 +159,9 @@ export type KeyboardEventData = {
159
159
  type: NonNullable<TextInputProps["keyboardType"]>;
160
160
  appearance: NonNullable<TextInputProps["keyboardAppearance"]>;
161
161
  };
162
+ export type KeyboardState = {
163
+ isVisible: boolean;
164
+ } & KeyboardEventData;
162
165
  export type KeyboardEventsModule = {
163
166
  addListener: (
164
167
  name: KeyboardControllerEvents,
@@ -0,0 +1,3 @@
1
+ import { findNodeHandle } from "react-native";
2
+
3
+ export { findNodeHandle };
@@ -0,0 +1,6 @@
1
+ import type { findNodeHandle as findNodeHandleRN } from "react-native";
2
+
3
+ type FindNodeHandleRN = typeof findNodeHandleRN;
4
+
5
+ export const findNodeHandle: FindNodeHandleRN = (componentOrHandle) =>
6
+ componentOrHandle as number | null;
@@ -1,7 +1,6 @@
1
1
  import React, { useMemo } from "react";
2
2
  import { Platform, StyleSheet, View } from "react-native";
3
3
 
4
- import { IS_FABRIC } from "../../architecture";
5
4
  import { RCTOverKeyboardView } from "../../bindings";
6
5
  import { useWindowDimensions } from "../../hooks";
7
6
 
@@ -18,8 +17,9 @@ const OverKeyboardView = ({
18
17
  () => [
19
18
  styles.absolute,
20
19
  // On iOS - stretch view to full window dimensions to make yoga work
21
- // On Android Fabric we temporarily use the same approach
22
- Platform.OS === "ios" || IS_FABRIC ? inner : undefined,
20
+ Platform.OS === "ios" ? inner : undefined,
21
+ // On Android - we are laid out by ShadowNode, so just stretch to full container
22
+ Platform.OS === "android" ? styles.stretch : undefined,
23
23
  ],
24
24
  [inner],
25
25
  );
@@ -28,7 +28,8 @@ const OverKeyboardView = ({
28
28
  <RCTOverKeyboardView visible={visible}>
29
29
  {/* `OverKeyboardView` should always have a single child */}
30
30
  <View collapsable={false} style={style}>
31
- {children}
31
+ {/* Match RN behavior and trigger mount/unmount when visibility changes */}
32
+ {visible && children}
32
33
  </View>
33
34
  </RCTOverKeyboardView>
34
35
  );
@@ -38,6 +39,12 @@ const styles = StyleSheet.create({
38
39
  absolute: {
39
40
  position: "absolute",
40
41
  },
42
+ stretch: {
43
+ top: 0,
44
+ bottom: 0,
45
+ left: 0,
46
+ right: 0,
47
+ },
41
48
  });
42
49
 
43
50
  export default OverKeyboardView;
@@ -1,8 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.IS_FABRIC = void 0;
7
- const IS_FABRIC = exports.IS_FABRIC = "nativeFabricUIManager" in global;
8
- //# sourceMappingURL=architecture.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["IS_FABRIC","exports","global"],"sources":["architecture.ts"],"sourcesContent":["export const IS_FABRIC = \"nativeFabricUIManager\" in global;\n"],"mappings":";;;;;;AAAO,MAAMA,SAAS,GAAAC,OAAA,CAAAD,SAAA,GAAG,uBAAuB,IAAIE,MAAM","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- export const IS_FABRIC = "nativeFabricUIManager" in global;
2
- //# sourceMappingURL=architecture.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["IS_FABRIC","global"],"sources":["architecture.ts"],"sourcesContent":["export const IS_FABRIC = \"nativeFabricUIManager\" in global;\n"],"mappings":"AAAA,OAAO,MAAMA,SAAS,GAAG,uBAAuB,IAAIC,MAAM","ignoreList":[]}
@@ -1 +0,0 @@
1
- export declare const IS_FABRIC: boolean;
@@ -1 +0,0 @@
1
- export const IS_FABRIC = "nativeFabricUIManager" in global;