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:
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/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
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index e12e15e..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
@@ -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
@@ -3020,7 +3018,7 @@ SPEC CHECKSUMS:
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
hermes-engine: 375b17d1732b179ad743a2a0c57569a0de17e767
LiquidGlass: e177e3bf641a7f4dc5fc596825b5d2b4fada4e9e
- NitroModules: e8ec707a245a85cf1eb4289f91a9372f9590a897
+ NitroModules: 5bc319d441f4983894ea66b1d392c519536e6d23
NitroSfsymbols: 5853b2baaf1a21db8a27d18d66b8fcd7fdafdc76
RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f
RCTDeprecation: 2b70c6e3abe00396cefd8913efbf6a2db01a2b36
@@ -3095,10 +3093,10 @@ SPEC CHECKSUMS:
ReactCommon: 424cc34cf5055d69a3dcf02f3436481afb8b0f6f
RNGestureHandler: cd4be101cfa17ea6bbd438710caa02e286a84381
RNScreens: c77cc7a5d1fbc23f0725b54e96eec81118453382
- ScrollEdgeBar: 3823674d457505ae0598b99e99dfc5c70015d062
+ 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 0c8d592..80a54b9 100644
--- a/example/package.json
+++ b/example/package.json
@@ -18,7 +18,7 @@
"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-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/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/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)',
+ },
});
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..5ad0e38 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,13 +10292,13 @@ __metadata:
languageName: node
linkType: hard
-"react-native-nitro-modules@npm:^0.33.3, react-native-nitro-modules@npm:^0.33.7":
- version: 0.33.7
- resolution: "react-native-nitro-modules@npm:0.33.7"
+"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/2fdec1ff28f9330d10d604bb241a0521af1273eed6894418101b32976ac97fe454762385fd0eef78b878efd905fd67101d70ae6452746791e23e850e6925eb36
+ checksum: 10c0/0acc6ca5f12e24a6601e682070f257a771b95214c11fba911b342af705071234544c93076900f43400c8ae2f1a6738011b120e4425813968102997860ffd7626
languageName: node
linkType: hard
@@ -10418,7 +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.33.3"
+ 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"
@@ -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