diff --git a/.github/workflows/verify-android.yml b/.github/workflows/verify-android.yml index ce38d9e2c5..c17129e6cb 100644 --- a/.github/workflows/verify-android.yml +++ b/.github/workflows/verify-android.yml @@ -79,7 +79,7 @@ jobs: curl -sSLO https://github.com/detekt/detekt/releases/download/v1.23.1/detekt-cli-1.23.1.zip unzip detekt-cli-1.23.1.zip - name: Run Detekt - run: ./detekt-cli-1.23.1/bin/detekt-cli + run: ./detekt-cli-1.23.1/bin/detekt-cli --config detekt.yml --build-upon-default-config unit-tests: name: 📖 Unit tests runs-on: ubuntu-latest diff --git a/.github/workflows/verify-cpp.yml b/.github/workflows/verify-cpp.yml index e421aaf715..f62e63ec7a 100644 --- a/.github/workflows/verify-cpp.yml +++ b/.github/workflows/verify-cpp.yml @@ -7,10 +7,12 @@ on: paths: - ".github/workflows/verify-cpp.yml" - "android/src/main/**" + - "common/cpp/**" pull_request: paths: - ".github/workflows/verify-cpp.yml" - "android/src/main/**" + - "common/cpp/**" jobs: lint: @@ -33,4 +35,4 @@ jobs: python -m pip install --upgrade pip pip install cpplint - name: Run cpplint - run: cpplint --linelength=230 --filter=-legal/copyright,-readability/todo,-build/namespaces,-whitespace/comments,-build/c++11,-runtime/int,-runtime/references --quiet --recursive android/src/main/ + run: cpplint --linelength=230 --filter=-legal/copyright,-readability/todo,-build/namespaces,-whitespace/comments,-build/c++11,-runtime/int,-runtime/references,-whitespace/indent_namespace --quiet --recursive android/src/main/ common/cpp/ diff --git a/FabricExample/ios/Podfile.lock b/FabricExample/ios/Podfile.lock index ebc7bc88d0..d974d42d4b 100644 --- a/FabricExample/ios/Podfile.lock +++ b/FabricExample/ios/Podfile.lock @@ -1283,6 +1283,28 @@ PODS: - ReactCommon/turbomodule/core - Yoga - react-native-keyboard-controller (1.16.8): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.11.18.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - react-native-keyboard-controller/common (= 1.16.8) + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga + - react-native-keyboard-controller/common (1.16.8): - DoubleConversion - glog - hermes-engine @@ -2164,7 +2186,7 @@ SPEC CHECKSUMS: React-Mapbuffer: 0502faf46cab8fb89cfc7bf3e6c6109b6ef9b5de React-microtasksnativemodule: 663bc64e3a96c5fc91081923ae7481adc1359a78 react-native-blur: b37343d4df1af48a17444156b674b26d5aec2425 - react-native-keyboard-controller: b9280bc833465038d4805dbd4ca66660f7f0dcd3 + react-native-keyboard-controller: ef23fc10134fc24ab13d331afe1fbc33374f185a react-native-safe-area-context: 9c33120e9eac7741a5364cc2d9f74665049b76b3 React-NativeModulesApple: 16fbd5b040ff6c492dacc361d49e63cba7a6a7a1 React-perflogger: ab51b7592532a0ea45bf6eed7e6cae14a368b678 diff --git a/FabricExample/src/screens/Examples/Toolbar/index.tsx b/FabricExample/src/screens/Examples/Toolbar/index.tsx index f82cf99071..a8d9d2b324 100644 --- a/FabricExample/src/screens/Examples/Toolbar/index.tsx +++ b/FabricExample/src/screens/Examples/Toolbar/index.tsx @@ -231,6 +231,7 @@ const styles = StyleSheet.create({ right: 0, }, header: { + color: "black", marginRight: 12, }, modal: { diff --git a/android/detekt.yml b/android/detekt.yml new file mode 100644 index 0000000000..3153d80f3c --- /dev/null +++ b/android/detekt.yml @@ -0,0 +1,3 @@ +complexity: + TooManyFunctions: + ignoreOverridden: true diff --git a/android/src/fabric/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt b/android/src/fabric/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt index 1b768111d7..ef17e3f6c6 100644 --- a/android/src/fabric/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt +++ b/android/src/fabric/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt @@ -2,6 +2,8 @@ package com.reactnativekeyboardcontroller import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.uimanager.LayoutShadowNode +import com.facebook.react.uimanager.ReactStylesDiffMap +import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.ViewManagerDelegate @@ -30,6 +32,15 @@ class OverKeyboardViewManager( override fun getShadowNodeClass(): Class = OverKeyboardHostShadowNode::class.java + override fun updateState( + view: OverKeyboardHostView, + props: ReactStylesDiffMap, + stateWrapper: StateWrapper, + ): Any? { + view.stateWrapper = stateWrapper + return null + } + @ReactProp(name = "visible") override fun setVisible( view: OverKeyboardHostView, diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt b/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt index 974e4bbebc..169d292b49 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt @@ -7,12 +7,17 @@ import android.view.MotionEvent import android.view.View import android.view.WindowManager import com.facebook.react.bridge.UiThreadUtil +import com.facebook.react.bridge.WritableMap +import com.facebook.react.bridge.WritableNativeMap import com.facebook.react.config.ReactFeatureFlags import com.facebook.react.uimanager.JSTouchDispatcher +import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.uimanager.events.EventDispatcher import com.facebook.react.views.view.ReactViewGroup +import com.reactnativekeyboardcontroller.extensions.dp +import com.reactnativekeyboardcontroller.extensions.getDisplaySize @SuppressLint("ViewConstructor") class OverKeyboardHostView( @@ -22,6 +27,8 @@ class OverKeyboardHostView( private var windowManager: WindowManager = reactContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager private var hostView: OverKeyboardRootViewGroup = OverKeyboardRootViewGroup(reactContext) + internal var stateWrapper: StateWrapper? = null + init { hostView.eventDispatcher = dispatcher } @@ -82,14 +89,24 @@ class OverKeyboardHostView( PixelFormat.TRANSLUCENT, ) + stretchTo(fullScreen = true) windowManager.addView(hostView, layoutParams) } fun hide() { if (hostView.isAttached) { windowManager.removeView(hostView) + stretchTo(fullScreen = false) } } + + private fun stretchTo(fullScreen: Boolean) { + val displaySize = reactContext.getDisplaySize() + val newStateData: WritableMap = WritableNativeMap() + newStateData.putDouble("screenWidth", if (fullScreen) displaySize.x.toFloat().dp else 0.0) + newStateData.putDouble("screenHeight", if (fullScreen) displaySize.y.toFloat().dp else 0.0) + stateWrapper?.updateState(newStateData) + } } @SuppressLint("ViewConstructor") diff --git a/android/src/main/jni/CMakeLists.txt b/android/src/main/jni/CMakeLists.txt new file mode 100644 index 0000000000..904b025148 --- /dev/null +++ b/android/src/main/jni/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 3.13) +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(LIB_LITERAL reactnativekeyboardcontroller) +set(LIB_TARGET_NAME react_codegen_${LIB_LITERAL}) + +set(LIB_ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) +set(LIB_COMMON_DIR ${LIB_ANDROID_DIR}/../common/cpp) +set(LIB_COMMON_COMPONENTS_DIR ${LIB_COMMON_DIR}/react/renderer/components/${LIB_LITERAL}) +set(LIB_ANDROID_GENERATED_JNI_DIR ${LIB_ANDROID_DIR}/build/generated/source/codegen/jni) +set(LIB_ANDROID_GENERATED_COMPONENTS_DIR ${LIB_ANDROID_GENERATED_JNI_DIR}/react/renderer/components/${LIB_LITERAL}) + +add_compile_options( + -fexceptions + -frtti + -std=c++20 + -Wall + -Wpedantic + -Wno-gnu-zero-variadic-macro-arguments + -Wno-dollar-in-identifier-extension +) + +file(GLOB LIB_CUSTOM_SRCS CONFIGURE_DEPENDS *.cpp ${LIB_COMMON_COMPONENTS_DIR}/*.cpp) +file(GLOB LIB_CODEGEN_SRCS CONFIGURE_DEPENDS ${LIB_ANDROID_GENERATED_JNI_DIR}/*.cpp ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}/*.cpp) + +add_library( + ${LIB_TARGET_NAME} + SHARED + ${LIB_CUSTOM_SRCS} + ${LIB_CODEGEN_SRCS} +) + +target_include_directories( + ${LIB_TARGET_NAME} + PUBLIC + . + ${LIB_COMMON_DIR} + ${LIB_ANDROID_GENERATED_JNI_DIR} + ${LIB_ANDROID_GENERATED_COMPONENTS_DIR} +) + +if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76) + target_link_libraries( + ${LIB_TARGET_NAME} + ReactAndroid::reactnative + ReactAndroid::jsi + fbjni::fbjni + ) +else() + target_link_libraries( + ${LIB_TARGET_NAME} + fbjni + folly_runtime + glog + jsi + react_codegen_rncore + react_debug + react_nativemodule_core + react_render_core + react_render_debug + react_render_graphics + react_render_mapbuffer + react_render_componentregistry + react_utils + rrc_view + turbomodulejsijni + yoga + ) +endif() + +target_compile_options( + ${LIB_TARGET_NAME} + PRIVATE + -DLOG_TAG=\"ReactNative\" + -fexceptions + -frtti + -std=c++20 + -Wall +) + +target_include_directories( + ${CMAKE_PROJECT_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) \ No newline at end of file diff --git a/android/src/main/jni/reactnativekeyboardcontroller.h b/android/src/main/jni/reactnativekeyboardcontroller.h new file mode 100644 index 0000000000..8b8d917830 --- /dev/null +++ b/android/src/main/jni/reactnativekeyboardcontroller.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +/** + * Note this import and that it is not present in autogenerated header file + * under android/build/generated/source/codegen/jni/reactnativekeyboardcontroller.h + * + * Here we are overriding autogenerated component descriptors by prioritizing our custom headers via include path setup. + */ +#include +#include +#include + +#include +#include + +namespace facebook::react { +JSI_EXPORT +std::shared_ptr reactnativekeyboardcontroller_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms); +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewComponentDescriptor.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewComponentDescriptor.h new file mode 100644 index 0000000000..9b295ed770 --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewComponentDescriptor.h @@ -0,0 +1,21 @@ +#pragma once + +#include "RNKCKeyboardControllerViewShadowNode.h" + +#include +#include +#include + +namespace facebook::react { + +class KeyboardControllerViewComponentDescriptor final + : public ConcreteComponentDescriptor { + public: + using ConcreteComponentDescriptor::ConcreteComponentDescriptor; + void adopt(ShadowNode &shadowNode) const override { + react_native_assert(dynamic_cast(&shadowNode)); + ConcreteComponentDescriptor::adopt(shadowNode); + } +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.cpp b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.cpp new file mode 100644 index 0000000000..5a6e9ce5c1 --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.cpp @@ -0,0 +1,7 @@ +#include "RNKCKeyboardControllerViewShadowNode.h" + +namespace facebook::react { + +extern const char KeyboardControllerViewComponentName[] = "KeyboardControllerView"; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.h new file mode 100644 index 0000000000..c402433a5c --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewShadowNode.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RNKCKeyboardControllerViewState.h" + +#include +#include +#include +#include + +namespace facebook::react { + +JSI_EXPORT extern const char KeyboardControllerViewComponentName[]; + +/* + * `ShadowNode` for component. + */ +using KeyboardControllerViewShadowNode = ConcreteViewShadowNode< + KeyboardControllerViewComponentName, + KeyboardControllerViewProps, + KeyboardControllerViewEventEmitter, + KeyboardControllerViewState>; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewState.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewState.h new file mode 100644 index 0000000000..af2c4ee93a --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardControllerViewState.h @@ -0,0 +1,21 @@ +#pragma once + +#ifdef ANDROID +#include +#endif + +namespace facebook::react { + +class KeyboardControllerViewState { + public: + KeyboardControllerViewState() = default; + +#ifdef ANDROID + KeyboardControllerViewState(KeyboardControllerViewState const &previousState, folly::dynamic data) {} + folly::dynamic getDynamic() const { + return {}; + } +#endif +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaComponentDescriptor.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaComponentDescriptor.h new file mode 100644 index 0000000000..9900476c3d --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaComponentDescriptor.h @@ -0,0 +1,20 @@ +#pragma once + +#include "RNKCKeyboardGestureAreaShadowNode.h" + +#include +#include +#include + +namespace facebook::react { +class KeyboardGestureAreaComponentDescriptor final + : public ConcreteComponentDescriptor { + public: + using ConcreteComponentDescriptor::ConcreteComponentDescriptor; + void adopt(ShadowNode &shadowNode) const override { + react_native_assert(dynamic_cast(&shadowNode)); + ConcreteComponentDescriptor::adopt(shadowNode); + } +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.cpp b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.cpp new file mode 100644 index 0000000000..418f2bdfde --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.cpp @@ -0,0 +1,7 @@ +#include "RNKCKeyboardGestureAreaShadowNode.h" + +namespace facebook::react { + +extern const char KeyboardGestureAreaComponentName[] = "KeyboardGestureArea"; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.h new file mode 100644 index 0000000000..0512148766 --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaShadowNode.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RNKCKeyboardGestureAreaState.h" + +#include +#include +#include +#include + +namespace facebook::react { + +JSI_EXPORT extern const char KeyboardGestureAreaComponentName[]; + +/* + * `ShadowNode` for component. + */ +using KeyboardGestureAreaShadowNode = ConcreteViewShadowNode< + KeyboardGestureAreaComponentName, + KeyboardGestureAreaProps, + KeyboardGestureAreaEventEmitter, + KeyboardGestureAreaState>; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaState.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaState.h new file mode 100644 index 0000000000..23620487ba --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCKeyboardGestureAreaState.h @@ -0,0 +1,21 @@ +#pragma once + +#ifdef ANDROID +#include +#endif + +namespace facebook::react { + +class KeyboardGestureAreaState { + public: + KeyboardGestureAreaState() = default; + +#ifdef ANDROID + KeyboardGestureAreaState(KeyboardGestureAreaState const &previousState, folly::dynamic data) {} + folly::dynamic getDynamic() const { + return {}; + } +#endif +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewComponentDescriptor.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewComponentDescriptor.h new file mode 100644 index 0000000000..b3e865bdfd --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewComponentDescriptor.h @@ -0,0 +1,31 @@ +#pragma once + +#include "RNKCOverKeyboardViewShadowNode.h" + +#include +#include +#include + +namespace facebook::react { + +class OverKeyboardViewComponentDescriptor final + : public ConcreteComponentDescriptor { + public: + using ConcreteComponentDescriptor::ConcreteComponentDescriptor; + void adopt(ShadowNode &shadowNode) const override { + auto& layoutableShadowNode = + static_cast(shadowNode); + auto& stateData = + static_cast( + *shadowNode.getState()) + .getData(); + + layoutableShadowNode.setSize( + Size{stateData.screenSize.width, stateData.screenSize.height}); + layoutableShadowNode.setPositionType(YGPositionTypeAbsolute); + + ConcreteComponentDescriptor::adopt(shadowNode); + } +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.cpp b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.cpp new file mode 100644 index 0000000000..e62343a46f --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.cpp @@ -0,0 +1,7 @@ +#include "RNKCOverKeyboardViewShadowNode.h" + +namespace facebook::react { + +extern const char OverKeyboardViewComponentName[] = "OverKeyboardView"; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.h new file mode 100644 index 0000000000..1b8cf9d15e --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewShadowNode.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RNKCOverKeyboardViewState.h" + +#include +#include +#include +#include + +namespace facebook::react { + +JSI_EXPORT extern const char OverKeyboardViewComponentName[]; + +/* + * `ShadowNode` for component. + */ +using OverKeyboardViewShadowNode = ConcreteViewShadowNode< + OverKeyboardViewComponentName, + OverKeyboardViewProps, + OverKeyboardViewEventEmitter, + OverKeyboardViewState>; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.cpp b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.cpp new file mode 100644 index 0000000000..5c3dfc4229 --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.cpp @@ -0,0 +1,12 @@ +#include "RNKCOverKeyboardViewState.h" + +namespace facebook::react { + +#ifdef ANDROID +folly::dynamic OverKeyboardViewState::getDynamic() const { + return folly::dynamic::object("screenWidth", screenSize.width)( + "screenHeight", screenSize.height); +} +#endif + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.h b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.h new file mode 100644 index 0000000000..f58bbe78f6 --- /dev/null +++ b/common/cpp/react/renderer/components/reactnativekeyboardcontroller/RNKCOverKeyboardViewState.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#ifdef ANDROID +#include +#endif + +#include + +namespace facebook::react { + +/* + * State for component. + */ +class OverKeyboardViewState final { + public: + using Shared = std::shared_ptr; + + + OverKeyboardViewState() {} + OverKeyboardViewState(Size screenSize_) : screenSize(screenSize_) {} + +#ifdef ANDROID + OverKeyboardViewState( + const OverKeyboardViewState& previousState, + folly::dynamic data) + : screenSize(Size{ + (Float)data["screenWidth"].getDouble(), + (Float)data["screenHeight"].getDouble()}) {} +#endif + + const Size screenSize{}; + +#ifdef ANDROID + folly::dynamic getDynamic() const; +#endif + +#pragma mark - Getters +}; + +} // namespace facebook::react diff --git a/cspell.json b/cspell.json index c0cc1ddda2..eb84a905f6 100644 --- a/cspell.json +++ b/cspell.json @@ -133,7 +133,23 @@ "drakula", "mathieu", "acthernoene", - "xcodeproj" + "xcodeproj", + "RNKC", + "fexceptions", + "frtti", + "fbjni", + "subspec", + "SRCROOT", + "glog", + "Wpedantic", + "DLOG", + "layoutable", + "rncore", + "turbomodulejsijni", + "componentregistry", + "mapbuffer", + "nativemodule", + "reactnative" ], "ignorePaths": [ "node_modules", diff --git a/example/src/screens/Examples/Toolbar/index.tsx b/example/src/screens/Examples/Toolbar/index.tsx index f82cf99071..a8d9d2b324 100644 --- a/example/src/screens/Examples/Toolbar/index.tsx +++ b/example/src/screens/Examples/Toolbar/index.tsx @@ -231,6 +231,7 @@ const styles = StyleSheet.create({ right: 0, }, header: { + color: "black", marginRight: 12, }, modal: { diff --git a/ios/views/KeyboardControllerView.mm b/ios/views/KeyboardControllerView.mm index 9c35253668..b8a656e7b3 100644 --- a/ios/views/KeyboardControllerView.mm +++ b/ios/views/KeyboardControllerView.mm @@ -20,10 +20,10 @@ #import #endif -#import #import #import #import +#import #import "KeyboardControllerModule-Header.h" #import "RCTFabricComponentsPlugins.h" diff --git a/ios/views/KeyboardGestureAreaManager.mm b/ios/views/KeyboardGestureAreaManager.mm index 74309f9a35..deabccc41c 100644 --- a/ios/views/KeyboardGestureAreaManager.mm +++ b/ios/views/KeyboardGestureAreaManager.mm @@ -14,10 +14,10 @@ #endif #ifdef RCT_NEW_ARCH_ENABLED -#import #import #import #import +#import #import "RCTFabricComponentsPlugins.h" #endif diff --git a/ios/views/OverKeyboardViewManager.mm b/ios/views/OverKeyboardViewManager.mm index d449b53985..37773157e7 100644 --- a/ios/views/OverKeyboardViewManager.mm +++ b/ios/views/OverKeyboardViewManager.mm @@ -16,10 +16,10 @@ #ifdef RCT_NEW_ARCH_ENABLED #import -#import #import #import #import +#import #import "RCTFabricComponentsPlugins.h" #endif diff --git a/package.json b/package.json index 0593adb299..8f3a301ee2 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,13 @@ "lib", "android", "ios", + "common", "cpp", "react-native-keyboard-controller.podspec", + "react-native.config.js", "jest", "!lib/typescript/example", + "!android/detekt.yml", "!android/build", "!android/src/test", "!android/.gradle", diff --git a/react-native-keyboard-controller.podspec b/react-native-keyboard-controller.podspec index 8729a0b458..aed1e75b56 100644 --- a/react-native-keyboard-controller.podspec +++ b/react-native-keyboard-controller.podspec @@ -58,4 +58,12 @@ Pod::Spec.new do |s| s.dependency "ReactCommon/turbomodule/core" end end + if new_arch_enabled + s.subspec "common" do |ss| + ss.source_files = ["common/cpp/**/*.{cpp,h}"] + ss.header_dir = "reactnativekeyboardcontroller" + ss.private_header_files = "common/cpp/**/*.{h}" + ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\"" } + end + end end diff --git a/react-native.config.js b/react-native.config.js new file mode 100644 index 0000000000..f7a1bae2b2 --- /dev/null +++ b/react-native.config.js @@ -0,0 +1,14 @@ +module.exports = { + dependency: { + platforms: { + android: { + componentDescriptors: [ + "KeyboardControllerViewComponentDescriptor", + "KeyboardGestureAreaComponentDescriptor", + "OverKeyboardViewComponentDescriptor", + ], + cmakeListsPath: "../android/src/main/jni/CMakeLists.txt", + }, + }, + }, +}; diff --git a/src/architecture.ts b/src/architecture.ts deleted file mode 100644 index 1f7aedb89f..0000000000 --- a/src/architecture.ts +++ /dev/null @@ -1 +0,0 @@ -export const IS_FABRIC = "nativeFabricUIManager" in global; diff --git a/src/specs/KeyboardControllerViewNativeComponent.ts b/src/specs/KeyboardControllerViewNativeComponent.ts index 65a64adfd3..db13802724 100644 --- a/src/specs/KeyboardControllerViewNativeComponent.ts +++ b/src/specs/KeyboardControllerViewNativeComponent.ts @@ -66,6 +66,6 @@ export interface NativeProps extends ViewProps { onFocusedInputSelectionChanged?: DirectEventHandler; } -export default codegenNativeComponent( - "KeyboardControllerView", -) as HostComponent; +export default codegenNativeComponent("KeyboardControllerView", { + interfaceOnly: true, +}) as HostComponent; diff --git a/src/specs/KeyboardGestureAreaNativeComponent.ts b/src/specs/KeyboardGestureAreaNativeComponent.ts index 58fa63863d..bb6dfe3524 100644 --- a/src/specs/KeyboardGestureAreaNativeComponent.ts +++ b/src/specs/KeyboardGestureAreaNativeComponent.ts @@ -15,6 +15,6 @@ export interface NativeProps extends ViewProps { textInputNativeID?: string; } -export default codegenNativeComponent( - "KeyboardGestureArea", -) as HostComponent; +export default codegenNativeComponent("KeyboardGestureArea", { + interfaceOnly: true, +}) as HostComponent; diff --git a/src/specs/OverKeyboardViewNativeComponent.ts b/src/specs/OverKeyboardViewNativeComponent.ts index f28b36067d..ca5872f3c6 100644 --- a/src/specs/OverKeyboardViewNativeComponent.ts +++ b/src/specs/OverKeyboardViewNativeComponent.ts @@ -7,6 +7,6 @@ export interface NativeProps extends ViewProps { visible?: boolean; } -export default codegenNativeComponent( - "OverKeyboardView", -) as HostComponent; +export default codegenNativeComponent("OverKeyboardView", { + interfaceOnly: true, +}) as HostComponent; diff --git a/src/views/OverKeyboardView/index.tsx b/src/views/OverKeyboardView/index.tsx index a4cc0078d1..dc81cb18ee 100644 --- a/src/views/OverKeyboardView/index.tsx +++ b/src/views/OverKeyboardView/index.tsx @@ -1,7 +1,6 @@ import React, { useMemo } from "react"; import { Platform, StyleSheet, View } from "react-native"; -import { IS_FABRIC } from "../../architecture"; import { RCTOverKeyboardView } from "../../bindings"; import { useWindowDimensions } from "../../hooks"; @@ -18,8 +17,9 @@ const OverKeyboardView = ({ () => [ styles.absolute, // On iOS - stretch view to full window dimensions to make yoga work - // On Android Fabric we temporarily use the same approach - Platform.OS === "ios" || IS_FABRIC ? inner : undefined, + Platform.OS === "ios" ? inner : undefined, + // On Android - we are laid out by ShadowNode, so just stretch to full container + Platform.OS === "android" ? styles.stretch : undefined, ], [inner], ); @@ -28,7 +28,8 @@ const OverKeyboardView = ({ {/* `OverKeyboardView` should always have a single child */} - {children} + {/* Match RN behavior and trigger mount/unmount when visibility changes */} + {visible && children} ); @@ -38,6 +39,12 @@ const styles = StyleSheet.create({ absolute: { position: "absolute", }, + stretch: { + top: 0, + bottom: 0, + left: 0, + right: 0, + }, }); export default OverKeyboardView;