├── .bundle └── config ├── .editorconfig ├── .eslintrc.js ├── .github └── workflows │ └── build-docs.yml ├── .gitignore ├── .node-version ├── .ruby-version ├── .watchmanconfig ├── .yarn └── releases │ └── yarn-3.3.1.cjs ├── .yarnrc.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── __tests__ └── App-test.tsx ├── android ├── app │ ├── build.gradle │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── rnbridgingtutorial │ │ │ └── ReactNativeFlipper.kt │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ └── file.html │ │ ├── java │ │ │ └── com │ │ │ │ └── rnbridgingtutorial │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ └── res │ │ │ ├── drawable │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── release │ │ └── java │ │ └── com │ │ └── rnbridgingtutorial │ │ └── ReactNativeFlipper.kt ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── app-info-package-classic ├── AppInfoPackageClassic.podspec ├── android │ ├── build.gradle │ ├── react-native-helpers.gradle │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── appinfopackageclassic │ │ │ ├── AppInfoClassicTurboPackage.java │ │ │ └── AppInfoModuleClassicImpl.java │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── appinfopackageclassic │ │ │ └── AppInfoModuleClassic.java │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── appinfopackageclassic │ │ └── AppInfoModuleClassic.java ├── ios │ ├── AppInfoModuleClassic.h │ ├── AppInfoModuleClassic.mm │ ├── AppInfoModuleClassicImpl.h │ └── AppInfoModuleClassicImpl.mm ├── package.json └── src │ ├── NativeAppInfoModuleClassic.ts │ └── index.ts ├── app-info-package ├── AppInfoPackage.podspec ├── android │ ├── build.gradle.kts │ ├── react-native-helpers.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── appinfopackage │ │ │ ├── AppInfoModuleImpl.kt │ │ │ └── AppInfoTurboPackage.kt │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── appinfopackage │ │ │ └── AppInfoModule.kt │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── appinfopackage │ │ └── AppInfoModule.kt ├── ios │ ├── AppInfoModule.h │ ├── AppInfoModule.mm │ ├── AppInfoModuleImpl.swift │ └── AppInfoPackage-Bridging-Header.h ├── package.json └── src │ ├── NativeAppInfoModule.ts │ └── index.ts ├── app.json ├── babel.config.js ├── bridging-tutorial-website ├── .gitignore ├── README.md ├── babel.config.js ├── docs │ ├── _codegen-for-old-arch-info.mdx │ ├── getting-started.mdx │ ├── guides │ │ ├── _android-turbo-package-boilerplate.mdx │ │ ├── _android-turbo-package.mdx │ │ ├── _category_.json │ │ ├── _codegen-spec.mdx │ │ ├── _complete-file.mdx │ │ ├── _exporting-objc-info.mdx │ │ ├── _link-package.mdx │ │ ├── _old-arch-android-module-file.mdx │ │ ├── _old-arch-android-viewmanager-file.mdx │ │ ├── _package-structure-boilerplate.mdx │ │ ├── app-info-module │ │ │ ├── _android-java-impl.mdx │ │ │ ├── _android-java-module.mdx │ │ │ ├── _android-java-moduleimpl.mdx │ │ │ ├── _android-kotlin-impl.mdx │ │ │ ├── _android-kotlin-module.mdx │ │ │ ├── _android-kotlin-moduleimpl.mdx │ │ │ ├── _category_.json │ │ │ ├── _ios-objc-impl.mdx │ │ │ ├── _ios-objc-module.mdx │ │ │ ├── _ios-objc-moduleimpl.mdx │ │ │ ├── _ios-swift-impl.mdx │ │ │ ├── _ios-swift-module.mdx │ │ │ ├── _ios-swift-moduleimpl.mdx │ │ │ ├── _result.mdx │ │ │ ├── android-impl.mdx │ │ │ ├── intro.mdx │ │ │ ├── ios-impl.mdx │ │ │ ├── js-spec.mdx │ │ │ ├── setup.mdx │ │ │ └── usage.mdx │ │ ├── conic-gradient-view │ │ │ ├── _android-java-impl.mdx │ │ │ ├── _android-java-view.mdx │ │ │ ├── _android-java-viewmanager.mdx │ │ │ ├── _android-kotlin-impl.mdx │ │ │ ├── _android-kotlin-view.mdx │ │ │ ├── _android-kotlin-viewmanager.mdx │ │ │ ├── _category_.json │ │ │ ├── _ios-objc-componentview.mdx │ │ │ ├── _ios-objc-impl.mdx │ │ │ ├── _ios-objc-view.mdx │ │ │ ├── _ios-objc-viewmanager.mdx │ │ │ ├── _result.mdx │ │ │ ├── android-impl.mdx │ │ │ ├── intro.mdx │ │ │ ├── ios-impl.mdx │ │ │ ├── js-spec.mdx │ │ │ ├── setup.mdx │ │ │ └── usage.mdx │ │ ├── guides-intro.mdx │ │ ├── native-list-view │ │ │ ├── _android-add-library-in-gradle.mdx │ │ │ ├── _android-card-item-layout.mdx │ │ │ ├── _android-fragment-list-layout.mdx │ │ │ ├── _android-java-data-item.mdx │ │ │ ├── _android-java-impl.mdx │ │ │ ├── _android-java-list-adapter.mdx │ │ │ ├── _android-java-list-fragment.mdx │ │ │ ├── _android-java-list-viewholder.mdx │ │ │ ├── _android-java-viewmanager.mdx │ │ │ ├── _android-kotlin-data-item.mdx │ │ │ ├── _android-kotlin-impl.mdx │ │ │ ├── _android-kotlin-list-adapter.mdx │ │ │ ├── _android-kotlin-list-fragment.mdx │ │ │ ├── _android-kotlin-list-viewholder.mdx │ │ │ ├── _android-kotlin-viewmanager.mdx │ │ │ ├── _category_.json │ │ │ ├── _ios-objc-componentview.mdx │ │ │ ├── _ios-objc-containerview.mdx │ │ │ ├── _ios-objc-data-item.mdx │ │ │ ├── _ios-objc-impl.mdx │ │ │ ├── _ios-objc-list-cell.mdx │ │ │ ├── _ios-objc-viewcontroller.mdx │ │ │ ├── _ios-objc-viewmanager.mdx │ │ │ ├── _ios-swift-componentview.mdx │ │ │ ├── _ios-swift-containerview.mdx │ │ │ ├── _ios-swift-data-item.mdx │ │ │ ├── _ios-swift-impl.mdx │ │ │ ├── _ios-swift-list-cell.mdx │ │ │ ├── _ios-swift-viewcontroller.mdx │ │ │ ├── _ios-swift-viewmanager.mdx │ │ │ ├── _result.mdx │ │ │ ├── android-impl.mdx │ │ │ ├── intro.mdx │ │ │ ├── ios-impl.mdx │ │ │ ├── js-spec.mdx │ │ │ ├── setup.mdx │ │ │ └── usage.mdx │ │ ├── range-slider-view │ │ │ ├── _android-add-library-in-gradle.mdx │ │ │ ├── _android-change-theme-to-material-3.mdx │ │ │ ├── _android-java-events.mdx │ │ │ ├── _android-java-impl.mdx │ │ │ ├── _android-java-view.mdx │ │ │ ├── _android-java-viewmanager.mdx │ │ │ ├── _android-kotlin-events.mdx │ │ │ ├── _android-kotlin-impl.mdx │ │ │ ├── _android-kotlin-view.mdx │ │ │ ├── _android-kotlin-viewmanager.mdx │ │ │ ├── _category_.json │ │ │ ├── _ios-add-library-in-podspec.mdx │ │ │ ├── _ios-objc-componentview.mdx │ │ │ ├── _ios-objc-exposing-swift-only-lib.mdx │ │ │ ├── _ios-objc-impl.mdx │ │ │ ├── _ios-objc-view.mdx │ │ │ ├── _ios-objc-viewmanager.mdx │ │ │ ├── _ios-swift-componentview.mdx │ │ │ ├── _ios-swift-impl.mdx │ │ │ ├── _ios-swift-view.mdx │ │ │ ├── _ios-swift-viewmanager.mdx │ │ │ ├── _result.mdx │ │ │ ├── android-impl.mdx │ │ │ ├── intro.mdx │ │ │ ├── ios-impl.mdx │ │ │ ├── js-spec.mdx │ │ │ ├── setup.mdx │ │ │ └── usage.mdx │ │ ├── save-file-picker-module │ │ │ ├── _android-java-impl.mdx │ │ │ ├── _android-java-module.mdx │ │ │ ├── _android-java-moduleimpl.mdx │ │ │ ├── _android-kotlin-impl.mdx │ │ │ ├── _android-kotlin-module.mdx │ │ │ ├── _android-kotlin-moduleimpl.mdx │ │ │ ├── _android-register-activity-launcher.mdx │ │ │ ├── _category_.json │ │ │ ├── _ios-objc-impl.mdx │ │ │ ├── _ios-objc-module.mdx │ │ │ ├── _ios-objc-moduleimpl.mdx │ │ │ ├── _ios-swift-bridging-header.mdx │ │ │ ├── _ios-swift-impl.mdx │ │ │ ├── _ios-swift-module.mdx │ │ │ ├── _ios-swift-moduleimpl.mdx │ │ │ ├── _result.mdx │ │ │ ├── _simplify-with-file-from-assets-info.mdx │ │ │ ├── android-impl.mdx │ │ │ ├── intro.mdx │ │ │ ├── ios-impl.mdx │ │ │ ├── js-spec.mdx │ │ │ ├── setup.mdx │ │ │ └── usage.mdx │ │ └── screen-orientation-module │ │ │ ├── _android-java-impl.mdx │ │ │ ├── _android-java-module.mdx │ │ │ ├── _android-java-moduleimpl.mdx │ │ │ ├── _android-kotlin-impl.mdx │ │ │ ├── _android-kotlin-module.mdx │ │ │ ├── _android-kotlin-moduleimpl.mdx │ │ │ ├── _category_.json │ │ │ ├── _ios-objc-impl.mdx │ │ │ ├── _ios-objc-module.mdx │ │ │ ├── _ios-objc-moduleimpl.mdx │ │ │ ├── _ios-swift-impl.mdx │ │ │ ├── _ios-swift-module.mdx │ │ │ ├── _ios-swift-moduleimpl.mdx │ │ │ ├── _result.mdx │ │ │ ├── android-impl.mdx │ │ │ ├── intro.mdx │ │ │ ├── ios-impl.mdx │ │ │ ├── js-spec.mdx │ │ │ ├── setup.mdx │ │ │ └── usage.mdx │ ├── module-reference │ │ ├── _category_.json │ │ ├── module-args-types-old.mdx │ │ ├── module-args-types.mdx │ │ ├── module-constants-old.mdx │ │ ├── module-constants.mdx │ │ ├── module-events-old.mdx │ │ ├── module-events.mdx │ │ ├── module-intro.mdx │ │ ├── module-method-types-old.mdx │ │ └── module-method-types.mdx │ ├── motivation.mdx │ └── view-reference │ │ ├── _category_.json │ │ ├── view-commands-old.mdx │ │ ├── view-commands.mdx │ │ ├── view-intro.mdx │ │ ├── view-props-types-old.mdx │ │ ├── view-props-types.mdx │ │ └── view-types.mdx ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.module.css │ │ └── index.tsx ├── static │ ├── .nojekyll │ ├── img │ │ ├── appinfo-android-studio-package.png │ │ ├── appinfo-result.png │ │ ├── conicgradient-result.png │ │ ├── favicon.ico │ │ ├── icon.png │ │ ├── icon.svg │ │ ├── screen-orientation-landscape-result.png │ │ ├── screen-orientation-portrait-result.png │ │ └── xcode-add-files-to.png │ └── video │ │ ├── native-list-android-result.mp4 │ │ ├── native-list-ios-result.mp4 │ │ ├── range-slider-android-result.mp4 │ │ ├── range-slider-ios-result.mp4 │ │ ├── save-file-picker-android-result.mp4 │ │ └── save-file-picker-ios-result.mp4 ├── tsconfig.json └── yarn.lock ├── conic-gradient-package-classic ├── ConicGradientPackageClassic.podspec ├── android │ ├── build.gradle │ ├── react-native-helpers.gradle │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── conicgradientpackageclassic │ │ │ ├── ConicGradientClassicTurboPackage.java │ │ │ └── ConicGradientClassicView.java │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── conicgradientpackageclassic │ │ │ └── ConicGradientClassicViewManager.java │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── conicgradientpackageclassic │ │ └── ConicGradientClassicViewManager.java ├── ios │ ├── ConicGradientClassicView.h │ ├── ConicGradientClassicView.mm │ ├── ConicGradientClassicViewComponentView.h │ ├── ConicGradientClassicViewComponentView.mm │ ├── ConicGradientClassicViewManager.h │ └── ConicGradientClassicViewManager.mm ├── package.json └── src │ ├── ConicGradientClassicView.tsx │ ├── ConicGradientClassicViewNativeComponent.ts │ └── index.ts ├── conic-gradient-package ├── ConicGradientPackage.podspec ├── android │ ├── build.gradle.kts │ ├── react-native-helpers.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── conicgradientpackage │ │ │ ├── ConicGradientTurboPackage.kt │ │ │ └── ConicGradientView.kt │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── conicgradientpackage │ │ │ └── ConicGradientViewManager.kt │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── conicgradientpackage │ │ └── ConicGradientViewManager.kt ├── ios │ ├── ConicGradientView.h │ ├── ConicGradientView.mm │ ├── ConicGradientViewComponentView.h │ ├── ConicGradientViewComponentView.mm │ ├── ConicGradientViewManager.h │ └── ConicGradientViewManager.mm ├── package.json └── src │ ├── ConicGradientView.tsx │ ├── ConicGradientViewNativeComponent.ts │ └── index.ts ├── index.js ├── ios ├── .xcode.env ├── Podfile ├── Podfile.lock ├── rnbridgingtutorial.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── rnbridgingtutorial.xcscheme ├── rnbridgingtutorial.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── rnbridgingtutorial │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ ├── LaunchScreen.storyboard │ ├── file.html │ ├── main.mm │ └── rnbridgingtutorial-Bridging-Header.h └── rnbridgingtutorialTests │ ├── Info.plist │ └── rnbridgingtutorialTests.m ├── jest.config.js ├── jest.setup.js ├── metro.config.js ├── native-list-package-classic ├── NativeListPackageClassic.podspec ├── android │ ├── build.gradle │ ├── react-native-helpers.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── nativelistpackageclassic │ │ │ │ ├── AndroidNativeListClassicViewFragment.java │ │ │ │ ├── ClassicDataItem.java │ │ │ │ ├── NativeListClassicAdapter.java │ │ │ │ ├── NativeListClassicTurboPackage.java │ │ │ │ └── NativeListClassicViewHolder.java │ │ └── res │ │ │ └── layout │ │ │ ├── card_item_classic.xml │ │ │ └── fragment_list_classic.xml │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── nativelistpackageclassic │ │ │ └── AndroidNativeListClassicViewManager.java │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── nativelistpackageclassic │ │ └── AndroidNativeListClassicViewManager.java ├── ios │ ├── ClassicDataItem.h │ ├── ClassicDataItem.mm │ ├── NativeListClassicCell.h │ ├── NativeListClassicCell.mm │ ├── RNNativeListClassicViewComponentView.h │ ├── RNNativeListClassicViewComponentView.mm │ ├── RNNativeListClassicViewContainerView.h │ ├── RNNativeListClassicViewContainerView.mm │ ├── RNNativeListClassicViewManager.h │ ├── RNNativeListClassicViewManager.mm │ ├── RNNativeListClassicViewViewController.h │ └── RNNativeListClassicViewViewController.mm ├── package.json └── src │ ├── AndroidNativeListClassicViewNativeComponent.ts │ ├── NativeListClassicView.android.tsx │ ├── NativeListClassicView.ios.tsx │ ├── NativeListClassicView.tsx │ ├── RNNativeListClassicViewNativeComponent.ts │ └── index.ts ├── native-list-package ├── NativeListPackage.podspec ├── android │ ├── build.gradle.kts │ ├── react-native-helpers.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── nativelistpackage │ │ │ │ ├── AndroidNativeListViewFragment.kt │ │ │ │ ├── DataItem.kt │ │ │ │ ├── NativeListAdapter.kt │ │ │ │ ├── NativeListTurboPackage.kt │ │ │ │ └── NativeListViewHolder.kt │ │ └── res │ │ │ └── layout │ │ │ ├── card_item.xml │ │ │ └── fragment_list.xml │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── nativelistpackage │ │ │ └── AndroidNativeListViewManager.kt │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── nativelistpackage │ │ └── AndroidNativeListViewManager.kt ├── ios │ ├── DataItem.swift │ ├── NativeListCell.swift │ ├── NativeListPackage-Bridging-Header.h │ ├── RNNativeListViewComponentView.h │ ├── RNNativeListViewComponentView.mm │ ├── RNNativeListViewContainerView.swift │ ├── RNNativeListViewManager.h │ ├── RNNativeListViewManager.mm │ └── RNNativeListViewViewController.swift ├── package.json └── src │ ├── AndroidNativeListViewNativeComponent.ts │ ├── NativeListView.android.tsx │ ├── NativeListView.ios.tsx │ ├── NativeListView.tsx │ ├── RNNativeListViewNativeComponent.ts │ └── index.ts ├── package.json ├── range-slider-package-classic ├── RangeSliderPackageClassic.podspec ├── android │ ├── build.gradle │ ├── react-native-helpers.gradle │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── rangesliderpackageclassic │ │ │ ├── OnRangeSliderClassicViewBeginDragEvent.java │ │ │ ├── OnRangeSliderClassicViewEndDragEvent.java │ │ │ ├── OnRangeSliderClassicViewValueChangeEvent.java │ │ │ ├── RangeSliderClassicTurboPackage.java │ │ │ └── RangeSliderClassicView.java │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── rangesliderpackageclassic │ │ │ └── RangeSliderClassicViewManager.java │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── rangesliderpackageclassic │ │ └── RangeSliderClassicViewManager.java ├── ios │ ├── RangeSliderClassicView.h │ ├── RangeSliderClassicView.mm │ ├── RangeSliderClassicViewComponentView.h │ ├── RangeSliderClassicViewComponentView.mm │ ├── RangeSliderClassicViewManager.h │ ├── RangeSliderClassicViewManager.mm │ ├── RangeSliderPackageClassic-Bridging-Header.h │ └── RangeUISliderWrapper.swift ├── package.json └── src │ ├── RangeSliderClassicView.tsx │ ├── RangeSliderClassicViewNativeComponent.ts │ └── index.ts ├── range-slider-package ├── RangeSliderPackage.podspec ├── android │ ├── build.gradle.kts │ ├── react-native-helpers.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── rangesliderpackage │ │ │ ├── OnRangeSliderViewBeginDragEvent.kt │ │ │ ├── OnRangeSliderViewEndDragEvent.kt │ │ │ ├── OnRangeSliderViewValueChangeEvent.kt │ │ │ ├── RangeSliderTurboPackage.kt │ │ │ └── RangeSliderView.kt │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── rangesliderpackage │ │ │ └── RangeSliderViewManager.kt │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── rangesliderpackage │ │ └── RangeSliderViewManager.kt ├── ios │ ├── RangeSliderPackage-Bridging-Header.h │ ├── RangeSliderView.swift │ ├── RangeSliderViewComponentView.h │ ├── RangeSliderViewComponentView.mm │ ├── RangeSliderViewManager.h │ └── RangeSliderViewManager.mm ├── package.json └── src │ ├── RangeSliderView.tsx │ ├── RangeSliderViewNativeComponent.ts │ └── index.ts ├── react-native.config.js ├── save-file-picker-package-classic ├── SaveFilePickerPackageClassic.podspec ├── android │ ├── build.gradle │ ├── react-native-helpers.gradle │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── savefilepickerpackageclassic │ │ │ ├── SaveFilePickerClassicModuleImpl.java │ │ │ └── SaveFilePickerClassicTurboPackage.java │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── savefilepickerpackageclassic │ │ │ └── SaveFilePickerClassicModule.java │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── savefilepickerpackageclassic │ │ └── SaveFilePickerClassicModule.java ├── ios │ ├── SaveFilePickerClassicModule.h │ ├── SaveFilePickerClassicModule.mm │ ├── SaveFilePickerClassicModuleImpl.h │ └── SaveFilePickerClassicModuleImpl.mm ├── package.json └── src │ ├── NativeSaveFilePickerClassicModule.ts │ └── index.ts ├── save-file-picker-package ├── SaveFilePickerPackage.podspec ├── android │ ├── build.gradle.kts │ ├── react-native-helpers.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── savefilepickerpackage │ │ │ ├── SaveFilePickerModuleImpl.kt │ │ │ └── SaveFilePickerTurboPackage.kt │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── savefilepickerpackage │ │ │ └── SaveFilePickerModule.kt │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── savefilepickerpackage │ │ └── SaveFilePickerModule.kt ├── ios │ ├── SaveFilePickerModule.h │ ├── SaveFilePickerModule.mm │ ├── SaveFilePickerModuleImpl.swift │ └── SaveFilePickerPackage-Bridging-Header.h ├── package.json └── src │ ├── NativeSaveFilePickerModule.ts │ └── index.ts ├── screen-orientation-package-classic ├── ScreenOrientationPackageClassic.podspec ├── android │ ├── build.gradle │ ├── react-native-helpers.gradle │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── screenorientationpackageclassic │ │ │ ├── ScreenOrientationClassicModuleImpl.java │ │ │ └── ScreenOrientationClassicTurboPackage.java │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── screenorientationpackageclassic │ │ │ └── ScreenOrientationClassicModule.java │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── screenorientationpackageclassic │ │ └── ScreenOrientationClassicModule.java ├── ios │ ├── ScreenOrientationClassicModule.h │ ├── ScreenOrientationClassicModule.mm │ ├── ScreenOrientationClassicModuleImpl.h │ └── ScreenOrientationClassicModuleImpl.mm ├── package.json └── src │ ├── NativeScreenOrientationClassicModule.ts │ └── index.ts ├── screen-orientation-package ├── ScreenOrientationPackage.podspec ├── android │ ├── build.gradle.kts │ ├── react-native-helpers.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── screenorientationpackage │ │ │ ├── ScreenOrientationModuleImpl.kt │ │ │ └── ScreenOrientationTurboPackage.kt │ │ ├── newarch │ │ └── java │ │ │ └── com │ │ │ └── screenorientationpackage │ │ │ └── ScreenOrientationModule.kt │ │ └── oldarch │ │ └── java │ │ └── com │ │ └── screenorientationpackage │ │ └── ScreenOrientationModule.kt ├── ios │ ├── ScreenOrientationModule.h │ ├── ScreenOrientationModule.mm │ ├── ScreenOrientationModuleImpl.swift │ └── ScreenOrientationPackage-Bridging-Header.h ├── package.json └── src │ ├── NativeScreenOrientationModule.ts │ └── index.ts ├── src ├── App.tsx ├── assets │ ├── arrow-back.png │ └── index.ts ├── components │ └── index.ts ├── navigation │ ├── NavigationRootStack.tsx │ ├── hooks.ts │ ├── index.ts │ ├── routes.ts │ └── types.ts └── screens │ ├── AppInfoScreen.tsx │ ├── ConicGradientScreen.tsx │ ├── HomeScreen.tsx │ ├── NativeListScreen.tsx │ ├── RangeSliderScreen.tsx │ ├── SaveFileScreen.tsx │ ├── ScreenOrientationScreen.tsx │ └── index.ts ├── tsconfig.json ├── tsconfig.spec.json └── yarn.lock /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | 7 | [*.{java,kt,h,m,mm,swift,gradle,gradle.kts,xml}] 8 | indent_style = space 9 | indent_size = 4 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | .pnp.* 43 | .yarn/* 44 | !.yarn/patches 45 | !.yarn/plugins 46 | !.yarn/releases 47 | !.yarn/sdks 48 | !.yarn/versions 49 | bridging-tutorial-website/.yarn/* 50 | 51 | # fastlane 52 | # 53 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 54 | # screenshots whenever they are needed. 55 | # For more information about the recommended setup visit: 56 | # https://docs.fastlane.tools/best-practices/source-control/ 57 | 58 | **/fastlane/report.xml 59 | **/fastlane/Preview.html 60 | **/fastlane/screenshots 61 | **/fastlane/test_output 62 | 63 | # Temporary files created by Metro to check the health of the file watcher 64 | .metro-health-check* 65 | 66 | # Bundle artifact 67 | *.jsbundle 68 | 69 | # Ruby / CocoaPods 70 | /ios/Pods/ 71 | /vendor/bundle/ 72 | 73 | coverage/ 74 | 75 | .vscode/* 76 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.6 2 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | enableGlobalCache: true 2 | 3 | enableTelemetry: false 4 | 5 | logFilters: 6 | # Missing Peer Dependency - only the package author can fix 7 | - code: YN0002 8 | level: discard 9 | # telling us what it needs to build; verbose and distracts from errors 10 | - code: YN0007 11 | level: discard 12 | # logs each package download; so verbose that it slows down iterm2 13 | - code: YN0013 14 | level: discard 15 | # architecture/os is incompatible and package will be skipped; expected and not useful signal 16 | - code: YN0076 17 | level: discard 18 | 19 | nodeLinker: node-modules 20 | 21 | yarnPath: .yarn/releases/yarn-3.3.1.cjs 22 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby File.read(File.join(__dir__, '.ruby-version')).strip 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.3' 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Mateusz Mędrek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /__tests__/App-test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import renderer from 'react-test-renderer'; 7 | 8 | import { App } from '../src/App'; 9 | 10 | // Note: test renderer must be required after react-native. 11 | 12 | test('renders correctly', async () => { 13 | await renderer.act(() => { 14 | const result = renderer.create(); 15 | 16 | expect(result.toJSON()).toBeDefined(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/debug.keystore -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /android/app/src/main/assets/file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Page Title 5 | 6 | 7 |
8 |

Sample HTML file

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Bridging Tutorial 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/release/java/com/rnbridgingtutorial/ReactNativeFlipper.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.rnbridgingtutorial 8 | 9 | import android.content.Context 10 | import com.facebook.react.ReactInstanceManager 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | object ReactNativeFlipper { 17 | @JvmStatic 18 | fun initializeFlipper(context: Context?, reactInstanceManager: ReactInstanceManager) { 19 | // Do nothing as we don't want to initialize Flipper on Release. 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "33.0.0" 6 | minSdkVersion = 21 7 | compileSdkVersion = 33 8 | targetSdkVersion = 33 9 | kotlinVersion = "1.6.10" 10 | 11 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 12 | ndkVersion = "23.1.7779620" 13 | } 14 | repositories { 15 | google() 16 | mavenCentral() 17 | } 18 | dependencies { 19 | classpath("com.android.tools.build:gradle:7.3.1") 20 | classpath("com.facebook.react:react-native-gradle-plugin") 21 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") 22 | // NOTE: Do not place your application dependencies here; they belong 23 | // in the individual module build.gradle files 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'rnbridgingtutorial' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/react-native-gradle-plugin') 5 | -------------------------------------------------------------------------------- /app-info-package-classic/AppInfoPackageClassic.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1' 6 | 7 | Pod::Spec.new do |s| 8 | s.name = "AppInfoPackageClassic" 9 | s.version = package["version"] 10 | s.summary = package["description"] 11 | s.description = package["description"] 12 | s.homepage = package["homepage"] 13 | s.license = package["license"] 14 | s.platforms = { :ios => "13.0" } 15 | s.author = package["author"] 16 | s.source = { :git => package["repository"], :tag => "#{s.version}" } 17 | 18 | s.source_files = "ios/**/*.{h,m,mm,swift}" 19 | 20 | if new_arch_enabled 21 | s.pod_target_xcconfig = { 22 | "DEFINES_MODULE" => "YES", 23 | "SWIFT_OBJC_INTERFACE_HEADER_NAME" => "AppInfoPackageClassic-Swift.h", 24 | # This is handy when we want to detect if new arch is enabled in Swift code 25 | # and can be used like: 26 | # #if APP_INFO_PACKAGE_CLASSIC_NEW_ARCH_ENABLED 27 | # // do sth when new arch is enabled 28 | # #else 29 | # // do sth when old arch is enabled 30 | # #endif 31 | "OTHER_SWIFT_FLAGS" => "-DAPP_INFO_PACKAGE_CLASSIC_NEW_ARCH_ENABLED" 32 | } 33 | else 34 | s.pod_target_xcconfig = { 35 | "DEFINES_MODULE" => "YES", 36 | "SWIFT_OBJC_INTERFACE_HEADER_NAME" => "AppInfoPackageClassic-Swift.h" 37 | } 38 | end 39 | 40 | # Install all React Native dependencies (RN >= 0.71 must be used) 41 | # 42 | # check source code for more context 43 | # https://github.com/facebook/react-native/blob/0.71-stable/scripts/react_native_pods.rb#L172#L180 44 | install_modules_dependencies(s) 45 | end 46 | -------------------------------------------------------------------------------- /app-info-package-classic/android/src/newarch/java/com/appinfopackageclassic/AppInfoModuleClassic.java: -------------------------------------------------------------------------------- 1 | package com.appinfopackageclassic; 2 | 3 | import com.facebook.react.bridge.ReactApplicationContext; 4 | import com.facebook.react.module.annotations.ReactModule; 5 | 6 | /** 7 | * Declare Java class for new arch native module implementation 8 | * 9 | * Each turbo module extends codegenerated spec class 10 | * 11 | * Class should be annotated with @ReactModule decorator 12 | */ 13 | @ReactModule(name = AppInfoModuleClassic.NAME) 14 | public class AppInfoModuleClassic extends NativeAppInfoModuleClassicSpec { 15 | public static final String NAME = AppInfoModuleClassicImpl.NAME; 16 | 17 | // Use shared module implementation and forward react application context 18 | private final AppInfoModuleClassicImpl moduleImpl; 19 | 20 | public AppInfoModuleClassic(ReactApplicationContext reactContext) { 21 | super(reactContext); 22 | this.moduleImpl = new AppInfoModuleClassicImpl(reactContext); 23 | } 24 | 25 | // Return the name of the module - it should match the name provided in JS specification 26 | @Override 27 | public String getName() { 28 | return NAME; 29 | } 30 | 31 | // Exported methods are overriden - based on the spec class 32 | @Override 33 | public String getAppBuildNumber() { 34 | return moduleImpl.getAppBuildNumber(); 35 | } 36 | 37 | @Override 38 | public String getAppBundleId() { 39 | return moduleImpl.getAppBundleId(); 40 | } 41 | 42 | @Override 43 | public String getAppVersion() { 44 | return moduleImpl.getAppVersion(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app-info-package-classic/ios/AppInfoModuleClassic.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | /** 4 | * Declare the ObjC interface for that native module class. 5 | * 6 | * It must extend NSObject (like every class in ObjC) and 7 | * implement RCTBridgeModule (like each RN native module). 8 | * 9 | * If the module emits events, it must extend RCTEventEmitter class. 10 | */ 11 | @interface AppInfoModuleClassic : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /app-info-package-classic/ios/AppInfoModuleClassicImpl.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AppInfoModuleClassicImpl : NSObject 4 | 5 | - (NSString *)getAppBuildNumber; 6 | - (NSString *)getAppBundleId; 7 | - (NSString *)getAppVersion; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /app-info-package-classic/ios/AppInfoModuleClassicImpl.mm: -------------------------------------------------------------------------------- 1 | #import "AppInfoModuleClassicImpl.h" 2 | 3 | /** 4 | * Native module's shared implementation 5 | */ 6 | @implementation AppInfoModuleClassicImpl 7 | 8 | - (NSString *)getAppBuildNumber 9 | { 10 | return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 11 | } 12 | 13 | - (NSString *)getAppBundleId 14 | { 15 | return [[NSBundle mainBundle] bundleIdentifier]; 16 | } 17 | 18 | - (NSString *)getAppVersion 19 | { 20 | return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /app-info-package-classic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "app-info-package-classic", 4 | "version": "0.0.1", 5 | "description": "App Info package (classic)", 6 | "react-native": "src", 7 | "source": "src", 8 | "main": "src", 9 | "module": "src", 10 | "files": [ 11 | "src", 12 | "android", 13 | "ios", 14 | "AppInfoPackageClassic.podspec", 15 | "!android/build", 16 | "!ios/build", 17 | "!**/__tests__", 18 | "!**/__mocks__" 19 | ], 20 | "repository": "repository url", 21 | "author": "author", 22 | "license": "MIT", 23 | "homepage": "homepage", 24 | "peerDependencies": { 25 | "react": "*", 26 | "react-native": "*" 27 | }, 28 | "codegenConfig": { 29 | "name": "AppInfoPackageClassic", 30 | "type": "all", 31 | "jsSrcsDir": "src", 32 | "android": { 33 | "javaPackageName": "com.appinfopackageclassic" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app-info-package-classic/src/NativeAppInfoModuleClassic.ts: -------------------------------------------------------------------------------- 1 | import type { TurboModule } from 'react-native'; 2 | import { TurboModuleRegistry } from 'react-native'; 3 | 4 | export interface Spec extends TurboModule { 5 | getAppBuildNumber(): string 6 | getAppBundleId(): string 7 | getAppVersion(): string 8 | } 9 | 10 | export default TurboModuleRegistry.getEnforcing('AppInfoModuleClassic'); -------------------------------------------------------------------------------- /app-info-package-classic/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as AppInfoModuleClassic } from './NativeAppInfoModuleClassic'; 2 | -------------------------------------------------------------------------------- /app-info-package/android/src/newarch/java/com/appinfopackage/AppInfoModule.kt: -------------------------------------------------------------------------------- 1 | package com.appinfopackage 2 | 3 | import com.facebook.react.bridge.ReactApplicationContext 4 | import com.facebook.react.module.annotations.ReactModule 5 | 6 | /** 7 | * Declare Kotlin class for new arch native module implementation 8 | * 9 | * Each turbo module extends codegenerated spec class 10 | * 11 | * Class should be annotated with @ReactModule decorator 12 | */ 13 | @ReactModule(name = AppInfoModule.NAME) 14 | class AppInfoModule( 15 | // Each native module class consumes react application context 16 | reactContext: ReactApplicationContext 17 | ) : NativeAppInfoModuleSpec(reactContext) { 18 | // Use shared module implementation and forward react application context 19 | private val moduleImpl = AppInfoModuleImpl(reactContext) 20 | 21 | // Return the name of the module - it should match the name provided in JS specification 22 | override fun getName() = NAME 23 | 24 | // Exported methods are overriden - based on the spec class 25 | override fun getAppBuildNumber() = moduleImpl.getAppBuildNumber() 26 | 27 | override fun getAppBundleId() = moduleImpl.getAppBundleId() 28 | 29 | override fun getAppVersion() = moduleImpl.getAppVersion() 30 | 31 | companion object { 32 | const val NAME = AppInfoModuleImpl.NAME 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app-info-package/android/src/oldarch/java/com/appinfopackage/AppInfoModule.kt: -------------------------------------------------------------------------------- 1 | package com.appinfopackage 2 | 3 | import com.facebook.react.bridge.ReactApplicationContext 4 | import com.facebook.react.bridge.ReactContextBaseJavaModule 5 | import com.facebook.react.bridge.ReactMethod 6 | import com.facebook.react.module.annotations.ReactModule 7 | 8 | /** 9 | * Declare Kotlin class for old arch native module implementation 10 | * 11 | * Each native module extends ReactContextBaseJavaModule class 12 | * 13 | * Class should be annotated with @ReactModule decorator 14 | */ 15 | @ReactModule(name = AppInfoModule.NAME) 16 | class AppInfoModule( 17 | // Each native module class consumes react application context 18 | reactContext: ReactApplicationContext 19 | ) : ReactContextBaseJavaModule(reactContext) { 20 | // Use shared module implementation and forward react application context 21 | private val moduleImpl = AppInfoModuleImpl(reactContext) 22 | 23 | // Return the name of the module - it should match the name provided in JS specification 24 | override fun getName() = NAME 25 | 26 | // Exported methods must be annotated with @ReactMethod decorator 27 | @ReactMethod(isBlockingSynchronousMethod = true) 28 | fun getAppBuildNumber() = moduleImpl.getAppBuildNumber() 29 | 30 | @ReactMethod(isBlockingSynchronousMethod = true) 31 | fun getAppBundleId() = moduleImpl.getAppBundleId() 32 | 33 | @ReactMethod(isBlockingSynchronousMethod = true) 34 | fun getAppVersion() = moduleImpl.getAppVersion() 35 | 36 | companion object { 37 | const val NAME = AppInfoModuleImpl.NAME 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app-info-package/ios/AppInfoModule.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | /** 4 | * When using Swift classes in ObjC header, the class must have its 5 | * "forward declaration" 6 | * 7 | * @see https://developer.apple.com/documentation/swift/importing-swift-into-objective-c#Include-Swift-Classes-in-Objective-C-Headers-Using-Forward-Declarations 8 | */ 9 | @class AppInfoModuleImpl; 10 | 11 | /** 12 | * Declare the ObjC interface for that native module class. 13 | * 14 | * It must extend NSObject (like every class in ObjC) and 15 | * implement RCTBridgeModule (like each RN native module). 16 | */ 17 | @interface AppInfoModule : NSObject 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /app-info-package/ios/AppInfoModuleImpl.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | @objc(AppInfoModuleImpl) 4 | public class AppInfoModuleImpl : NSObject { 5 | @objc public func getAppBuildNumber() -> String { 6 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String 7 | } 8 | 9 | @objc public func getAppBundleId() -> String { 10 | return Bundle.main.bundleIdentifier! 11 | } 12 | 13 | @objc public func getAppVersion() -> String { 14 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app-info-package/ios/AppInfoPackage-Bridging-Header.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/app-info-package/ios/AppInfoPackage-Bridging-Header.h -------------------------------------------------------------------------------- /app-info-package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "app-info-package", 4 | "version": "0.0.1", 5 | "description": "App Info package", 6 | "react-native": "src", 7 | "source": "src", 8 | "main": "src", 9 | "module": "src", 10 | "files": [ 11 | "src", 12 | "android", 13 | "ios", 14 | "AppInfoPackage.podspec", 15 | "!android/build", 16 | "!ios/build", 17 | "!**/__tests__", 18 | "!**/__fixtures__", 19 | "!**/__mocks__" 20 | ], 21 | "repository": "", 22 | "author": "", 23 | "license": "MIT", 24 | "homepage": "", 25 | "peerDependencies": { 26 | "react": "*", 27 | "react-native": "*" 28 | }, 29 | "codegenConfig": { 30 | "name": "AppInfoPackage", 31 | "type": "all", 32 | "jsSrcsDir": "src", 33 | "android": { 34 | "javaPackageName": "com.appinfopackage" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app-info-package/src/NativeAppInfoModule.ts: -------------------------------------------------------------------------------- 1 | import type { TurboModule } from 'react-native'; 2 | import { TurboModuleRegistry } from 'react-native'; 3 | 4 | export interface Spec extends TurboModule { 5 | getAppBuildNumber(): string 6 | getAppBundleId(): string 7 | getAppVersion(): string 8 | } 9 | 10 | export default TurboModuleRegistry.getEnforcing('AppInfoModule'); 11 | -------------------------------------------------------------------------------- /app-info-package/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as AppInfoModule } from './NativeAppInfoModule'; 2 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rnbridgingtutorial", 3 | "displayName": "rnbridgingtutorial" 4 | } -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 'module:metro-react-native-babel-preset' ], 3 | plugins: [ 4 | [ 5 | 'module-resolver', 6 | { 7 | root: [ './' ], 8 | extensions: [ 9 | '.ios.js', 10 | '.ios.ts', 11 | '.ios.tsx', 12 | '.android.js', 13 | '.android.ts', 14 | '.android.tsx', 15 | '.js', 16 | '.ts', 17 | '.tsx', 18 | '.json', 19 | ], 20 | alias: { 21 | 'app-info-package': './app-info-package', 22 | 'app-info-package-classic': './app-info-package-classic', 23 | 'conic-gradient-package': './conic-gradient-package', 24 | 'conic-gradient-package-classic': './conic-gradient-package-classic', 25 | 'native-list-package': './native-list-package', 26 | 'native-list-package-classic': './native-list-package-classic', 27 | 'range-slider-package': './range-slider-package', 28 | 'range-slider-package-classic': './range-slider-package-classic', 29 | 'save-file-picker-package': './save-file-picker-package', 30 | 'save-file-picker-package-classic': './save-file-picker-package-classic', 31 | 'screen-orientation-package': './screen-orientation-package', 32 | 'screen-orientation-package-classic': './screen-orientation-package-classic', 33 | }, 34 | }, 35 | ], 36 | [ 37 | '@babel/plugin-transform-react-jsx', 38 | { 39 | runtime: 'automatic', 40 | }, 41 | ], 42 | ], 43 | }; 44 | -------------------------------------------------------------------------------- /bridging-tutorial-website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /bridging-tutorial-website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /bridging-tutorial-website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ require.resolve('@docusaurus/core/lib/babel/preset') ], 3 | }; 4 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/_codegen-for-old-arch-info.mdx: -------------------------------------------------------------------------------- 1 | You may notice, that JS specs contain codegen-related methods, classes, types, etc. to make things more future-proof. 2 | 3 | That's because: 4 | 5 | - those elements are available since RN older versions (even from v0.65) 6 | - those elements are falling back to "old architecture" implementation (e.g. codegenNativeComponent) 7 | - it introduces type safety for exposed native parts on JS side 8 | - it's much easier to keep single specification on JS side - when old arch will be dropped, there'll be no need to change anything on JS side 9 | 10 | So to make it easier, let's use them, to get you more familiar with it 👍 11 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 3, 3 | "label": "Guides" 4 | } 5 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/_codegen-spec.mdx: -------------------------------------------------------------------------------- 1 | You can run codegen to generate native classes and interfaces, and also check if specification is defined in correct way: 2 | 3 | - on iOS: run `yarn codegen:ios`, the code-generated classes should be available under your app's `/ios/build/generated/ios` directory 4 | 5 | - on Android: `yarn codegen:android`, the code-generated classes should be available under the package's `//android/build/generated/source/codegen` directory 6 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/_complete-file.mdx: -------------------------------------------------------------------------------- 1 | import CodeBlock from '@theme/CodeBlock'; 2 | 3 |

4 | Complete {props.filename} file 5 |
{props.children}
6 |
7 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/_exporting-objc-info.mdx: -------------------------------------------------------------------------------- 1 | :::info 2 | 3 | To make Swift elements accessible to Objective-C world, we have to do 4 things: 4 | 5 | - make class extending `NSObject` 6 | - mark class and its methods (at least those methods that are meant to be exposed) as public 7 | - mark class with `@objc(exported-objc-name)` decorator 8 | - mark exposed methods with `@objc` decorator 9 | 10 | ::: 11 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/_old-arch-android-module-file.mdx: -------------------------------------------------------------------------------- 1 | import CodeBlock from '@theme/CodeBlock'; 2 | 3 |
4 | Old architecture module 5 |
6 | The implementation of old architecture module won't be visible in Android Studio when you have new architecture enabled. 7 | To handle that, you can open {props.filename} at other text editor and paste following content:

8 | {props.children} 9 |
10 |
11 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/_old-arch-android-viewmanager-file.mdx: -------------------------------------------------------------------------------- 1 | import CodeBlock from '@theme/CodeBlock'; 2 | 3 |
4 | Old architecture view manager 5 |
6 | The implementation of old architecture view manager won't be visible in Android Studio when you have new architecture enabled. 7 | To handle that, you can open {props.filename} at other text editor and paste following content:

8 | {props.children} 9 |
10 |
11 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/_android-java-impl.mdx: -------------------------------------------------------------------------------- 1 | import AndroidTurboPackage from '../_android-turbo-package.mdx'; 2 | 3 | import AndroidJavaModule from './_android-java-module.mdx'; 4 | import AndroidJavaModuleImpl from './_android-java-moduleimpl.mdx'; 5 | 6 | 7 | 8 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/_android-kotlin-impl.mdx: -------------------------------------------------------------------------------- 1 | import AndroidTurboPackage from '../_android-turbo-package.mdx'; 2 | 3 | import AndroidKotlinModule from './_android-kotlin-module.mdx'; 4 | import AndroidKotlinModuleImpl from './_android-kotlin-moduleimpl.mdx'; 5 | 6 | 7 | 8 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 2, 3 | "label": "AppInfo module" 4 | } 5 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/_ios-objc-impl.mdx: -------------------------------------------------------------------------------- 1 | import IosObjCModule from './_ios-objc-module.mdx'; 2 | import IosObjCModuleImpl from './_ios-objc-moduleimpl.mdx'; 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/_ios-swift-impl.mdx: -------------------------------------------------------------------------------- 1 | import IosSwiftModule from './_ios-swift-module.mdx'; 2 | import IosSwiftModuleImpl from './_ios-swift-moduleimpl.mdx'; 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/_ios-swift-moduleimpl.mdx: -------------------------------------------------------------------------------- 1 | import ExportingObjCInfo from '../_exporting-objc-info.mdx'; 2 | 3 | #### `AppInfoModuleImpl.swift` 4 | 5 | Let's start by creating a small pure Swift class that will directly retrieve all application informations: 6 | 7 | ```swift title="ios/AppInfoModuleImpl.swift" 8 | import Foundation 9 | 10 | @objc(AppInfoModuleImpl) 11 | public class AppInfoModuleImpl : NSObject { 12 | @objc public func getAppBuildNumber() -> String { 13 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String 14 | } 15 | 16 | @objc public func getAppBundleId() -> String { 17 | return Bundle.main.bundleIdentifier! 18 | } 19 | 20 | @objc public func getAppVersion() -> String { 21 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String 22 | } 23 | } 24 | ``` 25 | 26 | Here, we declare `AppInfoModuleImpl` class, which has 3 synchronous methods. 27 | 28 | 29 | 30 | Methods in the class are using `Bundle` class, for the reference, check out Apple's [dedicated docs section](https://developer.apple.com/documentation/foundation/bundle). 31 | 32 | We will use main `Bundle` instance to [retrieve some information about the app](https://developer.apple.com/documentation/foundation/bundle#1652578). 33 | 34 | In case of `getAppBundleId` method, we will use `bundleIdentifier` property, for other methods we use _generic_ `object(forInfoDictionaryKey:)` method, where the argument is a key from `Info.plist`. 35 | For possible `Info.plist` keys, visit ["About Info.plist keys and values"](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html). 36 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/_result.mdx: -------------------------------------------------------------------------------- 1 | import appInfoResult from '/img/appinfo-result.png'; 2 | 3 |
4 | AppInfo module in action 5 |
6 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/android-impl.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: Android implementation 3 | sidebar_position: 5 4 | title: Android implementation 5 | --- 6 | 7 | import Tabs from '@theme/Tabs'; 8 | import TabItem from '@theme/TabItem'; 9 | 10 | import AndroidJavaImpl from './_android-java-impl.mdx' 11 | import AndroidKotlinImpl from './_android-kotlin-impl.mdx' 12 | 13 | Let's use Android Studio to write Android code. Launch Android Studio and open the project under `/android` path. 14 | When the project is opened, find `app-info-package` inside project-tree. 15 | 16 | The `app-info-package` contains 3 packages with the same name `com.appinfopackage`. After expanding them, you'll notice that these contain following things: 17 | 18 | - code-generated Java spec files 19 | - `AppInfoModule` class stub files 20 | - `AppInfoModuleImpl` class stub file 21 | - `AppInfoTurboPackage` class stub file 22 | 23 | Let's start implementing! 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | You can check training repo for Kotlin implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package) and Java implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package-classic). 39 | 40 | That's Android part, now let's wrap things up and try to [use AppInfo module](./usage) in action! 41 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/intro.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: Intro 3 | sidebar_position: 1 4 | title: Intro 5 | --- 6 | 7 | import Result from './_result.mdx'; 8 | 9 | In this guide, you'll learn how to create a simple module with 3 synchronous methods. 10 | 11 | ### Difficulty 12 | 13 | Kids' stuff 👶 14 | 15 | ### Task 16 | 17 | As a user, I want to see the package name and version, so that I know if I use test or live version of the app. 18 | 19 | ### What's the plan? 20 | 21 | - create module's boilerplate 22 | - create JS spec 23 | - iOS implementation 24 | - Android implementation 25 | - use the module in action 26 | 27 | ### Result? 28 | 29 | 30 | 31 | Can't wait? Let's set up [module boilerplate](./setup). 32 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/ios-impl.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: iOS implementation 3 | sidebar_position: 4 4 | title: iOS implementation 5 | --- 6 | 7 | import Tabs from '@theme/Tabs'; 8 | import TabItem from '@theme/TabItem'; 9 | 10 | import IosObjCImpl from './_ios-objc-impl.mdx'; 11 | import IosSwiftImpl from './_ios-swift-impl.mdx'; 12 | 13 | Let's use XCode, to write iOS code. Open XCode, by running this command from the root directory of your app: 14 | 15 | ```sh 16 | xed ios 17 | ``` 18 | 19 | When workspace is opened, locate `Pods` project and expand it. Search for `Development Pods` and find `AppInfoPackage` inside. When it's expanded, it will show all files that we created under `app-info-package/ios` directory. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | You can check training repo for Objective-C & Swift implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package) and Objective-C-only implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package-classic). 35 | 36 | That's iOS part, now let's go to [Android](./android-impl)! 37 | 38 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/app-info-module/js-spec.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: JS specification 3 | sidebar_position: 3 4 | title: JS specification 5 | --- 6 | 7 | import CodegenSpec from '../_codegen-spec.mdx'; 8 | 9 | When all boilerplate is ready, let's navigate to `src/NativeAppInfoModule.ts`. To declare module spec, let's paste following content: 10 | 11 | ```tsx title="src/NativeAppInfoModule.ts" 12 | import type { TurboModule } from 'react-native'; 13 | import { TurboModuleRegistry } from 'react-native'; 14 | 15 | export interface Spec extends TurboModule { 16 | getAppBuildNumber(): string 17 | getAppBundleId(): string 18 | getAppVersion(): string 19 | } 20 | 21 | export default TurboModuleRegistry.getEnforcing('AppInfoModule'); 22 | ``` 23 | 24 | This does 2 things: 25 | - declares module specification with 3 synchronous methods, each one returning a string value 26 | - declares that module, should be available under `AppInfoModule` name 27 | 28 | 29 | 30 | After that, let's finalize JS part by exporting module from `index.ts` 31 | 32 | ```tsx title="src/index.ts" 33 | export { default as AppInfoModule } from './NativeAppInfoModule'; 34 | ``` 35 | 36 | JS part finished! Let's jump to [iOS implementation](./ios-impl). 37 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/_android-java-impl.mdx: -------------------------------------------------------------------------------- 1 | import AndroidTurboPackage from '../_android-turbo-package.mdx'; 2 | 3 | import AndroidJavaView from './_android-java-view.mdx'; 4 | import AndroidJavaViewManager from './_android-java-viewmanager.mdx'; 5 | 6 | 7 | 8 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/_android-kotlin-impl.mdx: -------------------------------------------------------------------------------- 1 | import AndroidTurboPackage from '../_android-turbo-package.mdx'; 2 | 3 | import AndroidKotlinView from './_android-kotlin-view.mdx' 4 | import AndroidKotlinViewManager from './_android-kotlin-viewmanager.mdx' 5 | 6 | 7 | 8 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 3, 3 | "label": "Conic gradient view" 4 | } 5 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/_ios-objc-impl.mdx: -------------------------------------------------------------------------------- 1 | import IosObjCComponentView from './_ios-objc-componentview.mdx' 2 | import IosObjCView from './_ios-objc-view.mdx' 3 | import IosObjCViewManager from './_ios-objc-viewmanager.mdx' 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/_ios-objc-viewmanager.mdx: -------------------------------------------------------------------------------- 1 | #### `ConicGradientViewManager.h` 2 | 3 | Let's navigate to `ios/ConicGradientViewManager.h` - the header file for the `ConicGradientViewManager` view manager class. It will extend `RCTViewManager` class. 4 | 5 | ```objc title="ios/ConicGradientViewManager.h 6 | #import 7 | 8 | /** 9 | * Declare the ObjC interface for that view manager class. 10 | * 11 | * It must extend RCTViewManager 12 | */ 13 | @interface ConicGradientViewManager : RCTViewManager 14 | 15 | @end 16 | ``` 17 | 18 | #### `ConicGradientViewManager.mm` 19 | 20 | Wrap everything up in `ios/ConicGradientViewManager.mm` 21 | 22 | ```objc title="ios/ConicGradientViewManager.mm" 23 | #import "ConicGradientViewManager.h" 24 | 25 | #if RCT_NEW_ARCH_ENABLED 26 | #else 27 | #import "ConicGradientView.h" 28 | #endif 29 | 30 | @implementation ConicGradientViewManager 31 | 32 | RCT_EXPORT_MODULE(ConicGradientView) 33 | 34 | RCT_EXPORT_VIEW_PROPERTY(colors, NSArray) 35 | RCT_EXPORT_VIEW_PROPERTY(locations, NSArray) 36 | RCT_EXPORT_VIEW_PROPERTY(centerPoint, CGPoint) 37 | 38 | #if RCT_NEW_ARCH_ENABLED 39 | #else 40 | - (UIView *)view 41 | { 42 | ConicGradientView *view = [ConicGradientView new]; 43 | return view; 44 | } 45 | #endif 46 | 47 | @end 48 | ``` 49 | 50 | In the implementation file for `ConicGradientViewManager` class we use `RCT_EXPORT_MODULE` macro with the `ConicGradientView` name that will be accessed on the JS side. 51 | The props are declared with `RCT_EXPORT_VIEW_PROPERTY` macro (1st arg - name of the prop; 2nd arg - its native type). 52 | Additionally, we are declaring managed view for the old architecture mode - for the new architecture mode, we just need to register the name of our module and the props it accepts. 53 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/_result.mdx: -------------------------------------------------------------------------------- 1 | import conicGradientResult from '/img/conicgradient-result.png'; 2 | 3 |
4 | Conic gradient view in action 5 |
6 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/android-impl.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: Android implementation 3 | sidebar_position: 5 4 | title: Android implementation 5 | --- 6 | 7 | import Tabs from '@theme/Tabs'; 8 | import TabItem from '@theme/TabItem'; 9 | 10 | import AndroidJavaImpl from './_android-java-impl.mdx'; 11 | import AndroidKotlinImpl from './_android-kotlin-impl.mdx'; 12 | 13 | Let's use Android Studio for writing Android code. Launch Android Studio and open the project under `/android` path 14 | When the project is opened, find `conic-gradient-package` inside project-tree 15 | 16 | The `conic-gradient-package` contains 3 packages with the same name `com.conicgradientpackage`. After expanding them, you'll notice that these contain following things: 17 | 18 | - code-generated Java spec files 19 | - `ConicGradientViewManager` view manager class stub files 20 | - `ConicGradientView` class stub file 21 | - `ConicGradientTurboPackage` class stub file 22 | 23 | Let's begin! 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | You can check training repo for Kotlin implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/conic-gradient-package) and Java implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/conic-gradient-package-classic). 39 | 40 | That's Android part, now let's wrap things up and try to [use Conic gradient](./usage) in action! 41 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/intro.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: Intro 3 | sidebar_position: 1 4 | title: Intro 5 | --- 6 | 7 | import Result from './_result.mdx' 8 | 9 | In this guide, you'll learn how to extend `` with [conic gradient](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient) background functionality. 10 | 11 | ### Difficulty 12 | 13 | Easier than you thought 🧑‍🎓 14 | 15 | ### Task 16 | 17 | As a user, I want to see the gradient background for the screen. 18 | 19 | ### What's the plan? 20 | 21 | - create view's boilerplate 22 | - creating JS spec 23 | - iOS implementation 24 | - Android implementation 25 | - using the view in action 26 | 27 | ### Result? 28 | 29 | 30 | 31 | Can't wait? Let's set up [view boilerplate](./setup). 32 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/conic-gradient-view/ios-impl.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: iOS implementation 3 | sidebar_position: 4 4 | title: iOS implementation 5 | --- 6 | 7 | import Tabs from '@theme/Tabs'; 8 | import TabItem from '@theme/TabItem'; 9 | 10 | import IosObjCImpl from './_ios-objc-impl.mdx' 11 | 12 | Let's use XCode, to write iOS code. Open XCode, by running this command from the root directory of your app: 13 | 14 | ```sh 15 | xed ios 16 | ``` 17 | 18 | When workspace is opened, locate `Pods` project and expand it. Search for `Development Pods` and find `ConicGradientPackage` inside. When it's expanded, it will show all files that we created under `conic-gradient-package/ios` directory. 19 | 20 | :::info 21 | 22 | Extending the `` is available only in Objective-C 23 | 24 | ::: 25 | 26 | 27 | 28 | You can check training repo for Objective-C-only implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/conic-gradient-package). 29 | 30 | That's iOS part, now let's go to [Android](./android-impl)! 31 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/guides-intro.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: Introduction 3 | sidebar_position: 1 4 | title: Introduction 5 | --- 6 | 7 | Following guides will showcase how to bring multiple platform features to a React Native application, from querying basic application information, through simple UI elements and interactions with the device, ending with complex layouts. 8 | 9 | Each guide is written in a way, that lets you consume them separately, without knowledge from the previous one, so you can just jump to any that you're interested in. 10 | 11 | However, if you're a total beginner in that topic, it's recommended to go in the order these are listed. 12 | 13 | For more reference on how to "translate" features like methods, events, view props, etc. defined in JS code to the platform-specific code, visit [module's reference](../module-reference/module-intro) and [view's reference](../view-reference/view-intro) sections. 14 | 15 | Available guides: 16 | 17 | - [app info module](./app-info-module/intro) - a simple module with synchronous methods 18 | 19 | - [conic gradient view](./conic-gradient-view/intro) - extended `` with custom gradient background 20 | 21 | - [save file picker module](./save-file-picker-module/intro) - a module that calls platform APIs and returns response via callback or promise method 22 | 23 | - [range slider view](./range-slider-view/intro) - a custom native component that wraps 3rd party native library 24 | 25 | - [screen orientation module](./screen-orientation-module/intro) - a simple module that emits events based on data from platform APIs 26 | 27 | - [AVAILABLE SOON] native list view - Android's Fragment & iOS UIViewController integration 28 | 29 | If you have any idea on additional guides, share it on [Bridging Tutorial's Github](https://github.com/mateusz1913/rnbridgingtutorial/discussions). 30 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_android-fragment-list-layout.mdx: -------------------------------------------------------------------------------- 1 | #### `fragment_list.xml` 2 | 3 | Open `android/src/main/res/layout/fragment_list.xml` file in Android Studio and paste the following code: 4 | 5 | ```xml title="android/src/main/res/layout/fragment_list.xml" 6 | 7 | 10 | 11 | 15 | 16 | 17 | ``` 18 | 19 | Here we're wrapping `RecyclerView` (the native list element) inside a `ConstraintLayout` and make it fill parent's size. 20 | As in the card item layout, we declare `android:id` attribute, to reference the `RecyclerView` later inside the code. 21 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_android-java-data-item.mdx: -------------------------------------------------------------------------------- 1 | #### `DataItem.java` 2 | 3 | After defining the layouts, let's jump to code and start by defining Java class `DataItem` which will be used to hold items passed from JS code: 4 | 5 | ```java title="android/src/main/java/com/nativelistpackage/DataItem.java" 6 | package com.nativelistpackage; 7 | 8 | public class DataItem { 9 | public String imageUrl; 10 | public String description; 11 | 12 | public DataItem(String imageUrl, String description) { 13 | this.imageUrl = imageUrl; 14 | this.description = description; 15 | } 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_android-java-impl.mdx: -------------------------------------------------------------------------------- 1 | import AndroidTurboPackage from '../_android-turbo-package.mdx'; 2 | 3 | import AndroidAddLibraryInGradle from './_android-add-library-in-gradle.mdx'; 4 | import AndroidCardItemLayout from './_android-card-item-layout.mdx'; 5 | import AndroidFragmentListLayout from './_android-fragment-list-layout.mdx'; 6 | import AndroidJavaDataItem from './_android-java-data-item.mdx'; 7 | import AndroidJavaListAdapter from './_android-java-list-adapter.mdx'; 8 | import AndroidJavaListFragment from './_android-java-list-fragment.mdx'; 9 | import AndroidJavaListViewHolder from './_android-java-list-viewholder.mdx'; 10 | import AndroidJavaViewManager from './_android-java-viewmanager.mdx'; 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_android-java-list-viewholder.mdx: -------------------------------------------------------------------------------- 1 | #### `NativeListViewHolder.java` 2 | 3 | Now, we need to define the view holder class that will be used by `RecyclerView` to keep reference to the UI elements inside single list item 4 | 5 | ```java title="android/src/main/java/com/nativelistpackage/NativeListViewHolder.java" 6 | package com.nativelistpackage; 7 | 8 | import android.view.View; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | public class NativeListViewHolder extends RecyclerView.ViewHolder { 14 | public ImageView imageView; 15 | public TextView label; 16 | 17 | public NativeListViewHolder(View itemView) { 18 | super(itemView); 19 | this.imageView = itemView.findViewById(R.id.list_card_image); 20 | this.label = itemView.findViewById(R.id.list_card_label); 21 | } 22 | } 23 | ``` 24 | 25 | Each class needs to extend base [`RecyclerView.ViewHolder`](https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ViewHolder) class. 26 | Additionally we declare properties for image and text views, to make it easier later to interact with them. 27 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_android-kotlin-data-item.mdx: -------------------------------------------------------------------------------- 1 | #### `DataItem.kt` 2 | 3 | After defining the layouts, let's jump to code and start by defining Kotlin data class `DataItem` which will be used to hold items passed from JS code: 4 | 5 | ```kotlin title="android/src/main/java/com/nativelistpackage/DataItem.kt" 6 | package com.nativelistpackage 7 | 8 | data class DataItem( 9 | val imageUrl: String, 10 | val description: String, 11 | ) 12 | ``` 13 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_android-kotlin-impl.mdx: -------------------------------------------------------------------------------- 1 | import AndroidTurboPackage from '../_android-turbo-package.mdx'; 2 | 3 | import AndroidAddLibraryInGradle from './_android-add-library-in-gradle.mdx'; 4 | import AndroidCardItemLayout from './_android-card-item-layout.mdx'; 5 | import AndroidFragmentListLayout from './_android-fragment-list-layout.mdx'; 6 | import AndroidKotlinDataItem from './_android-kotlin-data-item.mdx'; 7 | import AndroidKotlinListAdapter from './_android-kotlin-list-adapter.mdx'; 8 | import AndroidKotlinListFragment from './_android-kotlin-list-fragment.mdx'; 9 | import AndroidKotlinListViewHolder from './_android-kotlin-list-viewholder.mdx'; 10 | import AndroidKotlinViewManager from './_android-kotlin-viewmanager.mdx'; 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_android-kotlin-list-viewholder.mdx: -------------------------------------------------------------------------------- 1 | #### `NativeListViewHolder.kt` 2 | 3 | Now, we need to define the view holder class that will be used by `RecyclerView` to keep reference to the UI elements inside single list item 4 | 5 | ```kotlin title="android/src/main/java/com/nativelistpackage/NativeListViewHolder.kt" 6 | package com.nativelistpackage 7 | 8 | import android.view.View 9 | import android.widget.ImageView 10 | import android.widget.TextView 11 | import androidx.recyclerview.widget.RecyclerView 12 | 13 | class NativeListViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) { 14 | var imageView: ImageView 15 | var label: TextView 16 | 17 | init { 18 | imageView = itemView.findViewById(R.id.list_card_image) 19 | label = itemView.findViewById(R.id.list_card_label) 20 | } 21 | } 22 | ``` 23 | 24 | Each class needs to extend base [`RecyclerView.ViewHolder`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView.ViewHolder) class. 25 | Additionally we declare properties for image and text views, to make it easier later to interact with them. 26 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 7, 3 | "label": "Native list viewcontroller/fragment" 4 | } 5 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_ios-objc-data-item.mdx: -------------------------------------------------------------------------------- 1 | #### `DataItem.h` 2 | 3 | ```objc title="DataItem.h" 4 | #import 5 | 6 | @interface DataItem : NSObject 7 | 8 | @property (nonatomic, copy) NSString * _Nonnull imageUrl; 9 | @property (nonatomic, copy) NSString * _Nonnull itemDescription; 10 | 11 | - (instancetype)initWithImageUrl:(NSString * _Nonnull)imageUrl itemDescription:(NSString * _Nonnull)itemDescription; 12 | 13 | @end 14 | ``` 15 | 16 | We start by defining `DataItem` object's interface - it extends `NSObject` and declares two properties (`imageUrl` & `itemDescription`). 17 | 18 | #### `DataItem.mm` 19 | 20 | ```swift title="ios/DataItem.swift" 21 | #import "DataItem.h" 22 | 23 | @implementation DataItem 24 | 25 | - (instancetype)initWithImageUrl:(NSString *)imageUrl itemDescription:(NSString *)itemDescription 26 | { 27 | self = [super init]; 28 | if (self) { 29 | _imageUrl = imageUrl; 30 | _itemDescription = itemDescription; 31 | } 32 | return self; 33 | } 34 | 35 | @end 36 | ``` 37 | 38 | Next step is declaring implementation for the object. 39 | We will use it later when parsing `data` prop in Objective-C++ code 40 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_ios-objc-impl.mdx: -------------------------------------------------------------------------------- 1 | import IosObjCComponentView from './_ios-objc-componentview.mdx'; 2 | import IosObjCContainerView from './_ios-objc-containerview.mdx'; 3 | import IosObjCDataItem from './_ios-objc-data-item.mdx'; 4 | import IosObjCListCell from './_ios-objc-list-cell.mdx'; 5 | import IosObjCViewController from './_ios-objc-viewcontroller.mdx'; 6 | import IosObjCViewManager from './_ios-objc-viewmanager.mdx'; 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_ios-swift-data-item.mdx: -------------------------------------------------------------------------------- 1 | #### `DataItem.swift` 2 | 3 | Let's start by defining `DataItem` object which will be used to hold items passed from JS code: 4 | 5 | ```swift title="ios/DataItem.swift" 6 | import Foundation 7 | 8 | @objc(DataItem) 9 | public class DataItem: NSObject { 10 | @objc public var imageUrl: String = "" 11 | @objc public var itemDescription: String = "" 12 | 13 | @objc public init(imageUrl: String, itemDescription: String) { 14 | self.imageUrl = imageUrl 15 | self.itemDescription = itemDescription 16 | } 17 | } 18 | ``` 19 | 20 | The class (that extends from `NSObject`) defines two string fields and is exported to Objective-C - we will use it later when parsing `data` prop in Objective-C++ code. 21 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_ios-swift-impl.mdx: -------------------------------------------------------------------------------- 1 | import IosSwiftComponentView from './_ios-swift-componentview.mdx'; 2 | import IosSwiftContainerView from './_ios-swift-containerview.mdx'; 3 | import IosSwiftDataItem from './_ios-swift-data-item.mdx'; 4 | import IosSwiftListCell from './_ios-swift-list-cell.mdx'; 5 | import IosSwiftViewController from './_ios-swift-viewcontroller.mdx'; 6 | import IosSwiftViewManager from './_ios-swift-viewmanager.mdx'; 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/_result.mdx: -------------------------------------------------------------------------------- 1 | import nativeListAndroidResult from '/video/native-list-android-result.mp4'; 2 | import nativeListIosResult from '/video/native-list-ios-result.mp4'; 3 | 4 |
5 |
6 | 9 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/native-list-view/ios-impl.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: iOS implementation 3 | sidebar_position: 4 4 | title: iOS implementation 5 | --- 6 | 7 | import Tabs from '@theme/Tabs'; 8 | import TabItem from '@theme/TabItem'; 9 | 10 | import IosObjCImpl from './_ios-objc-impl.mdx'; 11 | import IosSwiftImpl from './_ios-swift-impl.mdx'; 12 | 13 | Let's use XCode, to write iOS code. Open XCode, by running this command from the root directory of your app: 14 | 15 | ```sh 16 | xed ios 17 | ``` 18 | 19 | When workspace is opened, locate `Pods` project and expand it. Search for `Development Pods` and find `NativeListPackage` inside. When it's expanded, it will show all files that we created under `native-list-package/ios` directory. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | You can check training repo for Objective-C & Swift implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/native-list-package) and Objective-C-only implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/native-list-package-classic). 35 | 36 | That's iOS part, now let's go to [Android](./android-impl)! 37 | -------------------------------------------------------------------------------- /bridging-tutorial-website/docs/guides/range-slider-view/_android-change-theme-to-material-3.mdx: -------------------------------------------------------------------------------- 1 | #### Change Android theme to `Material3` 2 | 3 | To use `MaterialComponents` library, we need to change the Android app's theme to the Material theme. 4 | To do that, let's navigate to our tutorial app and go to `styles.xml` in Android resources directory: 5 | 6 | ```diff title="android/app/src/main/res/values/styles.xml" 7 | -