From a1fd265dfc45cee215cddd63a3e979e7ed47ae2b Mon Sep 17 00:00:00 2001 From: jensvansteen Date: Wed, 8 Apr 2026 12:47:29 +0700 Subject: [PATCH 1/6] feat: refactor to plain fabric from nitro --- CONTRIBUTING.md | 33 +---- README.md | 17 ++- ScrollEdgeBar.podspec | 13 +- android/CMakeLists.txt | 24 ---- android/build.gradle | 118 ---------------- android/src/main/AndroidManifest.xml | 2 - android/src/main/cpp/cpp-adapter.cpp | 6 - .../nitro/scrolledgebar/ScrollEdgeBar.kt | 18 --- .../scrolledgebar/ScrollEdgeBarPackage.kt | 29 ---- ...crollEdgeBarBottomBarComponentDescriptor.h | 15 +++ .../RNScrollEdgeBarBottomBarShadowNode.cpp | 7 + .../RNScrollEdgeBarBottomBarShadowNode.h | 20 +++ .../RNScrollEdgeBarComponentDescriptor.h | 15 +++ .../RNScrollEdgeBarShadowNode.cpp | 7 + .../scrolledgebar/RNScrollEdgeBarShadowNode.h | 20 +++ ...RNScrollEdgeBarTopBarComponentDescriptor.h | 15 +++ .../RNScrollEdgeBarTopBarShadowNode.cpp | 7 + .../RNScrollEdgeBarTopBarShadowNode.h | 20 +++ example/ios/Podfile.lock | 4 +- example/src/screens/CalendarScreen.tsx | 12 +- ios/HybridScrollEdgeBar.swift | 70 +--------- ios/RNScrollEdgeBarBottomBarComponentView.h | 9 ++ ios/RNScrollEdgeBarBottomBarComponentView.mm | 48 +++++++ ios/RNScrollEdgeBarComponentView.h | 9 ++ ios/RNScrollEdgeBarComponentView.mm | 122 +++++++++++++++++ ios/RNScrollEdgeBarTopBarComponentView.h | 9 ++ ios/RNScrollEdgeBarTopBarComponentView.mm | 48 +++++++ nitro.json | 25 ---- package.json | 53 +++----- scripts/patch-nitrogen-scroll-edge-bar.js | 41 ------ scripts/verify-nitrogen-scroll-edge-bar.js | 40 ------ src/RNScrollEdgeBar.nitro.ts | 45 ------- ...RNScrollEdgeBarBottomBarNativeComponent.ts | 11 ++ src/fabric/RNScrollEdgeBarNativeComponent.ts | 21 +++ .../RNScrollEdgeBarTopBarNativeComponent.ts | 11 ++ src/index.tsx | 84 +++++++----- yarn.lock | 126 +----------------- 37 files changed, 516 insertions(+), 658 deletions(-) delete mode 100644 android/CMakeLists.txt delete mode 100644 android/build.gradle delete mode 100644 android/src/main/AndroidManifest.xml delete mode 100644 android/src/main/cpp/cpp-adapter.cpp delete mode 100644 android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBar.kt delete mode 100644 android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBarPackage.kt create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarComponentDescriptor.h create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.cpp create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.h create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarComponentDescriptor.h create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.cpp create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.h create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarComponentDescriptor.h create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.cpp create mode 100644 common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.h create mode 100644 ios/RNScrollEdgeBarBottomBarComponentView.h create mode 100644 ios/RNScrollEdgeBarBottomBarComponentView.mm create mode 100644 ios/RNScrollEdgeBarComponentView.h create mode 100644 ios/RNScrollEdgeBarComponentView.mm create mode 100644 ios/RNScrollEdgeBarTopBarComponentView.h create mode 100644 ios/RNScrollEdgeBarTopBarComponentView.mm delete mode 100644 nitro.json delete mode 100644 scripts/patch-nitrogen-scroll-edge-bar.js delete mode 100644 scripts/verify-nitrogen-scroll-edge-bar.js delete mode 100644 src/RNScrollEdgeBar.nitro.ts create mode 100644 src/fabric/RNScrollEdgeBarBottomBarNativeComponent.ts create mode 100644 src/fabric/RNScrollEdgeBarNativeComponent.ts create mode 100644 src/fabric/RNScrollEdgeBarTopBarNativeComponent.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8df7476..a23a386 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,38 +21,7 @@ yarn > Since the project relies on Yarn workspaces, you cannot use [`npm`](https://github.com/npm/cli) for development without manually migrating. -This project uses Nitro Modules. If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). - -You need to run [Nitrogen](https://nitro.margelo.com/docs/nitrogen) to generate the boilerplate code required for this project. The example app will not build without this step. - -Run **Nitrogen** in following cases: - -- When you make changes to any `*.nitro.ts` files. -- When running the project for the first time (since the generated files are not committed to the repository). - -To invoke **Nitrogen**, use the following command: - -```sh -yarn nitrogen -``` - -This command also reapplies the required Fabric unmount patch to: - -```sh -nitrogen/generated/ios/c++/views/HybridRNScrollEdgeBarComponent.mm -``` - -Do not run `nitrogen` directly unless you also rerun: - -```sh -yarn nitrogen:patch -``` - -To verify that the generated iOS component still contains the required Fabric lifecycle hooks, run: - -```sh -yarn nitrogen:verify -``` +This project currently uses plain React Native Fabric codegen for the iOS implementation. The [example app](/example/) demonstrates usage of the library. You need to run it to test any changes you make. diff --git a/README.md b/README.md index e2491d8..781c45e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # react-native-scroll-edge-bar -`react-native-scroll-edge-bar` is a Nitro-based React Native view for attaching custom top and bottom bars to a scroll view on iOS. +`react-native-scroll-edge-bar` is a Fabric-based React Native view for attaching custom top and bottom bars to a scroll view on iOS. -It currently targets the iOS 26 `safeAreaBar` APIs and is implemented only on iOS. Android scaffolding exists in the repo, but there is no Android feature implementation yet. +It currently targets the iOS 26 `safeAreaBar` APIs and is implemented only on iOS. ## Current Scope - iOS implementation: present - Android implementation: not implemented - Fabric / New Architecture: required -- Native dependency: `react-native-nitro-modules` +- Native dependency: none beyond standard React Native Fabric/codegen on iOS ## Public API @@ -35,16 +35,16 @@ Available components: - Extra offset to push the top bar below an external header. - `bottomBarOffset?: number` - Extra offset to lift the bottom bar above an external tab bar. -- Standard Nitro/RN view props such as `style` +- Standard RN view props such as `style` ### `ScrollEdgeBar.TopBar` props -- Standard Nitro/RN view props such as `style` +- Standard RN view props such as `style` - `children` ### `ScrollEdgeBar.BottomBar` props -- Standard Nitro/RN view props such as `style` +- Standard RN view props such as `style` - `children` ## Usage @@ -98,7 +98,7 @@ If your navigation header or tab bar is external to the scroll-edge-bar containe ## Installation ```sh -npm install react-native-scroll-edge-bar react-native-nitro-modules +npm install react-native-scroll-edge-bar ``` Then install iOS pods in your app: @@ -121,7 +121,6 @@ The example app in `example/` currently demonstrates: - iOS-only in practice - relies on view discovery and reparenting in Fabric, which is more fragile than a pure UIKit setup -- generated Nitrogen iOS component files currently contain manual logic; regenerating Nitrogen can overwrite those changes - the implementation is currently tuned around iOS 26 APIs ## Repo Notes @@ -129,7 +128,7 @@ The example app in `example/` currently demonstrates: Relevant files: - API surface: `src/index.tsx` -- Nitro types: `src/RNScrollEdgeBar.nitro.ts` +- Fabric specs: `src/fabric/*.ts` - iOS implementation: `ios/HybridScrollEdgeBar.swift` - example app: `example/src/App.tsx` diff --git a/ScrollEdgeBar.podspec b/ScrollEdgeBar.podspec index 9471d90..9984eca 100644 --- a/ScrollEdgeBar.podspec +++ b/ScrollEdgeBar.podspec @@ -15,16 +15,15 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/jensvansteen/react-native-scroll-edge-bar.git", :tag => "#{s.version}" } s.source_files = [ + "common/cpp/**/*.{cpp,h}", "ios/**/*.{swift}", "ios/**/*.{m,mm}", - "cpp/**/*.{hpp,cpp}", ] + s.project_header_files = "common/cpp/**/*.h" + s.pod_target_xcconfig = { + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\"" + } - s.dependency 'React-jsi' - s.dependency 'React-callinvoker' - - load 'nitrogen/generated/ios/RNScrollEdgeBar+autolinking.rb' - add_nitrogen_files(s) - + s.dependency 'React-Core' install_modules_dependencies(s) end diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt deleted file mode 100644 index 765edd9..0000000 --- a/android/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -project(scrolledgebar) -cmake_minimum_required(VERSION 3.9.0) - -set(PACKAGE_NAME scrolledgebar) -set(CMAKE_VERBOSE_MAKEFILE ON) -set(CMAKE_CXX_STANDARD 20) - -# Define C++ library and add all sources -add_library(${PACKAGE_NAME} SHARED src/main/cpp/cpp-adapter.cpp) - -# Add Nitrogen specs :) -include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/scrolledgebar+autolinking.cmake) - -# Set up local includes -include_directories("src/main/cpp" "../cpp") - -find_library(LOG_LIB log) - -# Link all libraries together -target_link_libraries( - ${PACKAGE_NAME} - ${LOG_LIB} - android # <-- Android core -) diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index 67f7a1b..0000000 --- a/android/build.gradle +++ /dev/null @@ -1,118 +0,0 @@ -buildscript { - ext.ScrollEdgeBar = [ - kotlinVersion: "2.0.21", - minSdkVersion: 24, - compileSdkVersion: 36, - targetSdkVersion: 36 - ] - - ext.getExtOrDefault = { prop -> - if (rootProject.ext.has(prop)) { - return rootProject.ext.get(prop) - } - - return ScrollEdgeBar[prop] - } - - repositories { - google() - mavenCentral() - } - - dependencies { - classpath "com.android.tools.build:gradle:8.7.2" - // noinspection DifferentKotlinGradleVersion - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}" - } -} - -def reactNativeArchitectures() { - def value = rootProject.getProperties().get("reactNativeArchitectures") - return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] -} - -apply plugin: "com.android.library" -apply plugin: "kotlin-android" -apply from: '../nitrogen/generated/android/scrolledgebar+autolinking.gradle' - -apply plugin: "com.facebook.react" - -android { - namespace "com.margelo.nitro.scrolledgebar" - - compileSdkVersion getExtOrDefault("compileSdkVersion") - - defaultConfig { - minSdkVersion getExtOrDefault("minSdkVersion") - targetSdkVersion getExtOrDefault("targetSdkVersion") - - externalNativeBuild { - cmake { - cppFlags "-frtti -fexceptions -Wall -fstack-protector-all" - arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON" - abiFilters (*reactNativeArchitectures()) - - buildTypes { - debug { - cppFlags "-O1 -g" - } - release { - cppFlags "-O2" - } - } - } - } - } - - externalNativeBuild { - cmake { - path "CMakeLists.txt" - } - } - - packagingOptions { - excludes = [ - "META-INF", - "META-INF/**", - "**/libc++_shared.so", - "**/libfbjni.so", - "**/libjsi.so", - "**/libfolly_json.so", - "**/libfolly_runtime.so", - "**/libglog.so", - "**/libhermes.so", - "**/libhermes-executor-debug.so", - "**/libhermes_executor.so", - "**/libreactnative.so", - "**/libreactnativejni.so", - "**/libturbomodulejsijni.so", - "**/libreact_nativemodule_core.so", - "**/libjscexecutor.so" - ] - } - - buildFeatures { - buildConfig true - prefab true - } - - buildTypes { - release { - minifyEnabled false - } - } - - lint { - disable "GradleCompatible" - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } -} - -dependencies { - implementation "com.facebook.react:react-android" - implementation project(":react-native-nitro-modules") -} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml deleted file mode 100644 index a2f47b6..0000000 --- a/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/android/src/main/cpp/cpp-adapter.cpp b/android/src/main/cpp/cpp-adapter.cpp deleted file mode 100644 index 31190d6..0000000 --- a/android/src/main/cpp/cpp-adapter.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include "scrolledgebarOnLoad.hpp" - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { - return margelo::nitro::scrolledgebar::initialize(vm); -} diff --git a/android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBar.kt b/android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBar.kt deleted file mode 100644 index deb23bb..0000000 --- a/android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBar.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.margelo.nitro.scrolledgebar - -import android.view.View -import com.facebook.proguard.annotations.DoNotStrip -import com.facebook.react.uimanager.ThemedReactContext - -@DoNotStrip -class HybridScrollEdgeBar(private val context: ThemedReactContext) : HybridRNScrollEdgeBarSpec() { - - override val view: View = View(context) - - override var estimatedTopBarHeight: Double? = null - override var estimatedBottomBarHeight: Double? = null - override var topBarOffset: Double? = null - override var bottomBarOffset: Double? = null - override var topEdgeEffectStyle: String? = null - override var bottomEdgeEffectStyle: String? = null -} diff --git a/android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBarPackage.kt b/android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBarPackage.kt deleted file mode 100644 index 0a6f012..0000000 --- a/android/src/main/java/com/margelo/nitro/scrolledgebar/ScrollEdgeBarPackage.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.margelo.nitro.scrolledgebar - -import com.facebook.react.BaseReactPackage -import com.facebook.react.bridge.NativeModule -import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.module.model.ReactModuleInfoProvider -import com.facebook.react.uimanager.ViewManager - -import com.margelo.nitro.scrolledgebar.views.HybridScrollEdgeBarManager - -class ScrollEdgeBarPackage : BaseReactPackage() { - override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { - return null - } - - override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { - return ReactModuleInfoProvider { HashMap() } - } - - override fun createViewManagers(reactContext: ReactApplicationContext): List> { - return listOf(HybridScrollEdgeBarManager()) - } - - companion object { - init { - System.loadLibrary("scrolledgebar") - } - } -} diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarComponentDescriptor.h b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarComponentDescriptor.h new file mode 100644 index 0000000..afc1aad --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarComponentDescriptor.h @@ -0,0 +1,15 @@ +#pragma once + +#include "RNScrollEdgeBarBottomBarShadowNode.h" + +#include + +namespace facebook::react { + +class RNScrollEdgeBarBottomBarComponentDescriptor final + : public ConcreteComponentDescriptor { + public: + using ConcreteComponentDescriptor::ConcreteComponentDescriptor; +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.cpp b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.cpp new file mode 100644 index 0000000..de5627d --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.cpp @@ -0,0 +1,7 @@ +#include "RNScrollEdgeBarBottomBarShadowNode.h" + +namespace facebook::react { + +const char RNScrollEdgeBarBottomBarComponentName[] = "RNScrollEdgeBarBottomBar"; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.h b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.h new file mode 100644 index 0000000..8a7d20f --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarBottomBarShadowNode.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +namespace facebook::react { + +extern const char RNScrollEdgeBarBottomBarComponentName[]; + +class RNScrollEdgeBarBottomBarShadowNode final + : public ConcreteViewShadowNode< + RNScrollEdgeBarBottomBarComponentName, + RNScrollEdgeBarBottomBarProps, + RNScrollEdgeBarBottomBarEventEmitter> { + public: + using ConcreteViewShadowNode::ConcreteViewShadowNode; +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarComponentDescriptor.h b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarComponentDescriptor.h new file mode 100644 index 0000000..259e339 --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarComponentDescriptor.h @@ -0,0 +1,15 @@ +#pragma once + +#include "RNScrollEdgeBarShadowNode.h" + +#include + +namespace facebook::react { + +class RNScrollEdgeBarComponentDescriptor final + : public ConcreteComponentDescriptor { + public: + using ConcreteComponentDescriptor::ConcreteComponentDescriptor; +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.cpp b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.cpp new file mode 100644 index 0000000..ed5aac1 --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.cpp @@ -0,0 +1,7 @@ +#include "RNScrollEdgeBarShadowNode.h" + +namespace facebook::react { + +const char RNScrollEdgeBarComponentName[] = "RNScrollEdgeBar"; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.h b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.h new file mode 100644 index 0000000..95639b6 --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarShadowNode.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +namespace facebook::react { + +extern const char RNScrollEdgeBarComponentName[]; + +class RNScrollEdgeBarShadowNode final + : public ConcreteViewShadowNode< + RNScrollEdgeBarComponentName, + RNScrollEdgeBarProps, + RNScrollEdgeBarEventEmitter> { + public: + using ConcreteViewShadowNode::ConcreteViewShadowNode; +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarComponentDescriptor.h b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarComponentDescriptor.h new file mode 100644 index 0000000..83010af --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarComponentDescriptor.h @@ -0,0 +1,15 @@ +#pragma once + +#include "RNScrollEdgeBarTopBarShadowNode.h" + +#include + +namespace facebook::react { + +class RNScrollEdgeBarTopBarComponentDescriptor final + : public ConcreteComponentDescriptor { + public: + using ConcreteComponentDescriptor::ConcreteComponentDescriptor; +}; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.cpp b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.cpp new file mode 100644 index 0000000..d1eb262 --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.cpp @@ -0,0 +1,7 @@ +#include "RNScrollEdgeBarTopBarShadowNode.h" + +namespace facebook::react { + +const char RNScrollEdgeBarTopBarComponentName[] = "RNScrollEdgeBarTopBar"; + +} // namespace facebook::react diff --git a/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.h b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.h new file mode 100644 index 0000000..6314c1f --- /dev/null +++ b/common/cpp/react/renderer/components/scrolledgebar/RNScrollEdgeBarTopBarShadowNode.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +namespace facebook::react { + +extern const char RNScrollEdgeBarTopBarComponentName[]; + +class RNScrollEdgeBarTopBarShadowNode final + : public ConcreteViewShadowNode< + RNScrollEdgeBarTopBarComponentName, + RNScrollEdgeBarTopBarProps, + RNScrollEdgeBarTopBarEventEmitter> { + public: + using ConcreteViewShadowNode::ConcreteViewShadowNode; +}; + +} // namespace facebook::react diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index e12e15e..3934f19 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2719,12 +2719,10 @@ PODS: - fmt - glog - hermes-engine - - NitroModules - RCT-Folly - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - - React-callinvoker - React-Core - React-debug - React-Fabric @@ -3095,7 +3093,7 @@ SPEC CHECKSUMS: ReactCommon: 424cc34cf5055d69a3dcf02f3436481afb8b0f6f RNGestureHandler: cd4be101cfa17ea6bbd438710caa02e286a84381 RNScreens: c77cc7a5d1fbc23f0725b54e96eec81118453382 - ScrollEdgeBar: 3823674d457505ae0598b99e99dfc5c70015d062 + ScrollEdgeBar: 7838bc5a8df069488b5612c3fedc07baf7f5e3a1 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: 6ca93c8c13f56baeec55eb608577619b17a4d64e diff --git a/example/src/screens/CalendarScreen.tsx b/example/src/screens/CalendarScreen.tsx index 7be1883..9548490 100644 --- a/example/src/screens/CalendarScreen.tsx +++ b/example/src/screens/CalendarScreen.tsx @@ -31,12 +31,12 @@ const events = [ durationHours: 2, color: '#AF52DE', }, - { - title: 'Lunch', - startHour: 13, - durationHours: 1, - color: '#FF9F0A', - }, + // { + // title: 'Lunch', + // startHour: 13, + // durationHours: 1, + // color: '#FF9F0A', + // }, { title: 'Focus Time', startHour: 15, diff --git a/ios/HybridScrollEdgeBar.swift b/ios/HybridScrollEdgeBar.swift index 28bc595..53771a1 100644 --- a/ios/HybridScrollEdgeBar.swift +++ b/ios/HybridScrollEdgeBar.swift @@ -1,6 +1,5 @@ import UIKit import SwiftUI -import NitroModules // MARK: - Marker Views @@ -12,63 +11,9 @@ class ScrollEdgeBarTopBarView: UIView {} @objc(ScrollEdgeBarBottomBarView) class ScrollEdgeBarBottomBarView: UIView {} -// MARK: - Nitro Hybrid Views - -class HybridScrollEdgeBarTopBar: HybridRNScrollEdgeBarTopBarSpec { - private let containerView = ScrollEdgeBarTopBarView() - var view: UIView { containerView } -} - -class HybridScrollEdgeBarBottomBar: HybridRNScrollEdgeBarBottomBarSpec { - private let containerView = ScrollEdgeBarBottomBarView() - var view: UIView { containerView } -} - -class HybridScrollEdgeBar: HybridRNScrollEdgeBarSpec { - private let containerView = ScrollEdgeBarContainerView() - - var view: UIView { containerView } - - var estimatedTopBarHeight: Double? = 60 { - didSet { - containerView.estimatedTopBarHeight = CGFloat(estimatedTopBarHeight ?? 60) - } - } - - var estimatedBottomBarHeight: Double? = 60 { - didSet { - containerView.estimatedBottomBarHeight = CGFloat(estimatedBottomBarHeight ?? 60) - } - } - - var topBarOffset: Double? = 0 { - didSet { - containerView.topBarOffset = CGFloat(topBarOffset ?? 0) - } - } - - var bottomBarOffset: Double? = 0 { - didSet { - containerView.bottomBarOffset = CGFloat(bottomBarOffset ?? 0) - } - } - - var topEdgeEffectStyle: String? = "automatic" { - didSet { - containerView.topEdgeEffectStyle = topEdgeEffectStyle ?? "automatic" - } - } - - var bottomEdgeEffectStyle: String? = "automatic" { - didSet { - containerView.bottomEdgeEffectStyle = bottomEdgeEffectStyle ?? "automatic" - } - } - -} - // MARK: - Container View +@objc(ScrollEdgeBarContainerView) @objcMembers class ScrollEdgeBarContainerView: UIView { var estimatedTopBarHeight: CGFloat = 60 @@ -135,17 +80,16 @@ class ScrollEdgeBarContainerView: UIView { } private func detectChildViews() { - // In Fabric/Nitro, React children are siblings of this view inside the - // generated component wrapper, not direct subviews of the container. + // In Fabric, React children are siblings of this view inside the + // component wrapper, not direct subviews of the container. let searchViews = superview?.subviews ?? subviews for subview in searchViews where subview !== self { if detectedTopBarView == nil, let topBarMarker = findView(ofType: ScrollEdgeBarTopBarView.self, in: subview) { - // Use the wrapper that holds both the marker and the React content. - detectedTopBarView = topBarMarker.superview ?? topBarMarker + detectedTopBarView = topBarMarker } else if detectedBottomBarView == nil, let bottomBarMarker = findView(ofType: ScrollEdgeBarBottomBarView.self, in: subview) { - detectedBottomBarView = bottomBarMarker.superview ?? bottomBarMarker + detectedBottomBarView = bottomBarMarker } else if detectedScrollView == nil, let scrollView = findScrollView(in: subview) { detectedScrollView = scrollView @@ -170,7 +114,7 @@ class ScrollEdgeBarContainerView: UIView { func setTopBarView(_ view: UIView?) { if let view { let marker = findView(ofType: ScrollEdgeBarTopBarView.self, in: view) - detectedTopBarView = marker?.superview ?? marker + detectedTopBarView = marker } else { detectedTopBarView = nil } @@ -180,7 +124,7 @@ class ScrollEdgeBarContainerView: UIView { func setBottomBarView(_ view: UIView?) { if let view { let marker = findView(ofType: ScrollEdgeBarBottomBarView.self, in: view) - detectedBottomBarView = marker?.superview ?? marker + detectedBottomBarView = marker } else { detectedBottomBarView = nil } diff --git a/ios/RNScrollEdgeBarBottomBarComponentView.h b/ios/RNScrollEdgeBarBottomBarComponentView.h new file mode 100644 index 0000000..0de821a --- /dev/null +++ b/ios/RNScrollEdgeBarBottomBarComponentView.h @@ -0,0 +1,9 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNScrollEdgeBarBottomBarComponentView : RCTViewComponentView + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/RNScrollEdgeBarBottomBarComponentView.mm b/ios/RNScrollEdgeBarBottomBarComponentView.mm new file mode 100644 index 0000000..006afe5 --- /dev/null +++ b/ios/RNScrollEdgeBarBottomBarComponentView.mm @@ -0,0 +1,48 @@ +#import "RNScrollEdgeBarBottomBarComponentView.h" + +#import +#import + +@interface ScrollEdgeBarBottomBarView : UIView +@end + +using namespace facebook::react; + +@implementation RNScrollEdgeBarBottomBarComponentView +{ + ScrollEdgeBarBottomBarView *_markerView; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + _markerView = [ScrollEdgeBarBottomBarView new]; + [self addSubview:_markerView]; + } + return self; +} + ++ (BOOL)shouldBeRecycled +{ + return NO; +} + +- (UIView *)currentContainerView +{ + return _markerView ?: self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + _markerView.frame = self.bounds; +} + +@end diff --git a/ios/RNScrollEdgeBarComponentView.h b/ios/RNScrollEdgeBarComponentView.h new file mode 100644 index 0000000..d32ade5 --- /dev/null +++ b/ios/RNScrollEdgeBarComponentView.h @@ -0,0 +1,9 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNScrollEdgeBarComponentView : RCTViewComponentView + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/RNScrollEdgeBarComponentView.mm b/ios/RNScrollEdgeBarComponentView.mm new file mode 100644 index 0000000..fef8178 --- /dev/null +++ b/ios/RNScrollEdgeBarComponentView.mm @@ -0,0 +1,122 @@ +#import "RNScrollEdgeBarComponentView.h" + +#import +#import +#import + +#import "RNScrollEdgeBarTopBarComponentView.h" +#import "RNScrollEdgeBarBottomBarComponentView.h" + +@interface ScrollEdgeBarContainerView : UIView +- (void)prepareForFabricUnmount; +- (void)setTopBarView:(UIView *)view; +- (void)setBottomBarView:(UIView *)view; +- (void)setScrollView:(UIView *)view; +@property (nonatomic, assign) CGFloat estimatedTopBarHeight; +@property (nonatomic, assign) CGFloat estimatedBottomBarHeight; +@property (nonatomic, assign) CGFloat topBarOffset; +@property (nonatomic, assign) CGFloat bottomBarOffset; +@property (nonatomic, copy) NSString *topEdgeEffectStyle; +@property (nonatomic, copy) NSString *bottomEdgeEffectStyle; +@end + +using namespace facebook::react; + +static NSString *RCTNSStringFromStdString(const std::string &value) +{ + return [NSString stringWithUTF8String:value.c_str()] ?: @""; +} + +static NSString *RCTNSStringFromTopEdgeEffectStyle(const facebook::react::RNScrollEdgeBarTopEdgeEffectStyle &value) +{ + return RCTNSStringFromStdString(facebook::react::toString(value)); +} + +static NSString *RCTNSStringFromBottomEdgeEffectStyle( + const facebook::react::RNScrollEdgeBarBottomEdgeEffectStyle &value) +{ + return RCTNSStringFromStdString(facebook::react::toString(value)); +} + +@implementation RNScrollEdgeBarComponentView + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + [self setContentView:[ScrollEdgeBarContainerView new]]; + } + return self; +} + ++ (BOOL)shouldBeRecycled +{ + return NO; +} + +- (ScrollEdgeBarContainerView *)scrollEdgeBarContainerView +{ + return (ScrollEdgeBarContainerView *)self.contentView; +} + +- (UIView *)resolvedContentViewForChild:(UIView *)childComponentView +{ + if ([childComponentView isKindOfClass:[RCTViewComponentView class]]) { + RCTViewComponentView *viewComponent = (RCTViewComponentView *)childComponentView; + return viewComponent.contentView ?: childComponentView; + } + return childComponentView; +} + +- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps +{ + const auto &newProps = *std::static_pointer_cast(props); + ScrollEdgeBarContainerView *view = [self scrollEdgeBarContainerView]; + + view.estimatedTopBarHeight = newProps.estimatedTopBarHeight; + view.estimatedBottomBarHeight = newProps.estimatedBottomBarHeight; + view.topBarOffset = newProps.topBarOffset; + view.bottomBarOffset = newProps.bottomBarOffset; + view.topEdgeEffectStyle = RCTNSStringFromTopEdgeEffectStyle(newProps.topEdgeEffectStyle); + view.bottomEdgeEffectStyle = RCTNSStringFromBottomEdgeEffectStyle(newProps.bottomEdgeEffectStyle); + + [super updateProps:props oldProps:oldProps]; +} + +- (void)mountChildComponentView:(UIView *)childComponentView + index:(NSInteger)index +{ + [super mountChildComponentView:childComponentView index:index]; + + UIView *resolvedView = [self resolvedContentViewForChild:childComponentView]; + ScrollEdgeBarContainerView *container = [self scrollEdgeBarContainerView]; + + if ([childComponentView isKindOfClass:[RNScrollEdgeBarTopBarComponentView class]]) { + [container setTopBarView:resolvedView]; + } else if ([childComponentView isKindOfClass:[RNScrollEdgeBarBottomBarComponentView class]]) { + [container setBottomBarView:resolvedView]; + } else { + [container setScrollView:resolvedView]; + } +} + +- (void)unmountChildComponentView:(UIView *)childComponentView + index:(NSInteger)index +{ + [[self scrollEdgeBarContainerView] prepareForFabricUnmount]; + [super unmountChildComponentView:childComponentView index:index]; +} + +- (void)invalidate +{ + [[self scrollEdgeBarContainerView] prepareForFabricUnmount]; + [super invalidate]; +} + +@end diff --git a/ios/RNScrollEdgeBarTopBarComponentView.h b/ios/RNScrollEdgeBarTopBarComponentView.h new file mode 100644 index 0000000..6a1e63a --- /dev/null +++ b/ios/RNScrollEdgeBarTopBarComponentView.h @@ -0,0 +1,9 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNScrollEdgeBarTopBarComponentView : RCTViewComponentView + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/RNScrollEdgeBarTopBarComponentView.mm b/ios/RNScrollEdgeBarTopBarComponentView.mm new file mode 100644 index 0000000..535bfe8 --- /dev/null +++ b/ios/RNScrollEdgeBarTopBarComponentView.mm @@ -0,0 +1,48 @@ +#import "RNScrollEdgeBarTopBarComponentView.h" + +#import +#import + +@interface ScrollEdgeBarTopBarView : UIView +@end + +using namespace facebook::react; + +@implementation RNScrollEdgeBarTopBarComponentView +{ + ScrollEdgeBarTopBarView *_markerView; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + _markerView = [ScrollEdgeBarTopBarView new]; + [self addSubview:_markerView]; + } + return self; +} + ++ (BOOL)shouldBeRecycled +{ + return NO; +} + +- (UIView *)currentContainerView +{ + return _markerView ?: self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + _markerView.frame = self.bounds; +} + +@end diff --git a/nitro.json b/nitro.json deleted file mode 100644 index 0e6c300..0000000 --- a/nitro.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "cxxNamespace": ["scrolledgebar"], - "ios": { - "iosModuleName": "RNScrollEdgeBar" - }, - "android": { - "androidNamespace": ["scrolledgebar"], - "androidCxxLibName": "RNScrollEdgeBar" - }, - "autolinking": { - "RNScrollEdgeBar": { - "swift": "HybridScrollEdgeBar", - "kotlin": "HybridScrollEdgeBar" - }, - "RNScrollEdgeBarTopBar": { - "swift": "HybridScrollEdgeBarTopBar", - "kotlin": "HybridScrollEdgeBarTopBar" - }, - "RNScrollEdgeBarBottomBar": { - "swift": "HybridScrollEdgeBarBottomBar", - "kotlin": "HybridScrollEdgeBarBottomBar" - } - }, - "ignorePaths": ["node_modules"] -} diff --git a/package.json b/package.json index cbd886f..30c8e5d 100644 --- a/package.json +++ b/package.json @@ -15,19 +15,10 @@ "files": [ "src", "lib", - "android", + "common", "ios", - "cpp", - "nitrogen", - "nitro.json", "*.podspec", - "react-native.config.js", "!ios/build", - "!android/build", - "!android/gradle", - "!android/gradlew", - "!android/gradlew.bat", - "!android/local.properties", "!**/__tests__", "!**/__fixtures__", "!**/__mocks__", @@ -35,12 +26,8 @@ ], "scripts": { "example": "yarn workspace react-native-scroll-edge-bar-example", - "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib", + "clean": "del-cli example/android/build example/android/app/build example/ios/build lib", "prepare": "bob build", - "nitrogen:generate": "nitrogen", - "nitrogen:patch": "node scripts/patch-nitrogen-scroll-edge-bar.js", - "nitrogen:verify": "node scripts/verify-nitrogen-scroll-edge-bar.js", - "nitrogen": "yarn nitrogen:generate ./src && yarn nitrogen:patch", "typecheck": "tsc", "lint": "eslint \"**/*.{js,ts,tsx}\"", "test": "jest", @@ -48,8 +35,7 @@ }, "keywords": [ "react-native", - "ios", - "android" + "ios" ], "repository": { "type": "git", @@ -81,36 +67,38 @@ "eslint-plugin-prettier": "^5.5.4", "jest": "^29.7.0", "lefthook": "^2.0.3", - "nitrogen": "^0.33.7", "prettier": "^2.8.8", "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "^0.33.7", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" }, "peerDependencies": { "react": "*", - "react-native": "*", - "react-native-nitro-modules": "^0.33.7" + "react-native": "*" }, "workspaces": [ "example" ], "packageManager": "yarn@4.11.0", + "codegenConfig": { + "name": "scrolledgebar", + "type": "all", + "jsSrcsDir": "./src/fabric", + "ios": { + "componentProvider": { + "RNScrollEdgeBar": "RNScrollEdgeBarComponentView", + "RNScrollEdgeBarTopBar": "RNScrollEdgeBarTopBarComponentView", + "RNScrollEdgeBarBottomBar": "RNScrollEdgeBarBottomBarComponentView" + } + } + }, "react-native-builder-bob": { "source": "src", "output": "lib", "targets": [ - [ - "custom", - { - "script": "nitrogen", - "clean": "nitrogen/" - } - ], [ "module", { @@ -164,8 +152,8 @@ } }, "create-react-native-library": { - "type": "nitro-view", - "languages": "kotlin-swift", + "type": "view", + "languages": "swift", "tools": [ "eslint", "jest", @@ -177,10 +165,5 @@ "dependencies": { "react-native-safe-area-context": "^5.6.2", "react-native-screens": "^4.22.0" - }, - "overrides": { - "react-native-nitro-sfsymbols": { - "react-native-nitro-modules": "$react-native-nitro-modules" - } } } diff --git a/scripts/patch-nitrogen-scroll-edge-bar.js b/scripts/patch-nitrogen-scroll-edge-bar.js deleted file mode 100644 index 1482a74..0000000 --- a/scripts/patch-nitrogen-scroll-edge-bar.js +++ /dev/null @@ -1,41 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -const file = path.join( - __dirname, - '..', - 'nitrogen', - 'generated', - 'ios', - 'c++', - 'views', - 'HybridRNScrollEdgeBarComponent.mm' -); - -if (!fs.existsSync(file)) { - console.error(`Missing generated file: ${file}`); - process.exit(1); -} - -let source = fs.readFileSync(file, 'utf8'); - -const target = `- (void)invalidate\n{\n [[self scrollEdgeBarContainerView] prepareForFabricUnmount];\n [super invalidate];\n}`; -const patch = `${target}\n\n- (void)unmountChildComponentView:(UIView *)childComponentView\n index:(NSInteger)index\n{\n [[self scrollEdgeBarContainerView] prepareForFabricUnmount];\n [super unmountChildComponentView:childComponentView index:index];\n}`; - -if ( - source.includes( - '- (void)unmountChildComponentView:(UIView *)childComponentView' - ) -) { - console.log('Nitrogen patch already applied.'); - process.exit(0); -} - -if (!source.includes(target)) { - console.error('Could not find invalidate block to patch.'); - process.exit(1); -} - -source = source.replace(target, patch); -fs.writeFileSync(file, source); -console.log('Applied ScrollEdgeBar Nitrogen patch.'); diff --git a/scripts/verify-nitrogen-scroll-edge-bar.js b/scripts/verify-nitrogen-scroll-edge-bar.js deleted file mode 100644 index 36ea5ee..0000000 --- a/scripts/verify-nitrogen-scroll-edge-bar.js +++ /dev/null @@ -1,40 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -const file = path.join( - __dirname, - '..', - 'nitrogen', - 'generated', - 'ios', - 'c++', - 'views', - 'HybridRNScrollEdgeBarComponent.mm' -); - -if (!fs.existsSync(file)) { - console.error(`Missing generated file: ${file}`); - process.exit(1); -} - -const source = fs.readFileSync(file, 'utf8'); -const checks = [ - '+ (BOOL)shouldBeRecycled {', - 'return NO;', - '- (void)invalidate', - 'prepareForFabricUnmount', - '- (void)unmountChildComponentView:(UIView *)childComponentView', - '[super unmountChildComponentView:childComponentView index:index];', -]; - -const missing = checks.filter((needle) => !source.includes(needle)); - -if (missing.length > 0) { - console.error('Nitrogen patch verification failed. Missing markers:'); - for (const item of missing) { - console.error(`- ${item}`); - } - process.exit(1); -} - -console.log('Nitrogen patch verification passed.'); diff --git a/src/RNScrollEdgeBar.nitro.ts b/src/RNScrollEdgeBar.nitro.ts deleted file mode 100644 index c4e4f84..0000000 --- a/src/RNScrollEdgeBar.nitro.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { - HybridView, - HybridViewMethods, - HybridViewProps, -} from 'react-native-nitro-modules'; - -// Main container -export interface RNScrollEdgeBarProps extends HybridViewProps { - /** Estimated top bar height (used before layout to prevent flicker) */ - estimatedTopBarHeight?: number; - /** Estimated bottom bar height (used before layout to prevent flicker) */ - estimatedBottomBarHeight?: number; - /** Extra offset to push the top bar below a transparent header */ - topBarOffset?: number; - /** Extra offset to lift the bottom bar above a tab bar */ - bottomBarOffset?: number; - /** iOS 26+: edge effect style for the top edge (`automatic`, `soft`, `hard`) */ - topEdgeEffectStyle?: string; - /** iOS 26+: edge effect style for the bottom edge (`automatic`, `soft`, `hard`) */ - bottomEdgeEffectStyle?: string; -} -export interface RNScrollEdgeBarMethods extends HybridViewMethods {} - -export type RNScrollEdgeBar = HybridView< - RNScrollEdgeBarProps, - RNScrollEdgeBarMethods ->; - -// Top bar slot -export interface RNScrollEdgeBarTopBarProps extends HybridViewProps {} -export interface RNScrollEdgeBarTopBarMethods extends HybridViewMethods {} - -export type RNScrollEdgeBarTopBar = HybridView< - RNScrollEdgeBarTopBarProps, - RNScrollEdgeBarTopBarMethods ->; - -// Bottom bar slot -export interface RNScrollEdgeBarBottomBarProps extends HybridViewProps {} -export interface RNScrollEdgeBarBottomBarMethods extends HybridViewMethods {} - -export type RNScrollEdgeBarBottomBar = HybridView< - RNScrollEdgeBarBottomBarProps, - RNScrollEdgeBarBottomBarMethods ->; diff --git a/src/fabric/RNScrollEdgeBarBottomBarNativeComponent.ts b/src/fabric/RNScrollEdgeBarBottomBarNativeComponent.ts new file mode 100644 index 0000000..89af36f --- /dev/null +++ b/src/fabric/RNScrollEdgeBarBottomBarNativeComponent.ts @@ -0,0 +1,11 @@ +import { + codegenNativeComponent, + type HostComponent, + type ViewProps, +} from 'react-native'; + +export interface NativeProps extends ViewProps {} + +export default codegenNativeComponent('RNScrollEdgeBarBottomBar', { + interfaceOnly: true, +}) as HostComponent; diff --git a/src/fabric/RNScrollEdgeBarNativeComponent.ts b/src/fabric/RNScrollEdgeBarNativeComponent.ts new file mode 100644 index 0000000..222fd2e --- /dev/null +++ b/src/fabric/RNScrollEdgeBarNativeComponent.ts @@ -0,0 +1,21 @@ +import { + codegenNativeComponent, + type CodegenTypes as CT, + type HostComponent, + type ViewProps, +} from 'react-native'; + +type ScrollEdgeEffectStyle = 'automatic' | 'soft' | 'hard'; + +export interface NativeProps extends ViewProps { + estimatedTopBarHeight?: CT.WithDefault; + estimatedBottomBarHeight?: CT.WithDefault; + topBarOffset?: CT.WithDefault; + bottomBarOffset?: CT.WithDefault; + topEdgeEffectStyle?: CT.WithDefault; + bottomEdgeEffectStyle?: CT.WithDefault; +} + +export default codegenNativeComponent('RNScrollEdgeBar', { + interfaceOnly: true, +}) as HostComponent; diff --git a/src/fabric/RNScrollEdgeBarTopBarNativeComponent.ts b/src/fabric/RNScrollEdgeBarTopBarNativeComponent.ts new file mode 100644 index 0000000..885d5c2 --- /dev/null +++ b/src/fabric/RNScrollEdgeBarTopBarNativeComponent.ts @@ -0,0 +1,11 @@ +import { + codegenNativeComponent, + type HostComponent, + type ViewProps, +} from 'react-native'; + +export interface NativeProps extends ViewProps {} + +export default codegenNativeComponent('RNScrollEdgeBarTopBar', { + interfaceOnly: true, +}) as HostComponent; diff --git a/src/index.tsx b/src/index.tsx index 73411ae..8e118b7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,69 +1,83 @@ import * as React from 'react'; -import { getHostComponent } from 'react-native-nitro-modules'; import type { ReactNode } from 'react'; import type { StyleProp, ViewStyle } from 'react-native'; -import type { - RNScrollEdgeBarMethods, - RNScrollEdgeBarProps, - RNScrollEdgeBarTopBarMethods, - RNScrollEdgeBarTopBarProps, - RNScrollEdgeBarBottomBarMethods, - RNScrollEdgeBarBottomBarProps, -} from './RNScrollEdgeBar.nitro'; -// Generated configs -const RNScrollEdgeBarConfig = require('../nitrogen/generated/shared/json/RNScrollEdgeBarConfig.json'); -const RNScrollEdgeBarTopBarConfig = require('../nitrogen/generated/shared/json/RNScrollEdgeBarTopBarConfig.json'); -const RNScrollEdgeBarBottomBarConfig = require('../nitrogen/generated/shared/json/RNScrollEdgeBarBottomBarConfig.json'); +import RNScrollEdgeBarNativeComponent, { + type NativeProps as RNScrollEdgeBarProps, +} from './fabric/RNScrollEdgeBarNativeComponent'; +import RNScrollEdgeBarTopBarNativeComponent, { + type NativeProps as RNScrollEdgeBarTopBarProps, +} from './fabric/RNScrollEdgeBarTopBarNativeComponent'; +import RNScrollEdgeBarBottomBarNativeComponent, { + type NativeProps as RNScrollEdgeBarBottomBarProps, +} from './fabric/RNScrollEdgeBarBottomBarNativeComponent'; + +export interface RNScrollEdgeBarMethods {} +export interface RNScrollEdgeBarTopBarMethods {} +export interface RNScrollEdgeBarBottomBarMethods {} -// Base components export type ScrollEdgeBarProps = RNScrollEdgeBarProps & { children?: ReactNode; style?: StyleProp; }; -const ScrollEdgeBarBase = getHostComponent< - RNScrollEdgeBarProps, - RNScrollEdgeBarMethods ->('RNScrollEdgeBar', () => RNScrollEdgeBarConfig); - export type ScrollEdgeBarTopBarProps = RNScrollEdgeBarTopBarProps & { children?: ReactNode; style?: StyleProp; }; -const TopBar = getHostComponent< - RNScrollEdgeBarTopBarProps, - RNScrollEdgeBarTopBarMethods ->('RNScrollEdgeBarTopBar', () => RNScrollEdgeBarTopBarConfig); - export type ScrollEdgeBarBottomBarProps = RNScrollEdgeBarBottomBarProps & { children?: ReactNode; style?: StyleProp; }; -const BottomBar = getHostComponent< - RNScrollEdgeBarBottomBarProps, - RNScrollEdgeBarBottomBarMethods ->('RNScrollEdgeBarBottomBar', () => RNScrollEdgeBarBottomBarConfig); - const ScrollEdgeBarComponent = React.forwardRef< - RNScrollEdgeBarMethods, + React.ElementRef, ScrollEdgeBarProps >((props, ref) => - React.createElement(ScrollEdgeBarBase as React.ElementType, { ...props, ref }) + React.createElement(RNScrollEdgeBarNativeComponent as React.ElementType, { + ...props, + ref, + }) +); + +const TopBar = React.forwardRef< + React.ElementRef, + ScrollEdgeBarTopBarProps +>((props, ref) => + React.createElement( + RNScrollEdgeBarTopBarNativeComponent as React.ElementType, + { + ...props, + ref, + } + ) +); + +const BottomBar = React.forwardRef< + React.ElementRef, + ScrollEdgeBarBottomBarProps +>((props, ref) => + React.createElement( + RNScrollEdgeBarBottomBarNativeComponent as React.ElementType, + { + ...props, + ref, + } + ) ); ScrollEdgeBarComponent.displayName = 'ScrollEdgeBar'; +TopBar.displayName = 'ScrollEdgeBar.TopBar'; +BottomBar.displayName = 'ScrollEdgeBar.BottomBar'; -// Compound component export const ScrollEdgeBar = Object.assign(ScrollEdgeBarComponent, { TopBar, BottomBar, }); export type { - RNScrollEdgeBarMethods, - RNScrollEdgeBarTopBarMethods, - RNScrollEdgeBarBottomBarMethods, + RNScrollEdgeBarProps, + RNScrollEdgeBarTopBarProps, + RNScrollEdgeBarBottomBarProps, }; diff --git a/yarn.lock b/yarn.lock index d57fdf6..b7ff173 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3353,17 +3353,6 @@ __metadata: languageName: node linkType: hard -"@ts-morph/common@npm:~0.28.1": - version: 0.28.1 - resolution: "@ts-morph/common@npm:0.28.1" - dependencies: - minimatch: "npm:^10.0.1" - path-browserify: "npm:^1.0.1" - tinyglobby: "npm:^0.2.14" - checksum: 10c0/d51276d840997e0f8f83e04f8b1689135bb12588a7ddbed575f87848d5737eeae31e242685d6449de27573e8ed30892157fea643393cb875e175f2711200bc50 - languageName: node - linkType: hard - "@types/babel__core@npm:^7.1.14": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" @@ -3855,7 +3844,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": +"ansi-styles@npm:^6.1.0": version: 6.2.3 resolution: "ansi-styles@npm:6.2.3" checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 @@ -4681,17 +4670,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^9.0.1": - version: 9.0.1 - resolution: "cliui@npm:9.0.1" - dependencies: - string-width: "npm:^7.2.0" - strip-ansi: "npm:^7.1.0" - wrap-ansi: "npm:^9.0.0" - checksum: 10c0/13441832e9efe7c7a76bd2b8e683555c478d461a9f249dc5db9b17fe8d4b47fa9277b503914b90bd00e4a151abb6b9b02b2288972ffe2e5e3ca40bcb1c2330d3 - languageName: node - linkType: hard - "clone@npm:^1.0.2": version: 1.0.4 resolution: "clone@npm:1.0.4" @@ -4706,13 +4684,6 @@ __metadata: languageName: node linkType: hard -"code-block-writer@npm:^13.0.3": - version: 13.0.3 - resolution: "code-block-writer@npm:13.0.3" - checksum: 10c0/87db97b37583f71cfd7eced8bf3f0a0a0ca53af912751a734372b36c08cd27f3e8a4878ec05591c0cd9ae11bea8add1423e132d660edd86aab952656dd41fd66 - languageName: node - linkType: hard - "collect-v8-coverage@npm:^1.0.0": version: 1.0.3 resolution: "collect-v8-coverage@npm:1.0.3" @@ -5455,13 +5426,6 @@ __metadata: languageName: node linkType: hard -"emoji-regex@npm:^10.3.0": - version: 10.6.0 - resolution: "emoji-regex@npm:10.6.0" - checksum: 10c0/1e4aa097bb007301c3b4b1913879ae27327fdc48e93eeefefe3b87e495eb33c5af155300be951b4349ff6ac084f4403dc9eff970acba7c1c572d89396a9a32d7 - languageName: node - linkType: hard - "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -6506,7 +6470,7 @@ __metadata: languageName: node linkType: hard -"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.3.0": +"get-east-asian-width@npm:^1.3.0": version: 1.4.0 resolution: "get-east-asian-width@npm:1.4.0" checksum: 10c0/4e481d418e5a32061c36fbb90d1b225a254cc5b2df5f0b25da215dcd335a3c111f0c2023ffda43140727a9cafb62dac41d022da82c08f31083ee89f714ee3b83 @@ -9150,7 +9114,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.0.1, minimatch@npm:^10.1.2": +"minimatch@npm:^10.1.2": version: 10.1.2 resolution: "minimatch@npm:10.1.2" dependencies: @@ -9350,21 +9314,6 @@ __metadata: languageName: node linkType: hard -"nitrogen@npm:^0.33.7": - version: 0.33.7 - resolution: "nitrogen@npm:0.33.7" - dependencies: - chalk: "npm:^5.3.0" - react-native-nitro-modules: "npm:^0.33.7" - ts-morph: "npm:^27.0.0" - yargs: "npm:^18.0.0" - zod: "npm:^4.0.5" - bin: - nitrogen: lib/index.js - checksum: 10c0/3e574428155925a17dcf62402ee8e70d10a5263380ce8f92b8cf0484663c79b64b4f3fee2793f55e2b7fb34b7e3f1fba7df678904bf59a500be09c4a36da9f31 - languageName: node - linkType: hard - "nocache@npm:^3.0.1": version: 3.0.4 resolution: "nocache@npm:3.0.4" @@ -9892,13 +9841,6 @@ __metadata: languageName: node linkType: hard -"path-browserify@npm:^1.0.1": - version: 1.0.1 - resolution: "path-browserify@npm:1.0.1" - checksum: 10c0/8b8c3fd5c66bd340272180590ae4ff139769e9ab79522e2eb82e3d571a89b8117c04147f65ad066dccfb42fcad902e5b7d794b3d35e0fd840491a8ddbedf8c66 - languageName: node - linkType: hard - "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -10350,7 +10292,7 @@ __metadata: languageName: node linkType: hard -"react-native-nitro-modules@npm:^0.33.3, react-native-nitro-modules@npm:^0.33.7": +"react-native-nitro-modules@npm:^0.33.3": version: 0.33.7 resolution: "react-native-nitro-modules@npm:0.33.7" peerDependencies: @@ -10445,12 +10387,10 @@ __metadata: eslint-plugin-prettier: "npm:^5.5.4" jest: "npm:^29.7.0" lefthook: "npm:^2.0.3" - nitrogen: "npm:^0.33.7" prettier: "npm:^2.8.8" react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:^0.33.7" react-native-safe-area-context: "npm:^5.6.2" react-native-screens: "npm:^4.22.0" release-it: "npm:^19.0.4" @@ -10459,7 +10399,6 @@ __metadata: peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.33.7 languageName: unknown linkType: soft @@ -11376,17 +11315,6 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^7.0.0, string-width@npm:^7.2.0": - version: 7.2.0 - resolution: "string-width@npm:7.2.0" - dependencies: - emoji-regex: "npm:^10.3.0" - get-east-asian-width: "npm:^1.0.0" - strip-ansi: "npm:^7.1.0" - checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 - languageName: node - linkType: hard - "string-width@npm:^8.1.0": version: 8.1.1 resolution: "string-width@npm:8.1.1" @@ -11637,7 +11565,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:0.2.15, tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": +"tinyglobby@npm:0.2.15, tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -11679,16 +11607,6 @@ __metadata: languageName: node linkType: hard -"ts-morph@npm:^27.0.0": - version: 27.0.2 - resolution: "ts-morph@npm:27.0.2" - dependencies: - "@ts-morph/common": "npm:~0.28.1" - code-block-writer: "npm:^13.0.3" - checksum: 10c0/224715cc6d97b8ff5afd3986f9629f912a0ebd83eaecbdca91c35cf10a98f607c663f666e7ea5e6afab00563d00dc80fa7a13552cc7f1cef735261c3217d0863 - languageName: node - linkType: hard - "tslib@npm:^2.0.1, tslib@npm:^2.1.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" @@ -12323,17 +12241,6 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^9.0.0": - version: 9.0.2 - resolution: "wrap-ansi@npm:9.0.2" - dependencies: - ansi-styles: "npm:^6.2.1" - string-width: "npm:^7.0.0" - strip-ansi: "npm:^7.1.0" - checksum: 10c0/3305839b9a0d6fb930cb63a52f34d3936013d8b0682ff3ec133c9826512620f213800ffa19ea22904876d5b7e9a3c1f40682f03597d986a4ca881fa7b033688c - languageName: node - linkType: hard - "wrappy@npm:1": version: 1.0.2 resolution: "wrappy@npm:1.0.2" @@ -12445,13 +12352,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^22.0.0": - version: 22.0.0 - resolution: "yargs-parser@npm:22.0.0" - checksum: 10c0/cb7ef81759c4271cb1d96b9351dbbc9a9ce35d3e1122d2b739bf6c432603824fa02c67cc12dcef6ea80283379d63495686e8f41cc7b06c6576e792aba4d33e1c - languageName: node - linkType: hard - "yargs@npm:^15.1.0": version: 15.4.1 resolution: "yargs@npm:15.4.1" @@ -12486,20 +12386,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^18.0.0": - version: 18.0.0 - resolution: "yargs@npm:18.0.0" - dependencies: - cliui: "npm:^9.0.1" - escalade: "npm:^3.1.1" - get-caller-file: "npm:^2.0.5" - string-width: "npm:^7.2.0" - y18n: "npm:^5.0.5" - yargs-parser: "npm:^22.0.0" - checksum: 10c0/bf290e4723876ea9c638c786a5c42ac28e03c9ca2325e1424bf43b94e5876456292d3ed905b853ebbba6daf43ed29e772ac2a6b3c5fb1b16533245d6211778f3 - languageName: node - linkType: hard - "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" @@ -12537,7 +12423,7 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.25.0 || ^4.0.0, zod@npm:^4.0.5": +"zod@npm:^3.25.0 || ^4.0.0": version: 4.3.6 resolution: "zod@npm:4.3.6" checksum: 10c0/860d25a81ab41d33aa25f8d0d07b091a04acb426e605f396227a796e9e800c44723ed96d0f53a512b57be3d1520f45bf69c0cb3b378a232a00787a2609625307 From 62a429f97d0e553bb1c72067d4c566758c2daed8 Mon Sep 17 00:00:00 2001 From: jensvansteen Date: Wed, 8 Apr 2026 12:53:00 +0700 Subject: [PATCH 2/6] chore: removed nitro modules depedency --- example/package.json | 1 - example/src/screens/PrDetailScreen.tsx | 11 +++-------- example/src/screens/TransitionShowcaseScreen.tsx | 15 +++++++++------ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/example/package.json b/example/package.json index 0c8d592..86a88b3 100644 --- a/example/package.json +++ b/example/package.json @@ -18,7 +18,6 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-gesture-handler": "^2.21.0", - "react-native-nitro-modules": "^0.33.3", "react-native-nitro-sfsymbols": "^1.2.0", "react-native-safe-area-context": "^5.6.2", "react-native-screens": "^4.22.0" diff --git a/example/src/screens/PrDetailScreen.tsx b/example/src/screens/PrDetailScreen.tsx index c22d9fb..f10db2d 100644 --- a/example/src/screens/PrDetailScreen.tsx +++ b/example/src/screens/PrDetailScreen.tsx @@ -88,14 +88,7 @@ export function PrDetailScreen() { - + {color.name} @@ -82,4 +79,10 @@ const styles = StyleSheet.create({ fontSize: 28, fontWeight: '700', }, + colorBlockLabelLight: { + color: 'rgba(255,255,255,0.72)', + }, + colorBlockLabelDark: { + color: 'rgba(0,0,0,0.32)', + }, }); From 2b9fbaee100cb19e7e33f68edd2be1ae251ba475 Mon Sep 17 00:00:00 2001 From: jensvansteen Date: Wed, 8 Apr 2026 13:50:29 +0700 Subject: [PATCH 3/6] chore: update lockfile --- yarn.lock | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/yarn.lock b/yarn.lock index b7ff173..c4c9815 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10292,16 +10292,6 @@ __metadata: languageName: node linkType: hard -"react-native-nitro-modules@npm:^0.33.3": - version: 0.33.7 - resolution: "react-native-nitro-modules@npm:0.33.7" - peerDependencies: - react: "*" - react-native: "*" - checksum: 10c0/2fdec1ff28f9330d10d604bb241a0521af1273eed6894418101b32976ac97fe454762385fd0eef78b878efd905fd67101d70ae6452746791e23e850e6925eb36 - languageName: node - linkType: hard - "react-native-nitro-sfsymbols@npm:^1.2.0": version: 1.2.0 resolution: "react-native-nitro-sfsymbols@npm:1.2.0" @@ -10360,7 +10350,6 @@ __metadata: react-native-builder-bob: "npm:^0.40.13" react-native-gesture-handler: "npm:^2.21.0" react-native-monorepo-config: "npm:^0.3.1" - react-native-nitro-modules: "npm:^0.33.3" react-native-nitro-sfsymbols: "npm:^1.2.0" react-native-safe-area-context: "npm:^5.6.2" react-native-screens: "npm:^4.22.0" From f7234b5a42a8a05c64e1efe56301aa0c00f8a17f Mon Sep 17 00:00:00 2001 From: jensvansteen Date: Wed, 8 Apr 2026 14:21:03 +0700 Subject: [PATCH 4/6] fix: ci update --- .github/workflows/ci.yml | 64 ---------------------------------------- 1 file changed, 64 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eeabe6a..78ce9e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,67 +57,6 @@ jobs: - name: Build package run: yarn prepare - build-android: - runs-on: ubuntu-latest - - env: - TURBO_CACHE_DIR: .turbo/android - - steps: - - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - name: Setup - uses: ./.github/actions/setup - - - name: Generate nitrogen code - run: yarn nitrogen - - - name: Cache turborepo for Android - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - with: - path: ${{ env.TURBO_CACHE_DIR }} - key: ${{ runner.os }}-turborepo-android-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-turborepo-android- - - - name: Check turborepo cache for Android - run: | - TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'build:android').cache.status") - - if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then - echo "turbo_cache_hit=1" >> $GITHUB_ENV - fi - - - name: Install JDK - if: env.turbo_cache_hit != 1 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 - with: - distribution: 'zulu' - java-version: '17' - - - name: Finalize Android SDK - if: env.turbo_cache_hit != 1 - run: | - /bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null" - - - name: Cache Gradle - if: env.turbo_cache_hit != 1 - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - with: - path: | - ~/.gradle/wrapper - ~/.gradle/caches - key: ${{ runner.os }}-gradle-${{ hashFiles('example/android/gradle/wrapper/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - - name: Build example for Android - env: - JAVA_OPTS: "-XX:MaxHeapSize=6g" - run: | - yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" - build-ios: runs-on: macos-latest @@ -134,9 +73,6 @@ jobs: - name: Setup uses: ./.github/actions/setup - - name: Generate nitrogen code - run: yarn nitrogen - - name: Cache turborepo for iOS uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: From 23449d9d9ef29e8318fad3b3405b6e3fba8472c1 Mon Sep 17 00:00:00 2001 From: jensvansteen Date: Wed, 8 Apr 2026 15:40:43 +0700 Subject: [PATCH 5/6] chore: metro connection fix --- example/ios/Podfile.lock | 8 ++++---- example/ios/ScrollEdgeBarExample/AppDelegate.swift | 10 ++++++++-- example/package.json | 1 + example/src/App.tsx | 5 ++++- example/src/screens/SearchBarScreen.tsx | 1 + yarn.lock | 11 +++++++++++ 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 3934f19..705f79a 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -36,7 +36,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - NitroModules (0.33.7): + - NitroModules (0.31.10): - boost - DoubleConversion - fast_float @@ -3018,7 +3018,7 @@ SPEC CHECKSUMS: glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 hermes-engine: 375b17d1732b179ad743a2a0c57569a0de17e767 LiquidGlass: e177e3bf641a7f4dc5fc596825b5d2b4fada4e9e - NitroModules: e8ec707a245a85cf1eb4289f91a9372f9590a897 + NitroModules: 5bc319d441f4983894ea66b1d392c519536e6d23 NitroSfsymbols: 5853b2baaf1a21db8a27d18d66b8fcd7fdafdc76 RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f RCTDeprecation: 2b70c6e3abe00396cefd8913efbf6a2db01a2b36 @@ -3095,8 +3095,8 @@ SPEC CHECKSUMS: RNScreens: c77cc7a5d1fbc23f0725b54e96eec81118453382 ScrollEdgeBar: 7838bc5a8df069488b5612c3fedc07baf7f5e3a1 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Yoga: 6ca93c8c13f56baeec55eb608577619b17a4d64e + Yoga: 7a9f26c70daf0b08d82ec2f862e9a8872442129e PODFILE CHECKSUM: 9f12b969a6ade18978b8031561752c8cfbb0aed8 -COCOAPODS: 1.16.2 +COCOAPODS: 1.15.2 diff --git a/example/ios/ScrollEdgeBarExample/AppDelegate.swift b/example/ios/ScrollEdgeBarExample/AppDelegate.swift index d62402f..79b5cfd 100644 --- a/example/ios/ScrollEdgeBarExample/AppDelegate.swift +++ b/example/ios/ScrollEdgeBarExample/AppDelegate.swift @@ -40,9 +40,15 @@ class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate { override func bundleURL() -> URL? { #if DEBUG - RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") + let provider = RCTBundleURLProvider.sharedSettings() + + #if targetEnvironment(simulator) + provider.jsLocation = "127.0.0.1" + #endif + + return provider.jsBundleURL(forBundleRoot: "index") #else - Bundle.main.url(forResource: "main", withExtension: "jsbundle") + return Bundle.main.url(forResource: "main", withExtension: "jsbundle") #endif } diff --git a/example/package.json b/example/package.json index 86a88b3..80a54b9 100644 --- a/example/package.json +++ b/example/package.json @@ -18,6 +18,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-gesture-handler": "^2.21.0", + "react-native-nitro-modules": "~0.31.10", "react-native-nitro-sfsymbols": "^1.2.0", "react-native-safe-area-context": "^5.6.2", "react-native-screens": "^4.22.0" diff --git a/example/src/App.tsx b/example/src/App.tsx index 3d17d77..08923f1 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -132,7 +132,10 @@ export default function App() { title: 'Search Bar', headerShadowVisible: false, headerTransparent: true, - headerLargeTitleEnabled: true, + headerSearchBarOptions: { + placement: 'stacked', + allowToolbarIntegration: false, + }, headerBackButtonDisplayMode: 'minimal', headerTintColor: DynamicColorIOS({ light: 'black', diff --git a/example/src/screens/SearchBarScreen.tsx b/example/src/screens/SearchBarScreen.tsx index aa2cc7f..1baeb9f 100644 --- a/example/src/screens/SearchBarScreen.tsx +++ b/example/src/screens/SearchBarScreen.tsx @@ -34,6 +34,7 @@ export function SearchBarScreen() { const styles = StyleSheet.create({ container: { flex: 1, + backgroundColor: 'white', }, topBar: { paddingHorizontal: 16, diff --git a/yarn.lock b/yarn.lock index c4c9815..5ad0e38 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10292,6 +10292,16 @@ __metadata: languageName: node linkType: hard +"react-native-nitro-modules@npm:~0.31.10": + version: 0.31.10 + resolution: "react-native-nitro-modules@npm:0.31.10" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/0acc6ca5f12e24a6601e682070f257a771b95214c11fba911b342af705071234544c93076900f43400c8ae2f1a6738011b120e4425813968102997860ffd7626 + languageName: node + linkType: hard + "react-native-nitro-sfsymbols@npm:^1.2.0": version: 1.2.0 resolution: "react-native-nitro-sfsymbols@npm:1.2.0" @@ -10350,6 +10360,7 @@ __metadata: react-native-builder-bob: "npm:^0.40.13" react-native-gesture-handler: "npm:^2.21.0" react-native-monorepo-config: "npm:^0.3.1" + react-native-nitro-modules: "npm:~0.31.10" react-native-nitro-sfsymbols: "npm:^1.2.0" react-native-safe-area-context: "npm:^5.6.2" react-native-screens: "npm:^4.22.0" From 5d889aead0add2c4620a4b85c4b95b8aeab00024 Mon Sep 17 00:00:00 2001 From: jensvansteen Date: Wed, 8 Apr 2026 15:55:26 +0700 Subject: [PATCH 6/6] chore: ruby depedencies updates --- example/Gemfile.lock | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/example/Gemfile.lock b/example/Gemfile.lock index d689dde..1031570 100644 --- a/example/Gemfile.lock +++ b/example/Gemfile.lock @@ -2,26 +2,18 @@ GEM remote: https://rubygems.org/ specs: CFPropertyList (3.0.9) - activesupport (7.1.6) - base64 - benchmark (>= 0.3) - bigdecimal + activesupport (6.1.7.10) concurrent-ruby (~> 1.0, >= 1.0.2) - connection_pool (>= 2.2.5) - drb i18n (>= 1.6, < 2) - logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - securerandom (>= 0.3) tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.8.8) public_suffix (>= 2.0.2, < 8.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) atomos (0.1.3) - base64 (0.3.0) benchmark (0.5.0) bigdecimal (4.0.1) claide (1.1.0) @@ -64,8 +56,6 @@ GEM cocoapods-try (1.2.0) colored2 (3.1.2) concurrent-ruby (1.3.3) - connection_pool (2.5.5) - drb (2.2.3) escape (0.0.4) ethon (0.15.0) ffi (>= 1.15.0) @@ -77,9 +67,9 @@ GEM mutex_m i18n (1.14.8) concurrent-ruby (~> 1.0) - json (2.18.1) + json (2.7.6) logger (1.7.0) - minitest (5.26.1) + minitest (5.25.4) molinillo (0.8.0) mutex_m (0.3.0) nanaimo (0.3.0) @@ -88,7 +78,6 @@ GEM public_suffix (4.0.7) rexml (3.4.4) ruby-macho (2.5.1) - securerandom (0.3.2) typhoeus (1.5.0) ethon (>= 0.9.0, < 0.16.0) tzinfo (2.0.6) @@ -100,6 +89,7 @@ GEM colored2 (~> 3.1) nanaimo (~> 0.3.0) rexml (>= 3.3.6, < 4.0) + zeitwerk (2.6.18) PLATFORMS ruby @@ -118,4 +108,4 @@ RUBY VERSION ruby 2.7.4p191 BUNDLED WITH - 2.1.4 + 2.4.22