diff --git a/.eslintrc.json b/.eslintrc.json index e70e9f7934..b10cd5e43a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -71,6 +71,7 @@ "@eslint-react/no-array-index-key": "warn", "@eslint-react/hooks-extra/no-direct-set-state-in-use-effect": "warn", "@eslint-react/hooks-extra/prefer-use-state-lazy-initialization": "warn", + "@eslint-react/hooks-extra/ensure-custom-hooks-using-other-hooks": "warn", "no-redeclare": "off", "@typescript-eslint/no-redeclare": "error", "no-use-before-define": "off", diff --git a/.github/workflows/android-build-paper.yml b/.github/workflows/android-build-paper.yml deleted file mode 100644 index c24918e623..0000000000 --- a/.github/workflows/android-build-paper.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Test Android build (Paper) - -on: - pull_request: - paths: - - .github/workflows/android-build-paper.yml - - packages/react-native-gesture-handler/android/** - push: - branches: - - main - workflow_dispatch: - -jobs: - build: - if: github.repository == 'software-mansion/react-native-gesture-handler' - - runs-on: ubuntu-latest - env: - WORKING_DIRECTORY: apps/expo-example - concurrency: - group: android-paper-${{ github.ref }} - cancel-in-progress: true - - steps: - - name: checkout - uses: actions/checkout@v4 - - - name: Use Java 17 - uses: actions/setup-java@v4 - with: - distribution: oracle - java-version: 17 - - - name: Use Node.js 24 - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: yarn - - - name: Install node dependencies - working-directory: ${{ env.WORKING_DIRECTORY }} - run: PAPER_ENABLED=1 yarn install --immutable - - - name: Build app - working-directory: ${{ env.WORKING_DIRECTORY }}/android - run: ./gradlew assembleDebug --console=plain -PreactNativeArchitectures=arm64-v8a diff --git a/.github/workflows/check-archs-consistency.yml b/.github/workflows/check-archs-consistency.yml deleted file mode 100644 index f579d61d44..0000000000 --- a/.github/workflows/check-archs-consistency.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Test consistency between Paper & Fabric - -on: - pull_request: - branches: - - main - paths: - - .github/workflows/check-archs-consistency.yml - - packages/react-native-gesture-handler/src/specs/** - - packages/react-native-gesture-handler/package.json - - apps/basic-example/package.json - push: - branches: - - main - workflow_dispatch: - -jobs: - check: - if: github.repository == 'software-mansion/react-native-gesture-handler' - runs-on: ubuntu-latest - concurrency: - group: check-archs-consistency-${{ github.ref }} - cancel-in-progress: true - - steps: - - name: checkout - uses: actions/checkout@v4 - - - name: Use Node.js 24 - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: yarn - - - name: Install node dependencies - run: yarn - - - name: Check Android Paper & Fabric generated interfaces consistency - run: yarn workspace react-native-gesture-handler architectures-consistency-check diff --git a/.github/workflows/docs-check.yml b/.github/workflows/docs-check.yml index 109cbec317..064990d766 100644 --- a/.github/workflows/docs-check.yml +++ b/.github/workflows/docs-check.yml @@ -25,7 +25,6 @@ jobs: uses: actions/setup-node@v6 with: node-version: 24 - cache: yarn - name: Install node dependencies working-directory: ${{ env.WORKING_DIRECTORY }} diff --git a/.github/workflows/ios-build-paper.yml b/.github/workflows/ios-build-paper.yml deleted file mode 100644 index b670f3c57c..0000000000 --- a/.github/workflows/ios-build-paper.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Test iOS build (paper) - -on: - pull_request: - paths: - - .github/workflows/ios-build-paper.yml - - packages/react-native-gesture-handler/RNGestureHandler.podspec - - packages/react-native-gesture-handler/apple/** - push: - branches: - - main - workflow_dispatch: - -jobs: - build: - if: github.repository == 'software-mansion/react-native-gesture-handler' - - runs-on: macos-14 - env: - WORKING_DIRECTORY: apps/expo-example - concurrency: - group: ios-paper-${{ matrix.working-directory }}-${{ github.ref }} - cancel-in-progress: true - - steps: - - name: checkout - uses: actions/checkout@v4 - - - name: Use latest stable Xcode - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '16.1' - - - name: Use Node.js 24 - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: yarn - - - name: Install node dependencies - working-directory: ${{ env.WORKING_DIRECTORY }} - run: PAPER_ENABLED=1 yarn install --immutable - - - name: Build app - working-directory: ${{ env.WORKING_DIRECTORY }} - run: npx react-native run-ios diff --git a/.github/workflows/rngh-api-v3.yml b/.github/workflows/rngh-api-v3.yml new file mode 100644 index 0000000000..e0489715a1 --- /dev/null +++ b/.github/workflows/rngh-api-v3.yml @@ -0,0 +1,38 @@ +name: Test Gesture Handler 3 API + +on: + pull_request: + paths: + - packages/react-native-gesture-handler/src/v3/** + - packages/react-native-gesture-handler/src/__tests__/RelationsTraversal.test.tsx + - packages/react-native-gesture-handler/src/__tests__/API_V3.test.tsx + push: + branches: + - main + workflow_dispatch: + +jobs: + check: + if: github.repository == 'software-mansion/react-native-gesture-handler' + + runs-on: ubuntu-latest + concurrency: + group: rngh-api-v3-${{ github.ref }} + cancel-in-progress: true + + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: Use Node.js 24 + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: yarn + + - name: Install node dependencies + run: yarn --immutable + + - name: Run tests + working-directory: packages/react-native-gesture-handler + run: yarn test RelationsTraversal API_V3 diff --git a/.github/workflows/yarn-validation.yml b/.github/workflows/yarn-validation.yml index 86bae4197b..efe47cf68b 100644 --- a/.github/workflows/yarn-validation.yml +++ b/.github/workflows/yarn-validation.yml @@ -45,9 +45,7 @@ jobs: **/package.json **/yarn.lock files_ignore: | - packages/react-native-gesture-handler/DrawerLayout/package.json packages/react-native-gesture-handler/ReanimatedDrawerLayout/package.json - packages/react-native-gesture-handler/Swipeable/package.json packages/react-native-gesture-handler/ReanimatedSwipeable/package.json packages/react-native-gesture-handler/jest-utils/package.json diff --git a/.lintstagedrc.json b/.lintstagedrc.json index 0e38d4e378..c310ce1deb 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -6,5 +6,5 @@ "yarn format:android" ], "packages/react-native-gesture-handler/apple/**/*.{h,m,mm,cpp}": "yarn format:apple", - "packages/react-native-gesture-handler/src/specs/*.ts": "yarn workspace react-native-gesture-handler sync-architectures" + "packages/react-native-gesture-handler/{shared,android/src}/**/*.{h,cpp}": "yarn format:cpp" } diff --git a/.yarn/patches/@react-native-community-slider-npm-4.5.7-658e0e58c9.patch b/.yarn/patches/@react-native-community-slider-npm-4.5.7-658e0e58c9.patch deleted file mode 100644 index 8fb13d8a71..0000000000 --- a/.yarn/patches/@react-native-community-slider-npm-4.5.7-658e0e58c9.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git a/android/src/main/jni/CMakeLists.txt b/android/src/main/jni/CMakeLists.txt -index f720c8e8808c01eab3446b0a819f48aa355077de..0484a6409c2c92ab6971a9b8d607e800a54dea9c 100644 ---- a/android/src/main/jni/CMakeLists.txt -+++ b/android/src/main/jni/CMakeLists.txt -@@ -9,15 +9,6 @@ set(LIB_COMMON_DIR ${LIB_ANDROID_DIR}/../common/cpp) - set(LIB_ANDROID_GENERATED_JNI_DIR ${LIB_ANDROID_DIR}/build/generated/source/codegen/jni) - set(LIB_ANDROID_GENERATED_COMPONENTS_DIR ${LIB_ANDROID_GENERATED_JNI_DIR}/react/renderer/components/${LIB_LITERAL}) - --add_compile_options( -- -fexceptions -- -frtti -- -std=c++20 -- -Wall -- -Wpedantic -- -Wno-gnu-zero-variadic-macro-arguments --) -- - file(GLOB LIB_CUSTOM_SRCS CONFIGURE_DEPENDS *.cpp ${LIB_COMMON_DIR}/react/renderer/components/${LIB_LITERAL}/*.cpp) - file(GLOB LIB_CODEGEN_SRCS CONFIGURE_DEPENDS ${LIB_ANDROID_GENERATED_JNI_DIR}/*.cpp ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}/*.cpp) - -@@ -70,6 +61,21 @@ else() - ) - endif() - -+if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 80) -+ target_compile_reactnative_options(${LIB_TARGET_NAME} PUBLIC) -+else() -+ target_compile_options( -+ ${LIB_TARGET_NAME} -+ PRIVATE -+ -fexceptions -+ -frtti -+ -std=c++20 -+ -Wall -+ -Wpedantic -+ -Wno-gnu-zero-variadic-macro-arguments -+ ) -+endif() -+ - target_compile_options( - ${LIB_TARGET_NAME} - PRIVATE diff --git a/apps/basic-example/Gemfile.lock b/apps/basic-example/Gemfile.lock index f2345fa62b..9f9cbc5984 100644 --- a/apps/basic-example/Gemfile.lock +++ b/apps/basic-example/Gemfile.lock @@ -5,27 +5,28 @@ GEM base64 nkf rexml - activesupport (7.2.2.1) + activesupport (7.1.5.1) base64 benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.3.1) + concurrent-ruby (~> 1.0, >= 1.0.2) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) logger (>= 1.4.2) minitest (>= 5.1) + mutex_m securerandom (>= 0.3) - tzinfo (~> 2.0, >= 2.0.5) + tzinfo (~> 2.0) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) atomos (0.1.3) - base64 (0.2.0) - benchmark (0.4.0) - bigdecimal (3.1.9) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) claide (1.1.0) cocoapods (1.15.2) addressable (~> 2.8) @@ -66,8 +67,8 @@ GEM cocoapods-try (1.2.0) colored2 (3.1.2) concurrent-ruby (1.3.3) - connection_pool (2.5.1) - drb (2.2.1) + connection_pool (2.5.3) + drb (2.2.3) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) @@ -79,7 +80,7 @@ GEM mutex_m i18n (1.14.7) concurrent-ruby (~> 1.0) - json (2.10.2) + json (2.12.2) logger (1.7.0) minitest (5.25.5) molinillo (0.8.0) @@ -91,7 +92,7 @@ GEM public_suffix (4.0.7) rexml (3.4.1) ruby-macho (2.5.1) - securerandom (0.4.1) + securerandom (0.3.2) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) @@ -121,4 +122,4 @@ RUBY VERSION ruby 3.3.5p100 BUNDLED WITH - 2.5.23 + 2.4.7 diff --git a/apps/basic-example/android/gradle.properties b/apps/basic-example/android/gradle.properties index 71e66b7803..9afe61598f 100644 --- a/apps/basic-example/android/gradle.properties +++ b/apps/basic-example/android/gradle.properties @@ -10,7 +10,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m -org.gradle.jvmargs=-Xmx512m -XX:MaxMetaspaceSize=512m +org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/apps/basic-example/babel.config.js b/apps/basic-example/babel.config.js index f7b3da3b33..8ba8eb658c 100644 --- a/apps/basic-example/babel.config.js +++ b/apps/basic-example/babel.config.js @@ -1,3 +1,4 @@ module.exports = { presets: ['module:@react-native/babel-preset'], + plugins: ['react-native-worklets/plugin'], }; diff --git a/apps/basic-example/ios/Podfile.lock b/apps/basic-example/ios/Podfile.lock index 29d57da90c..bbaa392846 100644 --- a/apps/basic-example/ios/Podfile.lock +++ b/apps/basic-example/ios/Podfile.lock @@ -2477,6 +2477,187 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga + - RNReanimated (4.2.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNReanimated/reanimated (= 4.2.0) + - RNWorklets + - SocketRocket + - Yoga + - RNReanimated/reanimated (4.2.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNReanimated/reanimated/apple (= 4.2.0) + - RNWorklets + - SocketRocket + - Yoga + - RNReanimated/reanimated/apple (4.2.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNWorklets + - SocketRocket + - Yoga + - RNWorklets (0.7.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNWorklets/worklets (= 0.7.1) + - SocketRocket + - Yoga + - RNWorklets/worklets (0.7.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNWorklets/worklets/apple (= 0.7.1) + - SocketRocket + - Yoga + - RNWorklets/worklets/apple (0.7.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - SocketRocket (0.7.1) - Yoga (0.0.0) @@ -2559,6 +2740,8 @@ DEPENDENCIES: - ReactCodegen (from `build/generated/ios/ReactCodegen`) - ReactCommon/turbomodule/core (from `../../../node_modules/react-native/ReactCommon`) - RNGestureHandler (from `../../../node_modules/react-native-gesture-handler`) + - RNReanimated (from `../node_modules/react-native-reanimated`) + - RNWorklets (from `../node_modules/react-native-worklets`) - SocketRocket (~> 0.7.1) - Yoga (from `../../../node_modules/react-native/ReactCommon/yoga`) @@ -2722,6 +2905,10 @@ EXTERNAL SOURCES: :path: "../../../node_modules/react-native/ReactCommon" RNGestureHandler: :path: "../../../node_modules/react-native-gesture-handler" + RNReanimated: + :path: "../node_modules/react-native-reanimated" + RNWorklets: + :path: "../node_modules/react-native-worklets" Yoga: :path: "../../../node_modules/react-native/ReactCommon/yoga" @@ -2732,7 +2919,7 @@ SPEC CHECKSUMS: FBLazyVector: a293a88992c4c33f0aee184acab0b64a08ff9458 fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 - hermes-engine: db854ab6e74b584dc130d3ed0be3425726bac226 + hermes-engine: eec912f8a125ae0d3ad67b2e7b81a227319aa13b RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: 2b70c6e3abe00396cefd8913efbf6a2db01a2b36 RCTRequired: f3540eee8094231581d40c5c6d41b0f170237a81 @@ -2802,9 +2989,11 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: ebcf3a78dc1bcdf054c9e8d309244bade6b31568 ReactCodegen: 554b421c45b7df35ac791da1b734335470b55fcc ReactCommon: 424cc34cf5055d69a3dcf02f3436481afb8b0f6f - RNGestureHandler: bd1bfdc9e156efbfda9628838df7d67f0401e4fb + RNGestureHandler: daca7462517d9d2958f95242cc87a7914704a82c + RNReanimated: 987d0b9af435441cc2ebc2a32ad06cafe8777d4e + RNWorklets: 12b2d7cdcb48acbdd0b324d1fa810f849089bd7b SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Yoga: 6ca93c8c13f56baeec55eb608577619b17a4d64e + Yoga: 7a9f26c70daf0b08d82ec2f862e9a8872442129e PODFILE CHECKSUM: ecce038d8e4749ee17b7dea28be0590cdc8b4836 diff --git a/apps/basic-example/package.json b/apps/basic-example/package.json index a717b2dbd6..f2e08dbc69 100644 --- a/apps/basic-example/package.json +++ b/apps/basic-example/package.json @@ -19,7 +19,9 @@ "dependencies": { "react": "19.2.0", "react-native": "0.83.0", - "react-native-gesture-handler": "workspace:*" + "react-native-gesture-handler": "workspace:*", + "react-native-reanimated": "^4.1.3", + "react-native-worklets": "^0.7.1" }, "devDependencies": { "@babel/core": "^7.25.2", diff --git a/apps/basic-example/src/App.tsx b/apps/basic-example/src/App.tsx index 8f5193ee0c..2a5fc77b2e 100644 --- a/apps/basic-example/src/App.tsx +++ b/apps/basic-example/src/App.tsx @@ -4,55 +4,57 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; import Navigator from './Navigator'; -import ComponentsScreen from './ComponentsScreen'; -import FinalScreen from './FinalScreen'; -import GestureCompositionScreen from './GestureCompositionScreen'; -import HomeScreen from './HomeScreen'; -import ViewFlatteningScreen from './ViewFlatteningScreen'; +import Text from './Text'; +import NativeDetector from './NativeDetector'; +import RuntimeDecoration from './RuntimeDecoration'; +import ContentsButton from './ContentsButton'; -const Stack = Navigator.create(); - -Stack.setRoutes({ - home: { - component: HomeScreen, - title: 'RNGH FabricExample', - rightButtonAction: () => { - Stack.navigateTo('gestureComposition'); - }, - }, - gestureComposition: { - component: GestureCompositionScreen, - title: 'Gesture Composition', - rightButtonAction: () => { - Stack.navigateTo('components'); - }, +const EXAMPLES = [ + { + name: 'Text', + component: Text, }, - components: { - component: ComponentsScreen, - title: 'Components', - rightButtonAction: () => { - Stack.navigateTo('viewFlattening'); - }, + { + name: 'Runtime Decoration', + component: RuntimeDecoration, }, - viewFlattening: { - component: ViewFlatteningScreen, - title: 'View Flattening', - rightButtonAction: () => { - Stack.navigateTo('final'); - }, + { + name: 'Native Detector', + component: NativeDetector, }, - final: { - component: FinalScreen, - title: 'Final Screen', + { + name: 'Contents Button', + component: ContentsButton, }, -}); +]; + +const Stack = Navigator.create(); +Stack.setRoutes( + Object.fromEntries( + EXAMPLES.map((example, index) => [ + example.name.toLowerCase().replace(/\s+/g, ''), + { + component: example.component, + title: example.name, + rightButtonAction: + index === EXAMPLES.length - 1 + ? undefined + : () => { + Stack.navigateTo( + EXAMPLES[index + 1].name.toLowerCase().replace(/\s+/g, '') + ); + }, + }, + ]) + ) +); export default function App() { return ( - + ); diff --git a/apps/basic-example/src/ComponentsScreen.tsx b/apps/basic-example/src/ComponentsScreen.tsx deleted file mode 100644 index 8a3eb59fd9..0000000000 --- a/apps/basic-example/src/ComponentsScreen.tsx +++ /dev/null @@ -1,193 +0,0 @@ -import React from 'react'; -import { - FlatList, - Gesture, - GestureDetector, - ScrollView, - Switch, - TextInput, - TouchableNativeFeedback, - TouchableOpacity, -} from 'react-native-gesture-handler'; -import { StyleSheet, Text, View } from 'react-native'; - -import { COLORS } from './colors'; - -function SwitchDemo() { - const [value, setValue] = React.useState(false); - - const pan = Gesture.Pan() - .onBegin(() => console.log('onBegin')) - .onUpdate(() => console.log('onUpdate')) // doesn't work on iOS - .onFinalize(() => console.log('onFinalize')); - - return ( - - RNGH Switch - - setValue(!value)} /> - - - ); -} - -function TextInputDemo() { - const [value, setValue] = React.useState('Hello!'); - - const pan = Gesture.Pan() - .onBegin(() => console.log('onBegin')) - .onUpdate(() => console.log('onUpdate')) - .onFinalize(() => console.log('onFinalize')); - - return ( - - RNGH TextInput - - - - - ); -} - -function TouchableNativeFeedbackDemo() { - return ( - - RNGH TouchableNativeFeedback - console.log('onPressIn')} - onPressOut={() => console.log('onPressOut')} - onLongPress={() => console.log('onLongPress')}> - - - - ); -} - -function TouchableOpacityDemo() { - return ( - - RNGH TouchableOpacity - console.log('onPressIn')} - onPressOut={() => console.log('onPressOut')} - onLongPress={() => console.log('onLongPress')}> - - - - ); -} - -function ScrollViewDemo() { - const pan = Gesture.Pan().onUpdate((e) => console.log('onUpdate', e.x, e.y)); - - return ( - - RNGH ScrollView - - - {Object.values(COLORS).map((color) => ( - - ))} - - - - Dragging here should not scroll - - - - - - - ); -} - -function FlatListDemo() { - return ( - - RNGH FlatList - - ( - - - - )} - keyExtractor={(e) => e} - /> - - - ); -} - -export default function ComponentsScreen() { - return ( - - - Gesture Handler also provides a set of components that support gestures. - - - - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - bold: { - fontWeight: 'bold', - textAlign: 'center', - marginHorizontal: 20, - }, - textInput: { - borderWidth: 1, - borderStyle: 'solid', - borderColor: 'darkgray', - width: 135, - padding: 10, - }, - text: { - marginVertical: 3, - }, - demo: { - marginVertical: 3, - alignItems: 'center', - }, - smallBox: { - width: 50, - height: 50, - }, - largeBox: { - width: 100, - height: 100, - }, - panBox: { - width: 100, - height: 75, - backgroundColor: 'lightgray', - alignItems: 'center', - justifyContent: 'center', - }, - panText: { - textAlign: 'center', - }, -}); diff --git a/apps/basic-example/src/ContentsButton.tsx b/apps/basic-example/src/ContentsButton.tsx new file mode 100644 index 0000000000..23906db5ad --- /dev/null +++ b/apps/basic-example/src/ContentsButton.tsx @@ -0,0 +1,522 @@ +import React from 'react'; +import { View, StyleSheet, Text, SafeAreaView } from 'react-native'; +import { + GestureHandlerRootView, + ScrollView, + RectButton, +} from 'react-native-gesture-handler'; + +export default function ComplexUI() { + return ( + + + + + + + + + + + + + + + + + + ); +} + +const colors = ['#782AEB', '#38ACDD', '#57B495', '#FF6259', '#FFD61E']; + +function Avatars() { + return ( + + {colors.map((color) => ( + + {color.slice(1, 3)} + + ))} + + ); +} + +function Gallery() { + return ( + + Basic Gallery + + + + + + + + + + ); +} + +function SizeConstraints() { + return ( + + Size Constraints + + + Min/Max + + + 1:1 + + + Flex + + + + ); +} + +function FlexboxTests() { + return ( + + Flexbox Layouts + + + Start + + + Center + + + End + + + + + Wrap 1 + + + Wrap 2 + + + Wrap 3 + + + Wrap 4 + + + + ); +} + +function PositioningTests() { + return ( + + Positioning + + + Z-Index + + + Absolute + + + Relative + + + + ); +} + +function SpacingTests() { + return ( + + Spacing & Overflow + + + Padding + + + Margin + + + Overflow Hidden Test + + + + ); +} + +function VisualEffects() { + return ( + + Visual Effects + + + Shadow + + + Opacity + + + + ); +} + +function ComplexCombinations() { + return ( + + Complex Combinations + + + Complex 1 + + + Complex 2 + + + Complex 3 + + + Complex 4 + + + + ); +} + +function Transforms() { + return ( + + Transform + + + Transform + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#f5f5f5', + }, + scrollContent: { + paddingBottom: 50, + }, + paddedContainer: { + padding: 16, + }, + section: { + marginBottom: 30, + }, + sectionTitle: { + fontSize: 18, + fontWeight: 'bold', + marginBottom: 12, + color: '#333', + }, + gap: { + gap: 10, + }, + row: { + flexDirection: 'row', + }, + + // Avatar styles + avatars: { + width: 90, + height: 90, + borderWidth: 2, + borderColor: '#001A72', + borderTopLeftRadius: 30, + borderTopRightRadius: 5, + borderBottomLeftRadius: 5, + borderBottomRightRadius: 30, + marginHorizontal: 4, + alignItems: 'center', + justifyContent: 'center', + }, + avatarLabel: { + color: '#F8F9FF', + fontSize: 24, + fontWeight: 'bold', + }, + + // Gallery styles + fullWidthButton: { + width: '100%', + height: 160, + backgroundColor: '#FF6259', + borderTopRightRadius: 30, + borderTopLeftRadius: 30, + borderWidth: 1, + borderColor: '#000', + }, + leftButton: { + flex: 1, + height: 160, + backgroundColor: '#FFD61E', + borderBottomLeftRadius: 30, + borderWidth: 5, + borderColor: '#000', + }, + rightButton: { + flex: 1, + backgroundColor: '#782AEB', + height: 160, + borderBottomRightRadius: 30, + borderWidth: 8, + borderColor: '#000', + }, + + // Size constraint styles + minMaxButton: { + minWidth: 80, + maxWidth: 120, + minHeight: 40, + maxHeight: 80, + backgroundColor: '#38ACDD', + borderRadius: 10, + justifyContent: 'center', + alignItems: 'center', + }, + aspectRatioButton: { + width: 80, + aspectRatio: 1, + backgroundColor: '#57B495', + borderRadius: 40, + justifyContent: 'center', + alignItems: 'center', + }, + flexGrowButton: { + flexGrow: 1, + height: 60, + backgroundColor: '#FF6259', + borderRadius: 15, + justifyContent: 'center', + alignItems: 'center', + }, + + // Flexbox styles + flexContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + height: 80, + backgroundColor: '#e0e0e0', + borderRadius: 10, + padding: 10, + marginBottom: 10, + }, + flexStart: { + alignSelf: 'flex-start', + backgroundColor: '#782AEB', + padding: 10, + borderRadius: 5, + }, + flexCenter: { + alignSelf: 'center', + backgroundColor: '#38ACDD', + padding: 10, + borderRadius: 5, + }, + flexEnd: { + alignSelf: 'flex-end', + backgroundColor: '#57B495', + padding: 10, + borderRadius: 5, + }, + flexWrapContainer: { + flexDirection: 'row', + flexWrap: 'wrap', + gap: 5, + }, + wrapItem: { + width: '48%', + height: 50, + backgroundColor: '#FFD61E', + borderRadius: 8, + justifyContent: 'center', + alignItems: 'center', + }, + + // Positioning styles + positionContainer: { + height: 80, + backgroundColor: '#e0e0e0', + borderRadius: 10, + position: 'relative', + }, + absoluteButton: { + position: 'absolute', + top: 10, + right: 10, + backgroundColor: '#FF6259', + padding: 8, + borderRadius: 5, + }, + relativeButton: { + position: 'relative', + top: 20, + left: 20, + backgroundColor: '#782AEB', + padding: 8, + borderRadius: 5, + }, + zIndexButton: { + position: 'absolute', + top: 10, + left: 10, + zIndex: 10, + backgroundColor: '#57B495', + padding: 8, + borderRadius: 5, + }, + + // Spacing styles + paddingButton: { + flex: 1, + backgroundColor: '#38ACDD', + paddingVertical: 20, + paddingHorizontal: 15, + borderRadius: 10, + justifyContent: 'center', + alignItems: 'center', + }, + marginButton: { + flex: 1, + backgroundColor: '#FFD61E', + margin: 10, + padding: 10, + borderRadius: 10, + justifyContent: 'center', + alignItems: 'center', + }, + overflowButton: { + flex: 1, + height: 60, + backgroundColor: '#782AEB', + borderRadius: 10, + overflow: 'hidden', + justifyContent: 'center', + alignItems: 'center', + }, + + // Visual effect styles + shadowButton: { + flex: 1, + height: 60, + backgroundColor: '#FF6259', + borderRadius: 10, + justifyContent: 'center', + alignItems: 'center', + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.3, + shadowRadius: 8, + elevation: 8, + }, + opacityButton: { + flex: 1, + height: 60, + backgroundColor: '#782AEB', + borderRadius: 10, + justifyContent: 'center', + alignItems: 'center', + opacity: 0.7, + }, + + // Complex combination styles + complexGrid: { + flexDirection: 'row', + flexWrap: 'wrap', + gap: 10, + }, + complexButton1: { + width: '48%', + height: 100, + backgroundColor: '#FF6259', + borderRadius: 20, + borderWidth: 2, + borderColor: '#782AEB', + justifyContent: 'center', + alignItems: 'center', + shadowColor: '#000', + shadowOffset: { width: 2, height: 2 }, + shadowOpacity: 0.2, + shadowRadius: 4, + elevation: 4, + marginBottom: 5, + }, + complexButton2: { + width: '48%', + minHeight: 80, + maxHeight: 120, + backgroundColor: '#38ACDD', + borderTopLeftRadius: 30, + borderBottomRightRadius: 30, + paddingVertical: 15, + paddingHorizontal: 10, + justifyContent: 'center', + alignItems: 'center', + overflow: 'hidden', + }, + complexButton3: { + width: '48%', + aspectRatio: 1.5, + backgroundColor: '#57B495', + borderRadius: 15, + borderWidth: 4, + borderColor: '#FFD61E', + justifyContent: 'center', + alignItems: 'center', + opacity: 0.9, + marginTop: 10, + }, + complexButton4: { + width: '48%', + height: 80, + backgroundColor: '#FFD61E', + borderRadius: 10, + borderWidth: 1, + borderColor: '#FF6259', + justifyContent: 'center', + alignItems: 'center', + shadowColor: '#782AEB', + shadowOffset: { width: 0, height: 6 }, + shadowOpacity: 0.4, + shadowRadius: 10, + elevation: 10, + marginTop: 10, + }, + + // Transform styles + transformButton: { + width: '48%', + height: 100, + backgroundColor: '#38ACDD', + borderRadius: 15, + justifyContent: 'center', + alignItems: 'center', + transform: [{ translateX: 100 }, { rotate: '15deg' }, { scale: 1.1 }], + }, + + // Text styles + buttonText: { + color: 'white', + fontWeight: 'bold', + textAlign: 'center', + }, + longText: { + color: 'white', + fontWeight: 'bold', + textAlign: 'center', + fontSize: 16, + }, +}); diff --git a/apps/basic-example/src/FinalScreen.tsx b/apps/basic-example/src/FinalScreen.tsx deleted file mode 100644 index 9e65cf8135..0000000000 --- a/apps/basic-example/src/FinalScreen.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react'; -import { Image, StyleSheet, Text, View } from 'react-native'; -// @ts-ignore TODO: remove once there is a .d.ts file with definitions -import openURLInBrowser from 'react-native/Libraries/Core/Devtools/openURLInBrowser'; - -import { COLORS } from './colors'; - -const SOFTWARE_MANSION_LOGO_URL = - 'https://pbs.twimg.com/profile_images/1243176655172009986/Jgdl2m15_400x400.jpg'; -const SOFTWARE_MANSION_TWITTER_URL = 'https://twitter.com/swmansion/'; - -export default function FinalScreen() { - return ( - - - React Native Gesture Handler is developed by Software Mansion. - - - We are actively porting React Native libraries to Fabric, including - React Native Screens and Reanimated. - - - Follow us on Twitter and stay tuned! @swmansion - - openURLInBrowser(SOFTWARE_MANSION_TWITTER_URL)}> - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - backgroundColor: COLORS.NAVY, - }, - text: { - textAlign: 'center', - color: 'white', - fontSize: 21, - marginHorizontal: 20, - marginVertical: 10, - }, - bold: { - fontWeight: 'bold', - }, - logo: { - width: 250, - height: 250, - }, -}); diff --git a/apps/basic-example/src/GestureCompositionScreen.tsx b/apps/basic-example/src/GestureCompositionScreen.tsx deleted file mode 100644 index 2eb920c62f..0000000000 --- a/apps/basic-example/src/GestureCompositionScreen.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import { Gesture, GestureDetector } from 'react-native-gesture-handler'; - -import { COLORS } from './colors'; - -function RaceDemo() { - const pan = Gesture.Pan() - .onStart(() => console.log('pan onStart')) - .onUpdate(() => console.log('pan onUpdate')) - .onEnd(() => console.log('pan onEnd')); - - const longPress = Gesture.LongPress() - .onStart(() => console.log('longPress onStart')) - .onEnd(() => console.log('longPress onEnd')); - - return ( - - - Gesture.Race(pan, longPress) - the first gesture that meets its - activation criteria will activate - - - - - - ); -} - -function ExclusiveDemo() { - const singleTap = Gesture.Tap().onStart(() => console.log('single tap!')); - const doubleTap = Gesture.Tap() - .onStart(() => console.log('double tap!')) - .numberOfTaps(2); - - return ( - - - Gesture.Exclusive(doubleTap, singleTap) - the second gesture will wait - for the failure of the first one - - - - - - ); -} - -function SimultaneousDemo() { - const pinch = Gesture.Pinch() - .onStart(() => console.log('pinch onStart')) - .onUpdate(() => console.log('pinch onUpdate')) - .onEnd(() => console.log('pinch onEnd')); - const rotation = Gesture.Rotation() - .onStart(() => console.log('rotation onStart')) - .onUpdate(() => console.log('rotation onUpdate')) - .onEnd(() => console.log('rotation onEnd')); - - return ( - - - Gesture.Simultaneous(pinch, rotation) - both gestures can activate and - process touches at the same time - - - - - - ); -} - -export default function ComponentsScreen() { - return ( - - - Gesture Handler provides a simple API for using multiple gestures at - once in different configurations. - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - bold: { - fontWeight: 'bold', - textAlign: 'center', - marginHorizontal: 20, - }, - text: { - marginVertical: 3, - marginHorizontal: 10, - textAlign: 'center', - }, - demo: { - marginVertical: 3, - alignItems: 'center', - }, - largeBox: { - width: 100, - height: 100, - }, - largerBox: { - width: 150, - height: 150, - }, -}); diff --git a/apps/basic-example/src/HomeScreen.tsx b/apps/basic-example/src/HomeScreen.tsx deleted file mode 100644 index 0c96155a61..0000000000 --- a/apps/basic-example/src/HomeScreen.tsx +++ /dev/null @@ -1,194 +0,0 @@ -import * as React from 'react'; -import { Animated, StyleSheet, Text, View } from 'react-native'; -import { - Gesture, - GestureDetector, - PanGestureHandler, - PanGestureHandlerStateChangeEvent, - State, -} from 'react-native-gesture-handler'; - -import { isFabric, isHermes } from './utils'; -import { COLORS } from './colors'; - -declare const performance: { - now: () => number; -}; - -interface GestureDetectorDemoProps { - color: string; -} - -export function GestureDetectorDemo({ color }: GestureDetectorDemoProps) { - const gesture = Gesture.Pan() - .onBegin(() => { - console.log(performance.now(), 'onBegin'); - }) - .onStart(() => { - console.log(performance.now(), 'onStart'); - }) - .onUpdate(() => { - console.log(performance.now(), 'onUpdate'); - }) - .onEnd(() => { - console.log(performance.now(), 'onEnd'); - }) - .onFinalize(() => { - console.log(performance.now(), 'onFinalize'); - }); - - return ( - - Gesture.Pan - - - - - ); -} - -interface ManualGestureDemoProps { - color: string; -} - -export function ManualGestureDemo({ color }: ManualGestureDemoProps) { - const gesture = Gesture.Manual() - .onTouchesDown(() => { - console.log(performance.now(), 'onTouchesDown'); - }) - .onTouchesMove(() => { - console.log(performance.now(), 'onTouchesMove'); - }) - .onTouchesUp(() => { - console.log(performance.now(), 'onTouchesUp'); - }); - - return ( - - Gesture.Manual - - - - - ); -} - -interface PanGestureHandlerDemoProps { - color: string; -} - -export function PanGestureHandlerDemo({ color }: PanGestureHandlerDemoProps) { - const onGestureEvent = () => { - console.log(performance.now(), 'onGestureEvent'); - }; - - const onHandlerStateChange = () => { - console.log(performance.now(), 'onHandlerStateChange'); - }; - - return ( - - PanGestureHandler - - - - - ); -} - -type AnimatedEventDemoProps = { - useNativeDriver: boolean; - color: string; -}; - -export function AnimatedEventDemo({ - useNativeDriver, - color, -}: AnimatedEventDemoProps) { - const drag = React.useRef(new Animated.Value(0)); - - const onGestureEvent = Animated.event( - [{ nativeEvent: { translationX: drag.current } }], - { useNativeDriver } - ); - - const onHandlerStateChange = (event: PanGestureHandlerStateChangeEvent) => { - if ( - event.nativeEvent.state === State.FAILED || - event.nativeEvent.state === State.CANCELLED || - event.nativeEvent.state === State.END - ) { - Animated.spring(drag.current, { - velocity: event.nativeEvent.velocityX, - tension: 10, - friction: 2, - toValue: 0, - useNativeDriver, - }).start(); - } - }; - - return ( - - - Animated.event useNativeDriver: {useNativeDriver.toString()} - - - - - - ); -} - -export default function HomeScreen() { - return ( - - Hello from React Native Gesture Handler! - - This example app runs on {isHermes() ? 'Hermes' : 'JSC'} with Fabric{' '} - {isFabric() ? 'enabled' : 'disabled'}. - - - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - bold: { - fontWeight: 'bold', - }, - text: { - marginVertical: 3, - }, - demo: { - marginVertical: 3, - alignItems: 'center', - }, - box: { - width: 50, - height: 50, - }, -}); diff --git a/apps/basic-example/src/NativeDetector.tsx b/apps/basic-example/src/NativeDetector.tsx new file mode 100644 index 0000000000..cf8f8933cc --- /dev/null +++ b/apps/basic-example/src/NativeDetector.tsx @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { Animated, Button, useAnimatedValue } from 'react-native'; +import { + GestureHandlerRootView, + GestureDetector, + usePanGesture, +} from 'react-native-gesture-handler'; + +export default function App() { + const [visible, setVisible] = React.useState(true); + + const value = useAnimatedValue(0); + const event = Animated.event( + [{ nativeEvent: { handlerData: { translationX: value } } }], + { + useNativeDriver: true, + } + ); + + const gesture = usePanGesture({ + onUpdate: event, + }); + + return ( + + + ); }; diff --git a/packages/docs-gesture-handler/src/components/CollapseButton/styles.module.css b/packages/docs-gesture-handler/src/components/CollapseButton/styles.module.css index 908df5fa09..43444e4535 100644 --- a/packages/docs-gesture-handler/src/components/CollapseButton/styles.module.css +++ b/packages/docs-gesture-handler/src/components/CollapseButton/styles.module.css @@ -13,6 +13,7 @@ font-size: 16px; color: var(--ifm-font-color-base); cursor: pointer; + user-select: none; } .arrow { diff --git a/packages/docs-gesture-handler/src/components/CollapsibleCode/index.tsx b/packages/docs-gesture-handler/src/components/CollapsibleCode/index.tsx index ae0ce28a48..8f78e2540b 100644 --- a/packages/docs-gesture-handler/src/components/CollapsibleCode/index.tsx +++ b/packages/docs-gesture-handler/src/components/CollapsibleCode/index.tsx @@ -4,33 +4,42 @@ import styles from './styles.module.css'; import CollapseButton from '@site/src/components/CollapseButton'; +import useFormattedCode from '@site/src/hooks/useFormattedCode'; interface Props { src: string; + label: string; + expandedLabel: string; lineBounds: number[]; } -export default function CollapsibleCode({ src, lineBounds }: Props) { +export default function CollapsibleCode({ + src, + label, + expandedLabel, + lineBounds, +}: Props) { const [collapsed, setCollapsed] = useState(true); + const code = useFormattedCode(src); if (!lineBounds) { - return {src}; + return {code}; } const [start, end] = lineBounds; - const codeLines = src.split('\n'); + const codeLines = code.split('\n'); const linesToShow = codeLines.slice(start, end + 1).join('\n'); return (
setCollapsed(!collapsed)} className={styles.collapseButton} /> - {collapsed ? linesToShow : src} + {collapsed ? linesToShow : code}
); } diff --git a/packages/docs-gesture-handler/src/css/overrides.css b/packages/docs-gesture-handler/src/css/overrides.css index bcab954495..573cce9917 100644 --- a/packages/docs-gesture-handler/src/css/overrides.css +++ b/packages/docs-gesture-handler/src/css/overrides.css @@ -55,6 +55,14 @@ table thead tr { border: transparent 2px solid; } +details tr { + background: var(--ifm-background-color); +} + +details thead { + background: var(--ifm-background-color); +} + @media (min-width: 996px) { .header-github { margin-left: 1.5em; @@ -111,6 +119,43 @@ table thead tr { font-family: var(--ifm-font-family-monospace); } +table [class*='codeBlockContent'] pre, +table [class*='codeBlockContent'] code { + border: none; + background-color: transparent; + font-family: var(--ifm-font-family-monospace); +} + +.codeCell { + vertical-align: top; +} + +.codeComparison { + display: flex; + flex-direction: column; + margin-bottom: 20px; + gap: 20px; +} + +.codeComparison pre, +.codeComparison code { + border: none; + background-color: transparent; + font-family: var(--ifm-font-family-monospace); +} + +.codeComparisonHeader { + text-align: center; + font-weight: bold; + padding: 10px; + border-bottom: 1px solid var(--swm-border); +} + +.codeHolder { + border: 1px solid var(--swm-border); + width: 100%; +} + /* Add small padding, when some of the lines are too long in a code block */ [class*='codeBlockLines'] span:last-of-type { margin-right: 1em; diff --git a/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/FlowChart.jsx b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/FlowChart.jsx new file mode 100644 index 0000000000..544377b02f --- /dev/null +++ b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/FlowChart.jsx @@ -0,0 +1,126 @@ +import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; +import { Network } from 'vis-network/standalone'; +import { useColorMode } from '@docusaurus/theme-common'; + +const COLORS = { + SWM_OFF_WHITE: '#f8f9ff', + SWM_PURPLE_LIGHT_100: '#782aeb', + SWM_NAVY_DARK_140: '#1b2445', + SWM_NAVY_DARK_100: '#001a72', +}; + +const mobileThreshold = 996; + +export default function FlowChart({ nodes, edges }) { + const containerRef = useRef(null); + const [isMobile, setIsMobile] = useState(false); + + const { colorMode } = useColorMode(); + const isDark = colorMode === 'dark'; + + useEffect(() => { + // This won't cause unnecessary re-renders as it's only run on mount + // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect + setIsMobile(window.innerWidth <= mobileThreshold); + + const handleResize = () => { + setIsMobile(window.innerWidth <= mobileThreshold); + }; + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + useEffect(() => { + const nodesOptions = { + shape: 'box', + margin: { top: 15, bottom: 15, left: 15, right: 15 }, + font: { + face: 'Aeonik', + size: isMobile ? 14 : 18, + color: isDark ? COLORS.SWM_OFF_WHITE : COLORS.SWM_PURPLE_LIGHT_100, + }, + color: { + background: isDark ? COLORS.SWM_NAVY_DARK_140 : COLORS.SWM_OFF_WHITE, + border: COLORS.SWM_PURPLE_LIGHT_100, + hover: { + background: isDark + ? COLORS.SWM_PURPLE_LIGHT_100 + : COLORS.SWM_OFF_WHITE, + border: COLORS.SWM_PURPLE_LIGHT_100, + }, + highlight: { + background: isDark + ? COLORS.SWM_PURPLE_LIGHT_100 + : COLORS.SWM_OFF_WHITE, + border: COLORS.SWM_PURPLE_LIGHT_100, + }, + }, + }; + + const edgesOptions = { + smooth: { + enabled: true, + type: 'continuous', + forceDirection: isMobile ? 'vertical' : 'horizontal', + roundness: 0.1, + }, + color: { + color: isDark ? COLORS.SWM_OFF_WHITE : COLORS.SWM_NAVY_DARK_100, + hover: COLORS.SWM_PURPLE_LIGHT_100, + highlight: COLORS.SWM_PURPLE_LIGHT_100, + }, + selfReference: { size: 25, angle: isMobile ? 0 : Math.PI / 2 }, + arrows: { to: { scaleFactor: 0.8 } }, + arrowStrikethrough: false, + }; + + const layoutOptions = { + hierarchical: { + direction: isMobile ? 'UD' : 'LR', + sortMethod: 'directed', + levelSeparation: isMobile ? 150 : 300, + nodeSpacing: isMobile ? 300 : 100, + }, + }; + + const interactionOptions = { + dragNodes: false, + dragView: false, + zoomView: false, + hover: true, + }; + + const options = { + nodes: nodesOptions, + edges: edgesOptions, + layout: layoutOptions, + physics: false, + interaction: interactionOptions, + }; + + const network = new Network( + containerRef.current, + { nodes, edges }, + options + ); + + network.once('afterDrawing', () => { + network.fit(); + }); + + return () => network.destroy(); + }, [isDark, edges, nodes, isMobile]); + + return ( +
+ ); +} diff --git a/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/GestureEventChart.jsx b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/GestureEventChart.jsx new file mode 100644 index 0000000000..6e601c0d5e --- /dev/null +++ b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/GestureEventChart.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { DataSet } from 'vis-network/standalone'; +import FlowChart from './FlowChart'; + +const nodes = new DataSet([ + { + id: 1, + label: 'onBegin', + level: 0, + }, + { + id: 2, + label: 'onActivate', + level: 1, + }, + { + id: 3, + label: 'onUpdate', + level: 2, + }, + { + id: 4, + label: 'onDeactivate', + level: 3, + }, + { + id: 5, + label: 'onFinalize', + level: 3, + }, +]); + +const edges = new DataSet([ + { from: 1, to: 2, arrows: 'to' }, + { from: 1, to: 5, arrows: 'to' }, + { from: 2, to: 3, arrows: 'to' }, + { from: 2, to: 4, arrows: 'to' }, + { from: 2, to: 5, arrows: 'to' }, + { from: 3, to: 3, arrows: 'to' }, + { from: 3, to: 4, arrows: 'to' }, + { from: 3, to: 5, arrows: 'to' }, + { from: 4, to: 5, arrows: 'to' }, +]); + +export function GestureEventFlowChart() { + return ; +} diff --git a/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/TouchEventChart.jsx b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/TouchEventChart.jsx new file mode 100644 index 0000000000..180a00dfde --- /dev/null +++ b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/TouchEventChart.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { DataSet } from 'vis-network/standalone'; +import FlowChart from './FlowChart'; + +const nodes = new DataSet([ + { + id: 1, + label: 'onTouchesDown', + level: 0, + }, + { + id: 2, + label: 'onTouchesMove', + level: 1, + }, + { + id: 3, + label: 'onTouchesUp', + level: 2, + }, + { + id: 4, + label: 'onTouchesCancel', + level: 2, + }, +]); + +const edges = new DataSet([ + { from: 1, to: 2, arrows: 'to' }, + { from: 1, to: 3, arrows: 'to' }, + { from: 2, to: 2, arrows: 'to' }, + { from: 2, to: 3, arrows: 'to' }, + { from: 1, to: 4, arrows: 'to' }, + { from: 2, to: 4, arrows: 'to' }, +]); + +export function TouchEventFlowChart() { + return ; +} diff --git a/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/index.ts b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/index.ts new file mode 100644 index 0000000000..8b6c443d84 --- /dev/null +++ b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/index.ts @@ -0,0 +1,2 @@ +export { GestureEventFlowChart } from './GestureEventChart'; +export { TouchEventFlowChart } from './TouchEventChart'; diff --git a/packages/docs-gesture-handler/src/hooks/useFormattedCode.tsx b/packages/docs-gesture-handler/src/hooks/useFormattedCode.tsx new file mode 100644 index 0000000000..b8e8b7704e --- /dev/null +++ b/packages/docs-gesture-handler/src/hooks/useFormattedCode.tsx @@ -0,0 +1,28 @@ +import { useEffect, useState } from 'react'; +import * as prettier from 'prettier/standalone'; +import tsParser from 'prettier/plugins/typescript'; +import estreeParser from 'prettier/plugins/estree'; + +const prettierOptions = { + parser: 'typescript', + plugins: [tsParser, estreeParser], +}; + +export default function useFormattedCode(code: string) { + const [formattedCode, setFormattedCode] = useState(code); + + useEffect(() => { + async function formatCode() { + try { + const newCode = await prettier.format(code, prettierOptions); + setFormattedCode(newCode); + } catch { + setFormattedCode(code); + } + } + + void formatCode(); + }, [code]); + + return formattedCode; +} diff --git a/packages/docs-gesture-handler/src/theme/MDXComponents/Details.js b/packages/docs-gesture-handler/src/theme/MDXComponents/Details.js index f13e9887da..8b99527971 100644 --- a/packages/docs-gesture-handler/src/theme/MDXComponents/Details.js +++ b/packages/docs-gesture-handler/src/theme/MDXComponents/Details.js @@ -5,7 +5,7 @@ const MDXDetails = (props) => { // Split summary item from the rest to pass it as a separate prop to the // Details theme component const summary = items.find( - (item) => React.isValidElement(item) && item.props?.mdxType === 'summary' + (item) => React.isValidElement(item) && item.type === 'summary' ); const children = <>{items.filter((item) => item !== summary)}; diff --git a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/common-gh.md b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/common-gh.md index 4c077a212a..74eb5b52d1 100644 --- a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/common-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/common-gh.md @@ -20,28 +20,28 @@ This section describes properties that can be used with all gesture handler comp Accepts a boolean value. Indicates whether the given handler should be analyzing stream of touch events or not. -When set to `false` we can be sure that the handler's state will **never** become [`ACTIVE`](/docs/under-the-hood/state#active). -If the value gets updated while the handler already started recognizing a gesture, then the handler's state it will immediately change to [`FAILED`](/docs/under-the-hood/state#failed) or [`CANCELLED`](/docs/under-the-hood/state#cancelled) (depending on its current state). +When set to `false` we can be sure that the handler's state will **never** become [`ACTIVE`](/docs/1.x/state#active). +If the value gets updated while the handler already started recognizing a gesture, then the handler's state it will immediately change to [`FAILED`](/docs/1.x/state#failed) or [`CANCELLED`](/docs/1.x/state#cancelled) (depending on its current state). Default value is `true`. ### `shouldCancelWhenOutside` Accepts a boolean value. -When `true` the handler will [cancel](/docs/under-the-hood/state#cancelled) or [fail](/docs/under-the-hood/state#failed) recognition (depending on its current state) whenever the finger leaves the area of the connected view. +When `true` the handler will [cancel](/docs/1.x/state#cancelled) or [fail](/docs/1.x/state#failed) recognition (depending on its current state) whenever the finger leaves the area of the connected view. Default value of this property is different depending on the handler type. Most handlers' `shouldCancelWhenOutside` property defaults to `false` except for the [`LongPressGestureHandler`](longpress-gh) and [`TapGestureHandler`](tap-gh) which default to `true`. ### `simultaneousHandlers` -Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set, the handler will be allowed to [activate](/docs/under-the-hood/state#active) even if one or more of the handlers provided by their refs are in an [`ACTIVE`](/docs/under-the-hood/state#active) state. It will also prevent the provided handlers from [cancelling](/docs/under-the-hood/state#cancelled) the current handler when they [activate](/docs/under-the-hood/state#active). Read more in the [cross handler interaction](interactions.md#simultaneous-recognition) section. +Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set, the handler will be allowed to [activate](/docs/1.x/state#active) even if one or more of the handlers provided by their refs are in an [`ACTIVE`](/docs/1.x/state#active) state. It will also prevent the provided handlers from [cancelling](/docs/1.x/state#cancelled) the current handler when they [activate](/docs/1.x/state#active). Read more in the [cross handler interaction](interactions.md#simultaneous-recognition) section. ### `waitFor` -Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set the handler will not [activate](/docs/under-the-hood/state#active) as long as the handlers provided by their refs are in the [`BEGAN`](/docs/under-the-hood/state#began) state. Read more in the [cross handler interaction](interactions.md#awaiting-other-handlers) section. +Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set the handler will not [activate](/docs/1.x/state#active) as long as the handlers provided by their refs are in the [`BEGAN`](/docs/1.x/state#began) state. Read more in the [cross handler interaction](interactions.md#awaiting-other-handlers) section. ### `hitSlop` -This parameter enables control over what part of the connected view area can be used to [begin](/docs/under-the-hood/state#began) recognizing the gesture. +This parameter enables control over what part of the connected view area can be used to [begin](/docs/1.x/state#began) recognizing the gesture. When a negative number is provided the bounds of the view will reduce the area by the given number of points in each of the sides evenly. Instead you can pass an object to specify how each boundary side should be reduced by providing different number of points for `left`, `right`, `top` or `bottom` sides. @@ -55,17 +55,17 @@ Specifying `width` or `height` is useful if we only want the gesture to activate ### `onGestureEvent` -Takes a callback that is going to be triggered for each subsequent touch event while the handler is in an [ACTIVE](/docs/under-the-hood/state#active) state. Event payload depends on the particular handler type. Common set of event data attributes is documented [below](#event-data) and handler specific attributes are documented on the corresponding handler pages. E.g. event payload for [`PinchGestureHandler`](rotation-gh#event-data) contains `scale` attribute that represents how the distance between fingers changed since when the gesture started. +Takes a callback that is going to be triggered for each subsequent touch event while the handler is in an [ACTIVE](/docs/1.x/state#active) state. Event payload depends on the particular handler type. Common set of event data attributes is documented [below](#event-data) and handler specific attributes are documented on the corresponding handler pages. E.g. event payload for [`PinchGestureHandler`](rotation-gh#event-data) contains `scale` attribute that represents how the distance between fingers changed since when the gesture started. Instead of a callback [`Animated.event`](https://reactnative.dev/docs/animated.html#event) object can be used. Also Animated events with `useNativeDriver` flag enabled **are fully supported**. ### `onHandlerStateChange` -Takes a callback that is going to be triggered when [state](/docs/under-the-hood/state) of the given handler changes. +Takes a callback that is going to be triggered when [state](/docs/1.x/state) of the given handler changes. The event payload contains the same payload as in case of [`onGestureEvent`](#ongestureevent) including handler specific event attributes some handlers may provide. -In addition `onHandlerStateChange` event payload contains `oldState` attribute which represents the [state](/docs/under-the-hood/state) of the handler right before the change. +In addition `onHandlerStateChange` event payload contains `oldState` attribute which represents the [state](/docs/1.x/state) of the handler right before the change. Instead of a callback [`Animated.event`](https://reactnative.dev/docs/animated.html#event) object can be used. Also Animated events with `useNativeDriver` flag enabled **are fully supported**. @@ -75,7 +75,7 @@ This section describes the attributes of event object being provided to [`onGest ### `state` -Current [state](/docs/under-the-hood/state) of the handler. Expressed as one of the constants exported under `State` object by the library. Refer to the section about [handler state](/docs/under-the-hood/state) to learn more about how to use it. +Current [state](/docs/1.x/state) of the handler. Expressed as one of the constants exported under `State` object by the library. Refer to the section about [handler state](/docs/1.x/state) to learn more about how to use it. ### `numberOfPointers` diff --git a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/force-gh.md b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/force-gh.md index d910ecb35f..d83a38f9b2 100644 --- a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/force-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/force-gh.md @@ -5,7 +5,7 @@ sidebar_label: Force touch --- A continuous gesture handler that recognizes force of a touch. It allows for tracking pressure of touch on some iOS devices. -The handler [activates](/docs/under-the-hood/state#active) when pressure of touch if greater or equal than `minForce`. It fails if pressure is greater than `maxForce` +The handler [activates](/docs/1.x/state#active) when pressure of touch if greater or equal than `minForce`. It fails if pressure is greater than `maxForce` Gesture callback can be used for continuous tracking of the touch pressure. It provides information for one finger (the first one). At the beginning of the gesture, the pressure factor is 0.0. As the pressure increases, the pressure factor increases proportionally. The maximum pressure is 1.0. @@ -19,11 +19,11 @@ See [set of properties inherited from base handler class](common-gh#properties). ### `minForce` -A minimal pressure that is required before handler can [activate](/docs/under-the-hood/state#active). Should be a value from range `[0.0, 1.0]`. Default is `0.2`. +A minimal pressure that is required before handler can [activate](/docs/1.x/state#active). Should be a value from range `[0.0, 1.0]`. Default is `0.2`. ### `maxForce` -A maximal pressure that could be applied for handler. If the pressure is greater, handler [fails](/docs/under-the-hood/state#failed). Should be a value from range `[0.0, 1.0]`. +A maximal pressure that could be applied for handler. If the pressure is greater, handler [fails](/docs/1.x/state#failed). Should be a value from range `[0.0, 1.0]`. ### `feedbackOnActivation` diff --git a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/longpress-gh.md b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/longpress-gh.md index 69db5218c3..fa53e37298 100644 --- a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/longpress-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/longpress-gh.md @@ -5,7 +5,7 @@ sidebar_label: Long press --- A discrete gesture handler that activates when the corresponding view is pressed for a sufficiently long time. -This handler's state will turn into [END](/docs/under-the-hood/state#end) immediately after the finger is released. +This handler's state will turn into [END](/docs/1.x/state#end) immediately after the finger is released. The handler will fail to recognize a touch event if the finger is lifted before the [minimum required time](#mindurationms) or if the finger is moved further than the [allowable distance](#maxdist). The handler is implemented using [UILongPressGestureRecognizer](https://developer.apple.com/documentation/uikit/uilongpressgesturerecognizer) on iOS and [LongPressGestureHandler](https://github.com/software-mansion/react-native-gesture-handler/blob/main/android/lib/src/main/java/com/swmansion/gesturehandler/LongPressGestureHandler.kt) on Android. @@ -20,7 +20,7 @@ Minimum time, expressed in milliseconds, that a finger must remain pressed on th ### `maxDist` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a long press gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. The default value is 10. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a long press gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/1.x/state#active), it will fail to recognize the gesture. The default value is 10. ## Event data diff --git a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pan-gh.md b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pan-gh.md index 8f3490e3e1..3cb640b7bd 100644 --- a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pan-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pan-gh.md @@ -6,7 +6,7 @@ sidebar_label: Pan A continuous gesture handler that can recognize a panning (dragging) gesture and track its movement. -The handler [activates](/docs/under-the-hood/state#active) when a finger is placed on the screen and moved some initial distance. +The handler [activates](/docs/1.x/state#active) when a finger is placed on the screen and moved some initial distance. Configurations such as a minimum initial distance, specific vertical or horizontal pan detection and [number of fingers](#minPointers) required for activation (allowing for multifinger swipes) may be specified. @@ -16,7 +16,7 @@ The handler is implemented using [UIPanGestureRecognizer](https://developer.appl ## Custom activation criteria -The `PanGestureHandler` component exposes a number of properties that can be used to customize the criteria under which a handler will [activate](/docs/under-the-hood/state#active) or [fail](/docs/under-the-hood/state#fail) when recognizing a gesture. +The `PanGestureHandler` component exposes a number of properties that can be used to customize the criteria under which a handler will [activate](/docs/1.x/state#active) or [fail](/docs/1.x/state#fail) when recognizing a gesture. When more than one of such a property is set, `PanGestureHandler` expects all criteria to be met for successful recognition and at most one of the criteria to be overstepped to fail recognition. For example when both [`minDeltaX`](#mindeltax) and [`minDeltaY`](#mindeltay) are set to 20 we expect the finger to travel by 20 points in both the X and Y axis before the handler activates. @@ -45,15 +45,15 @@ See [set of properties inherited from base handler class](common-gh#properties). ### `minDist` -Minimum distance the finger (or multiple finger) need to travel before the handler [activates](/docs/under-the-hood/state#active). Expressed in points. +Minimum distance the finger (or multiple finger) need to travel before the handler [activates](/docs/1.x/state#active). Expressed in points. ### `minPointers` -A number of fingers that is required to be placed before handler can [activate](/docs/under-the-hood/state#active). Should be a higher or equal to 0 integer. +A number of fingers that is required to be placed before handler can [activate](/docs/1.x/state#active). Should be a higher or equal to 0 integer. ### `maxPointers` -When the given number of fingers is placed on the screen and handler hasn't yet [activated](/docs/under-the-hood/state#active) it will fail recognizing the gesture. Should be a higher or equal to 0 integer. +When the given number of fingers is placed on the screen and handler hasn't yet [activated](/docs/1.x/state#active) it will fail recognizing the gesture. Should be a higher or equal to 0 integer. ### `activeOffsetX` diff --git a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pinch-gh.md b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pinch-gh.md index 6e3c60b9dc..53c0de7063 100644 --- a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pinch-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/pinch-gh.md @@ -5,7 +5,7 @@ sidebar_label: Pinch --- A continuous gesture handler that recognizes pinch gesture. It allows for tracking the distance between two fingers and use that information to scale or zoom your content. -The handler [activates](/docs/under-the-hood/state#active) when fingers are placed on the screen and change their position. +The handler [activates](/docs/1.x/state#active) when fingers are placed on the screen and change their position. Gesture callback can be used for continuous tracking of the pinch gesture. It provides information about velocity, anchor (focal) point of gesture and scale. The distance between the fingers is reported as a scale factor. At the beginning of the gesture, the scale factor is 1.0. As the distance between the two fingers increases, the scale factor increases proportionally. diff --git a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/tap-gh.md b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/tap-gh.md index 26f648111e..7fbfe6b04c 100644 --- a/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/tap-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-1.x/api/gesture-handlers/tap-gh.md @@ -11,7 +11,7 @@ The fingers involved in these gestures must not move significantly from their in The required number of taps and allowed distance from initial position may be configured. For example, you might configure tap gesture recognizers to detect single taps, double taps, or triple taps. -In order for a handler to [activate](/docs/under-the-hood/state#active), specified gesture requirements such as minPointers, numberOfTaps, maxDist, maxDurationMs, and maxDelayMs (explained below) must be met. Immediately after the handler [activates](/docs/under-the-hood/state#active), it will [END](/docs/under-the-hood/state#end). +In order for a handler to [activate](/docs/1.x/state#active), specified gesture requirements such as minPointers, numberOfTaps, maxDist, maxDurationMs, and maxDelayMs (explained below) must be met. Immediately after the handler [activates](/docs/1.x/state#active), it will [END](/docs/1.x/state#end). ## Properties @@ -19,7 +19,7 @@ See [set of properties inherited from base handler class](common-gh#properties). ### `minPointers` -Minimum number of pointers (fingers) required to be placed before the handler [activates](/docs/under-the-hood/state#active). Should be a positive integer. The default value is 1. +Minimum number of pointers (fingers) required to be placed before the handler [activates](/docs/1.x/state#active). Should be a positive integer. The default value is 1. ### `maxDurationMs` @@ -31,19 +31,19 @@ Maximum time, expressed in milliseconds, that can pass before the next tap — i ### `numberOfTaps` -Number of tap gestures required to [activate](/docs/under-the-hood/state#active) the handler. The default value is 1. +Number of tap gestures required to [activate](/docs/1.x/state#active) the handler. The default value is 1. ### `maxDeltaX` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the X axis during a tap gesture. If the finger travels further than the defined distance along the X axis and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the X axis during a tap gesture. If the finger travels further than the defined distance along the X axis and the handler hasn't yet [activated](/docs/1.x/state#active), it will fail to recognize the gesture. ### `maxDeltaY` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the Y axis during a tap gesture. If the finger travels further than the defined distance along the Y axis and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the Y axis during a tap gesture. If the finger travels further than the defined distance along the Y axis and the handler hasn't yet [activated](/docs/1.x/state#active), it will fail to recognize the gesture. ### `maxDist` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a tap gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a tap gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/1.x/state#active), it will fail to recognize the gesture. ## Event data diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/components/_category_.json b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/_category_.json new file mode 100644 index 0000000000..b209621c3f --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Components", + "position": 4, + "link": { + "type": "generated-index" + } +} diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/components/buttons.mdx b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/buttons.mdx new file mode 100644 index 0000000000..cde390a556 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/buttons.mdx @@ -0,0 +1,178 @@ +--- +id: buttons +title: Buttons +sidebar_label: Buttons +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; +import GifGallery from '@site/components/GifGallery'; + + + + + +Gesture handler library provides native components that can act as buttons. These can be treated as a replacement to `TouchableHighlight` or `TouchableOpacity` from RN core. Gesture handler's buttons recognize touches in native which makes the recognition process deterministic, allows for rendering ripples on Android in highly performant way (`TouchableNativeFeedback` requires that touch event does a roundtrip to JS before we can update ripple effect, which makes ripples lag a bit on older phones), and provides native and platform default interaction for buttons that are placed in a scrollable container (in which case the interaction is slightly delayed to prevent button from highlighting when you fling). + +Currently Gesture handler library exposes three components that render native touchable elements under the hood: + +- [`BaseButton`](/docs/2.x/components/buttons/#basebutton) +- [`RectButton`](/docs/2.x/components/buttons/#rectbutton) +- [`BorderlessButton`](/docs/2.x/components/buttons/#borderlessbutton) + +On top of that all the buttons are wrapped with `NativeViewGestureHandler` and therefore allow for all the [common gesture handler properties](/docs/2.x/gesture-handlers/common-gh/) and `NativeViewGestureHandler`'s [extra properties](/docs/2.x/gesture-handlers/nativeview-gh#properties) to be applied to them. + +**IMPORTANT**: In order to make buttons accessible, you have to wrap your children in a `View` with `accessible` and `accessibilityRole="button"` props. +Example: + +```javascript +// Not accessible: +const NotAccessibleButton = () => ( + + Foo + +); +// Accessible: +const AccessibleButton = () => ( + + + Bar + + +); +``` + +It is applicable for both iOS and Android platform. On iOS, you won't be able to even select the button, on Android you won't be able to click it in accessibility mode. + +## `BaseButton` + +Can be used as a base class if you'd like to implement some custom interaction for when the button is pressed. + +Below is a list of properties specific to `BaseButton` component: + +### `onActiveStateChange` + +function that gets triggered when button changes from inactive to active and vice versa. It passes active state as a boolean variable as a first parameter for that method. + +### `onPress` + +function that gets triggered when the button gets pressed (analogous to `onPress` in `TouchableHighlight` from RN core). + +### `onLongPress` + +function that gets triggered when the button gets pressed for at least `delayLongPress` milliseconds. + +### `rippleColor` (**Android only**) + +defines color of native [ripple](https://developer.android.com/reference/android/graphics/drawable/RippleDrawable) animation used since API level 21. + +### `exclusive` + +defines if more than one button could be pressed simultaneously. By default set `true`. + +### `delayLongPress` + +defines the delay, in milliseconds, after which the `onLongPress` callback gets called. By default set to 600. + +## `RectButton` + +This type of button component should be used when you deal with rectangular elements or blocks of content that can be pressed, for example table rows or buttons with text and icons. This component provides a platform specific interaction, rendering a rectangular ripple on Android or highlighting the background on iOS and on older versions of Android. In addition to the props of [`BaseButton`](/docs/2.x/components/buttons#basebutton), it accepts the following: + +Below is a list of properties specific to `RectButton` component: + +### `underlayColor` + +this is the background color that will be dimmed when button is in active state. + +### `activeOpacity` (**iOS only**) + +opacity applied to the underlay when button is in active state. + +## `BorderlessButton` + +This type of button component should be used with simple icon-only or text-only buttons. The interaction will be different depending on platform: on Android a borderless ripple will be rendered (it means that the ripple will animate into a circle that can span outside of the view bounds), whereas on iOS the button will be dimmed (similar to how `TouchableOpacity` works). In addition to the props of [`BaseButton`](/docs/2.x/components/buttons#basebutton), it accepts the following: + +Below is a list of properties specific to `BorderlessButton` component: + +### `borderless` (**Android only**) + +set this to `false` if you want the ripple animation to render only within view bounds. + +### `activeOpacity` (**iOS only**) + +opacity applied to the button when it is in an active state. + +## Design patterns + +Components listed here were not designed to behave and look in the same way on both platforms but rather to be used for handling similar behaviour on iOS and Android taking into consideration their's design concepts. + +If you wish to get specific information about platforms design patterns, visit [official Apple docs](https://developer.apple.com/design/human-interface-guidelines/components/menus-and-actions/buttons) and [Material.io guideline](https://material.io/components/buttons#text-button), which widely describe how to implement coherent design. + +This library allows to use native components with native feedback in adequate situations. + +If you do not wish to implement custom design approach, `RectButton` and `BorderlessButton` seem to be absolutely enough and there's no need to use anything else. In all the remaining cases you can always rely on `BaseButton` which is a superclass for the other button classes and can be used as a generic `Touchable` replacement that can be customized to your needs. + +Below we list some of the common usecases for button components to be used along with the type of button that should be used according to the platform specific design guidelines. + +### Lists and action buttons + +If you have a list with clickable items or have an action button that need to display as a separate UI block (vs being inlined in a text) you should use `RectButton`. It changes opacity on click and additionally supports a ripple effect on Android. + + + + + + +To determine emphasis of button it's vital to use fill color or leave it transparent especially on Android. +For medium emphasis you may consider outlined buttons which are used for lower impact than fill buttons. + + + + + +### Icon or text only buttons + +Use `BorderlessButton` for simple icon-only or text-only buttons. The interaction will be different depending on platform: on Android a borderless ripple will be rendered, whereas on iOS the button will be dimmed. +It should be used if you wish to handle non-crucial actions and supportive behaviour. + + + + + + +### `PureNativeButton` + +Use a `PureNativeButton` for accessing the native Component used for build more complex buttons listed above. +It's normally is not recommended to use, but it might be useful if we want to wrap it using Animated or Reanimated. + +```javascript +import { + createNativeWrapper, + PureNativeButton, +} from 'react-native-gesture-handler'; +import Animated from 'react-native-reanimated'; +const { event, Value, createAnimatedComponent } = Animated; + +const AnimatedRawButton = createNativeWrapper( + createAnimatedComponent(PureNativeButton), + { + shouldCancelWhenOutside: false, + shouldActivateOnStart: false, + } +); + +export default class App extends React.Component { + constructor(props) { + super(props); + const state = new Value(); + this._onGestureEvent = event([ + { + nativeEvent: { state }, + }, + ]); + } + + render() { + return ; + } +} +``` diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/components/pressable.mdx b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/pressable.mdx new file mode 100644 index 0000000000..d7455d3973 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/pressable.mdx @@ -0,0 +1,162 @@ +--- +id: pressable +title: Pressable +sidebar_label: Pressable +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; +import GifGallery from '@site/components/GifGallery'; + + + + + +:::info +This component is a drop-in replacement for the `Pressable` component. +::: + +`Pressable` is a component that can detect various stages of tap, press, and hover interactions on any of its children. + +### Usage: + +To use `Pressable`, import it in the following way: + +```js +import { Pressable } from 'react-native-gesture-handler'; +``` + +## Properties + +### `children` + +either children or a render function that receives a boolean reflecting whether +the component is currently pressed. + +### `style` + +either view styles or a function that receives a boolean reflecting whether +the component is currently pressed and returns view styles. + +### `onPress` + +called after `onPressOut` when a single tap gesture is detected. + +### `onPressIn` + +called before `onPress` when a touch is engaged. + +### `onPressOut` + +called before `onPress` when a touch is released. + +### `onLongPress` + +called immediately after pointer has been down for at least `delayLongPress` milliseconds (`500` ms by default). + +After `onLongPress` has been called, `onPressOut` will be called as soon as the pointer is lifted and `onPress` will not be called at all. + +### `cancelable` + +whether a press gesture can be interrupted by a parent gesture such as a scroll event. Defaults to `true`. + +### `onHoverIn` (Web only) + +called when pointer is hovering over the element. + +### `onHoverOut` (Web only) + +called when pointer stops hovering over the element. + +### `delayHoverIn` (Web only) + +duration to wait after hover in before calling `onHoverIn`. + +### `delayHoverOut` (Web only) + +duration to wait after hover out before calling `onHoverOut`. + +### `delayLongPress` + +duration (in milliseconds) from `onPressIn` before `onLongPress` is called. + +### `disabled` + +whether the `Pressable` behavior is disabled. + +### `hitSlop` (Android & iOS only) + +additional distance outside of the view in which a press is detected and `onPressIn` is triggered. + +Accepts values of type `number` or [`Rect`](https://reactnative.dev/docs/rect) + +### `pressRetentionOffset` (Android & iOS only) + +additional distance outside of the view (or `hitSlop` if present) in which a touch is considered a +press before `onPressOut` is triggered. + +Accepts values of type `number` or [`Rect`](https://reactnative.dev/docs/rect) + +### `android_disableSound` (Android only) + +if `true`, doesn't play system sound on touch. + +### `android_ripple` (Android only) + +enables the Android ripple effect and configures its color, radius and other parameters. + +Accepts values of type [`RippleConfig`](https://reactnative.dev/docs/pressable#rippleconfig) + +### `testOnly_pressed` + +used only for documentation or testing (e.g. snapshot testing). + +### `unstable_pressDelay` + +duration (in milliseconds) to wait after press down before calling `onPressIn`. + +### Example: + +See the full [pressable example](https://github.com/software-mansion/react-native-gesture-handler/blob/main/apps/common-app/src/new_api/pressable/index.tsx) from `GestureHandler` example app. + +import GestureStateFlowExample from '@site/src/examples/GestureStateFlowExample'; + +```js +import { View, Text, StyleSheet } from 'react-native'; +import { Pressable } from 'react-native-gesture-handler'; + +export default function Example() { + return ( + (pressed ? styles.highlight : styles.pressable)} + hitSlop={20} + pressRetentionOffset={20}> + + Pressable! + + + ); +} + +const styles = StyleSheet.create({ + pressable: { + width: 120, + height: 120, + backgroundColor: 'mediumpurple', + borderWidth: StyleSheet.hairlineWidth, + }, + highlight: { + width: 120, + height: 120, + backgroundColor: 'red', + borderWidth: StyleSheet.hairlineWidth, + }, + textWrapper: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + text: { + color: 'black', + }, +}); +``` diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/components/reanimated-drawer-layout.mdx b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/reanimated-drawer-layout.mdx new file mode 100644 index 0000000000..8a5e2e6584 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/reanimated-drawer-layout.mdx @@ -0,0 +1,201 @@ +--- +id: reanimated-drawer-layout +title: Reanimated Drawer Layout +sidebar_label: Reanimated Drawer Layout +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +Cross-platform replacement for the React Native's [DrawerLayoutAndroid](http://reactnative.dev/docs/drawerlayoutandroid.html) component. +For detailed usage of standard parameters, please refer to the [React Native docs](http://reactnative.dev/docs/drawerlayoutandroid.html). + +### Usage: + +To use it, import it in the following way: + +```js +import ReanimatedDrawerLayout from 'react-native-gesture-handler/ReanimatedDrawerLayout'; +``` + +## Properties: + +### `drawerType` + +specifies the way the drawer will be displayed. +Accepts values of the `DrawerPosition` enum. Defaults to `FRONT`. + +- `FRONT` the drawer will be displayed above the content view. +- `BACK` the drawer will be displayed below the content view, revealed by sliding away the content view. +- `SLIDE` the drawer will appear attached to the content view, opening it slides both the drawer and the content view. + +| `FRONT` | `BACK` | `SLIDE` | +| ----------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------- | +| | | | + +### `edgeWidth` + +width of the invisible, draggable area on the edge of the content view, which can be dragged to open the drawer. + +### `hideStatusBar` + +a boolean value. When set to `true`, drawer component will use [StatusBar API](http://reactnative.dev/docs/statusbar.html) to hide the OS status bar when the drawer is dragged or idle in the `open` position. + +### `statusBarAnimation` + +a string with possible values: `slide`, `none` or `fade`. Defaults to `slide`. +May be used in combination with `hideStatusBar` to select the animation used for hiding the status bar. +See [StatusBar API](http://reactnative.dev/docs/statusbar.html#statusbaranimation) docs. + +### `overlayColor` + +color of the background overlay on top of the content window when the drawer is `open`. +This color's opacity animates from 0% to 100% as the drawer transitions from closed to open. Defaults to `rgba(0, 0, 0, 0.7)`. + +### `renderNavigationView` + +a renderer function for the drawer component, provided with a `progress` parameter. + +- `progress` - `SharedValue` that indicates the progress of drawer opening/closing animation. + - equals `0` when the `drawer` is closed and `1` when the `drawer` is opened + - can be used by the `drawer` component to animated its children while the `drawer` is opening or closing + +### `onDrawerClose` + +a function which is called when the drawer has been closed. + +### `onDrawerOpen` + +a function which is called when the drawer has been opened. + +### `onDrawerSlide` + +a function which is called when drawer is moving or animating, provided with a `progress` parameter. + +- `progress` - `SharedValue` that indicates the progress of drawer opening/closing animation. + - equals `0` when the `drawer` is closed and `1` when the `drawer` is opened + - can be used by the `drawer` component to animated its children while the `drawer` is opening or closing + +### `onDrawerStateChanged` + +a function which is called when the status of the drawer changes. It takes two arguments: + +- `newState` - interaction state of the drawer. It can be one of the following: + - `DrawerState.IDLE` + - `DrawerState.DRAGGING` + - `DrawerState.SETTLING` +- `drawerWillShow` - `true` when `drawer` started animating to `open` position, `false` otherwise. + +### `enableTrackpadTwoFingerGesture` (iOS only) + +enables two-finger gestures on supported devices, for example iPads with trackpads. +If not enabled, the gesture will require click + drag, with `enableTrackpadTwoFingerGesture` swiping with two fingers will also trigger the gesture. + +### `children` + +either a component that's rendered in the content view or a function. +If `children` is a function, it is provided with a `progress` parameter. + +- `progress` - `SharedValue` that indicates the progress of drawer opening/closing animation. + - equals `0` when the `drawer` is closed and `1` when the `drawer` is opened + - can be used by the `drawer` component to animated its children while the `drawer` is opening or closing + +### `mouseButton(value: MouseButton)` (Web & Android only) + +allows users to choose which mouse button should handler respond to. +The enum `MouseButton` consists of the following predefined fields: + +- `LEFT` +- `RIGHT` +- `MIDDLE` +- `BUTTON_4` +- `BUTTON_5` +- `ALL` + +Arguments can be combined using `|` operator, e.g. `mouseButton(MouseButton.LEFT | MouseButton.RIGHT)`. Defaults to `MouseButton.LEFT`. + +### `enableContextMenu(value: boolean)` (Web only) + +specifies whether context menu should be enabled after clicking on underlying view with right mouse button. Defaults to `false`. + +## Methods + +### `openDrawer(options)` + +`openDrawer` accepts an optional `options` parameter, which is an object with the following optional properties: + +- `initialVelocity` - the initial velocity of the object attached to the spring. Defaults to `0`. +- `animationSpeed` - controls speed of the animation. Defaults to `1`. + +### `closeDrawer(options)` + +`closeDrawer` accepts an optional `options` parameter, which is an object with the following optional properties: + +- `initialVelocity` - initial velocity of the object attached to the spring. Defaults to `0`. +- `animationSpeed` - controls speed of the animation. Defaults to `1`. + +## Example: + +See the [reanimated drawer layout example](https://github.com/software-mansion/react-native-gesture-handler/blob/main/apps/common-app/src/release_tests/reanimatedDrawerLayout/index.tsx) from GestureHandler example app. + +```js +import React, { useRef } from 'react'; +import { StyleSheet, Text, View } from 'react-native'; +import { Gesture, GestureDetector } from 'react-native-gesture-handler'; + +import ReanimatedDrawerLayout, { + DrawerType, + DrawerPosition, + DrawerLayoutMethods, +} from 'react-native-gesture-handler/ReanimatedDrawerLayout'; + +const DrawerPage = () => { + return ( + + Lorem ipsum + + ); +}; + +export default function ReanimatedDrawerExample() { + const drawerRef = useRef < DrawerLayoutMethods > null; + const tapGesture = Gesture.Tap() + .runOnJS(true) + .onStart(() => drawerRef.current?.openDrawer()); + + return ( + } + drawerPosition={DrawerPosition.LEFT} + drawerType={DrawerType.FRONT}> + + + + Open drawer + + + + + ); +} + +const styles = StyleSheet.create({ + drawerContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'pink', + }, + innerContainer: { + flex: 1, + backgroundColor: 'white', + alignItems: 'center', + justifyContent: 'center', + gap: 20, + }, + box: { + padding: 20, + backgroundColor: 'pink', + }, +}); +``` diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/components/reanimated_swipeable.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/reanimated_swipeable.md new file mode 100644 index 0000000000..bbf58d07fc --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/reanimated_swipeable.md @@ -0,0 +1,251 @@ +--- +id: reanimated_swipeable +title: Reanimated Swipeable +sidebar_label: Reanimated Swipeable +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; +import GifGallery from '@site/components/GifGallery' + + + + + +:::info +This component is a drop-in replacement for the `Swipeable` component, rewritten using `Reanimated`. +::: + +Reanimated `Swipeable` allows for implementing swipeable rows or similar interaction. It renders its children within a panable container allows for horizontal swiping left and right. While swiping one of two "action" containers can be shown depends on whether user swipes left or right (containers can be rendered by `renderLeftActions` or `renderRightActions` props). + +### Usage: + +To use it, import it in the following way: + +```js +import Swipeable from 'react-native-gesture-handler/ReanimatedSwipeable'; +``` + +## Properties + +### `friction` + +a number that specifies how much the visual interaction will be delayed compared to the gesture distance. +e.g. value of `1` will indicate that the swipeable panel should exactly follow the gesture, `2` means it is going to be two times "slower". + +### `leftThreshold` + +distance from the left edge at which released panel will animate to the open state (or the open panel will animate into the closed state). By default it's a half of the panel's width. + +### `rightThreshold` + +distance from the right edge at which released panel will animate to the open state (or the open panel will animate into the closed state). By default it's a half of the panel's width. + +### `dragOffsetFromLeftEdge` + +distance that the panel must be dragged from the left edge to be considered a swipe. The default value is `10`. + +### `dragOffsetFromRightEdge` + +distance that the panel must be dragged from the right edge to be considered a swipe. The default value is `10`. + +### `overshootLeft` + +a boolean value indicating if the swipeable panel can be pulled further than the left actions panel's width. It is set to `true` by default as long as the left panel render function is present. + +### `overshootRight` + +a boolean value indicating if the swipeable panel can be pulled further than the right actions panel's width. It is set to `true` by default as long as the right panel render function is present. + +### `overshootFriction` + +a number that specifies how much the visual interaction will be delayed compared to the gesture distance at overshoot. Default value is `1`, it mean no friction, for a native feel, try `8` or above. + +### `onSwipeableOpen` + +a function that is called when `swipeable` is opened (either right or left). +Receives swipe direction as an argument. + +### `onSwipeableClose` + +a function that is called when `swipeable` is closed. +Receives swipe direction as an argument. + +### `onSwipeableWillOpen` + +a function that is called when `swipeable` starts animating on open (either right or left). +Receives swipe direction as an argument. + +### `onSwipeableWillClose` + +a function that is called when `swipeable` starts animating on close. +Receives swipe direction as an argument. + +### `onSwipeableOpenStartDrag` + +a function that is called when a user starts to drag the `swipable` to open. +Receives swipe direction as an argument. + +### `onSwipeableCloseStartDrag` + +a function that is called when a user starts to drag the `swipable` to close. +Receives swipe direction as an argument. + +### `renderLeftActions` + +a function that returns a component which will be rendered under the swipeable after swiping it to the right. +The function receives the following arguments: + +- `progress` - a `SharedValue` representing swiping progress relative to the width of the returned element. + - Equals `0` when `swipeable` is closed, `1` when `swipeable` is opened. + - When the element overshoots it's opened position the value tends towards `Infinity`. +- `translation` - a horizontal offset of the `swipeable` relative to its closed position. +- `swipeableMethods` - provides an object exposing the methods listed [here](#methods). + +This function must return a `ReactNode`. + +To support `rtl` flexbox layouts use `flexDirection` styling. + +### `renderRightActions` + +a function that returns a component which will be rendered under the swipeable after swiping it to the left. +The function receives the following arguments: + +- `progress` - a `SharedValue` representing swiping progress relative to the width of the returned element. + - Equals `0` when `swipeable` is closed, `1` when `swipeable` is opened. + - When the element overshoots it's opened position the value tends towards `Infinity`. +- `translation` - a horizontal offset of the `swipeable` relative to its closed position. +- `swipeableMethods` - provides an object exposing the methods listed [here](#methods). + +This function must return a `ReactNode`. + +To support `rtl` flexbox layouts use `flexDirection` styling. + +### `containerStyle` + +style object for the container (`Animated.View`), for example to override `overflow: 'hidden'`. + +### `childrenContainerStyle` + +style object for the children container (`Animated.View`), for example to apply `flex: 1`. + +### `simultaneousWithExternalGesture` + +A gesture configuration to be recognized simultaneously with the swipeable gesture. This is useful for allowing other gestures to work simultaneously with swipeable gesture handler. + +For example, to enable a pan gesture alongside the swipeable gesture: + +```jsx +const panGesture = Gesture.Pan(); + + + + +``` + +More details can be found in the [gesture composition documentation](../fundamentals/gesture-composition.md#simultaneouswithexternalgesture). + +### `enableTrackpadTwoFingerGesture` (iOS only) + +Enables two-finger gestures on supported devices, for example iPads with trackpads. +If not enabled the gesture will require click + drag, with `enableTrackpadTwoFingerGesture` swiping with two fingers will also trigger the gesture. + +### `mouseButton(value: MouseButton)` (Web & Android only) + +Allows users to choose which mouse button should handler respond to. The enum `MouseButton` consists of the following predefined fields: + +- `LEFT` +- `RIGHT` +- `MIDDLE` +- `BUTTON_4` +- `BUTTON_5` +- `ALL` + +Arguments can be combined using `|` operator, e.g. `mouseButton(MouseButton.LEFT | MouseButton.RIGHT)`. Default value is set to `MouseButton.LEFT`. + +### `enableContextMenu(value: boolean)` (Web only) + +Specifies whether context menu should be enabled after clicking on underlying view with right mouse button. Default value is set to `false`. + +## Methods + +Using reference to `Swipeable` it's possible to trigger some actions on it + +### `close` + +a method that closes component. + +### `openLeft` + +a method that opens component on left side. + +### `openRight` + +a method that opens component on right side. + +### `reset` + +a method that resets the swiping states of this `Swipeable` component. + +Unlike method `close`, this method does not trigger any animation. + +### Example: + +For a more in-depth presentation of differences between the new and the legacy implementations, +see [swipeable example](https://github.com/software-mansion/react-native-gesture-handler/blob/main/apps/common-app/src/release_tests/swipeableReanimation/index.tsx) from GestureHandler Example App. + +```jsx +import React from 'react'; +import { Text, StyleSheet } from 'react-native'; + +import { GestureHandlerRootView } from 'react-native-gesture-handler'; +import ReanimatedSwipeable from 'react-native-gesture-handler/ReanimatedSwipeable'; +import Reanimated, { + SharedValue, + useAnimatedStyle, +} from 'react-native-reanimated'; + +function RightAction(prog: SharedValue, drag: SharedValue) { + const styleAnimation = useAnimatedStyle(() => { + console.log('showRightProgress:', prog.value); + console.log('appliedTranslation:', drag.value); + + return { + transform: [{ translateX: drag.value + 50 }], + }; + }); + + return ( + + Text + + ); +} + +export default function Example() { + return ( + + + Swipe me! + + + ); +} + +const styles = StyleSheet.create({ + rightAction: { width: 50, height: 50, backgroundColor: 'purple' }, + separator: { + width: '100%', + borderTopWidth: 1, + }, + swipeable: { + height: 50, + backgroundColor: 'papayawhip', + alignItems: 'center', + }, +}); +``` diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/components/touchables.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/touchables.md new file mode 100644 index 0000000000..6d1f19107f --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/components/touchables.md @@ -0,0 +1,56 @@ +--- +id: touchables +title: Touchables +sidebar_label: Touchables +--- + +:::warning +Touchables will be removed in the future version of Gesture Handler. Use Pressable instead. +::: + +Gesture Handler library provides an implementation of RN's touchable components that are based on [native buttons](buttons.mdx) and does not rely on JS responder system utilized by RN. Our touchable implementation follows the same API and aims to be a drop-in replacement for touchables available in React Native. + +React Native's touchables API can be found here: + +- [Touchable Native Feedback](https://reactnative.dev/docs/touchablenativefeedback) +- [Touchable Highlight](https://reactnative.dev/docs/touchablehighlight) +- [Touchable Opacity](https://reactnative.dev/docs/touchableopacity) +- [Touchable Without Feedback](https://reactnative.dev/docs/touchablewithoutfeedback) + +All major touchable properties (except from `pressRetentionOffset`) have been adopted and should behave in a similar way as with RN's touchables. + +The motivation for using RNGH touchables as a replacement for these imported from React Native is to follow built-in native behavior more closely by utilizing platform native touch system instead of relying on the JS responder system. +These touchables and their feedback behavior are deeply integrated with native +gesture ecosystem and could be connected with other native components (e.g. `ScrollView`) and Gesture Handlers easily and in a more predictable way, which +follows native apps' behavior. + +Our intention was to make switch for these touchables as simple as possible. In order to use RNGH's touchables the only thing you need to do is to change library from which you import touchable components. +need only to change imports of touchables. + +:::info +Gesture Handler's TouchableOpacity uses native driver for animations by default. If this causes problems for you, you can set `useNativeAnimations` prop to false. +::: + +### Example: + +```javascript +import { + TouchableNativeFeedback, + TouchableHighlight, + TouchableOpacity, + TouchableWithoutFeedback, +} from 'react-native'; +``` + +has to be replaced with: + +```javascript +import { + TouchableNativeFeedback, + TouchableHighlight, + TouchableOpacity, + TouchableWithoutFeedback, +} from 'react-native-gesture-handler'; +``` + +For a comparison of both touchable implementations see our [touchables example](https://github.com/software-mansion/react-native-gesture-handler/blob/main/apps/common-app/src/release_tests/touchables/index.tsx) diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/_category_.json b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/_category_.json new file mode 100644 index 0000000000..ea8044f531 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Fundamentals", + "position": 1, + "link": { + "type": "generated-index" + } +} diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/gesture-composition.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/gesture-composition.md new file mode 100644 index 0000000000..31657f617c --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/gesture-composition.md @@ -0,0 +1,408 @@ +--- +id: gesture-composition +title: Gesture composition & interactions +sidebar_label: Gesture composition & interactions +sidebar_position: 3 +--- + +Composing gestures is much simpler in RNGH2, you don't need to create a ref for every gesture that depends on another one. Instead you can use `Race`, `Simultaneous` and `Exclusive` methods provided by the `Gesture` object. + +## Race + +Only one of the provided gestures can become active at the same time. The first gesture to become active will cancel the rest of the gestures. It accepts variable number of arguments. +It is the equivalent to having more than one gesture handler without defining `simultaneousHandlers` and `waitFor` props. + +For example, lets say that you have a component that you want to make draggable but you also want to show additional options on long press. Presumably you would not want the component to move after the long press activates. You can accomplish this using `Race`: + +> Note: the `useSharedValue` and `useAnimatedStyle` are part of [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/). + +```js +import { GestureDetector, Gesture } from 'react-native-gesture-handler'; +import Animated, { + useSharedValue, + useAnimatedStyle, + withTiming, +} from 'react-native-reanimated'; + +function App() { + const offset = useSharedValue({ x: 0, y: 0 }); + const start = useSharedValue({ x: 0, y: 0 }); + const popupPosition = useSharedValue({ x: 0, y: 0 }); + const popupAlpha = useSharedValue(0); + + const animatedStyles = useAnimatedStyle(() => { + return { + transform: [ + { translateX: offset.value.x }, + { translateY: offset.value.y }, + ], + }; + }); + + const animatedPopupStyles = useAnimatedStyle(() => { + return { + transform: [ + { translateX: popupPosition.value.x }, + { translateY: popupPosition.value.y }, + ], + opacity: popupAlpha.value, + }; + }); + + const dragGesture = Gesture.Pan() + .onStart((_e) => { + popupAlpha.value = withTiming(0); + }) + .onUpdate((e) => { + offset.value = { + x: e.translationX + start.value.x, + y: e.translationY + start.value.y, + }; + }) + .onEnd(() => { + start.value = { + x: offset.value.x, + y: offset.value.y, + }; + }); + + const longPressGesture = Gesture.LongPress().onStart((_event) => { + popupPosition.value = { x: offset.value.x, y: offset.value.y }; + popupAlpha.value = withTiming(1); + }); + + const composed = Gesture.Race(dragGesture, longPressGesture); + + return ( + + + + + + + ); +} +``` + +## Simultaneous + +All of the provided gestures can activate at the same time. Activation of one will not cancel the other. +It is the equivalent to having some gesture handlers, each with `simultaneousHandlers` prop set to the other handlers. + +For example, if you want to make a gallery app, you might want user to be able to zoom, rotate and pan around photos. You can do it with `Simultaneous`: + +> Note: the `useSharedValue` and `useAnimatedStyle` are part of [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/). + +```js +import { GestureDetector, Gesture } from 'react-native-gesture-handler'; +import Animated, { + useSharedValue, + useAnimatedStyle, +} from 'react-native-reanimated'; + +function App() { + const offset = useSharedValue({ x: 0, y: 0 }); + const start = useSharedValue({ x: 0, y: 0 }); + const scale = useSharedValue(1); + const savedScale = useSharedValue(1); + const rotation = useSharedValue(0); + const savedRotation = useSharedValue(0); + const animatedStyles = useAnimatedStyle(() => { + return { + transform: [ + { translateX: offset.value.x }, + { translateY: offset.value.y }, + { scale: scale.value }, + { rotateZ: `${rotation.value}rad` }, + ], + }; + }); + + const dragGesture = Gesture.Pan() + .averageTouches(true) + .onUpdate((e) => { + offset.value = { + x: e.translationX + start.value.x, + y: e.translationY + start.value.y, + }; + }) + .onEnd(() => { + start.value = { + x: offset.value.x, + y: offset.value.y, + }; + }); + + const zoomGesture = Gesture.Pinch() + .onUpdate((event) => { + scale.value = savedScale.value * event.scale; + }) + .onEnd(() => { + savedScale.value = scale.value; + }); + + const rotateGesture = Gesture.Rotation() + .onUpdate((event) => { + rotation.value = savedRotation.value + event.rotation; + }) + .onEnd(() => { + savedRotation.value = rotation.value; + }); + + const composed = Gesture.Simultaneous( + dragGesture, + Gesture.Simultaneous(zoomGesture, rotateGesture) + ); + + return ( + + + + + + ); +} +``` + +## Exclusive + +Only one of the provided gestures can become active, with the first one having a higher priority than the second one (if both gestures are still possible, the second one will wait for the first one to fail before it activates), second one having a higher priority than the third one, and so on. +It is equivalent to having some gesture handlers where the second one has the `waitFor` prop set to the first handler, third one has the `waitFor` prop set to the first and the second one, and so on. + +For example, if you want to make a component that responds to single tap as well as to a double tap, you can accomplish that using `Exclusive`: + +> Note: the `useSharedValue` and `useAnimatedStyle` are part of [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/). + +```js +import { GestureDetector, Gesture } from 'react-native-gesture-handler'; + +function App() { + const singleTap = Gesture.Tap().onEnd((_event, success) => { + if (success) { + console.log('single tap!'); + } + }); + const doubleTap = Gesture.Tap() + .numberOfTaps(2) + .onEnd((_event, success) => { + if (success) { + console.log('double tap!'); + } + }); + + const taps = Gesture.Exclusive(doubleTap, singleTap); + + return ( + + + + ); +} +``` + +# Cross-component interactions + +You may have noticed that gesture composition described above requires you to mount all of the composed gestures under a single `GestureDetector`, effectively attaching them to the same underlying component. You can customize how gestures interact with each other across multiple components in a couple of ways: + +## requireExternalGestureToFail + +`requireExternalGestureToFail` allows to delay activation of the handler until all handlers passed as arguments to this method fail (or don't begin at all). + +For example, you may want to have two nested components, both of them can be tapped by the user to trigger different actions: outer view requires one tap, but the inner one requires 2 taps. If you don't want the first tap on the inner view to activate the outer handler, you must make the outer gesture wait until the inner one fails: + +```jsx +import React from 'react'; +import { View, StyleSheet } from 'react-native'; +import { + GestureDetector, + Gesture, + GestureHandlerRootView, +} from 'react-native-gesture-handler'; + +export default function Example() { + const innerTap = Gesture.Tap() + .numberOfTaps(2) + .onStart(() => { + console.log('inner tap'); + }); + + const outerTap = Gesture.Tap() + .onStart(() => { + console.log('outer tap'); + }) + .requireExternalGestureToFail(innerTap); + + return ( + + + + + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + outer: { + width: 250, + height: 250, + backgroundColor: 'lightblue', + }, + inner: { + width: 100, + height: 100, + backgroundColor: 'blue', + alignSelf: 'center', + }, +}); +``` + +## blocksExternalGesture + +`blocksExternalGesture` works similarly to `requireExternalGestureToFail` but the direction of the relation is reversed - instead of being one-to-many relation, it's many-to-one. It's especially useful for making lists where the `ScrollView` component needs to wait for every gesture underneath it. All that's required to do is to pass a ref, for example: + +```jsx +import React, { useRef } from 'react'; +import { StyleSheet } from 'react-native'; +import { + GestureDetector, + Gesture, + GestureHandlerRootView, + ScrollView, +} from 'react-native-gesture-handler'; +import Animated, { + useSharedValue, + useAnimatedStyle, + withTiming, +} from 'react-native-reanimated'; + +const ITEMS = ['red', 'green', 'blue', 'yellow']; + +function Item({ backgroundColor, scrollRef }) { + const scale = useSharedValue(1); + const zIndex = useSharedValue(1); + + const pinch = Gesture.Pinch() + .blocksExternalGesture(scrollRef) + .onBegin(() => { + zIndex.value = 100; + }) + .onChange((e) => { + scale.value *= e.scaleChange; + }) + .onFinalize(() => { + scale.value = withTiming(1, undefined, (finished) => { + if (finished) { + zIndex.value = 1; + } + }); + }); + + const animatedStyles = useAnimatedStyle(() => ({ + transform: [{ scale: scale.value }], + zIndex: zIndex.value, + })); + + return ( + + + + ); +} + +export default function Example() { + const scrollRef = useRef(); + + return ( + + + {ITEMS.map((item) => ( + + ))} + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + item: { + flex: 1, + aspectRatio: 1, + }, +}); +``` + +## simultaneousWithExternalGesture + +`simultaneousWithExternalGesture` allows gestures across different components to be recognized simultaneously. For example, you may want to have two nested views, both with tap gesture attached. Both of them require one tap, but tapping the inner one should also activate the gesture attached to the outer view: + +```jsx +import React from 'react'; +import { View, StyleSheet } from 'react-native'; +import { + GestureDetector, + Gesture, + GestureHandlerRootView, +} from 'react-native-gesture-handler'; + +export default function Example() { + const innerTap = Gesture.Tap() + .onStart(() => { + console.log('inner tap'); + }); + + const outerTap = Gesture.Tap() + .onStart(() => { + console.log('outer tap'); + }) + .simultaneousWithExternalGesture(innerTap); + + return ( + + + + + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + outer: { + width: 250, + height: 250, + backgroundColor: 'lightblue', + }, + inner: { + width: 100, + height: 100, + backgroundColor: 'blue', + alignSelf: 'center', + }, +}); +``` \ No newline at end of file diff --git a/packages/docs-gesture-handler/docs/fundamentals/installation.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/installation.md similarity index 87% rename from packages/docs-gesture-handler/docs/fundamentals/installation.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/installation.md index 4ca8b0e532..43977e49e9 100644 --- a/packages/docs-gesture-handler/docs/fundamentals/installation.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/installation.md @@ -24,7 +24,7 @@ import TabItem from '@theme/TabItem'; | 2.10.0+ | 0.64.0+ | | 2.0.0+ | 0.63.0+ | -In order to fully utilize the [touch events](/docs/gestures/touch-events/) you also need to use `react-native-reanimated` 2.3.0 or newer. +In order to fully utilize the [touch events](/docs/2.x/gestures/touch-events/) you also need to use `react-native-reanimated` 2.3.0 or newer. Setting up `react-native-gesture-handler` is pretty straightforward: @@ -123,15 +123,7 @@ cd ios && pod install && cd .. #### Web -There is no additional configuration required for the web, however, since the Gesture Handler 2.10.0 the new web implementation is enabled by default. We recommend you to check if the gestures in your app are working as expected since their behavior should now resemble the native platforms. If you don't want to use the new implementation, you can still revert back to the legacy one by enabling it at the beginning of your `index.js` file: - -```js -import { enableLegacyWebImplementation } from 'react-native-gesture-handler'; - -enableLegacyWebImplementation(true); -``` - -Nonetheless, it's recommended to adapt to the new implementation, as the legacy one will be dropped in the next major release of Gesture Handler. +There is no additional configuration required for the web. #### With [wix/react-native-navigation](https://github.com/wix/react-native-navigation) diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/introduction.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/introduction.md new file mode 100644 index 0000000000..f7dc0376d9 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/introduction.md @@ -0,0 +1,122 @@ +--- +id: introduction +title: Introduction +sidebar_label: Introduction +sidebar_position: 1 +slug: / +--- + +Gesture Handler provides a declarative API exposing the native platform's touch and gesture system to React Native. It's designed to be a replacement of React Native's built in touch system called [Gesture Responder System](http://reactnative.dev/docs/gesture-responder-system). Using native touch handling allows to address the performance limitations of React Native's Gesture Responder System. It also provides more control over the platform's native components that can handle gestures on their own. If you want to learn more, we recommend [this talk](https://www.youtube.com/watch?v=V8maYc4R2G0) by [Krzysztof Magiera](https://twitter.com/kzzzf) in which he explains issues with the responder system. + +The main benefits of using React Native Gesture Handler are: + +- A way to use a platform's native touch handling system for recognizing gestures (like pinch, rotation, pan and a few others). +- The ability to define relations between gestures to ensure gestures, and possibly native components, will not conflict with each other. +- Mechanisms to use touchable components that run in native thread and follow platform default behavior; e.g. in the event they are in a scrollable component, turning into pressed state is slightly delayed to prevent it from highlighting when you fling. +- Close integration with [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/) to process touch events on the UI thread. +- Support for different input devices like touch screens, pens and mice. +- Ability to include any native component into the Gesture Handler's touch system, making it work alongside your gestures. + +:::info +We recommended to use Reanimated to implement gesture-driven animations with Gesture Handler. Its more advanced features rely heavily on worklets and the UI runtime provided by Reanimated. +::: + +## Learning resources + +### Apps + +[Gesture Handler Example App](https://github.com/software-mansion/react-native-gesture-handler/tree/main/apps/expo-example) – official gesture handler "showcase" app. + +### Talks and workshops + +[Declarative future of gestures and animations in React Native](https://www.youtube.com/watch?v=kdq4z2708VM) by [Krzysztof Magiera](https://twitter.com/kzzzf) - talk that explains motivation behind creating gesture handler library. It also presents [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) and how and when it can be used with gesture handler. + +[React Native workshop with Expo team @ReactEurope 2018](https://youtu.be/JSIoE_ReeDk?t=41m49s) by [Brent Vatne](https://twitter.com/notbrent) – great workshop explaining gesture handler in details and presenting a few exercises that will help get you started. + +[Living in an async world of React Native](https://www.youtube.com/watch?v=-Izgons3mec) by [Krzysztof Magiera](https://twitter.com/kzzzf) – talk which highlights some issue with the React Native's touch system Gesture Handler aims to address. Also the motivation for building this library is explained. + +[React Native Touch & Gesture](https://www.youtube.com/watch?v=V8maYc4R2G0) by [Krzysztof Magiera](https://twitter.com/kzzzf) - talk explaining JS responder system limitations and points out some of the core features of Gesture Handler. + +## Contributing + +If you are interested in the project and want to contribute or support it in other ways don't hesitate to contact anyone from the team on Twitter or Bluesky (links below)! + +All PRs are welcome, but talk to us before you start working on something big. + +The easiest way to get started with contributing code is by: + +- Reviewing the list of [open issues](https://github.com/software-mansion/react-native-gesture-handler/issues) and trying to solve the one that seem approachable to you. +- Updating the [documentation](https://github.com/software-mansion/react-native-gesture-handler/blob/main/docs) whenever you see some information is unclear, missing or out of date. + +Code is only one way how you can contribute. You may want to consider [replying on issues](https://github.com/software-mansion/react-native-gesture-handler/issues) if you know how to help. + +## Community + +We are very proud of the community that has been build around this package. We really appreciate all your help regardless of it is a pull request, issue report, helping others by commenting on existing issues or posting some demo or video tutorial on social media. +If you've build something with this library you'd like to share, please contact us as we'd love to help share it with others. + +### Gesture Handler Team 🚀 + +
+ +
+
+ +
+
Jakub Piasecki
+ + +
+ +
+
+ +
+
Michał Bert
+ +
+ +
+
+ +
+
Ignacy Łątka
+ +
+ +
+
+ +
+
Krzysztof Magiera
+ + +
+ +
+ +### Sponsors + +We really appreciate our sponsors! Thanks to them we can develop our library and make the react-native world a better place. Special thanks for: + + diff --git a/packages/docs-gesture-handler/docs/fundamentals/states-events.mdx b/packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/states-events.mdx similarity index 100% rename from packages/docs-gesture-handler/docs/fundamentals/states-events.mdx rename to packages/docs-gesture-handler/versioned_docs/version-2.x/fundamentals/states-events.mdx diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/_category_.json b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/_category_.json similarity index 100% rename from packages/docs-gesture-handler/docs/gesture-handlers/_category_.json rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/_category_.json diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/about-handlers.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/about-handlers.md similarity index 70% rename from packages/docs-gesture-handler/docs/gesture-handlers/about-handlers.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/about-handlers.md index c67eb59173..6565c773a2 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/about-handlers.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/about-handlers.md @@ -6,7 +6,7 @@ sidebar_position: 1 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: Gesture handlers are the core building blocks of this library. @@ -16,10 +16,10 @@ Each handler type is capable of recognizing one type of gesture (pan, pinch, etc Handlers analyze touch stream synchronously in the UI thread. This allows for uninterrupted interactions even when the Javascript thread is blocked. -Each handler works as an isolated state machine. It takes touch stream as an input and based on it, it can flip between [states](/docs/under-the-hood/state). +Each handler works as an isolated state machine. It takes touch stream as an input and based on it, it can flip between [states](/docs/2.x/under-the-hood/state). When a gesture starts, based on the position where the finger was placed, a set of handlers that may be interested in recognizing the gesture is selected. All the touch events (touch down, move, up, or when other fingers are placed or lifted) are delivered to all of the handlers selected initially. -When one gesture becomes [active](/docs/under-the-hood/state#active), it cancels all the other gestures (read more about how to influence this process in ["Cross handler interactions"](/docs/gesture-handlers/interactions) section). +When one gesture becomes [active](/docs/2.x/under-the-hood/state#active), it cancels all the other gestures (read more about how to influence this process in ["Cross handler interactions"](/docs/2.x/gesture-handlers/interactions) section). Gesture handler components do not instantiate a native view in the view hierarchy. Instead, they are kept in library's own registry and are only connected to native views. When using any of the gesture handler components, it is important for it to have a native view rendered as a child. Since handler components don't have corresponding views in the hierarchy, the events registered with them are actually hooked into the underlying view. @@ -28,23 +28,23 @@ Since handler components don't have corresponding views in the hierarchy, the ev Currently, the library provides the following list of gestures. Their parameters and attributes they provide to gesture events are documented under each gesture page: -- [`PanGestureHandler`](/docs/gesture-handlers/pan-gh) -- [`TapGestureHandler`](/docs/gesture-handlers/tap-gh) -- [`LongPressGestureHandler`](/docs/gesture-handlers/longpress-gh) -- [`RotationGestureHandler`](/docs/gesture-handlers/rotation-gh) -- [`FlingGestureHandler`](/docs/gesture-handlers/fling-gh) -- [`PinchGestureHandler`](/docs/gesture-handlers/pinch-gh) -- [`ForceTouchGestureHandler`](/docs/gesture-handlers/force-gh) +- [`PanGestureHandler`](/docs/2.x/gesture-handlers/pan-gh) +- [`TapGestureHandler`](/docs/2.x/gesture-handlers/tap-gh) +- [`LongPressGestureHandler`](/docs/2.x/gesture-handlers/longpress-gh) +- [`RotationGestureHandler`](/docs/2.x/gesture-handlers/rotation-gh) +- [`FlingGestureHandler`](/docs/2.x/gesture-handlers/fling-gh) +- [`PinchGestureHandler`](/docs/2.x/gesture-handlers/pinch-gh) +- [`ForceTouchGestureHandler`](/docs/2.x/gesture-handlers/force-gh) ### Discrete vs continuous We distinguish between two types of gestures: discrete and continuous. -Continuous gesture handlers can be [active](/docs/under-the-hood/state#active) for a long period of time and will generate a stream of [gesture events](/docs/gesture-handlers/common-gh#ongestureevent) until the gesture is [over](/docs/under-the-hood/state#ended). -An example of a continuous handler is [`PanGestureHandler`](/docs/gesture-handlers/pan-gh) that once [activated](/docs/under-the-hood/state#active), will start providing updates about [translation](/docs/gesture-handlers/pan-gh#translationx) and other properties. +Continuous gesture handlers can be [active](/docs/2.x/under-the-hood/state#active) for a long period of time and will generate a stream of [gesture events](/docs/2.x/gesture-handlers/common-gh#ongestureevent) until the gesture is [over](/docs/2.x/under-the-hood/state#ended). +An example of a continuous handler is [`PanGestureHandler`](/docs/2.x/gesture-handlers/pan-gh) that once [activated](/docs/2.x/under-the-hood/state#active), will start providing updates about [translation](/docs/2.x/gesture-handlers/pan-gh#translationx) and other properties. -On the other hand, discrete gesture handlers once [activated](/docs/under-the-hood/state#active) will not stay in the active state but will [end](/docs/under-the-hood/state#ended) immediately. -[`LongPressGestureHandler`](/docs/gesture-handlers/longpress-gh) is a discrete handler, as it only detects if the finger is placed for a sufficiently long period of time, it does not track finger movements (as that's the responsibility of [`PanGestureHandler`](/docs/gesture-handlers/pan-gh)). +On the other hand, discrete gesture handlers once [activated](/docs/2.x/under-the-hood/state#active) will not stay in the active state but will [end](/docs/2.x/under-the-hood/state#ended) immediately. +[`LongPressGestureHandler`](/docs/2.x/gesture-handlers/longpress-gh) is a discrete handler, as it only detects if the finger is placed for a sufficiently long period of time, it does not track finger movements (as that's the responsibility of [`PanGestureHandler`](/docs/2.x/gesture-handlers/pan-gh)). Keep in mind that `onGestureEvent` is only generated in continuous gesture handlers and shouldn't be used in the `TapGestureHandler` and other discrete handlers. @@ -77,7 +77,7 @@ class Multitap extends Component { ### Using native components -Gesture handler library exposes a set of components normally available in React Native that are wrapped in [`NativeViewGestureHandler`](/docs/gesture-handlers/nativeview-gh). +Gesture handler library exposes a set of components normally available in React Native that are wrapped in [`NativeViewGestureHandler`](/docs/2.x/gesture-handlers/nativeview-gh). Here is a list of exposed components: - `ScrollView` @@ -86,7 +86,7 @@ Here is a list of exposed components: - `TextInput` - `DrawerLayoutAndroid` (**Android only**) -If you want to use other handlers or [buttons](/docs/components/buttons) nested in a `ScrollView`, use the [`waitFor`](/docs/gesture-handlers/common-gh#waitfor) property to define interaction between a handler and `ScrollView` +If you want to use other handlers or [buttons](/docs/2.x/components/buttons) nested in a `ScrollView`, use the [`waitFor`](/docs/2.x/gesture-handlers/common-gh#waitfor) property to define interaction between a handler and `ScrollView` ### Events with `useNativeDriver` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/common-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/common-gh.md similarity index 66% rename from packages/docs-gesture-handler/docs/gesture-handlers/common-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/common-gh.md index 58421e27ac..0133c4e096 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/common-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/common-gh.md @@ -6,7 +6,7 @@ sidebar_position: 4 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: This page covers the common set of properties all gesture handler components expose. @@ -25,34 +25,34 @@ This section describes properties that can be used with all gesture handler comp Accepts a boolean value. Indicates whether the given handler should be analyzing stream of touch events or not. -When set to `false` we can be sure that the handler's state will **never** become [`ACTIVE`](/docs/under-the-hood/state#active). -If the value gets updated while the handler already started recognizing a gesture, then the handler's state it will immediately change to [`FAILED`](/docs/under-the-hood/state#failed) or [`CANCELLED`](/docs/under-the-hood/state#cancelled) (depending on its current state). +When set to `false` we can be sure that the handler's state will **never** become [`ACTIVE`](/docs/2.x/under-the-hood/state#active). +If the value gets updated while the handler already started recognizing a gesture, then the handler's state it will immediately change to [`FAILED`](/docs/2.x/under-the-hood/state#failed) or [`CANCELLED`](/docs/2.x/under-the-hood/state#cancelled) (depending on its current state). Default value is `true`. ### `shouldCancelWhenOutside` Accepts a boolean value. -When `true` the handler will [cancel](/docs/under-the-hood/state#cancelled) or [fail](/docs/under-the-hood/state#failed) recognition (depending on its current state) whenever the finger leaves the area of the connected view. +When `true` the handler will [cancel](/docs/2.x/under-the-hood/state#cancelled) or [fail](/docs/2.x/under-the-hood/state#failed) recognition (depending on its current state) whenever the finger leaves the area of the connected view. Default value of this property is different depending on the handler type. -Most handlers' `shouldCancelWhenOutside` property defaults to `false` except for the [`LongPressGestureHandler`](/docs/gesture-handlers/longpress-gh) and [`TapGestureHandler`](/docs/gesture-handlers/tap-gh) which default to `true`. +Most handlers' `shouldCancelWhenOutside` property defaults to `false` except for the [`LongPressGestureHandler`](/docs/2.x/gesture-handlers/longpress-gh) and [`TapGestureHandler`](/docs/2.x/gesture-handlers/tap-gh) which default to `true`. ### `cancelsTouchesInView` (**iOS only**) Accepts a boolean value. -When `true`, the handler will cancel touches for native UI components (`UIButton`, `UISwitch`, etc) it's attached to when it becomes [`ACTIVE`](/docs/under-the-hood/state#active). +When `true`, the handler will cancel touches for native UI components (`UIButton`, `UISwitch`, etc) it's attached to when it becomes [`ACTIVE`](/docs/2.x/under-the-hood/state#active). Default value is `true`. ### `simultaneousHandlers` -Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set, the handler will be allowed to [activate](/docs/under-the-hood/state#active) even if one or more of the handlers provided by their refs are in an [`ACTIVE`](/docs/under-the-hood/state#active) state. It will also prevent the provided handlers from [cancelling](/docs/under-the-hood/state#cancelled) the current handler when they [activate](/docs/under-the-hood/state#active). Read more in the [cross handler interaction](/docs/gesture-handlers/interactions#simultaneous-recognition) section. +Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set, the handler will be allowed to [activate](/docs/2.x/under-the-hood/state#active) even if one or more of the handlers provided by their refs are in an [`ACTIVE`](/docs/2.x/under-the-hood/state#active) state. It will also prevent the provided handlers from [cancelling](/docs/2.x/under-the-hood/state#cancelled) the current handler when they [activate](/docs/2.x/under-the-hood/state#active). Read more in the [cross handler interaction](/docs/2.x/gesture-handlers/interactions#simultaneous-recognition) section. ### `waitFor` -Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set the handler will not [activate](/docs/under-the-hood/state#active) as long as the handlers provided by their refs are in the [`BEGAN`](/docs/under-the-hood/state#began) state. Read more in the [cross handler interaction](/docs/gesture-handlers/interactions#awaiting-other-handlers) section. +Accepts a react ref object or an array of refs to other handler components (refs should be created using [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html)). When set the handler will not [activate](/docs/2.x/under-the-hood/state#active) as long as the handlers provided by their refs are in the [`BEGAN`](/docs/2.x/under-the-hood/state#began) state. Read more in the [cross handler interaction](/docs/2.x/gesture-handlers/interactions#awaiting-other-handlers) section. ### `hitSlop` -This parameter enables control over what part of the connected view area can be used to [begin](/docs/under-the-hood/state#began) recognizing the gesture. +This parameter enables control over what part of the connected view area can be used to [begin](/docs/2.x/under-the-hood/state#began) recognizing the gesture. When a negative number is provided the bounds of the view will reduce the area by the given number of points in each of the sides evenly. Instead you can pass an object to specify how each boundary side should be reduced by providing different number of points for `left`, `right`, `top` or `bottom` sides. @@ -74,17 +74,17 @@ This parameter allows to specify which cursor should be used when gesture activa ### `onGestureEvent` -Takes a callback that is going to be triggered for each subsequent touch event while the handler is in an [ACTIVE](/docs/under-the-hood/state#active) state. Event payload depends on the particular handler type. Common set of event data attributes is documented [below](#event-data) and handler specific attributes are documented on the corresponding handler pages. E.g. event payload for [`PinchGestureHandler`](/docs/gesture-handlers/rotation-gh#event-data) contains `scale` attribute that represents how the distance between fingers changed since when the gesture started. +Takes a callback that is going to be triggered for each subsequent touch event while the handler is in an [ACTIVE](/docs/2.x/under-the-hood/state#active) state. Event payload depends on the particular handler type. Common set of event data attributes is documented [below](#event-data) and handler specific attributes are documented on the corresponding handler pages. E.g. event payload for [`PinchGestureHandler`](/docs/2.x/gesture-handlers/rotation-gh#event-data) contains `scale` attribute that represents how the distance between fingers changed since when the gesture started. Instead of a callback [`Animated.event`](https://reactnative.dev/docs/animated.html#event) object can be used. Also Animated events with `useNativeDriver` flag enabled **are fully supported**. ### `onHandlerStateChange` -Takes a callback that is going to be triggered when [state](/docs/under-the-hood/state) of the given handler changes. +Takes a callback that is going to be triggered when [state](/docs/2.x/under-the-hood/state) of the given handler changes. The event payload contains the same payload as in case of [`onGestureEvent`](#ongestureevent) including handler specific event attributes some handlers may provide. -In addition `onHandlerStateChange` event payload contains `oldState` attribute which represents the [state](/docs/under-the-hood/state) of the handler right before the change. +In addition `onHandlerStateChange` event payload contains `oldState` attribute which represents the [state](/docs/2.x/under-the-hood/state) of the handler right before the change. Instead of a callback [`Animated.event`](https://reactnative.dev/docs/animated.html#event) object can be used. Also Animated events with `useNativeDriver` flag enabled **are fully supported**. @@ -94,7 +94,7 @@ This section describes the attributes of event object being provided to [`onGest ### `state` -Current [state](/docs/under-the-hood/state) of the handler. Expressed as one of the constants exported under `State` object by the library. Refer to the section about [handler state](/docs/under-the-hood/state) to learn more about how to use it. +Current [state](/docs/2.x/under-the-hood/state) of the handler. Expressed as one of the constants exported under `State` object by the library. Refer to the section about [handler state](/docs/2.x/under-the-hood/state) to learn more about how to use it. ### `numberOfPointers` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/create-native-wrapper.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/create-native-wrapper.md similarity index 67% rename from packages/docs-gesture-handler/docs/gesture-handlers/create-native-wrapper.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/create-native-wrapper.md index aa84e63b37..1bd50a5485 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/create-native-wrapper.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/create-native-wrapper.md @@ -6,7 +6,7 @@ sidebar_position: 13 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: Creates provided component with NativeViewGestureHandler, allowing it to be part of RNGH's @@ -20,7 +20,7 @@ The component we want to wrap. ### config -Config is an object with properties that can be used on [`NativeViewGestureHandler`](/docs/gesture-handlers/nativeview-gh) +Config is an object with properties that can be used on [`NativeViewGestureHandler`](/docs/2.x/gesture-handlers/nativeview-gh) ## Returns diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/fling-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/fling-gh.md similarity index 77% rename from packages/docs-gesture-handler/docs/gesture-handlers/fling-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/fling-gh.md index baedfc15e1..171f43087d 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/fling-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/fling-gh.md @@ -6,18 +6,18 @@ sidebar_position: 9 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A discrete gesture handler that activates when the movement is sufficiently long and fast. -Handler gets [ACTIVE](/docs/under-the-hood/state#active) when movement is sufficiently long and it does not take too much time. -When handler gets activated it will turn into [END](/docs/under-the-hood/state#end) state when finger is released. +Handler gets [ACTIVE](/docs/2.x/under-the-hood/state#active) when movement is sufficiently long and it does not take too much time. +When handler gets activated it will turn into [END](/docs/2.x/under-the-hood/state#end) state when finger is released. The handler will fail to recognize if the finger is lifted before being activated. The handler is implemented using [UISwipeGestureRecognizer](https://developer.apple.com/documentation/uikit/uiswipegesturerecognizer) on iOS and from scratch on Android. ## Properties -See [set of properties inherited from base handler class](/docs/gesture-handlers/common-gh#properties). Below is a list of properties specific to `FlingGestureHandler` component: +See [set of properties inherited from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). Below is a list of properties specific to `FlingGestureHandler` component: ### `direction` @@ -39,7 +39,7 @@ Determine exact number of points required to handle the fling gesture. ## Event data -See [set of event attributes from base handler class](/docs/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `FlingGestureHandler`: +See [set of event attributes from base handler class](/docs/2.x/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `FlingGestureHandler`: ### `x` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/force-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/force-gh.md similarity index 71% rename from packages/docs-gesture-handler/docs/gesture-handlers/force-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/force-gh.md index 6e23205984..110ca1780d 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/force-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/force-gh.md @@ -6,11 +6,11 @@ sidebar_position: 11 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A continuous gesture handler that recognizes force of a touch. It allows for tracking pressure of touch on some iOS devices. -The handler [activates](/docs/under-the-hood/state#active) when pressure of touch if greater or equal than `minForce`. It fails if pressure is greater than `maxForce` +The handler [activates](/docs/2.x/under-the-hood/state#active) when pressure of touch if greater or equal than `minForce`. It fails if pressure is greater than `maxForce` Gesture callback can be used for continuous tracking of the touch pressure. It provides information for one finger (the first one). At the beginning of the gesture, the pressure factor is 0.0. As the pressure increases, the pressure factor increases proportionally. The maximum pressure is 1.0. @@ -20,15 +20,15 @@ Since this behaviour is only provided on some iOS devices, this handler should n # Properties -See [set of properties inherited from base handler class](/docs/gesture-handlers/common-gh#properties). Below is a list of properties specific to `ForceTouchGestureHandler` component: +See [set of properties inherited from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). Below is a list of properties specific to `ForceTouchGestureHandler` component: ### `minForce` -A minimal pressure that is required before handler can [activate](/docs/under-the-hood/state#active). Should be a value from range `[0.0, 1.0]`. Default is `0.2`. +A minimal pressure that is required before handler can [activate](/docs/2.x/under-the-hood/state#active). Should be a value from range `[0.0, 1.0]`. Default is `0.2`. ### `maxForce` -A maximal pressure that could be applied for handler. If the pressure is greater, handler [fails](/docs/under-the-hood/state#failed). Should be a value from range `[0.0, 1.0]`. +A maximal pressure that could be applied for handler. If the pressure is greater, handler [fails](/docs/2.x/under-the-hood/state#failed). Should be a value from range `[0.0, 1.0]`. ### `feedbackOnActivation` @@ -36,7 +36,7 @@ Boolean value defining if haptic feedback has to be performed on activation. ## Event data -See [set of event attributes from base handler class](/docs/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `ForceTouchGestureHandler`: +See [set of event attributes from base handler class](/docs/2.x/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `ForceTouchGestureHandler`: ### `force` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/interactions.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/interactions.md similarity index 77% rename from packages/docs-gesture-handler/docs/gesture-handlers/interactions.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/interactions.md index 64b9636051..e225e0e2b0 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/interactions.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/interactions.md @@ -6,10 +6,10 @@ sidebar_position: 3 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: -Gesture handlers can "communicate" with each other to support complex gestures and control how they _[activate](/docs/under-the-hood/state#active)_ in certain scenarios. +Gesture handlers can "communicate" with each other to support complex gestures and control how they _[activate](/docs/2.x/under-the-hood/state#active)_ in certain scenarios. There are two means of achieving that described in the sections below. In each case, it is necessary to provide a reference of one handler as a property to the other. @@ -17,17 +17,17 @@ Gesture handler relies on ref objects created using [`React.createRef()`](https: ## Simultaneous recognition -By default, only one gesture handler is allowed to be in the [`ACTIVE`](/docs/under-the-hood/state#active) state. -So when a gesture handler recognizes a gesture it [cancels](/docs/under-the-hood/state#cancelled) all other handlers in the [`BEGAN`](/docs/under-the-hood/state#began) state and prevents any new handlers from receiving a stream of touch events as long as it remains [`ACTIVE`](/docs/under-the-hood/state#active). +By default, only one gesture handler is allowed to be in the [`ACTIVE`](/docs/2.x/under-the-hood/state#active) state. +So when a gesture handler recognizes a gesture it [cancels](/docs/2.x/under-the-hood/state#cancelled) all other handlers in the [`BEGAN`](/docs/2.x/under-the-hood/state#began) state and prevents any new handlers from receiving a stream of touch events as long as it remains [`ACTIVE`](/docs/2.x/under-the-hood/state#active). -This behavior can be altered using the [`simultaneousHandlers`](/docs/gesture-handlers/common-gh#simultaneoushandlers) property (available for all types of handlers). +This behavior can be altered using the [`simultaneousHandlers`](/docs/2.x/gesture-handlers/common-gh#simultaneoushandlers) property (available for all types of handlers). This property accepts a ref or an array of refs to other handlers. -Handlers connected in this way will be allowed to remain in the [`ACTIVE`](/docs/under-the-hood/state#active) state at the same time. +Handlers connected in this way will be allowed to remain in the [`ACTIVE`](/docs/2.x/under-the-hood/state#active) state at the same time. ### Use cases Simultaneous recognition needs to be used when implementing a photo preview component that supports zooming (scaling) the photo, rotating and panning it while zoomed in. -In this case we would use a [`PinchGestureHandler`](/docs/gesture-handlers/pinch-gh), [`RotationGestureHandler`](/docs/gesture-handlers/rotation-gh) and [`PanGestureHandler`](/docs/gesture-handlers/pan-gh) that would have to simultaneously recognize gestures. +In this case we would use a [`PinchGestureHandler`](/docs/2.x/gesture-handlers/pinch-gh), [`RotationGestureHandler`](/docs/2.x/gesture-handlers/rotation-gh) and [`PanGestureHandler`](/docs/2.x/gesture-handlers/pan-gh) that would have to simultaneously recognize gestures. ### Example @@ -75,7 +75,7 @@ class PinchableBox extends React.Component { A good example where awaiting is necessary is when we want to have single and double tap handlers registered for one view (a button). In such a case we need to make single tap handler await a double tap. -Otherwise if we try to perform a double tap the single tap handler will fire just after we hit the button for the first time, consequently [cancelling](/docs/under-the-hood/state#cancelled) the double tap handler. +Otherwise if we try to perform a double tap the single tap handler will fire just after we hit the button for the first time, consequently [cancelling](/docs/2.x/under-the-hood/state#cancelled) the double tap handler. ### Example diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/longpress-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/longpress-gh.md similarity index 80% rename from packages/docs-gesture-handler/docs/gesture-handlers/longpress-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/longpress-gh.md index 2b2e751b99..4d01bab2a5 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/longpress-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/longpress-gh.md @@ -6,18 +6,18 @@ sidebar_position: 7 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A discrete gesture handler that activates when the corresponding view is pressed for a sufficiently long time. -This handler's state will turn into [END](/docs/under-the-hood/state#end) immediately after the finger is released. +This handler's state will turn into [END](/docs/2.x/under-the-hood/state#end) immediately after the finger is released. The handler will fail to recognize a touch event if the finger is lifted before the [minimum required time](#mindurationms) or if the finger is moved further than the [allowable distance](#maxdist). The handler is implemented using [UILongPressGestureRecognizer](https://developer.apple.com/documentation/uikit/uilongpressgesturerecognizer) on iOS and [LongPressGestureHandler](https://github.com/software-mansion/react-native-gesture-handler/blob/main/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt) on Android. ## Properties -See [set of properties inherited from base handler class](/docs/gesture-handlers/common-gh#properties). Below is a list of properties specific to the `LongPressGestureHandler` component: +See [set of properties inherited from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). Below is a list of properties specific to the `LongPressGestureHandler` component: ### `minDurationMs` @@ -25,11 +25,11 @@ Minimum time, expressed in milliseconds, that a finger must remain pressed on th ### `maxDist` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a long press gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. The default value is 10. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a long press gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/2.x/under-the-hood/state#active), it will fail to recognize the gesture. The default value is 10. ## Event data -See [set of event attributes from base handler class](/docs/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to the `LongPressGestureHandler` component: +See [set of event attributes from base handler class](/docs/2.x/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to the `LongPressGestureHandler` component: ### `x` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/nativeview-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/nativeview-gh.md similarity index 64% rename from packages/docs-gesture-handler/docs/gesture-handlers/nativeview-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/nativeview-gh.md index 5c494c9bff..f8712a0d24 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/nativeview-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/nativeview-gh.md @@ -6,17 +6,17 @@ sidebar_position: 12 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A gesture handler that allows other touch handling components to participate in RNGH's gesture system. -Used by [`createNativeWrapper()`](/docs/gesture-handlers/create-native-wrapper). +Used by [`createNativeWrapper()`](/docs/2.x/gesture-handlers/create-native-wrapper). ## Properties -See [set of properties inherited from base handler class](/docs/gesture-handlers/common-gh#properties). Below is a list of properties specific to `NativeViewGestureHandler` component: +See [set of properties inherited from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). Below is a list of properties specific to `NativeViewGestureHandler` component: ### `shouldActivateOnStart` (**Android only**) diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/pan-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/pan-gh.md similarity index 80% rename from packages/docs-gesture-handler/docs/gesture-handlers/pan-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/pan-gh.md index d70c80cdd0..3cf8218652 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/pan-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/pan-gh.md @@ -6,12 +6,12 @@ sidebar_position: 5 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A continuous gesture handler that can recognize a panning (dragging) gesture and track its movement. -The handler [activates](/docs/under-the-hood/state#active) when a finger is placed on the screen and moved some initial distance. +The handler [activates](/docs/2.x/under-the-hood/state#active) when a finger is placed on the screen and moved some initial distance. Configurations such as a minimum initial distance, specific vertical or horizontal pan detection and [number of fingers](#minPointers) required for activation (allowing for multifinger swipes) may be specified. @@ -21,7 +21,7 @@ The handler is implemented using [UIPanGestureRecognizer](https://developer.appl ## Custom activation criteria -The `PanGestureHandler` component exposes a number of properties that can be used to customize the criteria under which a handler will [activate](/docs/under-the-hood/state#active) or [fail](/docs/under-the-hood/state#fail) when recognizing a gesture. +The `PanGestureHandler` component exposes a number of properties that can be used to customize the criteria under which a handler will [activate](/docs/2.x/under-the-hood/state#active) or [fail](/docs/2.x/under-the-hood/state#fail) when recognizing a gesture. When more than one of such a property is set, `PanGestureHandler` expects all criteria to be met for successful recognition and at most one of the criteria to be overstepped to fail recognition. For example when both [`minDeltaX`](#mindeltax) and [`minDeltaY`](#mindeltay) are set to 20 we expect the finger to travel by 20 points in both the X and Y axis before the handler activates. @@ -46,19 +46,19 @@ If you wish to track the "center of mass" virtual pointer and account for its ch ## Properties -See [set of properties inherited from base handler class](/docs/gesture-handlers/common-gh#properties). Below is a list of properties specific to `PanGestureHandler` component: +See [set of properties inherited from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). Below is a list of properties specific to `PanGestureHandler` component: ### `minDist` -Minimum distance the finger (or multiple finger) need to travel before the handler [activates](/docs/under-the-hood/state#active). Expressed in points. +Minimum distance the finger (or multiple finger) need to travel before the handler [activates](/docs/2.x/under-the-hood/state#active). Expressed in points. ### `minPointers` -A number of fingers that is required to be placed before handler can [activate](/docs/under-the-hood/state#active). Should be a higher or equal to 0 integer. +A number of fingers that is required to be placed before handler can [activate](/docs/2.x/under-the-hood/state#active). Should be a higher or equal to 0 integer. ### `maxPointers` -When the given number of fingers is placed on the screen and handler hasn't yet [activated](/docs/under-the-hood/state#active) it will fail recognizing the gesture. Should be a higher or equal to 0 integer. +When the given number of fingers is placed on the screen and handler hasn't yet [activated](/docs/2.x/under-the-hood/state#active) it will fail recognizing the gesture. Should be a higher or equal to 0 integer. ### `activeOffsetX` @@ -88,37 +88,37 @@ If only one number `p` is given a range of `(-inf, p)` will be used if `p` is hi > This method is deprecated but supported for backward compatibility. Instead of using `maxDeltaX={N}` you can do `failOffsetX={[-N, N]}`. -When the finger travels the given distance expressed in points along X axis and handler hasn't yet [activated](/docs/under-the-hood/state#active) it will fail recognizing the gesture. +When the finger travels the given distance expressed in points along X axis and handler hasn't yet [activated](/docs/2.x/under-the-hood/state#active) it will fail recognizing the gesture. ### `maxDeltaY` > This method is deprecated but supported for backward compatibility. Instead of using `maxDeltaY={N}` you can do `failOffsetY={[-N, N]}`. -When the finger travels the given distance expressed in points along Y axis and handler hasn't yet [activated](/docs/under-the-hood/state#active) it will fail recognizing the gesture. +When the finger travels the given distance expressed in points along Y axis and handler hasn't yet [activated](/docs/2.x/under-the-hood/state#active) it will fail recognizing the gesture. ### `minOffsetX` > This method is deprecated but supported for backward compatibility. Instead of using `minOffsetX={N}` you can do `activeOffsetX={N}`. -Minimum distance along X (in points) axis the finger (or multiple finger) need to travel before the handler [activates](/docs/under-the-hood/state#active). If set to a lower or equal to 0 value we expect the finger to travel "left" by the given distance. When set to a higher or equal to 0 number the handler will activate on a movement to the "right". If you wish for the movement direction to be ignored use [`minDeltaX`](#mindeltax) instead. +Minimum distance along X (in points) axis the finger (or multiple finger) need to travel before the handler [activates](/docs/2.x/under-the-hood/state#active). If set to a lower or equal to 0 value we expect the finger to travel "left" by the given distance. When set to a higher or equal to 0 number the handler will activate on a movement to the "right". If you wish for the movement direction to be ignored use [`minDeltaX`](#mindeltax) instead. ### `minOffsetY` > This method is deprecated but supported for backward compatibility. Instead of using `minOffsetY={N}` you can do `activeOffsetY={N}`. -Minimum distance along Y (in points) axis the finger (or multiple finger) need to travel before the handler [activates](/docs/under-the-hood/state#active). If set to a lower or equal to 0 value we expect the finger to travel "up" by the given distance. When set to a higher or equal to 0 number the handler will activate on a movement to the "bottom". If you wish for the movement direction to be ignored use [`minDeltaY`](#mindeltay) instead. +Minimum distance along Y (in points) axis the finger (or multiple finger) need to travel before the handler [activates](/docs/2.x/under-the-hood/state#active). If set to a lower or equal to 0 value we expect the finger to travel "up" by the given distance. When set to a higher or equal to 0 number the handler will activate on a movement to the "bottom". If you wish for the movement direction to be ignored use [`minDeltaY`](#mindeltay) instead. ### `minDeltaX` > This method is deprecated but supported for backward compatibility. Instead of using `minDeltaX={N}` you can do `activeOffsetX={[-N, N]}`. -Minimum distance along X (in points) axis the finger (or multiple finger) need to travel (left or right) before the handler [activates](/docs/under-the-hood/state#active). Unlike [`minoffsetx`](#minoffsetx) this parameter accepts only non-lower or equal to 0 numbers that represents the distance in point units. If you want for the handler to [activate](/docs/under-the-hood/state#active) for the movement in one particular direction use [`minOffsetX`](#minoffsetx) instead. +Minimum distance along X (in points) axis the finger (or multiple finger) need to travel (left or right) before the handler [activates](/docs/2.x/under-the-hood/state#active). Unlike [`minoffsetx`](#minoffsetx) this parameter accepts only non-lower or equal to 0 numbers that represents the distance in point units. If you want for the handler to [activate](/docs/2.x/under-the-hood/state#active) for the movement in one particular direction use [`minOffsetX`](#minoffsetx) instead. ### `minDeltaY` > This method is deprecated but supported for backward compatibility. Instead of using `minDeltaY={N}` you can do `activeOffsetY={[-N, N]}`. -Minimum distance along Y (in points) axis the finger (or multiple finger) need to travel (top or bottom) before the handler [activates](/docs/under-the-hood/state#active). Unlike [`minOffsetY`](#minoffsety) this parameter accepts only non-lower or equal to 0 numbers that represents the distance in point units. If you want for the handler to [activate](/docs/under-the-hood/state#active) for the movement in one particular direction use [`minOffsetY`](#minoffsety) instead. +Minimum distance along Y (in points) axis the finger (or multiple finger) need to travel (top or bottom) before the handler [activates](/docs/2.x/under-the-hood/state#active). Unlike [`minOffsetY`](#minoffsety) this parameter accepts only non-lower or equal to 0 numbers that represents the distance in point units. If you want for the handler to [activate](/docs/2.x/under-the-hood/state#active) for the movement in one particular direction use [`minOffsetY`](#minoffsety) instead. ### `avgTouches` (Android only) @@ -130,7 +130,7 @@ Enables two-finger gestures on supported devices, for example iPads with trackpa ## Event data -See [set of event attributes from base handler class](/docs/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `PanGestureHandler`: +See [set of event attributes from base handler class](/docs/2.x/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `PanGestureHandler`: ### `translationX` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/pinch-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/pinch-gh.md similarity index 83% rename from packages/docs-gesture-handler/docs/gesture-handlers/pinch-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/pinch-gh.md index adf4ae9442..c1b52f36d8 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/pinch-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/pinch-gh.md @@ -6,11 +6,11 @@ sidebar_position: 10 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A continuous gesture handler that recognizes pinch gesture. It allows for tracking the distance between two fingers and use that information to scale or zoom your content. -The handler [activates](/docs/under-the-hood/state#active) when fingers are placed on the screen and change their position. +The handler [activates](/docs/2.x/under-the-hood/state#active) when fingers are placed on the screen and change their position. Gesture callback can be used for continuous tracking of the pinch gesture. It provides information about velocity, anchor (focal) point of gesture and scale. The distance between the fingers is reported as a scale factor. At the beginning of the gesture, the scale factor is 1.0. As the distance between the two fingers increases, the scale factor increases proportionally. @@ -22,11 +22,11 @@ The handler is implemented using [UIPinchGestureRecognizer](https://developer.ap ## Properties -Properties provided to `PinchGestureHandler` do not extend [common set of properties from base handler class](/docs/gesture-handlers/common-gh#properties). +Properties provided to `PinchGestureHandler` do not extend [common set of properties from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). ## Event data -See [set of event attributes from base handler class](/docs/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `PinchGestureHandler`: +See [set of event attributes from base handler class](/docs/2.x/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `PinchGestureHandler`: ### `scale` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/rotation-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/rotation-gh.md similarity index 80% rename from packages/docs-gesture-handler/docs/gesture-handlers/rotation-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/rotation-gh.md index b6b20f931c..c43f798163 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/rotation-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/rotation-gh.md @@ -6,12 +6,12 @@ sidebar_position: 8 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A continuous gesture handler that can recognize a rotation gesture and track its movement. -The handler [activates](/docs/under-the-hood/state#active) when fingers are placed on the screen and change position in a proper way. +The handler [activates](/docs/2.x/under-the-hood/state#active) when fingers are placed on the screen and change position in a proper way. Gesture callback can be used for continuous tracking of the rotation gesture. It provides information about the gesture such as the amount rotated, the focal point of the rotation (anchor), and its instantaneous velocity. @@ -19,11 +19,11 @@ The handler is implemented using [UIRotationGestureRecognizer](https://developer ## Properties -Properties provided to `RotationGestureHandler` do not extend [common set of properties from base handler class](/docs/gesture-handlers/common-gh#properties). +Properties provided to `RotationGestureHandler` do not extend [common set of properties from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). ## Event data -See [set of event attributes from base handler class](/docs/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `RotationGestureHandler`: +See [set of event attributes from base handler class](/docs/2.x/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to `RotationGestureHandler`: ### `rotation` diff --git a/packages/docs-gesture-handler/docs/gesture-handlers/tap-gh.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/tap-gh.md similarity index 70% rename from packages/docs-gesture-handler/docs/gesture-handlers/tap-gh.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/tap-gh.md index c151632c03..349c1fab5f 100644 --- a/packages/docs-gesture-handler/docs/gesture-handlers/tap-gh.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gesture-handlers/tap-gh.md @@ -6,7 +6,7 @@ sidebar_position: 6 --- :::warning -The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/gestures/gesture) instead. Check out our [upgrading guide](/docs/guides/upgrading-to-2) for more information. +The old API will be removed in the future version of Gesture Handler. Please migrate to [gestures API](/docs/2.x/gestures/gesture) instead. Check out our [upgrading guide](/docs/2.x/guides/upgrading-to-2) for more information. ::: A discrete gesture handler that recognizes one or many taps. @@ -16,15 +16,15 @@ The fingers involved in these gestures must not move significantly from their in The required number of taps and allowed distance from initial position may be configured. For example, you might configure tap gesture recognizers to detect single taps, double taps, or triple taps. -In order for a handler to [activate](/docs/under-the-hood/state#active), specified gesture requirements such as minPointers, numberOfTaps, maxDist, maxDurationMs, and maxDelayMs (explained below) must be met. Immediately after the handler [activates](/docs/under-the-hood/state#active), it will [END](/docs/under-the-hood/state#end). +In order for a handler to [activate](/docs/2.x/under-the-hood/state#active), specified gesture requirements such as minPointers, numberOfTaps, maxDist, maxDurationMs, and maxDelayMs (explained below) must be met. Immediately after the handler [activates](/docs/2.x/under-the-hood/state#active), it will [END](/docs/2.x/under-the-hood/state#end). ## Properties -See [set of properties inherited from base handler class](/docs/gesture-handlers/common-gh#properties). Below is a list of properties specific to the `TapGestureHandler` component: +See [set of properties inherited from base handler class](/docs/2.x/gesture-handlers/common-gh#properties). Below is a list of properties specific to the `TapGestureHandler` component: ### `minPointers` -Minimum number of pointers (fingers) required to be placed before the handler [activates](/docs/under-the-hood/state#active). Should be a positive integer. The default value is 1. +Minimum number of pointers (fingers) required to be placed before the handler [activates](/docs/2.x/under-the-hood/state#active). Should be a positive integer. The default value is 1. ### `maxDurationMs` @@ -36,23 +36,23 @@ Maximum time, expressed in milliseconds, that can pass before the next tap — i ### `numberOfTaps` -Number of tap gestures required to [activate](/docs/under-the-hood/state#active) the handler. The default value is 1. +Number of tap gestures required to [activate](/docs/2.x/under-the-hood/state#active) the handler. The default value is 1. ### `maxDeltaX` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the X axis during a tap gesture. If the finger travels further than the defined distance along the X axis and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the X axis during a tap gesture. If the finger travels further than the defined distance along the X axis and the handler hasn't yet [activated](/docs/2.x/under-the-hood/state#active), it will fail to recognize the gesture. ### `maxDeltaY` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the Y axis during a tap gesture. If the finger travels further than the defined distance along the Y axis and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel along the Y axis during a tap gesture. If the finger travels further than the defined distance along the Y axis and the handler hasn't yet [activated](/docs/2.x/under-the-hood/state#active), it will fail to recognize the gesture. ### `maxDist` -Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a tap gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/under-the-hood/state#active), it will fail to recognize the gesture. +Maximum distance, expressed in points, that defines how far the finger is allowed to travel during a tap gesture. If the finger travels further than the defined distance and the handler hasn't yet [activated](/docs/2.x/under-the-hood/state#active), it will fail to recognize the gesture. ## Event data -See [set of event attributes from base handler class](/docs/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to the `TapGestureHandler` component: +See [set of event attributes from base handler class](/docs/2.x/gesture-handlers/common-gh#event-data). Below is a list of gesture event attributes specific to the `TapGestureHandler` component: ### `x` diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_category_.json b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_category_.json new file mode 100644 index 0000000000..26dbe96e2b --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Gestures", + "position": 3, + "link": { + "type": "generated-index" + } +} diff --git a/packages/docs-gesture-handler/docs/gestures/_shared/base-continuous-gesture-callbacks.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-continuous-gesture-callbacks.md similarity index 100% rename from packages/docs-gesture-handler/docs/gestures/_shared/base-continuous-gesture-callbacks.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-continuous-gesture-callbacks.md diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-continuous-gesture-config.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-continuous-gesture-config.md new file mode 100644 index 0000000000..f829d626e9 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-continuous-gesture-config.md @@ -0,0 +1,5 @@ +### Properties common to all continuous gestures: + +### `manualActivation(value: boolean)` + +When `true` the handler will not activate by itself even if its activation criteria are met. Instead you can manipulate its state using [state manager](/docs/2.x/gestures/state-manager/). diff --git a/packages/docs-gesture-handler/docs/gestures/_shared/base-gesture-callbacks.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-callbacks.md similarity index 100% rename from packages/docs-gesture-handler/docs/gestures/_shared/base-gesture-callbacks.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-callbacks.md diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-config.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-config.md new file mode 100644 index 0000000000..6a39d4cb75 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-config.md @@ -0,0 +1,68 @@ +### Properties common to all gestures: + +### `enabled(value: boolean)` + +Indicates whether the given handler should be analyzing stream of touch events or not. +When set to `false` we can be sure that the handler's state will **never** become [`ACTIVE`](/docs/2.x/fundamentals/states-events#active). +If the value gets updated while the handler already started recognizing a gesture, then the handler's state it will immediately change to [`FAILED`](/docs/2.x/fundamentals/states-events#failed) or [`CANCELLED`](/docs/2.x/fundamentals/states-events#cancelled) (depending on its current state). +Default value is `true`. + +### `shouldCancelWhenOutside(value: boolean)` + +When `true` the handler will [cancel](/docs/2.x/fundamentals/states-events#cancelled) or [fail](/docs/2.x/fundamentals/states-events#failed) recognition (depending on its current state) whenever the finger leaves the area of the connected view. +Default value of this property is different depending on the handler type. +Most handlers' `shouldCancelWhenOutside` property defaults to `false` except for the [`LongPressGesture`](/docs/2.x/gestures/long-press-gesture) and [`TapGesture`](/docs/2.x/gestures/tap-gesture) which default to `true`. + +### `hitSlop(settings)` + +This parameter enables control over what part of the connected view area can be used to [begin](/docs/2.x/fundamentals/states-events#began) recognizing the gesture. +When a negative number is provided the bounds of the view will reduce the area by the given number of points in each of the sides evenly. + +Instead you can pass an object to specify how each boundary side should be reduced by providing different number of points for `left`, `right`, `top` or `bottom` sides. +You can alternatively provide `horizontal` or `vertical` instead of specifying directly `left`, `right` or `top` and `bottom`. +Finally, the object can also take `width` and `height` attributes. +When `width` is set it is only allow to specify one of the sides `right` or `left`. +Similarly when `height` is provided only `top` or `bottom` can be set. +Specifying `width` or `height` is useful if we only want the gesture to activate on the edge of the view. In which case for example we can set `left: 0` and `width: 20` which would make it possible for the gesture to be recognize when started no more than 20 points from the left edge. + +**IMPORTANT:** Note that this parameter is primarily designed to reduce the area where gesture can activate. Hence it is only supported for all the values (except `width` and `height`) to be non positive (0 or lower). Although on Android it is supported for the values to also be positive and therefore allow to expand beyond view bounds but not further than the parent view bounds. To achieve this effect on both platforms you can use React Native's View [hitSlop](https://reactnative.dev/docs/view.html#hitslop) property. + +### `withRef(ref)` + +Sets a ref to the gesture object, allowing for interoperability with the old +API. + +### `withTestId(testID)` + +Sets a `testID` property for gesture object, allowing for querying for it in tests. + +### `cancelsTouchesInView(value)` (**iOS only**) + +Accepts a boolean value. +When `true`, the gesture will cancel touches for native UI components (`UIButton`, `UISwitch`, etc) it's attached to when it becomes [`ACTIVE`](/docs/2.x/fundamentals/states-events#active). +Default value is `true`. + +### `runOnJS(value: boolean)` + +When `react-native-reanimated` is installed, the callbacks passed to the gestures are automatically workletized and run on the UI thread when called. This option allows for changing this behavior: when `true`, all the callbacks will be run on the JS thread instead of the UI thread, regardless of whether they are worklets or not. +Defaults to `false`. + +### `simultaneousWithExternalGesture(otherGesture1, otherGesture2, ...)` + +Adds a gesture that should be recognized simultaneously with this one. + +**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/2.x/fundamentals/gesture-composition). [`GestureDetector`](/docs/2.x/gestures/gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized. + +### `requireExternalGestureToFail(otherGesture1, otherGesture2, ...)` + +Adds a relation requiring another gesture to fail, before this one can activate. + +### `blocksExternalGesture(otherGesture1, otherGesture2, ...)` + +Adds a relation that makes other gestures wait with activation until this gesture fails (or doesn't start at all). + +**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/2.x/fundamentals/gesture-composition).[`GestureDetector`](/docs/2.x/gestures/gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized. + +### `activeCursor(value)` (Web only) + +This parameter allows to specify which cursor should be used when gesture activates. Supports all CSS cursor values (e.g. `"grab"`, `"zoom-in"`). Default value is set to `"auto"`. diff --git a/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-event-data.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-event-data.md new file mode 100644 index 0000000000..674f2fb478 --- /dev/null +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/base-gesture-event-data.md @@ -0,0 +1,19 @@ +### Event attributes common to all gestures: + +### `state` + +Current [state](/docs/2.x/fundamentals/states-events) of the handler. Expressed as one of the constants exported under `State` object by the library. + +### `numberOfPointers` + +Represents the number of pointers (fingers) currently placed on the screen. + +### `pointerType` + +Indicates the type of pointer device in use. This value is represented by the `PointerType` enum, which includes the following fields: + +- `TOUCH` - represents finger +- `STYLUS` - represents stylus or digital pen +- `MOUSE` - represents computer mouse +- `KEY` - represents keyboard +- `OTHER` - represents unknown device type that is not relevant diff --git a/packages/docs-gesture-handler/docs/gestures/_shared/gesture-detector-functional1.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/gesture-detector-functional1.md similarity index 100% rename from packages/docs-gesture-handler/docs/gestures/_shared/gesture-detector-functional1.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/_shared/gesture-detector-functional1.md diff --git a/packages/docs-gesture-handler/docs/gestures/composed-gestures.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/composed-gestures.md similarity index 88% rename from packages/docs-gesture-handler/docs/gestures/composed-gestures.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/composed-gestures.md index f9fd18f36a..5eb0ef45c5 100644 --- a/packages/docs-gesture-handler/docs/gestures/composed-gestures.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/composed-gestures.md @@ -5,7 +5,7 @@ sidebar_label: Composed gestures sidebar_position: 13 --- -Composed gestures (`Race`, `Simultaneous`, `Exclusive`) provide a simple way of building relations between gestures. See [Gesture Composition](/docs/fundamentals/gesture-composition) for more details. +Composed gestures (`Race`, `Simultaneous`, `Exclusive`) provide a simple way of building relations between gestures. See [Gesture Composition](/docs/2.x/fundamentals/gesture-composition) for more details. ## Reference diff --git a/packages/docs-gesture-handler/docs/gestures/fling-gesture.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/fling-gesture.md similarity index 94% rename from packages/docs-gesture-handler/docs/gestures/fling-gesture.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/fling-gesture.md index fef89e4868..58a6812429 100644 --- a/packages/docs-gesture-handler/docs/gestures/fling-gesture.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/fling-gesture.md @@ -30,8 +30,8 @@ import BaseEventConfig from './\_shared/base-gesture-config.md'; import BaseEventCallbacks from './\_shared/base-gesture-callbacks.md'; A discrete gesture that activates when the movement is sufficiently long and fast. -Gesture gets [ACTIVE](/docs/fundamentals/states-events#active) when movement is sufficiently long and it does not take too much time. -When gesture gets activated it will turn into [END](/docs/fundamentals/states-events#end) state when finger is released. +Gesture gets [ACTIVE](/docs/2.x/fundamentals/states-events#active) when movement is sufficiently long and it does not take too much time. +When gesture gets activated it will turn into [END](/docs/2.x/fundamentals/states-events#end) state when finger is released. The gesture will fail to recognize if the finger is lifted before being activated.
diff --git a/packages/docs-gesture-handler/docs/gestures/force-touch-gesture.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/force-touch-gesture.md similarity index 84% rename from packages/docs-gesture-handler/docs/gestures/force-touch-gesture.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/force-touch-gesture.md index d3f85e6edd..8227c7dea2 100644 --- a/packages/docs-gesture-handler/docs/gestures/force-touch-gesture.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/force-touch-gesture.md @@ -16,7 +16,7 @@ import BaseEventCallbacks from './\_shared/base-gesture-callbacks.md'; import BaseContinuousEventCallbacks from './\_shared/base-continuous-gesture-callbacks.md'; A continuous gesture that recognizes force of a touch. It allows for tracking pressure of touch on some iOS devices. -The gesture [activates](/docs/fundamentals/states-events#active) when pressure of touch is greater than or equal to `minForce`. It fails if pressure is greater than `maxForce`. +The gesture [activates](/docs/2.x/fundamentals/states-events#active) when pressure of touch is greater than or equal to `minForce`. It fails if pressure is greater than `maxForce`. Gesture callback can be used for continuous tracking of the touch pressure. It provides information for one finger (the first one). At the beginning of the gesture, the pressure factor is 0.0. As the pressure increases, the pressure factor increases proportionally. The maximum pressure is 1.0. @@ -47,11 +47,11 @@ function App() { ### `minForce(value: number)` -A minimal pressure that is required before gesture can [activate](/docs/fundamentals/states-events#active). Should be a value from range `[0.0, 1.0]`. Default is `0.2`. +A minimal pressure that is required before gesture can [activate](/docs/2.x/fundamentals/states-events#active). Should be a value from range `[0.0, 1.0]`. Default is `0.2`. ### `maxForce(value: number)` -A maximal pressure that could be applied for gesture. If the pressure is greater, gesture [fails](/docs/fundamentals/states-events#failed). Should be a value from range `[0.0, 1.0]`. +A maximal pressure that could be applied for gesture. If the pressure is greater, gesture [fails](/docs/2.x/fundamentals/states-events#failed). Should be a value from range `[0.0, 1.0]`. ### `feedbackOnActivation(value: boolean)` diff --git a/packages/docs-gesture-handler/docs/gestures/gesture-detector.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/gesture-detector.md similarity index 93% rename from packages/docs-gesture-handler/docs/gestures/gesture-detector.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/gesture-detector.md index cd8ca83a7d..a4184af36b 100644 --- a/packages/docs-gesture-handler/docs/gestures/gesture-detector.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/gesture-detector.md @@ -35,7 +35,7 @@ A gesture object containing the configuration and callbacks. Can be any of the b :::info GestureDetector will decide whether to use Reanimated to process provided gestures based on callbacks they have. If any of the callbacks is a worklet, tools provided by the Reanimated will be utilized bringing ability to handle gestures synchronously. -Starting with Reanimated 2.3.0 Gesture Handler will provide a [StateManager](/docs/gestures/state-manager) in the [touch events](/docs/gestures/touch-events) that allows for managing the state of the gesture. +Starting with Reanimated 2.3.0 Gesture Handler will provide a [StateManager](/docs/2.x/gestures/state-manager) in the [touch events](/docs/2.x/gestures/touch-events) that allows for managing the state of the gesture. ::: ### `userSelect` (Web only) @@ -66,7 +66,9 @@ Specifies whether context menu should be enabled after clicking on underlying vi - {/* Don't do this! */} + + {' '} + {/* Don't do this! */} diff --git a/packages/docs-gesture-handler/docs/gestures/gesture.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/gesture.md similarity index 66% rename from packages/docs-gesture-handler/docs/gestures/gesture.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/gesture.md index 08bc5888d7..94454ad961 100644 --- a/packages/docs-gesture-handler/docs/gestures/gesture.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/gesture.md @@ -26,43 +26,43 @@ function App() { ### Gesture.Tap() -Creates a new instance of [`TapGesture`](/docs/gestures/tap-gesture.md) with its default config and no callbacks. +Creates a new instance of [`TapGesture`](/docs/2.x/gestures/tap-gesture) with its default config and no callbacks. ### Gesture.Pan() -Creates a new instance of [`PanGesture`](/docs/gestures/pan-gesture.md) with its default config and no callbacks. +Creates a new instance of [`PanGesture`](/docs/2.x/gestures/pan-gesture) with its default config and no callbacks. ### Gesture.LongPress() -Creates a new instance of [`LongPressGesture`](/docs/gestures/long-press-gesture.md) with its default config and no callbacks. +Creates a new instance of [`LongPressGesture`](/docs/2.x/gestures/long-press-gesture) with its default config and no callbacks. ### Gesture.Fling() -Creates a new instance of [`FlingGesture`](/docs/gestures/fling-gesture.md) with its default config and no callbacks. +Creates a new instance of [`FlingGesture`](/docs/2.x/gestures/fling-gesture) with its default config and no callbacks. ### Gesture.Pinch() -Creates a new instance of [`PinchGesture`](/docs/gestures/pinch-gesture.md) with its default config and no callbacks. +Creates a new instance of [`PinchGesture`](/docs/2.x/gestures/pinch-gesture) with its default config and no callbacks. ### Gesture.Rotation() -Creates a new instance of [`RotationGesture`](/docs/gestures/rotation-gesture.md) with its default config and no callbacks. +Creates a new instance of [`RotationGesture`](/docs/2.x/gestures/rotation-gesture) with its default config and no callbacks. ### Gesture.Hover() -Creates a new instance of [`HoverGesture`](/docs/gestures/hover-gesture.md) with its default config and no callbacks. +Creates a new instance of [`HoverGesture`](/docs/2.x/gestures/hover-gesture) with its default config and no callbacks. ### Gesture.ForceTouch() -Creates a new instance of [`ForceTouchGesture`](/docs/gestures/force-touch-gesture.md) with its default config and no callbacks. +Creates a new instance of [`ForceTouchGesture`](/docs/2.x/gestures/force-touch-gesture) with its default config and no callbacks. ### Gesture.Manual() -Creates a new instance of [`ManualGesture`](/docs/gestures/manual-gesture.md) with its default config and no callbacks. +Creates a new instance of [`ManualGesture`](/docs/2.x/gestures/manual-gesture) with its default config and no callbacks. ### Gesture.Native() -Creates a new instance of [`NativeGesture`](/docs/gestures/native-gesture.md) with its default config and no callbacks. +Creates a new instance of [`NativeGesture`](/docs/2.x/gestures/native-gesture) with its default config and no callbacks. ### Gesture.Race(gesture1, gesture2, gesture3, ...): ComposedGesture diff --git a/packages/docs-gesture-handler/docs/gestures/hover-gesture.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/hover-gesture.md similarity index 92% rename from packages/docs-gesture-handler/docs/gestures/hover-gesture.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/hover-gesture.md index 5ad5628dca..6b794fd4bf 100644 --- a/packages/docs-gesture-handler/docs/gestures/hover-gesture.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/hover-gesture.md @@ -59,10 +59,9 @@ function App() { } ``` - ## Remarks -- Don't rely on `Hover` gesture to continue after the mouse button is clicked or the stylus touches the screen. If you want to handle both cases, [compose](/docs/fundamentals/gesture-composition) it with [`Pan` gesture](/docs/gestures/pan-gesture). +- Don't rely on `Hover` gesture to continue after the mouse button is clicked or the stylus touches the screen. If you want to handle both cases, [compose](/docs/2.x/fundamentals/gesture-composition) it with [`Pan` gesture](/docs/2.x/gestures/pan-gesture). ## Config @@ -95,11 +94,11 @@ Defaults to `HoverEffect.None` ### `x` -X coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/gestures/gesture-detector). Expressed in point units. +X coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/2.x/gestures/gesture-detector). Expressed in point units. ### `y` -Y coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/gestures/gesture-detector). Expressed in point units. +Y coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/2.x/gestures/gesture-detector). Expressed in point units. ### `absoluteX` diff --git a/packages/docs-gesture-handler/docs/gestures/long-press-gesture.md b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/long-press-gesture.md similarity index 84% rename from packages/docs-gesture-handler/docs/gestures/long-press-gesture.md rename to packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/long-press-gesture.md index f92814e255..61f5431703 100644 --- a/packages/docs-gesture-handler/docs/gestures/long-press-gesture.md +++ b/packages/docs-gesture-handler/versioned_docs/version-2.x/gestures/long-press-gesture.md @@ -30,8 +30,8 @@ import BaseEventConfig from './\_shared/base-gesture-config.md'; import BaseEventCallbacks from './\_shared/base-gesture-callbacks.md'; A discrete gesture that activates when the corresponding view is pressed for a sufficiently long time. -This gesture's state will turn into [END](/docs/fundamentals/states-events#end) immediately after the finger is released. -The gesture will fail to recognize a touch event if the finger is lifted before the [minimum required time](/docs/gestures/long-press-gesture#mindurationvalue-number) or if the finger is moved further than the [allowable distance](/docs/gestures/long-press-gesture#maxdistancevalue-number). +This gesture's state will turn into [END](/docs/2.x/fundamentals/states-events#end) immediately after the finger is released. +The gesture will fail to recognize a touch event if the finger is lifted before the [minimum required time](/docs/2.x/gestures/long-press-gesture#mindurationvalue-number) or if the finger is moved further than the [allowable distance](/docs/2.x/gestures/long-press-gesture#maxdistancevalue-number).