@react-native-ohos/react-native-keyboard-controller 1.16.8 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.OpenSource +2 -2
- package/README.md +105 -29
- package/harmony/keyboard_controller/BuildProfile.ets +1 -1
- package/harmony/keyboard_controller/Index.ets +1 -0
- package/harmony/keyboard_controller/oh-package-lock.json5 +7 -7
- package/harmony/keyboard_controller/oh-package.json5 +1 -1
- package/harmony/keyboard_controller/src/main/cpp/ClippingScrollViewComponentDescriptor.h +86 -0
- package/harmony/keyboard_controller/src/main/cpp/ClippingScrollViewComponentInstance.cpp +104 -0
- package/harmony/keyboard_controller/src/main/cpp/ClippingScrollViewComponentInstance.h +64 -0
- package/harmony/keyboard_controller/src/main/cpp/ClippingScrollViewJSIBinder.h +60 -0
- package/harmony/keyboard_controller/src/main/cpp/KeyboardControllerViewComponentInstance.cpp +8 -1
- package/harmony/keyboard_controller/src/main/cpp/KeyboardGestureAreaComponentInstance.cpp +2 -2
- package/harmony/keyboard_controller/src/main/cpp/KeyboardToolbarGroupViewComponentDescriptor.h +46 -0
- package/harmony/keyboard_controller/src/main/cpp/KeyboardToolbarGroupViewComponentInstance.cpp +37 -0
- package/harmony/keyboard_controller/src/main/cpp/KeyboardToolbarGroupViewComponentInstance.h +32 -0
- package/harmony/keyboard_controller/src/main/cpp/KeyboardToolbarGroupViewJSIBinder.h +23 -0
- package/harmony/keyboard_controller/src/main/cpp/RNKeyboardController.cpp +58 -1
- package/harmony/keyboard_controller/src/main/cpp/RNKeyboardControllerPackage.h +20 -0
- package/harmony/keyboard_controller/src/main/cpp/ViewHierarchyNavigator.cpp +65 -44
- package/harmony/keyboard_controller/src/main/cpp/ViewHierarchyNavigator.h +22 -3
- package/harmony/keyboard_controller/src/main/cpp/keyboardControllerPackage.cpp +17 -4
- package/harmony/keyboard_controller/src/main/cpp/keyboardControllerPackage.h +9 -1
- package/harmony/keyboard_controller/src/main/ets/{RNKeyboardControllerPackage.ts → RNKeyboardControllerPackage.ets} +9 -5
- package/harmony/keyboard_controller/src/main/ets/RNKeyboardControllerTurboModule.ts +29 -5
- package/harmony/keyboard_controller/src/main/ets/Type.ts +2 -1
- package/harmony/keyboard_controller.har +0 -0
- package/lib/commonjs/animated.js +20 -9
- package/lib/commonjs/animated.js.map +1 -1
- package/lib/commonjs/architecture.js +8 -0
- package/lib/commonjs/architecture.js.map +1 -0
- package/lib/commonjs/bindings.js +37 -2
- package/lib/commonjs/bindings.js.map +1 -1
- package/lib/commonjs/bindings.native.js +25 -2
- package/lib/commonjs/bindings.native.js.map +1 -1
- package/lib/commonjs/compat.js +50 -0
- package/lib/commonjs/compat.js.map +1 -0
- package/lib/commonjs/components/KeyboardAvoidingView/hooks.js +21 -15
- package/lib/commonjs/components/KeyboardAvoidingView/hooks.js.map +1 -1
- package/lib/commonjs/components/KeyboardAvoidingView/index.js +36 -11
- package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js +51 -16
- package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +2 -2
- package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
- package/lib/commonjs/components/KeyboardChatScrollView/hooks.js +13 -0
- package/lib/commonjs/components/KeyboardChatScrollView/hooks.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/index.js +122 -0
- package/lib/commonjs/components/KeyboardChatScrollView/index.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/types.js +6 -0
- package/lib/commonjs/components/KeyboardChatScrollView/types.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +221 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +149 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js +240 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/types.js +6 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useEndVisible.js +40 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useEndVisible.js.map +1 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js +92 -0
- package/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/Arrow.js +2 -3
- package/lib/commonjs/components/KeyboardToolbar/Arrow.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/Button.js +2 -3
- package/lib/commonjs/components/KeyboardToolbar/Button.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Background.js +13 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Background.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Content.js +25 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Content.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Done.js +58 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Done.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Next.js +49 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Next.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Prev.js +49 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/Prev.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/index.js +42 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/index.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/types.js +6 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/components/types.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/context.js +17 -0
- package/lib/commonjs/components/KeyboardToolbar/compound/context.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/constants.js +17 -0
- package/lib/commonjs/components/KeyboardToolbar/constants.js.map +1 -0
- package/lib/commonjs/components/KeyboardToolbar/index.js +95 -84
- package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/types.js.map +1 -1
- package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js +120 -0
- package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js.map +1 -0
- package/lib/commonjs/components/ScrollViewWithBottomPadding/styles.js +15 -0
- package/lib/commonjs/components/ScrollViewWithBottomPadding/styles.js.map +1 -0
- package/lib/commonjs/components/hooks/useColorScheme.js +1 -1
- package/lib/commonjs/components/hooks/useColorScheme.js.map +1 -1
- package/lib/commonjs/components/hooks/useCombinedRef.js +24 -0
- package/lib/commonjs/components/hooks/useCombinedRef.js.map +1 -0
- package/lib/commonjs/components/hooks/useScrollState.js +62 -0
- package/lib/commonjs/components/hooks/useScrollState.js.map +1 -0
- package/lib/commonjs/components/index.js +7 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/constants.js +3 -1
- package/lib/commonjs/constants.js.map +1 -1
- package/lib/commonjs/context.js +1 -0
- package/lib/commonjs/context.js.map +1 -1
- package/lib/commonjs/hooks/index.js +14 -1
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useKeyboardState/index.js +39 -0
- package/lib/commonjs/hooks/useKeyboardState/index.js.map +1 -0
- package/lib/commonjs/index.js +27 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal.js +36 -0
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/commonjs/module.js +21 -12
- package/lib/commonjs/module.js.map +1 -1
- package/lib/commonjs/specs/ClippingScrollViewDecoratorViewNativeComponent.js +12 -0
- package/lib/commonjs/specs/ClippingScrollViewDecoratorViewNativeComponent.js.map +1 -0
- package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js +8 -2
- package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js +2 -1
- package/lib/commonjs/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/KeyboardToolbarGroupViewNativeComponent.js +12 -0
- package/lib/commonjs/specs/KeyboardToolbarGroupViewNativeComponent.js.map +1 -0
- package/lib/commonjs/specs/NativeKeyboardController.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/findNodeHandle/index.js +9 -0
- package/lib/commonjs/utils/findNodeHandle/index.js.map +1 -0
- package/lib/commonjs/utils/findNodeHandle/index.native.js +13 -0
- package/lib/commonjs/utils/findNodeHandle/index.native.js.map +1 -0
- package/lib/commonjs/views/KeyboardExtender/index.js +30 -0
- package/lib/commonjs/views/KeyboardExtender/index.js.map +1 -0
- package/lib/commonjs/views/index.js +7 -0
- package/lib/commonjs/views/index.js.map +1 -1
- package/lib/module/animated.js +22 -11
- package/lib/module/animated.js.map +1 -1
- package/lib/module/architecture.js +2 -0
- package/lib/module/architecture.js.map +1 -0
- package/lib/module/bindings.js +36 -2
- package/lib/module/bindings.js.map +1 -1
- package/lib/module/bindings.native.js +24 -2
- package/lib/module/bindings.native.js.map +1 -1
- package/lib/module/compat.js +43 -0
- package/lib/module/compat.js.map +1 -0
- package/lib/module/components/KeyboardAvoidingView/hooks.js +22 -16
- package/lib/module/components/KeyboardAvoidingView/hooks.js.map +1 -1
- package/lib/module/components/KeyboardAvoidingView/index.js +35 -11
- package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/index.js +54 -19
- package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
- package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +2 -2
- package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
- package/lib/module/components/KeyboardChatScrollView/hooks.js +2 -0
- package/lib/module/components/KeyboardChatScrollView/hooks.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/index.js +115 -0
- package/lib/module/components/KeyboardChatScrollView/index.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/types.js +2 -0
- package/lib/module/components/KeyboardChatScrollView/types.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +207 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +143 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js +234 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/types.js +2 -0
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/useEndVisible.js +33 -0
- package/lib/module/components/KeyboardChatScrollView/useEndVisible.js.map +1 -0
- package/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js +87 -0
- package/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/Arrow.js +2 -2
- package/lib/module/components/KeyboardToolbar/Arrow.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/Button.js +2 -2
- package/lib/module/components/KeyboardToolbar/Button.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/compound/components/Background.js +6 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Background.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Content.js +18 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Content.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Done.js +50 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Done.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Next.js +41 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Next.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Prev.js +41 -0
- package/lib/module/components/KeyboardToolbar/compound/components/Prev.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/compound/components/index.js +6 -0
- package/lib/module/components/KeyboardToolbar/compound/components/index.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/compound/components/types.js +2 -0
- package/lib/module/components/KeyboardToolbar/compound/components/types.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/compound/context.js +10 -0
- package/lib/module/components/KeyboardToolbar/compound/context.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/constants.js +11 -0
- package/lib/module/components/KeyboardToolbar/constants.js.map +1 -0
- package/lib/module/components/KeyboardToolbar/index.js +95 -85
- package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/types.js.map +1 -1
- package/lib/module/components/ScrollViewWithBottomPadding/index.js +112 -0
- package/lib/module/components/ScrollViewWithBottomPadding/index.js.map +1 -0
- package/lib/module/components/ScrollViewWithBottomPadding/styles.js +9 -0
- package/lib/module/components/ScrollViewWithBottomPadding/styles.js.map +1 -0
- package/lib/module/components/hooks/useColorScheme.js +1 -1
- package/lib/module/components/hooks/useColorScheme.js.map +1 -1
- package/lib/module/components/hooks/useCombinedRef.js +18 -0
- package/lib/module/components/hooks/useCombinedRef.js.map +1 -0
- package/lib/module/components/hooks/useScrollState.js +56 -0
- package/lib/module/components/hooks/useScrollState.js.map +1 -0
- package/lib/module/components/index.js +1 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/constants.js +3 -0
- package/lib/module/constants.js.map +1 -1
- package/lib/module/context.js +1 -0
- package/lib/module/context.js.map +1 -1
- package/lib/module/hooks/index.js +3 -1
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useKeyboardState/index.js +33 -0
- package/lib/module/hooks/useKeyboardState/index.js.map +1 -0
- package/lib/module/index.js +3 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal.js +35 -0
- package/lib/module/internal.js.map +1 -1
- package/lib/module/module.js +21 -12
- package/lib/module/module.js.map +1 -1
- package/lib/module/specs/ClippingScrollViewDecoratorViewNativeComponent.js +6 -0
- package/lib/module/specs/ClippingScrollViewDecoratorViewNativeComponent.js.map +1 -0
- package/lib/module/specs/KeyboardControllerViewNativeComponent.js +7 -1
- package/lib/module/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
- package/lib/module/specs/KeyboardGestureAreaNativeComponent.js +2 -1
- package/lib/module/specs/KeyboardGestureAreaNativeComponent.js.map +1 -1
- package/lib/module/specs/KeyboardToolbarGroupViewNativeComponent.js +5 -0
- package/lib/module/specs/KeyboardToolbarGroupViewNativeComponent.js.map +1 -0
- package/lib/module/specs/NativeKeyboardController.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/findNodeHandle/index.js +2 -0
- package/lib/module/utils/findNodeHandle/index.js.map +1 -0
- package/lib/module/utils/findNodeHandle/index.native.js +3 -0
- package/lib/module/utils/findNodeHandle/index.native.js.map +1 -0
- package/lib/module/views/KeyboardExtender/index.js +23 -0
- package/lib/module/views/KeyboardExtender/index.js.map +1 -0
- package/lib/module/views/index.js +1 -0
- package/lib/module/views/index.js.map +1 -1
- package/lib/typescript/animated.d.ts +2 -38
- package/lib/typescript/architecture.d.ts +1 -0
- package/lib/typescript/bindings.d.ts +15 -1
- package/lib/typescript/bindings.native.d.ts +10 -1
- package/lib/typescript/compat.d.ts +12 -0
- package/lib/typescript/components/KeyboardAvoidingView/index.d.ts +5 -0
- package/lib/typescript/components/KeyboardAwareScrollView/index.d.ts +4 -1
- package/lib/typescript/components/KeyboardChatScrollView/hooks.d.ts +2 -0
- package/lib/typescript/components/KeyboardChatScrollView/index.d.ts +17 -0
- package/lib/typescript/components/KeyboardChatScrollView/types.d.ts +113 -0
- package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts +132 -0
- package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/index.d.ts +18 -0
- package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/index.ios.d.ts +21 -0
- package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts +37 -0
- package/lib/typescript/components/KeyboardChatScrollView/useEndVisible.d.ts +17 -0
- package/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts +45 -0
- package/lib/typescript/components/KeyboardToolbar/Button.d.ts +2 -2
- package/lib/typescript/components/KeyboardToolbar/compound/components/Background.d.ts +6 -0
- package/lib/typescript/components/KeyboardToolbar/compound/components/Content.d.ts +7 -0
- package/lib/typescript/components/KeyboardToolbar/compound/components/Done.d.ts +7 -0
- package/lib/typescript/components/KeyboardToolbar/compound/components/Next.d.ts +4 -0
- package/lib/typescript/components/KeyboardToolbar/compound/components/Prev.d.ts +4 -0
- package/lib/typescript/components/KeyboardToolbar/compound/components/index.d.ts +5 -0
- package/lib/typescript/components/KeyboardToolbar/compound/components/types.d.ts +14 -0
- package/lib/typescript/components/KeyboardToolbar/compound/context.d.ts +9 -0
- package/lib/typescript/components/KeyboardToolbar/constants.d.ts +10 -0
- package/lib/typescript/components/KeyboardToolbar/index.d.ts +12 -45
- package/lib/typescript/components/KeyboardToolbar/types.d.ts +24 -1
- package/lib/typescript/components/ScrollViewWithBottomPadding/index.d.ts +30 -0
- package/lib/typescript/components/ScrollViewWithBottomPadding/styles.d.ts +7 -0
- package/lib/typescript/components/hooks/useCombinedRef.d.ts +3 -0
- package/lib/typescript/components/hooks/useScrollState.d.ts +17 -0
- package/lib/typescript/components/index.d.ts +3 -0
- package/lib/typescript/constants.d.ts +1 -0
- package/lib/typescript/context.d.ts +1 -0
- package/lib/typescript/hooks/index.d.ts +2 -0
- package/lib/typescript/hooks/useKeyboardState/index.d.ts +4 -0
- package/lib/typescript/index.d.ts +4 -3
- package/lib/typescript/internal.d.ts +4 -0
- package/lib/typescript/specs/ClippingScrollViewDecoratorViewNativeComponent.d.ts +10 -0
- package/lib/typescript/specs/KeyboardControllerViewNativeComponent.d.ts +4 -0
- package/lib/typescript/specs/KeyboardToolbarGroupViewNativeComponent.d.ts +6 -0
- package/lib/typescript/specs/NativeKeyboardController.d.ts +6 -2
- package/lib/typescript/types.d.ts +80 -5
- package/lib/typescript/utils/findNodeHandle/index.d.ts +4 -0
- package/lib/typescript/utils/findNodeHandle/index.native.d.ts +2 -0
- package/lib/typescript/views/KeyboardExtender/index.d.ts +5 -0
- package/lib/typescript/views/index.d.ts +1 -0
- package/package.json +15 -9
- package/src/animated.tsx +41 -48
- package/src/architecture.ts +1 -0
- package/src/bindings.native.ts +37 -2
- package/src/bindings.ts +40 -1
- package/src/compat.ts +44 -0
- package/src/components/KeyboardAvoidingView/hooks.ts +24 -17
- package/src/components/KeyboardAvoidingView/index.tsx +62 -18
- package/src/components/KeyboardAwareScrollView/index.tsx +75 -20
- package/src/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.ts +2 -2
- package/src/components/KeyboardChatScrollView/hooks.ts +2 -0
- package/src/components/KeyboardChatScrollView/index.tsx +164 -0
- package/src/components/KeyboardChatScrollView/types.ts +117 -0
- package/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts +268 -0
- package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts +260 -0
- package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ts +374 -0
- package/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts +39 -0
- package/src/components/KeyboardChatScrollView/useEndVisible.ts +66 -0
- package/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts +149 -0
- package/src/components/KeyboardToolbar/Arrow.tsx +2 -2
- package/src/components/KeyboardToolbar/Button.tsx +4 -4
- package/src/components/KeyboardToolbar/compound/components/Background.tsx +9 -0
- package/src/components/KeyboardToolbar/compound/components/Content.tsx +25 -0
- package/src/components/KeyboardToolbar/compound/components/Done.tsx +57 -0
- package/src/components/KeyboardToolbar/compound/components/Next.tsx +49 -0
- package/src/components/KeyboardToolbar/compound/components/Prev.tsx +49 -0
- package/src/components/KeyboardToolbar/compound/components/index.ts +5 -0
- package/src/components/KeyboardToolbar/compound/components/types.ts +15 -0
- package/src/components/KeyboardToolbar/compound/context.ts +25 -0
- package/src/components/KeyboardToolbar/constants.ts +14 -0
- package/src/components/KeyboardToolbar/index.tsx +143 -146
- package/src/components/KeyboardToolbar/types.ts +33 -1
- package/src/components/ScrollViewWithBottomPadding/index.tsx +216 -0
- package/src/components/ScrollViewWithBottomPadding/styles.ts +10 -0
- package/src/components/hooks/useColorScheme.ts +2 -1
- package/src/components/hooks/useCombinedRef.ts +22 -0
- package/src/components/hooks/useScrollState.ts +81 -0
- package/src/components/index.ts +3 -0
- package/src/constants.ts +4 -0
- package/src/context.ts +2 -0
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useKeyboardState/index.ts +52 -0
- package/src/index.ts +5 -1
- package/src/internal.ts +62 -0
- package/src/module.ts +21 -9
- package/src/specs/ClippingScrollViewDecoratorViewNativeComponent.ts +19 -0
- package/src/specs/KeyboardControllerViewNativeComponent.ts +14 -3
- package/src/specs/KeyboardGestureAreaNativeComponent.ts +1 -0
- package/src/specs/KeyboardToolbarGroupViewNativeComponent.ts +10 -0
- package/src/specs/NativeKeyboardController.ts +6 -2
- package/src/types.ts +91 -5
- package/src/utils/findNodeHandle/index.native.ts +3 -0
- package/src/utils/findNodeHandle/index.ts +6 -0
- package/src/views/KeyboardExtender/index.tsx +30 -0
- package/src/views/index.ts +1 -0
- package/lib/commonjs/monkey-patch.android.js +0 -57
- package/lib/commonjs/monkey-patch.android.js.map +0 -1
- package/lib/commonjs/monkey-patch.js +0 -11
- package/lib/commonjs/monkey-patch.js.map +0 -1
- package/lib/module/monkey-patch.android.js +0 -47
- package/lib/module/monkey-patch.android.js.map +0 -1
- package/lib/module/monkey-patch.js +0 -5
- package/lib/module/monkey-patch.js.map +0 -1
- package/lib/typescript/monkey-patch.android.d.ts +0 -2
- package/lib/typescript/monkey-patch.d.ts +0 -2
- package/src/monkey-patch.android.ts +0 -44
- package/src/monkey-patch.ts +0 -4
- /package/harmony/keyboard_controller/{ts.ts → ts.ets} +0 -0
|
@@ -8,7 +8,10 @@ import Reanimated, {
|
|
|
8
8
|
useSharedValue,
|
|
9
9
|
} from "react-native-reanimated";
|
|
10
10
|
|
|
11
|
+
import { KeyboardControllerNative } from "../../bindings";
|
|
11
12
|
import { useWindowDimensions } from "../../hooks";
|
|
13
|
+
import { findNodeHandle } from "../../utils/findNodeHandle";
|
|
14
|
+
import useCombinedRef from "../hooks/useCombinedRef";
|
|
12
15
|
|
|
13
16
|
import { useKeyboardAnimation, useTranslateAnimation } from "./hooks";
|
|
14
17
|
|
|
@@ -26,6 +29,12 @@ export type KeyboardAvoidingViewBaseProps = {
|
|
|
26
29
|
* may be non-zero in some cases. Defaults to 0.
|
|
27
30
|
*/
|
|
28
31
|
keyboardVerticalOffset?: number;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* When true, detect the view position in the window automatically.
|
|
35
|
+
* keyboardVerticalOffset remains an additive offset.
|
|
36
|
+
*/
|
|
37
|
+
automaticOffset?: boolean;
|
|
29
38
|
} & ViewProps;
|
|
30
39
|
|
|
31
40
|
export type KeyboardAvoidingViewProps = KeyboardAvoidingViewBaseProps &
|
|
@@ -76,6 +85,7 @@ const KeyboardAvoidingView = forwardRef<
|
|
|
76
85
|
contentContainerStyle,
|
|
77
86
|
enabled = true,
|
|
78
87
|
keyboardVerticalOffset = 0,
|
|
88
|
+
automaticOffset = false,
|
|
79
89
|
style,
|
|
80
90
|
onLayout: onLayoutProps,
|
|
81
91
|
...props
|
|
@@ -83,6 +93,7 @@ const KeyboardAvoidingView = forwardRef<
|
|
|
83
93
|
ref,
|
|
84
94
|
) => {
|
|
85
95
|
const initialFrame = useSharedValue<LayoutRectangle | null>(null);
|
|
96
|
+
const internalRef = React.useRef<View | null>(null);
|
|
86
97
|
const frame = useDerivedValue(() => initialFrame.value || defaultLayout);
|
|
87
98
|
|
|
88
99
|
const { translate, padding } = useTranslateAnimation();
|
|
@@ -106,35 +117,67 @@ const KeyboardAvoidingView = forwardRef<
|
|
|
106
117
|
[relativeKeyboardHeight],
|
|
107
118
|
);
|
|
108
119
|
|
|
109
|
-
const onLayoutWorklet = useCallback(
|
|
110
|
-
|
|
120
|
+
const onLayoutWorklet = useCallback(
|
|
121
|
+
(layout: LayoutRectangle) => {
|
|
122
|
+
"worklet";
|
|
111
123
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
if (
|
|
125
|
+
keyboard.isClosed.value ||
|
|
126
|
+
initialFrame.value === null ||
|
|
127
|
+
behavior !== "height"
|
|
128
|
+
) {
|
|
129
|
+
// eslint-disable-next-line react-compiler/react-compiler
|
|
130
|
+
initialFrame.value = layout;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
[behavior],
|
|
134
|
+
);
|
|
117
135
|
const onLayout = useCallback<NonNullable<ViewProps["onLayout"]>>(
|
|
118
136
|
(e) => {
|
|
119
|
-
runOnUI(onLayoutWorklet)(e.nativeEvent.layout);
|
|
120
137
|
onLayoutProps?.(e);
|
|
138
|
+
|
|
139
|
+
const layout = e.nativeEvent.layout;
|
|
140
|
+
|
|
141
|
+
if (automaticOffset) {
|
|
142
|
+
const tag = findNodeHandle(internalRef.current);
|
|
143
|
+
|
|
144
|
+
if (tag !== null) {
|
|
145
|
+
return KeyboardControllerNative.viewPositionInWindow(tag)
|
|
146
|
+
.then((position) => {
|
|
147
|
+
runOnUI(onLayoutWorklet)({
|
|
148
|
+
...layout,
|
|
149
|
+
x: position.x,
|
|
150
|
+
y: position.y,
|
|
151
|
+
});
|
|
152
|
+
})
|
|
153
|
+
.catch(() => {
|
|
154
|
+
runOnUI(onLayoutWorklet)(layout);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return runOnUI(onLayoutWorklet)(layout);
|
|
121
160
|
},
|
|
122
|
-
[onLayoutProps],
|
|
161
|
+
[onLayoutProps, automaticOffset],
|
|
123
162
|
);
|
|
124
163
|
|
|
125
164
|
const animatedStyle = useAnimatedStyle(() => {
|
|
165
|
+
if (!enabled) {
|
|
166
|
+
return {};
|
|
167
|
+
}
|
|
168
|
+
|
|
126
169
|
const bottom = interpolateToRelativeKeyboardHeight(
|
|
127
170
|
keyboard.progress.value,
|
|
128
171
|
);
|
|
129
172
|
const translateY = interpolateToRelativeKeyboardHeight(translate.value);
|
|
130
173
|
const paddingBottom = interpolateToRelativeKeyboardHeight(padding.value);
|
|
131
|
-
const
|
|
174
|
+
const height = frame.value.height - bottom;
|
|
132
175
|
|
|
133
|
-
switch (behavior)
|
|
176
|
+
switch (behavior) {
|
|
134
177
|
case "height":
|
|
135
|
-
if (!keyboard.isClosed.value) {
|
|
178
|
+
if (!keyboard.isClosed.value && height > 0) {
|
|
136
179
|
return {
|
|
137
|
-
height
|
|
180
|
+
height,
|
|
138
181
|
flex: 0,
|
|
139
182
|
};
|
|
140
183
|
}
|
|
@@ -142,21 +185,22 @@ const KeyboardAvoidingView = forwardRef<
|
|
|
142
185
|
return {};
|
|
143
186
|
|
|
144
187
|
case "position":
|
|
145
|
-
return { bottom
|
|
188
|
+
return { bottom };
|
|
146
189
|
|
|
147
190
|
case "padding":
|
|
148
|
-
return { paddingBottom:
|
|
191
|
+
return { paddingBottom: bottom };
|
|
149
192
|
|
|
150
193
|
case "translate-with-padding":
|
|
151
194
|
return {
|
|
152
195
|
paddingBottom: paddingBottom,
|
|
153
|
-
transform: [{ translateY: -translateY}],
|
|
196
|
+
transform: [{ translateY: -translateY }],
|
|
154
197
|
};
|
|
155
198
|
|
|
156
199
|
default:
|
|
157
200
|
return {};
|
|
158
201
|
}
|
|
159
202
|
}, [behavior, enabled, interpolateToRelativeKeyboardHeight]);
|
|
203
|
+
const combinedRef = useCombinedRef(internalRef, ref);
|
|
160
204
|
const isPositionBehavior = behavior === "position";
|
|
161
205
|
const containerStyle = isPositionBehavior ? contentContainerStyle : style;
|
|
162
206
|
const combinedStyles = useMemo(
|
|
@@ -166,7 +210,7 @@ const KeyboardAvoidingView = forwardRef<
|
|
|
166
210
|
|
|
167
211
|
if (isPositionBehavior) {
|
|
168
212
|
return (
|
|
169
|
-
<View ref={
|
|
213
|
+
<View ref={combinedRef} style={style} onLayout={onLayout} {...props}>
|
|
170
214
|
<Reanimated.View style={combinedStyles}>{children}</Reanimated.View>
|
|
171
215
|
</View>
|
|
172
216
|
);
|
|
@@ -174,7 +218,7 @@ const KeyboardAvoidingView = forwardRef<
|
|
|
174
218
|
|
|
175
219
|
return (
|
|
176
220
|
<Reanimated.View
|
|
177
|
-
ref={
|
|
221
|
+
ref={combinedRef}
|
|
178
222
|
onLayout={onLayout}
|
|
179
223
|
style={combinedStyles}
|
|
180
224
|
{...props}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useMemo,
|
|
7
|
+
} from "react";
|
|
8
|
+
import { Platform } from "react-native";
|
|
3
9
|
import Reanimated, {
|
|
4
10
|
interpolate,
|
|
11
|
+
runOnUI,
|
|
5
12
|
scrollTo,
|
|
6
13
|
useAnimatedReaction,
|
|
7
14
|
useAnimatedRef,
|
|
@@ -10,11 +17,13 @@ import Reanimated, {
|
|
|
10
17
|
useSharedValue,
|
|
11
18
|
} from "react-native-reanimated";
|
|
12
19
|
|
|
20
|
+
import { KeyboardControllerNative } from "../../bindings";
|
|
13
21
|
import {
|
|
14
22
|
useFocusedInputHandler,
|
|
15
23
|
useReanimatedFocusedInput,
|
|
16
24
|
useWindowDimensions,
|
|
17
25
|
} from "../../hooks";
|
|
26
|
+
import { findNodeHandle } from "../../utils/findNodeHandle";
|
|
18
27
|
|
|
19
28
|
import { useSmoothKeyboardHandler } from "./useSmoothKeyboardHandler";
|
|
20
29
|
import { debounce, scrollDistanceWithRespectToSnapPoints } from "./utils";
|
|
@@ -45,6 +54,10 @@ export type KeyboardAwareScrollViewProps = {
|
|
|
45
54
|
ScrollViewComponent?: React.ComponentType<ScrollViewProps>;
|
|
46
55
|
} & ScrollViewProps;
|
|
47
56
|
|
|
57
|
+
export type KeyboardAwareScrollViewRef = ScrollView & {
|
|
58
|
+
assureFocusedInputVisible: () => void;
|
|
59
|
+
};
|
|
60
|
+
|
|
48
61
|
/*
|
|
49
62
|
* Everything begins from `onStart` handler. This handler is called every time,
|
|
50
63
|
* when keyboard changes its size or when focused `TextInput` was changed. In
|
|
@@ -84,7 +97,7 @@ export type KeyboardAwareScrollViewProps = {
|
|
|
84
97
|
*
|
|
85
98
|
*/
|
|
86
99
|
const KeyboardAwareScrollView = forwardRef<
|
|
87
|
-
|
|
100
|
+
KeyboardAwareScrollViewRef,
|
|
88
101
|
React.PropsWithChildren<KeyboardAwareScrollViewProps>
|
|
89
102
|
>(
|
|
90
103
|
(
|
|
@@ -112,23 +125,31 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
112
125
|
const scrollBeforeKeyboardMovement = useSharedValue(0);
|
|
113
126
|
const { input } = useReanimatedFocusedInput();
|
|
114
127
|
const layout = useSharedValue<FocusedInputLayoutChangedEvent | null>(null);
|
|
128
|
+
const scrollViewPageY = useSharedValue(0);
|
|
115
129
|
|
|
116
130
|
const { height } = useWindowDimensions();
|
|
117
131
|
|
|
118
132
|
const onRef = useCallback((assignedRef: Reanimated.ScrollView) => {
|
|
119
|
-
if (typeof ref === "function") {
|
|
120
|
-
ref(assignedRef);
|
|
121
|
-
} else if (ref) {
|
|
122
|
-
ref.current = assignedRef;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
133
|
scrollViewAnimatedRef(assignedRef);
|
|
126
134
|
}, []);
|
|
127
135
|
const onScrollViewLayout = useCallback(
|
|
128
|
-
(e: LayoutChangeEvent) => {
|
|
129
|
-
|
|
136
|
+
async (e: LayoutChangeEvent) => {
|
|
137
|
+
const handle = findNodeHandle(scrollViewAnimatedRef.current);
|
|
138
|
+
|
|
139
|
+
scrollViewTarget.value = handle;
|
|
130
140
|
|
|
131
141
|
onLayout?.(e);
|
|
142
|
+
|
|
143
|
+
if (handle !== null) {
|
|
144
|
+
try {
|
|
145
|
+
const { y } =
|
|
146
|
+
await KeyboardControllerNative.viewPositionInWindow(handle);
|
|
147
|
+
|
|
148
|
+
scrollViewPageY.value = y;
|
|
149
|
+
} catch {
|
|
150
|
+
// Keep the previous top boundary when the view is not mounted yet.
|
|
151
|
+
}
|
|
152
|
+
}
|
|
132
153
|
},
|
|
133
154
|
[onLayout],
|
|
134
155
|
);
|
|
@@ -175,9 +196,9 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
175
196
|
return interpolatedScrollTo;
|
|
176
197
|
}
|
|
177
198
|
|
|
178
|
-
if (
|
|
179
|
-
const positionOnScreen = visibleRect -
|
|
180
|
-
const topOfScreen = scrollPosition.value +
|
|
199
|
+
if (point < scrollViewPageY.value) {
|
|
200
|
+
const positionOnScreen = visibleRect - bottomOffset;
|
|
201
|
+
const topOfScreen = scrollPosition.value + point;
|
|
181
202
|
|
|
182
203
|
scrollTo(
|
|
183
204
|
scrollViewAnimatedRef,
|
|
@@ -191,6 +212,26 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
191
212
|
},
|
|
192
213
|
[bottomOffset, enabled, height, rest.snapToOffsets],
|
|
193
214
|
);
|
|
215
|
+
const performScrollWithPositionRestoration = useCallback(
|
|
216
|
+
(newPosition: number) => {
|
|
217
|
+
"worklet";
|
|
218
|
+
|
|
219
|
+
const prevScrollPosition = scrollPosition.value;
|
|
220
|
+
|
|
221
|
+
// eslint-disable-next-line react-compiler/react-compiler
|
|
222
|
+
scrollPosition.value = newPosition;
|
|
223
|
+
maybeScroll(keyboardHeight.value, true);
|
|
224
|
+
scrollPosition.value = prevScrollPosition;
|
|
225
|
+
},
|
|
226
|
+
[maybeScroll],
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
useEffect(() => {
|
|
230
|
+
// Recalculate from the pre-keyboard position to avoid accumulating an already applied offset.
|
|
231
|
+
runOnUI(performScrollWithPositionRestoration)(
|
|
232
|
+
scrollBeforeKeyboardMovement.value,
|
|
233
|
+
);
|
|
234
|
+
}, [bottomOffset]);
|
|
194
235
|
|
|
195
236
|
const syncKeyboardFrame = useCallback(
|
|
196
237
|
(e: NativeEvent) => {
|
|
@@ -211,7 +252,6 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
211
252
|
(customHeight?: number) => {
|
|
212
253
|
"worklet";
|
|
213
254
|
|
|
214
|
-
const prevScrollPosition = scrollPosition.value;
|
|
215
255
|
const prevLayout = layout.value;
|
|
216
256
|
|
|
217
257
|
if (!input.value?.layout) {
|
|
@@ -226,12 +266,27 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
226
266
|
height: customHeight ?? input.value.layout.height,
|
|
227
267
|
},
|
|
228
268
|
};
|
|
229
|
-
|
|
230
|
-
maybeScroll(keyboardHeight.value, true);
|
|
231
|
-
scrollPosition.value = prevScrollPosition;
|
|
269
|
+
performScrollWithPositionRestoration(position.value);
|
|
232
270
|
layout.value = prevLayout;
|
|
233
271
|
},
|
|
234
|
-
[
|
|
272
|
+
[performScrollWithPositionRestoration],
|
|
273
|
+
);
|
|
274
|
+
const assureFocusedInputVisible = useCallback(() => {
|
|
275
|
+
runOnUI(scrollFromCurrentPosition)();
|
|
276
|
+
}, [scrollFromCurrentPosition]);
|
|
277
|
+
|
|
278
|
+
useImperativeHandle(
|
|
279
|
+
ref,
|
|
280
|
+
() => {
|
|
281
|
+
const current = scrollViewAnimatedRef.current;
|
|
282
|
+
if (current) {
|
|
283
|
+
Object.assign(current, { assureFocusedInputVisible });
|
|
284
|
+
return current as unknown as KeyboardAwareScrollViewRef;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return { assureFocusedInputVisible } as KeyboardAwareScrollViewRef;
|
|
288
|
+
},
|
|
289
|
+
[assureFocusedInputVisible],
|
|
235
290
|
);
|
|
236
291
|
const onChangeText = useCallback(() => {
|
|
237
292
|
"worklet";
|
|
@@ -388,7 +443,7 @@ const KeyboardAwareScrollView = forwardRef<
|
|
|
388
443
|
scrollEventThrottle={16}
|
|
389
444
|
>
|
|
390
445
|
{children}
|
|
391
|
-
<Reanimated.View style={view} />
|
|
446
|
+
{enabled && <Reanimated.View style={view} />}
|
|
392
447
|
</ScrollViewComponent>
|
|
393
448
|
);
|
|
394
449
|
},
|
|
@@ -69,8 +69,8 @@ export const useSmoothKeyboardHandler: typeof useKeyboardHandler = (
|
|
|
69
69
|
persistedHeight.value = height.value;
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
|
-
//
|
|
73
|
-
deps
|
|
72
|
+
// create shallow copy (if deps specified) since `useAnimatedReaction` modifies them
|
|
73
|
+
deps ? [...deps] : deps,
|
|
74
74
|
);
|
|
75
75
|
|
|
76
76
|
useKeyboardHandler(
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React, { forwardRef, useCallback, useMemo } from "react";
|
|
2
|
+
import { StyleSheet } from "react-native";
|
|
3
|
+
import {
|
|
4
|
+
makeMutable,
|
|
5
|
+
useAnimatedRef,
|
|
6
|
+
useAnimatedStyle,
|
|
7
|
+
useDerivedValue,
|
|
8
|
+
} from "react-native-reanimated";
|
|
9
|
+
import Reanimated from "react-native-reanimated";
|
|
10
|
+
|
|
11
|
+
import useCombinedRef from "../hooks/useCombinedRef";
|
|
12
|
+
import ScrollViewWithBottomPadding from "../ScrollViewWithBottomPadding";
|
|
13
|
+
|
|
14
|
+
import { useChatKeyboard } from "./useChatKeyboard";
|
|
15
|
+
import { useEndVisible } from "./useEndVisible";
|
|
16
|
+
import { useExtraContentPadding } from "./useExtraContentPadding";
|
|
17
|
+
|
|
18
|
+
import type { KeyboardChatScrollViewProps } from "./types";
|
|
19
|
+
import type { LayoutChangeEvent } from "react-native";
|
|
20
|
+
|
|
21
|
+
const ZERO_CONTENT_PADDING = makeMutable(0);
|
|
22
|
+
const ZERO_BLANK_SPACE = makeMutable(0);
|
|
23
|
+
|
|
24
|
+
const KeyboardChatScrollView = forwardRef<
|
|
25
|
+
Reanimated.ScrollView,
|
|
26
|
+
React.PropsWithChildren<KeyboardChatScrollViewProps>
|
|
27
|
+
>(
|
|
28
|
+
(
|
|
29
|
+
{
|
|
30
|
+
children,
|
|
31
|
+
ScrollViewComponent = Reanimated.ScrollView,
|
|
32
|
+
inverted = false,
|
|
33
|
+
keyboardLiftBehavior = "always",
|
|
34
|
+
freeze = false,
|
|
35
|
+
offset = 0,
|
|
36
|
+
extraContentPadding = ZERO_CONTENT_PADDING,
|
|
37
|
+
blankSpace = ZERO_BLANK_SPACE,
|
|
38
|
+
applyWorkaroundForContentInsetHitTestBug = false,
|
|
39
|
+
onLayout: onLayoutProp,
|
|
40
|
+
onContentSizeChange: onContentSizeChangeProp,
|
|
41
|
+
onEndVisible,
|
|
42
|
+
...rest
|
|
43
|
+
},
|
|
44
|
+
ref,
|
|
45
|
+
) => {
|
|
46
|
+
const scrollViewRef = useAnimatedRef<Reanimated.ScrollView>();
|
|
47
|
+
const onRef = useCombinedRef(ref, scrollViewRef);
|
|
48
|
+
const freezeSV = useDerivedValue(() =>
|
|
49
|
+
typeof freeze === "boolean" ? freeze : freeze.value,
|
|
50
|
+
);
|
|
51
|
+
const {
|
|
52
|
+
padding,
|
|
53
|
+
currentHeight,
|
|
54
|
+
contentOffsetY,
|
|
55
|
+
scroll,
|
|
56
|
+
layout,
|
|
57
|
+
size,
|
|
58
|
+
onLayout: onLayoutInternal,
|
|
59
|
+
onContentSizeChange: onContentSizeChangeInternal,
|
|
60
|
+
} = useChatKeyboard(scrollViewRef, {
|
|
61
|
+
inverted,
|
|
62
|
+
keyboardLiftBehavior,
|
|
63
|
+
freeze: freezeSV,
|
|
64
|
+
offset,
|
|
65
|
+
blankSpace,
|
|
66
|
+
extraContentPadding,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
useExtraContentPadding({
|
|
70
|
+
scrollViewRef,
|
|
71
|
+
extraContentPadding,
|
|
72
|
+
keyboardPadding: padding,
|
|
73
|
+
blankSpace,
|
|
74
|
+
scroll,
|
|
75
|
+
layout,
|
|
76
|
+
size,
|
|
77
|
+
contentOffsetY,
|
|
78
|
+
inverted,
|
|
79
|
+
keyboardLiftBehavior,
|
|
80
|
+
freeze: freezeSV,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
useEndVisible({
|
|
84
|
+
scroll,
|
|
85
|
+
layout,
|
|
86
|
+
size,
|
|
87
|
+
inverted,
|
|
88
|
+
onEndVisible,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const totalPadding = useDerivedValue(() =>
|
|
92
|
+
Math.max(blankSpace.value, padding.value + extraContentPadding.value),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// Scroll indicator inset = keyboard + extraContentPadding (excludes blankSpace).
|
|
96
|
+
// Apps that render into the unsafe area can supply a negative
|
|
97
|
+
// scrollIndicatorInsets adjustment at the application layer.
|
|
98
|
+
const indicatorPadding = useDerivedValue(
|
|
99
|
+
() => padding.value + extraContentPadding.value,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const onLayout = useCallback(
|
|
103
|
+
(e: LayoutChangeEvent) => {
|
|
104
|
+
onLayoutInternal(e);
|
|
105
|
+
onLayoutProp?.(e);
|
|
106
|
+
},
|
|
107
|
+
[onLayoutInternal, onLayoutProp],
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const onContentSizeChange = useCallback(
|
|
111
|
+
(w: number, h: number) => {
|
|
112
|
+
onContentSizeChangeInternal(w, h);
|
|
113
|
+
onContentSizeChangeProp?.(w, h);
|
|
114
|
+
},
|
|
115
|
+
[onContentSizeChangeInternal, onContentSizeChangeProp],
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Invisible view whose animated style changes every frame during keyboard
|
|
119
|
+
// animation. On Fabric, this forces Reanimated to schedule a commit,
|
|
120
|
+
// which flushes the scrollTo call in the same frame (fixing de-synchronization).
|
|
121
|
+
// see https://github.com/software-mansion/react-native-reanimated/issues/9000
|
|
122
|
+
const commitStyle = useAnimatedStyle(
|
|
123
|
+
() => ({
|
|
124
|
+
transform: [{ translateY: -currentHeight.value }],
|
|
125
|
+
}),
|
|
126
|
+
[],
|
|
127
|
+
);
|
|
128
|
+
const commit = useMemo(
|
|
129
|
+
() => [styles.commitView, commitStyle],
|
|
130
|
+
[commitStyle],
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<>
|
|
135
|
+
<ScrollViewWithBottomPadding
|
|
136
|
+
ref={onRef}
|
|
137
|
+
{...rest}
|
|
138
|
+
applyWorkaroundForContentInsetHitTestBug={
|
|
139
|
+
applyWorkaroundForContentInsetHitTestBug
|
|
140
|
+
}
|
|
141
|
+
bottomPadding={totalPadding}
|
|
142
|
+
contentOffsetY={contentOffsetY}
|
|
143
|
+
inverted={inverted}
|
|
144
|
+
scrollIndicatorPadding={indicatorPadding}
|
|
145
|
+
ScrollViewComponent={ScrollViewComponent}
|
|
146
|
+
onContentSizeChange={onContentSizeChange}
|
|
147
|
+
onLayout={onLayout}
|
|
148
|
+
>
|
|
149
|
+
{children}
|
|
150
|
+
</ScrollViewWithBottomPadding>
|
|
151
|
+
<Reanimated.View style={commit} />
|
|
152
|
+
</>
|
|
153
|
+
);
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const styles = StyleSheet.create({
|
|
158
|
+
commitView: {
|
|
159
|
+
display: "none",
|
|
160
|
+
position: "absolute",
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
export default KeyboardChatScrollView;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnimatedScrollViewComponent,
|
|
3
|
+
ScrollViewContentInsets,
|
|
4
|
+
} from "../ScrollViewWithBottomPadding";
|
|
5
|
+
import type { KeyboardLiftBehavior } from "./useChatKeyboard/types";
|
|
6
|
+
import type { ScrollViewProps } from "react-native";
|
|
7
|
+
import type { SharedValue } from "react-native-reanimated";
|
|
8
|
+
|
|
9
|
+
export type KeyboardChatScrollViewProps = {
|
|
10
|
+
/** Custom component for `ScrollView`. Default is `ScrollView`. */
|
|
11
|
+
ScrollViewComponent?: AnimatedScrollViewComponent;
|
|
12
|
+
/** Whether list are using `inverted` prop. Default is `false`. */
|
|
13
|
+
inverted?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The distance between the bottom of the screen and the `ScrollView`.
|
|
16
|
+
* When the keyboard appears, the `ScrollView` will only push content by the effective
|
|
17
|
+
* distance (`keyboardHeight - offset`) instead of the full keyboard height.
|
|
18
|
+
*
|
|
19
|
+
* Useful when the input is not at the very bottom of the screen (e.g., above safe area, above
|
|
20
|
+
* bottom tabs, etc. - in this case offset should be equal to the height of the elements between
|
|
21
|
+
* `ScrollView` and bottom of the screen).
|
|
22
|
+
*
|
|
23
|
+
* Default is `0`.
|
|
24
|
+
*/
|
|
25
|
+
offset?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Determines how the chat content should behave when the keyboard appears, specifically whether
|
|
28
|
+
* the scroll view should automatically lift its content to keep it visible above the keyboard.
|
|
29
|
+
*
|
|
30
|
+
* Possible values:
|
|
31
|
+
* - `'always'`: The content always lifts along with the keyboard, ensuring the messages from the bottom part of screen
|
|
32
|
+
* remain visible regardless of the current scroll position. This is the default behavior for most chat applications (used in Telegram).
|
|
33
|
+
* - `'whenAtEnd'`: The content lifts only if the scroll view is at the end (i.e., the last message
|
|
34
|
+
* is visible or near the bottom). This prevents unnecessary adjustments when the user is scrolling
|
|
35
|
+
* through older messages (ChatGPT mobile app behavior).
|
|
36
|
+
* - `'persistent'`: The content always lifts when the keyboard appears (similar to `'always'`), but
|
|
37
|
+
* does not reset (lower) when the keyboard hides. This mimics behaviors where the view remains adjusted
|
|
38
|
+
* after keyboard dismissal to maintain focus on the latest content without shifting back (Claude mobile app behavior).
|
|
39
|
+
* - `'never'`: The content does not lift at all when the keyboard appears. Use this for scenarios
|
|
40
|
+
* when you don't want to disturb user attention with animations (Perplexity mobile app behavior).
|
|
41
|
+
*
|
|
42
|
+
* Default is `'always'`.
|
|
43
|
+
*/
|
|
44
|
+
keyboardLiftBehavior?: KeyboardLiftBehavior;
|
|
45
|
+
/**
|
|
46
|
+
* When `true`, freezes all keyboard-driven layout changes (padding, content offset, scroll position).
|
|
47
|
+
* Useful when dismissing the keyboard to open a bottom sheet — prevents visual disruption
|
|
48
|
+
* while the sheet is visible.
|
|
49
|
+
*
|
|
50
|
+
* Default is `false`.
|
|
51
|
+
*/
|
|
52
|
+
freeze?: boolean | SharedValue<boolean>;
|
|
53
|
+
/**
|
|
54
|
+
* A shared value representing additional padding from external elements
|
|
55
|
+
* (e.g., a growing multiline `TextInput` in a `KeyboardStickyView`).
|
|
56
|
+
*
|
|
57
|
+
* When this value changes:
|
|
58
|
+
* - The scrollable range is always extended/contracted (via `contentInset`).
|
|
59
|
+
* - The scroll position is conditionally adjusted based on `keyboardLiftBehavior`.
|
|
60
|
+
*
|
|
61
|
+
* Default is `undefined` (no extra padding).
|
|
62
|
+
*/
|
|
63
|
+
extraContentPadding?: SharedValue<number>;
|
|
64
|
+
/**
|
|
65
|
+
* When `true`, applies a runtime workaround for a React Native 0.81+ bug
|
|
66
|
+
* where the ScrollView's `contentInset` area does not respond to touch/scroll
|
|
67
|
+
* gestures (facebook/react-native#54123).
|
|
68
|
+
*
|
|
69
|
+
* This uses Objective-C runtime method swizzling on the ScrollView's container
|
|
70
|
+
* view, which is inherently fragile. Only enable if you are affected by the
|
|
71
|
+
* upstream bug and understand the risks.
|
|
72
|
+
*
|
|
73
|
+
* iOS only. Default is `false`.
|
|
74
|
+
*/
|
|
75
|
+
applyWorkaroundForContentInsetHitTestBug?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* A shared value representing a minimum inset floor (in pixels).
|
|
78
|
+
*
|
|
79
|
+
* When set, the total bottom padding is computed as:
|
|
80
|
+
* `max(blankSpace, keyboardPadding + extraContentPadding)`
|
|
81
|
+
*
|
|
82
|
+
* This means the keyboard "absorbs" into the minimum padding rather than adding to it:
|
|
83
|
+
* - When `blankSpace >= keyboard + extraContentPadding`: content does NOT move on keyboard open/close.
|
|
84
|
+
* - When `blankSpace < keyboard + extraContentPadding`: content moves, but only by the excess amount.
|
|
85
|
+
*
|
|
86
|
+
* Useful in AI chat apps where a sent message needs space below it (to push it to the top
|
|
87
|
+
* of the viewport) while the AI response streams in, without that space causing extra movement
|
|
88
|
+
* when the keyboard opens.
|
|
89
|
+
*
|
|
90
|
+
* Default is `undefined` (equivalent to `0` — no minimum floor).
|
|
91
|
+
*/
|
|
92
|
+
blankSpace?: SharedValue<number>;
|
|
93
|
+
/**
|
|
94
|
+
* Fires whenever the effective content inset changes — the static `contentInset`
|
|
95
|
+
* prop combined with the dynamic keyboard-driven padding.
|
|
96
|
+
*
|
|
97
|
+
* Useful on Android, where the synthetic content inset is not reflected in the native
|
|
98
|
+
* `onScroll` event payload. Consumers such as virtualized lists computing their own
|
|
99
|
+
* `scrollToEnd` target can use this to track the current inset alongside scroll offsets.
|
|
100
|
+
*/
|
|
101
|
+
onContentInsetChange?: (insets: ScrollViewContentInsets) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Fires whenever the visibility of the content "end" changes — both when the user
|
|
104
|
+
* arrives at the end and when they leave it. The boolean parameter reflects the new state.
|
|
105
|
+
*
|
|
106
|
+
* For non-inverted lists, the "end" is the bottom of the content. For inverted lists
|
|
107
|
+
* (`inverted={true}`), the "end" is the top of the scroll view, where the latest messages
|
|
108
|
+
* are rendered. The same internal detection drives `keyboardLiftBehavior="whenAtEnd"`.
|
|
109
|
+
*
|
|
110
|
+
* The callback can be either a plain JS function or a Reanimated worklet — the type is
|
|
111
|
+
* detected automatically. Worklets run on the UI thread; plain functions are dispatched
|
|
112
|
+
* via `runOnJS`.
|
|
113
|
+
*
|
|
114
|
+
* Fires once on mount with the initial state (after the scroll view has been measured).
|
|
115
|
+
*/
|
|
116
|
+
onEndVisible?: (visible: boolean) => void;
|
|
117
|
+
} & ScrollViewProps;
|