diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 7b5ffa04..89a3e253 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - master + - next paths: - '.github/workflows/android.yml' - 'android/**' @@ -11,6 +12,7 @@ on: push: branches: - master + - next concurrency: group: ${{ github.ref }}-android diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index e8cb5b88..eb418aa5 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - master + - next paths: - '.github/workflows/ios.yml' - 'ios/**' @@ -11,6 +12,7 @@ on: push: branches: - master + - next concurrency: group: ${{ github.ref }}-ios diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5ca0f3ac..22315be2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,9 +4,11 @@ on: pull_request: branches: - master + - next push: branches: - master + - next concurrency: group: ${{ github.ref }}-js diff --git a/.gitignore b/.gitignore index 644a9566..fe823466 100644 --- a/.gitignore +++ b/.gitignore @@ -47,12 +47,6 @@ npm-debug.log yarn-debug.log yarn-error.log -# BUCK -buck-out/ -\.buckd/ -android/app/libs -android/keystores/debug.keystore - # Expo .expo/* @@ -76,3 +70,4 @@ lefthook.yml # testing /coverage .cxx +example/ios/PagerViewExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/README.md b/README.md index f608dd4f..37b7caa8 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ For advanced usage please take a look into our [example project](https://github. | `pageMargin: number` | Blank space to be shown between pages | both | | `keyboardDismissMode: ('none' / 'on-drag')` | Determines whether the keyboard gets dismissed in response to a drag | both | | `orientation: Orientation` | Set `horizontal` or `vertical` scrolling orientation (it does **not** work dynamically) | both | -| `overScrollMode: OverScrollMode` | Used to override default value of overScroll mode. Can be `auto`, `always` or `never`. Defaults to `auto` | Android | +| `overScrollMode: OverScrollMode` | Used to override default value of overScroll mode. Can be `auto`, `always` or `never`. Defaults to `auto` | Android | | `offscreenPageLimit: number` | Set the number of pages that should be retained to either side of the currently visible page(s). Pages beyond this limit will be recreated from the adapter when needed. Defaults to RecyclerView's caching strategy. The given value must either be larger than 0. | Android | | `overdrag: boolean` | Allows for overscrolling after reaching the end or very beginning or pages. Defaults to `false` | iOS | | `layoutDirection: ('ltr' / 'rtl' / 'locale')` | Specifies layout direction. Use `ltr` or `rtl` to set explicitly or `locale` to deduce from the default language script of a locale. Defaults to `locale` | both | diff --git a/android/src/fabric/java/com/reactnativepagerview/LEGACY_PagerViewViewManager.kt b/android/src/fabric/java/com/reactnativepagerview/LEGACY_PagerViewViewManager.kt new file mode 100644 index 00000000..b202b4c1 --- /dev/null +++ b/android/src/fabric/java/com/reactnativepagerview/LEGACY_PagerViewViewManager.kt @@ -0,0 +1,17 @@ +package com.reactnativepagerview + +import com.facebook.react.uimanager.ViewGroupManager +import android.widget.FrameLayout +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.uimanager.ThemedReactContext + +// Note: The LEGACY_ variant is an iOS-only feature and the related Android files +// are only included because of and relevant to auxiliary processes, like Codegen. +@ReactModule(name = LEGACY_PagerViewViewManagerImpl.NAME) +class LEGACY_PagerViewViewManager : ViewGroupManager() { + override fun getName() = LEGACY_PagerViewViewManagerImpl.NAME + + override fun createViewInstance(context: ThemedReactContext): FrameLayout { + throw Error("LEGACY_RNCViewPager is an iOS-only feature") + } +} diff --git a/android/src/fabric/java/com/reactnativepagerview/PagerViewViewManager.kt b/android/src/fabric/java/com/reactnativepagerview/PagerViewViewManager.kt index 46ff4ca1..aa974a6b 100644 --- a/android/src/fabric/java/com/reactnativepagerview/PagerViewViewManager.kt +++ b/android/src/fabric/java/com/reactnativepagerview/PagerViewViewManager.kt @@ -173,6 +173,11 @@ class PagerViewViewManager : ViewGroupManager(), RNCViewPa return } + @ReactProp(name = "useLegacy") + override fun setUseLegacy(view: NestedScrollableHost?, value: Boolean) { + return + } + fun goTo(root: NestedScrollableHost?, selectedPage: Int, scrollWithAnimation: Boolean) { if (root == null) { return diff --git a/android/src/main/java/com/reactnativepagerview/LEGACY_PagerViewViewManagerImpl.kt b/android/src/main/java/com/reactnativepagerview/LEGACY_PagerViewViewManagerImpl.kt new file mode 100644 index 00000000..7cecdc82 --- /dev/null +++ b/android/src/main/java/com/reactnativepagerview/LEGACY_PagerViewViewManagerImpl.kt @@ -0,0 +1,7 @@ +package com.reactnativepagerview + +// Note: The LEGACY_ variant is an iOS-only feature and the related Android files +// are only included because of and relevant to auxiliary processes, like Codegen. +object LEGACY_PagerViewViewManagerImpl { + const val NAME = "LEGACY_RNCViewPager" +} diff --git a/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt b/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt index 194bf0aa..b09b6e1c 100644 --- a/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt +++ b/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt @@ -12,6 +12,6 @@ class PagerViewPackage : ReactPackage { } override fun createViewManagers(reactContext: ReactApplicationContext): List> { - return listOf(PagerViewViewManager()) + return listOf(PagerViewViewManager(), LEGACY_PagerViewViewManager()) } } diff --git a/android/src/paper/java/com/reactnativepagerview/LEGACY_PagerViewViewManager.kt b/android/src/paper/java/com/reactnativepagerview/LEGACY_PagerViewViewManager.kt new file mode 100644 index 00000000..b202b4c1 --- /dev/null +++ b/android/src/paper/java/com/reactnativepagerview/LEGACY_PagerViewViewManager.kt @@ -0,0 +1,17 @@ +package com.reactnativepagerview + +import com.facebook.react.uimanager.ViewGroupManager +import android.widget.FrameLayout +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.uimanager.ThemedReactContext + +// Note: The LEGACY_ variant is an iOS-only feature and the related Android files +// are only included because of and relevant to auxiliary processes, like Codegen. +@ReactModule(name = LEGACY_PagerViewViewManagerImpl.NAME) +class LEGACY_PagerViewViewManager : ViewGroupManager() { + override fun getName() = LEGACY_PagerViewViewManagerImpl.NAME + + override fun createViewInstance(context: ThemedReactContext): FrameLayout { + throw Error("LEGACY_RNCViewPager is an iOS-only feature") + } +} diff --git a/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerComponentDescriptor.h b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerComponentDescriptor.h new file mode 100644 index 00000000..b5b1b1df --- /dev/null +++ b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerComponentDescriptor.h @@ -0,0 +1,12 @@ +#pragma once + +#include "RNCViewPagerShadowNode.h" +#include + +namespace facebook { +namespace react { + +using RNCViewPagerComponentDescriptor = ConcreteComponentDescriptor; + +} +} diff --git a/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerShadowNode.cpp b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerShadowNode.cpp new file mode 100644 index 00000000..a81506ac --- /dev/null +++ b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerShadowNode.cpp @@ -0,0 +1,35 @@ +#include "RNCViewPagerShadowNode.h" + +#include +#include + +namespace facebook { +namespace react { + +const char RNCViewPagerComponentName[] = "RNCViewPager"; + +void RNCViewPagerShadowNode::updateStateIfNeeded() { + ensureUnsealed(); + + auto contentBoundingRect = Rect{}; + for (const auto &childNode : getLayoutableChildNodes()) { + contentBoundingRect.unionInPlace(childNode->getLayoutMetrics().frame); + } + + auto state = getStateData(); + + if (state.contentBoundingRect != contentBoundingRect) { + state.contentBoundingRect = contentBoundingRect; + setStateData(std::move(state)); + } +} + +#pragma mark - LayoutableShadowNode + +void RNCViewPagerShadowNode::layout(LayoutContext layoutContext) { + ConcreteViewShadowNode::layout(layoutContext); + updateStateIfNeeded(); +} + +} +} diff --git a/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerShadowNode.h b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerShadowNode.h new file mode 100644 index 00000000..1aaece35 --- /dev/null +++ b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerShadowNode.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace facebook { +namespace react { + +extern const char RNCViewPagerComponentName[]; + +class RNCViewPagerShadowNode final : public ConcreteViewShadowNode< + RNCViewPagerComponentName, + RNCViewPagerProps, + RNCViewPagerEventEmitter, + RNCViewPagerState> { +public: + using ConcreteViewShadowNode::ConcreteViewShadowNode; + +#pragma mark - LayoutableShadowNode + + void layout(LayoutContext layoutContext) override; + +private: + void updateStateIfNeeded(); +}; + +} +} diff --git a/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerState.cpp b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerState.cpp new file mode 100644 index 00000000..a99afaff --- /dev/null +++ b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerState.cpp @@ -0,0 +1,11 @@ +#include "RNCViewPagerState.h" + +namespace facebook { +namespace react { + +Size RNCViewPagerState::getContentSize() const { + return contentBoundingRect.size; +} + +} +} diff --git a/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerState.h b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerState.h new file mode 100644 index 00000000..ac43dadf --- /dev/null +++ b/common/cpp/react/renderer/components/RNCViewPager/RNCViewPagerState.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace facebook { +namespace react { + +class RNCViewPagerState final { +public: + Point contentOffset; + Rect contentBoundingRect; + + Size getContentSize() const; + +}; + +} +} diff --git a/example/.node-version b/example/.node-version new file mode 100644 index 00000000..3c032078 --- /dev/null +++ b/example/.node-version @@ -0,0 +1 @@ +18 diff --git a/example/android/app/src/main/java/com/pagerviewexample/MainActivity.java b/example/android/app/src/main/java/com/pagerviewexample/MainActivity.java index 71e2bf96..9cc54d9c 100644 --- a/example/android/app/src/main/java/com/pagerviewexample/MainActivity.java +++ b/example/android/app/src/main/java/com/pagerviewexample/MainActivity.java @@ -1,5 +1,11 @@ package com.pagerviewexample; +import com.facebook.react.ReactActivity; +import com.facebook.react.ReactActivityDelegate; +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; +import com.facebook.react.defaults.DefaultReactActivityDelegate; + + import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; diff --git a/example/android/build.gradle b/example/android/build.gradle index d43616bd..5bbae15f 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -10,12 +10,15 @@ buildscript { // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. ndkVersion = "23.1.7779620" } + repositories { google() mavenCentral() + maven { url 'https://www.jitpack.io' } } + dependencies { classpath("com.android.tools.build:gradle") classpath("com.facebook.react:react-native-gradle-plugin") } -} \ No newline at end of file +} diff --git a/example/ios/PagerViewExample.xcodeproj/project.pbxproj b/example/ios/PagerViewExample.xcodeproj/project.pbxproj index e3ad9882..954e500b 100644 --- a/example/ios/PagerViewExample.xcodeproj/project.pbxproj +++ b/example/ios/PagerViewExample.xcodeproj/project.pbxproj @@ -570,6 +570,7 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", + _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION, ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -597,6 +598,13 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + " ", + "-Wl -ld_classic ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; @@ -638,6 +646,10 @@ "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION, + ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -662,6 +674,13 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + " ", + "-Wl -ld_classic ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 79d93dfc..5d3a9eb0 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -375,7 +375,8 @@ PODS: - React-jsinspector (0.72.6) - React-logger (0.72.6): - glog - - react-native-pager-view (6.2.1): + - react-native-pager-view (6.3.0): + - RCT-Folly (= 2021.07.22.00) - React-Core - react-native-safe-area-context (4.5.2): - RCT-Folly @@ -754,7 +755,7 @@ SPEC CHECKSUMS: React-jsiexecutor: 3bf18ff7cb03cd8dfdce08fbbc0d15058c1d71ae React-jsinspector: 194e32c6aab382d88713ad3dd0025c5f5c4ee072 React-logger: cebf22b6cf43434e471dc561e5911b40ac01d289 - react-native-pager-view: d211379f61895b6349bd7e571b44a26d005c2975 + react-native-pager-view: 40d9ec4a63ed74f8aa2f1e1bba7c1e0b4080d8a6 react-native-safe-area-context: 1d596539b05a78f2b346e954e7c577f6f9be7544 React-NativeModulesApple: 02e35e9a51e10c6422f04f5e4076a7c02243fff2 React-perflogger: e3596db7e753f51766bceadc061936ef1472edc3 @@ -784,4 +785,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 4c96e1cc59fd0774de51faf6e28ddf171307d5ed -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.1 diff --git a/example/metro.config.js b/example/metro.config.js index b8232145..55e79a9a 100644 --- a/example/metro.config.js +++ b/example/metro.config.js @@ -31,15 +31,6 @@ const config = { return acc; }, {}), }, - - transformer: { - getTransformOptions: async () => ({ - transform: { - experimentalImportSupport: false, - inlineRequires: true, - }, - }), - }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/example/src/App.tsx b/example/src/App.tsx index eca97d7c..085db363 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -12,6 +12,7 @@ import { Alert, I18nManager, DevSettings, + Platform, } from 'react-native'; import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; @@ -33,7 +34,7 @@ import CoverflowExample from './tabView/CoverflowExample'; import ReanimatedOnPageScrollExample from './ReanimatedOnPageScrollExample'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { SafeAreaProvider } from 'react-native-safe-area-context'; -import { GestureHandlerRootView } from 'react-native-gesture-handler'; +import { NextBasicPagerViewExample } from './NextBasicPagerViewExample'; const examples = [ { component: BasicPagerViewExample, name: 'Basic Example' }, @@ -66,6 +67,13 @@ const examples = [ { component: CoverflowExample, name: 'CoverflowExample' }, ]; +if (Platform.OS === 'ios') { + examples.unshift({ + component: NextBasicPagerViewExample, + name: '🔜 Next Basic Example', + }); +} + function App() { const navigation = useNavigation(); return ( @@ -95,60 +103,61 @@ export function Navigation() { const [mode, setMode] = React.useState<'native' | 'js'>('js'); const NavigationStack = mode === 'js' ? Stack : NativeStack; return ( - - - - - ( -