diff --git a/.circleci/Dockerfiles/Dockerfile.android b/.circleci/Dockerfiles/Dockerfile.android index 8d0e28803a5fc8..74e062c88cc5c8 100644 --- a/.circleci/Dockerfiles/Dockerfile.android +++ b/.circleci/Dockerfiles/Dockerfile.android @@ -21,7 +21,6 @@ LABEL maintainer="Héctor Ramos " # set default environment variables ENV GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs=\"-Xmx512m -XX:+HeapDumpOnOutOfMemoryError\"" -ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8" ENV KOTLIN_HOME="third-party/kotlin" ADD .buckconfig /app/.buckconfig diff --git a/.circleci/config.yml b/.circleci/config.yml index a5e010bc47c79a..2aa83b58a5b508 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,13 +47,27 @@ references: checkout_cache_key: &checkout_cache_key v1-checkout gems_cache_key: &gems_cache_key v1-gems-{{ checksum "Gemfile.lock" }} gradle_cache_key: &gradle_cache_key v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }} - hermes_cache_key: &hermes_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_workspace_cache_key: &hermes_workspace_cache_key v4-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_workspace_debug_cache_key: &hermes_workspace_debug_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-debug-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }} hermes_windows_cache_key: &hermes_windows_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "tmp/hermes/hermesversion" }} - hermes_tarball_cache_key: &hermes_tarball_cache_key v3-hermes-tarball-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v2-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }} + hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v1-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }} pods_cache_key: &pods_cache_key v8-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }} windows_yarn_cache_key: &windows_yarn_cache_key v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} yarn_cache_key: &yarn_cache_key v5-yarn-cache-{{ .Environment.CIRCLE_JOB }} + cache_paths: + hermes_workspace_macos_cache_paths: &hermes_workspace_macos_cache_paths + - ~/react-native/sdks/hermes/build_host_hermesc + - ~/react-native/sdks/hermes/build_iphoneos + - ~/react-native/sdks/hermes/build_catalyst + - ~/react-native/sdks/hermes/build_iphonesimulator + - ~/react-native/sdks/hermes/build_macosx + - ~/react-native/sdks/hermes/destroot + hermes_tarball_cache_paths: &hermes_tarball_cache_paths + - /tmp/hermes/hermes-runtime-darwin/ + # ------------------------- # Filters # ------------------------- @@ -173,12 +187,6 @@ commands: - ~/.cache/yarn key: << parameters.yarn_base_cache_key >>-{{ arch }}-{{ checksum "yarn.lock" }} - install_github_bot_deps: - steps: - - run: - name: "Yarn: Install dependencies (GitHub bots)" - command: cd bots && yarn install --non-interactive --cache-folder ~/.cache/yarn - brew_install: parameters: package: @@ -247,7 +255,6 @@ commands: type: enum enum: ["android", "ios"] steps: - - install_github_bot_deps - run: name: Report size of RNTester.app (analysis-bot) command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" scripts/circleci/report-bundle-size.sh << parameters.platform >> || true @@ -259,34 +266,68 @@ commands: set_tarball_path: type: boolean default: False + flavor: + type: string + default: "Debug" steps: - - restore_cache: - keys: - - *hermes_tarball_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - restore_cache: + keys: + - *hermes_tarball_debug_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - restore_cache: + keys: + - *hermes_tarball_release_cache_key - when: condition: << parameters.set_tarball_path >> steps: - run: - name: Set HERMES_TARBALL_PATH if present + name: Set HERMES_ENGINE_TARBALL_PATH if present command: | BASE_PATH=/tmp/hermes/hermes-runtime-darwin/ if [ ! -d $BASE_PATH ]; then echo "Hermes tarball base path not present ($BASE_PATH). Build it from source." exit 0 fi - TARBALL=$(ls /tmp/hermes/hermes-runtime-darwin/) - TARBALL_PATH=$BASE_PATH$TARBALL + if [[ << parameters.flavor >> == "Debug" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-debug-*.tar.gz + elif [[ << parameters.flavor >> == "Release" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-release-*.tar.gz + else + echo "Unsupported build type << parameters.flavor >>." + exit 0 + fi + # /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-release-v0.70.0.tar.gz + # /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-debug-v0.70.0.tar.gz + TARBALL_PATH=$(ls $BASE_PATH$TARBALL_FILENAME) if [ ! -f $TARBALL_PATH ]; then echo "Hermes tarball not present ($TARBALL_PATH). Build it from source." exit 0 fi + echo "Found Hermes tarball at $TARBALL_PATH" echo "export HERMES_ENGINE_TARBALL_PATH=$TARBALL_PATH" >> $BASH_ENV - steps: << parameters.steps >> - - save_cache: - key: *hermes_tarball_cache_key - paths: - - /tmp/hermes/hermes-runtime-darwin/ + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - save_cache: + key: *hermes_tarball_debug_cache_key + paths: *hermes_tarball_cache_paths + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - save_cache: + key: *hermes_tarball_release_cache_key + paths: *hermes_tarball_cache_paths # ------------------------- # JOBS @@ -304,7 +345,6 @@ jobs: - checkout - run_yarn - - install_github_bot_deps # Note: The yarn gpg key needs to be refreshed to work around https://github.com/yarnpkg/yarn/issues/7866 - run: @@ -353,6 +393,11 @@ jobs: command: yarn flow-check-android when: always + - run: + name: Run TypeScript tests + command: yarn test-typescript + when: always + - run: name: Sanity checks command: | @@ -653,6 +698,9 @@ jobs: newarchitecture: type: boolean default: false + jsengine: + type: string + default: "Hermes" environment: - PROJECT_NAME: "AndroidTemplateProject" steps: @@ -660,6 +708,16 @@ jobs: - run_yarn - attach_workspace: at: . + - when: + condition: + equal: ["JSC", << parameters.jsengine >>] + steps: + - run: + name: Set enableHermes in buld.gradle to false + command: | + node ./scripts/set-rn-engine.js -e jsc + echo "Hermes disabled." + grep enableHermes: template/android/app/build.gradle - run: name: Create Android template project @@ -671,7 +729,7 @@ jobs: yarn - run: - name: Build the template application for << parameters.flavor >> with New Architecture set << parameters.newarchitecture >> + name: Build the template application for << parameters.flavor >> with New Architecture set to << parameters.newarchitecture >>, and using the << parameters.jsengine>> JS engine. command: cd /tmp/$PROJECT_NAME/android/ && ./gradlew assemble<< parameters.flavor >> -PnewArchEnabled=<< parameters.newarchitecture >> # ------------------------- @@ -689,11 +747,24 @@ jobs: jsengine: type: string default: "Hermes" + flipper: + type: string + default: "WithFlipper" environment: - PROJECT_NAME: "iOSTemplateProject" - HERMES_WS_DIR: *hermes_workspace_root - steps: + # Early exit in case of Release and WithFlipper. The two does not make sense together. + # Unfortunately, the `exclude` parameter of `matrix` does not work, so we have to do it manually. + - when: + condition: + and: + - equal: [ << parameters.flavor >>, "Release"] + - equal: [ << parameters.flipper >>, "WithFlipper" ] + steps: + - run: + command: circleci-agent step halt # this interrupts the job successfully. + # Valid configuration, we can continue - checkout_code_with_cache - run_yarn - attach_workspace: @@ -716,7 +787,7 @@ jobs: node ./scripts/set-rn-template-version.js "file:$PATH_TO_PACKAGE" node cli.js init $PROJECT_NAME --directory "/tmp/$PROJECT_NAME" --template $REPO_ROOT --verbose --skip-install - run: - name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>> + name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>>; Flipper << parameters.flipper >> command: | cd /tmp/$PROJECT_NAME yarn install @@ -736,6 +807,10 @@ jobs: export USE_HERMES=0 fi + if [[ << parameters.flipper >> == "WithoutFlipper" ]]; then + export NO_FLIPPER=1 + fi + bundle exec pod install - run: name: Build template project @@ -812,16 +887,19 @@ jobs: - checkout_code_with_cache - run: - name: Install Node + name: Disable NVM + # Use choco to manage node versions due to https://github.com/npm/cli/issues/4234 + command: nvm off + + - run: + name: Install Node JS # Note: Version set separately for non-Windows builds, see above. - command: | - nvm install 16 - nvm use 16 + command: choco install nodejs-lts # Setup Dependencies - run: - name: Install Yarn - command: choco install yarn + name: Enable Yarn with corepack + command: corepack enable - run: name: Display Environment info @@ -905,7 +983,7 @@ jobs: # ------------------------- prepare_hermes_workspace: docker: - - image: debian:bullseye + - image: debian:11 environment: - HERMES_WS_DIR: *hermes_workspace_root - HERMES_VERSION_FILE: "sdks/.hermesversion" @@ -933,7 +1011,7 @@ jobs: fi cat /tmp/hermes/hermesversion - restore_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key - run: name: Download Hermes tarball command: | @@ -943,7 +1021,7 @@ jobs: cat /tmp/hermes/hermesversion - save_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key paths: - /tmp/hermes/download/ - /tmp/hermes/hermes/ @@ -968,7 +1046,7 @@ jobs: libreadline-dev libicu-dev zip python3 - *attach_hermes_workspace - restore_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key - run: name: Set up workspace command: | @@ -987,7 +1065,7 @@ jobs: cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/. fi - save_cache: - key: *hermes_cache_key + key: *hermes_workspace_cache_key paths: - /tmp/hermes/linux64-bin/ - /tmp/hermes/hermes/destroot/ @@ -999,61 +1077,98 @@ jobs: - linux64-bin build_hermes_macos: + parameters: + flavor: + type: string + default: "Debug" executor: reactnativeios environment: - HERMES_WS_DIR: *hermes_workspace_root steps: - checkout_code_with_cache - *attach_hermes_workspace - - restore_cache: - key: *hermes_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - restore_cache: + keys: + - *hermes_workspace_debug_cache_key + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - restore_cache: + keys: + - *hermes_workspace_release_cache_key - run: name: Set up workspace command: | mkdir -p /tmp/hermes/osx-bin mkdir -p ~/react-native/sdks/hermes cp -r $HERMES_WS_DIR/hermes/* ~/react-native/sdks/hermes/. - - run: - name: Install dependencies - command: | - brew install cmake + - brew_install: + package: cmake - with_hermes_tarball_cache_span: + flavor: << parameters.flavor >> steps: - run: name: Build the Hermes iOS frameworks command: | cd ~/react-native/sdks/hermes - ./utils/build-ios-framework.sh + BUILD_TYPE="<< parameters.flavor >>" ./utils/build-ios-framework.sh - run: name: Build the Hermes Mac frameworks command: | cd ~/react-native/sdks/hermes - ./utils/build-mac-framework.sh + BUILD_TYPE="<< parameters.flavor >>" ./utils/build-mac-framework.sh cp build_macosx/bin/hermesc /tmp/hermes/osx-bin/. - run: name: Package the Hermes Apple frameworks command: | + echo "Packaging Hermes Apple frameworks for << parameters.flavor >> build type" + cd ~/react-native/sdks/hermes - . ./utils/build-apple-framework.sh + BUILD_TYPE="<< parameters.flavor >>" source ./utils/build-apple-framework.sh mkdir -p /tmp/cocoapods-package-root/destroot mkdir -p /tmp/hermes/output cp -R ./destroot /tmp/cocoapods-package-root cp LICENSE /tmp/cocoapods-package-root - tar -C /tmp/cocoapods-package-root/ -czvf /tmp/hermes/output/hermes-runtime-darwin-v$(get_release_version).tar.gz . + if [[ << parameters.flavor >> == "Debug" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-debug-v$(get_release_version).tar.gz + elif [[ << parameters.flavor >> == "Release" ]]; then + TARBALL_FILENAME=hermes-runtime-darwin-release-v$(get_release_version).tar.gz + else + echo "Unsupported build type << parameters.flavor >>." + exit 0 + fi + + tar -C /tmp/cocoapods-package-root/ -czvf /tmp/hermes/output/$TARBALL_FILENAME . mkdir -p /tmp/hermes/hermes-runtime-darwin - cp /tmp/hermes/output/hermes-runtime-darwin-v$(get_release_version).tar.gz /tmp/hermes/hermes-runtime-darwin/. - - save_cache: - key: *hermes_cache_key - paths: - - ~/react-native/sdks/hermes/build_host_hermesc - - ~/react-native/sdks/hermes/build_iphoneos - - ~/react-native/sdks/hermes/build_catalyst - - ~/react-native/sdks/hermes/build_iphonesimulator - - ~/react-native/sdks/hermes/build_macosx - - ~/react-native/sdks/hermes/destroot + cp /tmp/hermes/output/$TARBALL_FILENAME /tmp/hermes/hermes-runtime-darwin/. + + # TODO: Remove this once the client side is aware of -release and -debug tarballs + if [[ << parameters.flavor >> == "Debug" ]]; then + cp /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-debug-v$(get_release_version).tar.gz /tmp/hermes/hermes-runtime-darwin/hermes-runtime-darwin-v$(get_release_version).tar.gz + fi + ls /tmp/hermes/hermes-runtime-darwin/ + - when: + condition: + equal: [ << parameters.flavor >>, "Debug"] + steps: + - save_cache: + key: *hermes_workspace_debug_cache_key + paths: *hermes_workspace_macos_cache_paths + - when: + condition: + equal: [ << parameters.flavor >>, "Release"] + steps: + - save_cache: + key: *hermes_workspace_release_cache_key + paths: *hermes_workspace_macos_cache_paths - store_artifacts: path: /tmp/hermes/hermes-runtime-darwin/ - store_artifacts: @@ -1240,7 +1355,6 @@ jobs: condition: matches: { pattern: '^pull\/.*$', value: << pipeline.git.branch >> } steps: - - install_github_bot_deps - run: name: Post link to PR build artifacts (pull-bot) command: GITHUB_TOKEN="$PUBLIC_PULLBOT_GITHUB_TOKEN_A""$PUBLIC_PULLBOT_GITHUB_TOKEN_B" scripts/circleci/post-artifacts-link.sh || true @@ -1337,6 +1451,7 @@ workflows: matrix: parameters: newarchitecture: [true, false] + jsengine: ["Hermes", "JSC"] flavor: ["Debug", "Release"] - test_buck - test_ios_template: @@ -1347,6 +1462,7 @@ workflows: architecture: ["NewArch", "OldArch"] flavor: ["Debug", "Release"] jsengine: ["Hermes", "JSC"] + flipper: ["WithFlipper", "WithoutFlipper"] - test_ios_rntester: requires: - build_hermes_macos @@ -1390,6 +1506,9 @@ workflows: filters: *only_release_tags requires: - prepare_hermes_workspace + matrix: + parameters: + flavor: ["Debug", "Release"] - build_hermesc_windows: filters: *only_release_tags requires: diff --git a/.circleci/verdaccio.yml b/.circleci/verdaccio.yml new file mode 100644 index 00000000000000..37e5d23b380227 --- /dev/null +++ b/.circleci/verdaccio.yml @@ -0,0 +1,44 @@ +storage: ./storage +auth: + htpasswd: + file: ./htpasswd +uplinks: + npmjs: + url: https://registry.npmjs.org/ + max_fails: 40 + maxage: 30m + timeout: 60s + fail_timeout: 10m + cache: false + agent_options: + keepAlive: true + maxSockets: 40 + maxFreeSockets: 10 +packages: + # Group and isolate all local packages, avoid being proxy from outside + '@react-native/*': + access: $all + publish: $all + # The below specific entries can be removed once they are renamed and have the @react-native prefix + '@react-native-community/eslint-config': + access: $all + publish: $all + '@react-native-community/eslint-plugin': + access: $all + publish: $all + 'react-native-codegen': + access: $all + publish: $all + 'react-native-gradle-plugin': + access: $all + publish: $all + '@*/*': + access: $all + publish: $authenticated + proxy: npmjs + '**': + access: $all + publish: $all + proxy: npmjs +logs: + - {type: file, path: verdaccio.log, format: json, level: warn} diff --git a/.eslintignore b/.eslintignore index 11d4192591a096..55ea7e257b58bd 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,5 @@ **/main.js **/staticBundle.js -bots/node_modules docs/generatedComponentApiDocs.js flow/ flow-typed/ diff --git a/.eslintrc.js b/.eslintrc.js index d07d0d884c0b5c..c2adaccf1a2edc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -71,5 +71,17 @@ module.exports = { jest: true, }, }, + { + files: ['types/**/*.{ts,tsx}'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint/eslint-plugin'], + rules: { + '@typescript-eslint/no-unused-vars': 'off', + 'react-native/no-inline-styles': 'off', + '@typescript-eslint/no-shadow': 'off', + 'no-self-compare': 'off', + 'react/self-closing-comp': 'off', + }, + }, ], }; diff --git a/.flowconfig b/.flowconfig index c7c1c4d19621e2..e12ccbe8b78b71 100644 --- a/.flowconfig +++ b/.flowconfig @@ -6,7 +6,7 @@ /template/.* ; Ignore the Dangerfile -/bots/dangerfile.js +/packages/react-native-bots/dangerfile.js ; Ignore "BUCK" generated dirs /\.buckd/ @@ -74,4 +74,4 @@ untyped-import untyped-type-import [version] -^0.186.0 +^0.187.1 diff --git a/.flowconfig.android b/.flowconfig.android index a3572186109c56..e7ea8692d40289 100644 --- a/.flowconfig.android +++ b/.flowconfig.android @@ -6,7 +6,7 @@ /template/.* ; Ignore the Dangerfile -/bots/dangerfile.js +/packages/react-native-bots/dangerfile.js ; Ignore "BUCK" generated dirs /\.buckd/ @@ -74,4 +74,4 @@ untyped-import untyped-type-import [version] -^0.186.0 +^0.187.1 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 38dbd76f893b2b..113169229179c8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,7 +9,7 @@ # GitHub Settings, Bots /.github/ @hramos -/bots @hramos +/packages/react-native-bots @hramos # Continuous Integration /.circleci/ @hramos diff --git a/.github/workflows/autorebase.yml b/.github/workflows/autorebase.yml index 9cb17dd30d652a..cf0f7f130e1891 100644 --- a/.github/workflows/autorebase.yml +++ b/.github/workflows/autorebase.yml @@ -2,8 +2,13 @@ name: Automatic Rebase on: issue_comment: types: [created] +permissions: + contents: read jobs: rebase: + permissions: + contents: write # for cirrus-actions/rebase to push code to rebase + pull-requests: read # for cirrus-actions/rebase to get info about PR name: Rebase if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') runs-on: ubuntu-latest diff --git a/.github/workflows/danger_pr.yml b/.github/workflows/danger_pr.yml index b1fc1097c9a80e..06f8a2e830201c 100644 --- a/.github/workflows/danger_pr.yml +++ b/.github/workflows/danger_pr.yml @@ -20,11 +20,8 @@ jobs: - name: Run Yarn Install on Root run: yarn install working-directory: . - - name: Run Yarn Install inside Bots - run: yarn install - working-directory: bots - name: Danger run: yarn danger ci --use-github-checks --failOnErrors - working-directory: bots + working-directory: packages/react-native-bots env: DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index c954afb75a0f3b..c0c9c37bdca05b 100644 --- a/.gitignore +++ b/.gitignore @@ -68,7 +68,6 @@ local.properties node_modules *.log .nvm -/bots/node_modules/ package-lock.json # OS X @@ -111,9 +110,11 @@ package-lock.json # react-native-codegen /React/FBReactNativeSpec/FBReactNativeSpec /packages/react-native-codegen/lib +/packages/react-native-codegen/tmp/ /ReactCommon/react/renderer/components/rncore/ /packages/rn-tester/NativeModuleExample/ScreenshotManagerSpec* + # Additional SDKs /sdks/download /sdks/hermes diff --git a/BUCK b/BUCK index a9be35d9b64393..978528e13b49b4 100644 --- a/BUCK +++ b/BUCK @@ -251,6 +251,7 @@ REACT_PUBLIC_HEADERS = { "React/RCTBorderStyle.h": RCTVIEWS_PATH + "RCTBorderStyle.h", "React/RCTBridge+Private.h": RCTBASE_PATH + "RCTBridge+Private.h", "React/RCTBridge.h": RCTBASE_PATH + "RCTBridge.h", + "React/RCTBridgeConstants.h": RCTBASE_PATH + "RCTBridgeConstants.h", "React/RCTBridgeDelegate.h": RCTBASE_PATH + "RCTBridgeDelegate.h", "React/RCTBridgeMethod.h": RCTBASE_PATH + "RCTBridgeMethod.h", "React/RCTBridgeModule.h": RCTBASE_PATH + "RCTBridgeModule.h", @@ -338,6 +339,7 @@ REACT_PUBLIC_HEADERS = { "React/RCTSurfaceView.h": RCTBASE_PATH + "Surface/RCTSurfaceView.h", "React/RCTTextDecorationLineType.h": RCTVIEWS_PATH + "RCTTextDecorationLineType.h", "React/RCTTouchHandler.h": RCTBASE_PATH + "RCTTouchHandler.h", + "React/RCTTurboModuleRegistry.h": RCTBASE_PATH + "RCTTurboModuleRegistry.h", "React/RCTUIManager.h": RCTMODULES_PATH + "RCTUIManager.h", "React/RCTUIManagerObserverCoordinator.h": RCTMODULES_PATH + "RCTUIManagerObserverCoordinator.h", "React/RCTUIManagerUtils.h": RCTMODULES_PATH + "RCTUIManagerUtils.h", @@ -603,6 +605,7 @@ rn_apple_library( ], inherited_buck_flags = get_static_library_ios_flags(), labels = [ + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], @@ -828,6 +831,7 @@ rn_apple_library( "depslint_never_remove", # Some old NativeModule still relies on +load unfortunately. "disable_plugins_only_validation", "extension_api_allow_unsafe_unavailable_usages", + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], @@ -878,6 +882,7 @@ rn_apple_library( labels = [ "depslint_never_remove", # Some old NativeModule still relies on +load unfortunately. "disable_plugins_only_validation", + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], @@ -937,6 +942,7 @@ rn_apple_library( "depslint_never_remove", # Some old NativeModule still relies on +load unfortunately. "disable_plugins_only_validation", "extension_api_allow_unsafe_unavailable_usages", + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], @@ -985,6 +991,7 @@ rn_apple_library( "depslint_never_remove", # Some old NativeModule still relies on +load unfortunately. "disable_plugins_only_validation", "extension_api_allow_unsafe_unavailable_usages", + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], @@ -1037,6 +1044,7 @@ rn_apple_library( "depslint_never_remove", # Some old NativeModule still relies on +load unfortunately. "disable_plugins_only_validation", "extension_api_allow_unsafe_unavailable_usages", + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], @@ -1118,6 +1126,7 @@ rn_apple_library( "depslint_never_remove", # Some old NativeModule still relies on +load unfortunately. "disable_plugins_only_validation", "extension_api_allow_unsafe_unavailable_usages", + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], @@ -1285,6 +1294,7 @@ rn_apple_library( labels = [ "depslint_never_remove", "disable_plugins_only_validation", + "fbios_link_group:xplat/default/public.react_native.infra", "pfh:ReactNative_CommonInfrastructurePlaceholder", "supermodule:xplat/default/public.react_native.infra", ], diff --git a/CHANGELOG.md b/CHANGELOG.md index d17b15bbf4c6a0..24e721adc63caa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,225 @@ # Changelog +## v0.70.1 + +### Added + +- Add more debugging settings for *HermesExecutorFactory* ([32d12e89f8](https://github.com/facebook/react-native/commit/32d12e89f864a106433c8e54c10691d7876333ee) by [@Kudo](https://github.com/Kudo)) +- Support TypeScript array types for turbo module (component only) ([33d1291e1a](https://github.com/facebook/react-native/commit/33d1291e1a96497a4f994e9d622248a745ee1ea6) by [@ZihanChen-MSFT](https://github.com/ZihanChen-MSFT)) + +### Changed + +- Accept TypeScript type `T | null | undefined` as a maybe type of T in turbo module. ([9ecd203eec](https://github.com/facebook/react-native/commit/9ecd203eec97e7d21d10311d950c9f8f30c7a4b1) by [@ZihanChen-MSFT](https://github.com/ZihanChen-MSFT)) +- Bump react-native-gradle-plugin to 0.70.3 ([e33633644c](https://github.com/facebook/react-native/commit/e33633644c70ea39af6e450fcf31d9458051fd5f) by [@dmytrorykun](https://github.com/dmytrorykun)) +- Bump react-native-codegen to 0.70.5 ([6a8c38eef2](https://github.com/facebook/react-native/commit/6a8c38eef272e79e52a35941afa9c3fe9e8fc191) by [@dmytrorykun](https://github.com/dmytrorykun)) +- Hermes version bump for 0.70.1 ([5132211228](https://github.com/facebook/react-native/commit/5132211228a5b9e36d58c1f7e2c99ccaabe1ba3d) by [@dmytrorykun](https://github.com/dmytrorykun)) + +### Fixed + +- Fix hermes profiler ([81564c1a3d](https://github.com/facebook/react-native/commit/81564c1a3dae4222858de2a9a34089097f665e82) by [@janicduplessis](https://github.com/janicduplessis)) + +#### Android specific + +- Support PlatformColor in borderColor ([2d5db284b0](https://github.com/facebook/react-native/commit/2d5db284b061aec33af671b25065632e20217f62) by [@danilobuerger](https://github.com/danilobuerger)) +- Avoid crash in ForwardingCookieHandler if webview is disabled ([5451cd48bd](https://github.com/facebook/react-native/commit/5451cd48bd0166ba70d516e3a11c6786bc22171a) by [@Pajn](https://github.com/Pajn)) +- Correctly resolve classes with FindClass(..) ([361b310bcc](https://github.com/facebook/react-native/commit/361b310bcc8dddbff42cf63495649291c894d661) by [@evancharlton](https://github.com/evancharlton)) + +#### iOS specific + +- Fix KeyboardAvoidingView height when "Prefer Cross-Fade Transitions" is enabled ([4b9382c250](https://github.com/facebook/react-native/commit/4b9382c250261aab89b271618f8b68083ba01785) by [@gabrieldonadel](https://github.com/gabrieldonadel)) +- Fix React module build error with swift integration on new architecture mode ([3afef3c167](https://github.com/facebook/react-native/commit/3afef3c16702cefa5115b059a08741fba255b2db) by [@Kudo](https://github.com/Kudo)) +- Fix ios pod install error ([0cae4959b7](https://github.com/facebook/react-native/commit/0cae4959b750ea051dcd04e4c9374e02b1de6e7a) by [@Romick2005](https://github.com/Romick2005)) + +## 0.70.0 + +### Breaking + +- Remove jest/preprocessor from the react-native package ([0301cb285b](https://github.com/facebook/react-native/commit/0301cb285b2e85b48a397fe58d565196654d9754) by [@motiz88](https://github.com/motiz88)) +- Remove nonstandard Promise.prototype.done ([018d5cf985](https://github.com/facebook/react-native/commit/018d5cf985497273dd700b56168cf1cf64f498d5) by [@motiz88](https://github.com/motiz88)) + +### Added + +- Support TypeScript array types for turbo module (module only) ([f0c4c291e1](https://github.com/facebook/react-native/commit/f0c4c291e12a8e76f91d3841d65291f0f1f16714) by [@ZihanChen-MSFT](https://github.com/ZihanChen-MSFT)) +- Added files for `avn`, `nodenv`, and other managers that set the node.js version in reactive native project including testing ([933fbb1b2b](https://github.com/facebook/react-native/commit/933fbb1b2b4d2b7c802bf1f2be4c47e5b442a850) by [@ramonmedel](https://github.com/ramonmedel)) +- Support BigInt in Hermes ([11bae63bb1](https://github.com/facebook/react-native/commit/11bae63bb1f833802ec6ce01342ebdd1d61e9252) by [@jpporto](https://github.com/jpporto)) +- The old Hermes instrumented stats migrated to the new one ([c37f719567](https://github.com/facebook/react-native/commit/c37f7195675df67d23c3c008ec5ab5fd7b8d0394) by [@jpporto](https://github.com/jpporto)) +- Modified **getDefaultJSExecutorFactory** method ([87cfd386cb](https://github.com/facebook/react-native/commit/87cfd386cb2e02bfa440c94706d9d0274f83070c) by [@KunalFarmah98](https://github.com/KunalFarmah98)) +- `EventEmitter#emit` now freezes the set of listeners before iterating over them, meaning listeners that are added or removed will not affect that iteration. ([e5c5dcd9e2](https://github.com/facebook/react-native/commit/e5c5dcd9e26e9443f59864d9763b049e0bda98e7) by [@yungsters](https://github.com/yungsters)) +- Added File and Blob globals to eslint community config ([d881c87231](https://github.com/facebook/react-native/commit/d881c872314e55e17b198a41c86528d79092d222) by [@shamilovtim](https://github.com/shamilovtim)) +- C++ TurboModule methods can now use mixed types ([3c569f546c](https://github.com/facebook/react-native/commit/3c569f546ca78b23fbcb9773a1273dd9710f8c60) by [@appden](https://github.com/appden)) +- Add useNativeDriver as a param for setValue for Animated ([73191edb72](https://github.com/facebook/react-native/commit/73191edb7255b1ba5e9a0955a25c14250186a676) by [@genkikondo](https://github.com/genkikondo)) +- Add `Animated.Numeric` Flow type ([9eb7629ac6](https://github.com/facebook/react-native/commit/9eb7629ac66abc23b91b81d420891d68bbd4f578) by [@motiz88](https://github.com/motiz88)) +- Add LTI annotations to function params ([c940eb0c49](https://github.com/facebook/react-native/commit/c940eb0c49518b82a3999dcac3027aa70018c763), [e7a4dbcefc](https://github.com/facebook/react-native/commit/e7a4dbcefc9e393c41f4a796d522211bc1e60b6f), [d96744e277](https://github.com/facebook/react-native/commit/d96744e27711c4fa4dfad1b5a796283a232e60af) by [@pieterv](https://github.com/pieterv)) + +#### Android specific + +- Accessibility announcement for list and grid in FlatList ([2d5882132f](https://github.com/facebook/react-native/commit/2d5882132fb2c533fe9bbba83576b8fac4aca727), [105a2397b6](https://github.com/facebook/react-native/commit/105a2397b6b187a9669ba1c028508a7bb9664009) by [@fabriziobertoglio1987](https://github.com/fabriziobertoglio1987)) +- Add READ_VOICEMAIL and WRITE_VOICEMAIL permissions to PermisionsAndroid library. ([8a2be3e143](https://github.com/facebook/react-native/commit/8a2be3e1438dd145ccb5374d6ef60811047d23aa) by [@zolbooo](https://github.com/zolbooo)) +- Add POST_NOTIFICATIONS, NEARBY_WIFI_DEVICES permission ([0a854c7c8b](https://github.com/facebook/react-native/commit/0a854c7c8b7ffc382c43fa460651a4b4de34c3c7) by [@vincent-paing](https://github.com/vincent-paing)) +- Extend the React Native Gradle plugin to accept a config from package.json ([5f3c5aa529](https://github.com/facebook/react-native/commit/5f3c5aa529ed75414eb339c3d8fd2c9628534621) by [@cortinico](https://github.com/cortinico)) +- Ability to pass a Typeface object to ReactFontManager in addition to a font resource ID ([e2dd2e2a6e](https://github.com/facebook/react-native/commit/e2dd2e2a6ed17b366a3e2ec0942ea1d82a404c5d) by [@thurn](https://github.com/thurn)) +- Option to enable lazyViewManager support with `ViewManagerOnDemandReactPackage` ([d4b59cd9d0](https://github.com/facebook/react-native/commit/d4b59cd9d02a8c4eda3ac4bf89cfe8161847adf0) by [@javache](https://github.com/javache)) +- Support for dataUri in form data ([c663c0ec9d](https://github.com/facebook/react-native/commit/c663c0ec9deee7281f819f222bb29ad79e99f3b8) by [@hetanthakkar1](https://github.com/hetanthakkar1)) +- Add android-only prop documentation at the TextInput js level. ([f2e23215ca](https://github.com/facebook/react-native/commit/f2e23215ca14c3c630aa931cdd114187589ac0fb)) +- Update template to gitignore `android/app/.cxx` ([542d43df9d](https://github.com/facebook/react-native/commit/542d43df9d84a88f742c273391f2596546b4c804) by [@leotm](https://github.com/leotm)) + +#### iOS specific + +- Add Mac Catalyst compatibility (can be enabled in Podfile) ([2fb6a3393d](https://github.com/facebook/react-native/commit/2fb6a3393d545a93518d1b2906bd9453458660a0) by [@Arkkeeper](https://github.com/Arkkeeper)) +- Enabled Hermes Intl ([3fa3aeba93](https://github.com/facebook/react-native/commit/3fa3aeba93f226b97e324f3643b98382947e5985) by [@neildhar](https://github.com/neildhar)) +- HTTP Response headers added to the error object passed to JS code. ([9eb2826f9b](https://github.com/facebook/react-native/commit/9eb2826f9beac5b7476f33e68803ca5a024867db)) +- Add userInterfaceStyle to Alert to override user interface style for iOS 13+ ([47bd78f64f](https://github.com/facebook/react-native/commit/47bd78f64f334b770edc7fabd4b9cceb07a7a503) by [@luoxuhai](https://github.com/luoxuhai)) +- Add function to cleanup codegen folders ([71692889b0](https://github.com/facebook/react-native/commit/71692889b0d89b033c07ef87ee3dbf6d62d79235) by [@cipolleschi](https://github.com/cipolleschi)) +- Cocoapods function to add the `CLANG_CXX_LANGUAGE_STANDARD` to all the targets if needed ([ca8174e15f](https://github.com/facebook/react-native/commit/ca8174e15f77cbeecb7ff7a5a583abb668817777) by [@f-meloni](https://github.com/f-meloni)) +- Support codegen from a single folder ([05aaba9514](https://github.com/facebook/react-native/commit/05aaba95145df0b7f541e391a9f64ba3402cac35) by [@cipolleschi](https://github.com/cipolleschi)) +- Run script phases tests in CI ([c171a6e157](https://github.com/facebook/react-native/commit/c171a6e1572f64b2ab9b26d431c07581d4ae832b) by [@cipolleschi](https://github.com/cipolleschi)) + +### Changed + +- Bump React Native Codegen to 0.70.0 ([a22ceecc84](https://github.com/facebook/react-native/commit/a22ceecc849fc62c926643f4d121cf1e4575c693) by [@dmytrorykun](https://github.com/dmytrorykun), [2a274c1a08](https://github.com/facebook/react-native/commit/2a274c1a082c3291d2df1a4b960bf654e217a4dd) by [@cortinico](https://github.com/cortinico), [ce4246a05c](https://github.com/facebook/react-native/commit/ce4246a05c96cd6fe805499960b105267ac044bb) by [@dmytrorykun](https://github.com/dmytrorykun)) +- Upgrade RN CLI to v9.0.0, Metro to 0.72.1 ([0c2fe96998](https://github.com/facebook/react-native/commit/0c2fe969984fff0676f99fe034b3e49d38ed7db6) by [@thymikee](https://github.com/thymikee), [7e580b97bf](https://github.com/facebook/react-native/commit/7e580b97bf63436978d053926e04adeb9ae6f75f) by [@kelset](https://github.com/kelset), [c504d038c4](https://github.com/facebook/react-native/commit/c504d038c470f7a13fb345f57261172c7c85248c) by [@thymikee](https://github.com/thymikee), [f1d624823f](https://github.com/facebook/react-native/commit/f1d624823fe23eb3d30de00cf78beb71dc1b8413) by [@kelset](https://github.com/kelset), [2b49ac6f8b](https://github.com/facebook/react-native/commit/2b49ac6f8b04953be4cd5bf0b1325986b117763c) by [@thymikee](https://github.com/thymikee)) +- Doc: fix minimum iOS version in requirements section ([ec3c8f4380](https://github.com/facebook/react-native/commit/ec3c8f43800a027a0a717367360421089e7293fd) by [@Simon-TechForm](https://github.com/Simon-TechForm)) +- Remove "Early" in Js error reporting pipeline ([0646551d76](https://github.com/facebook/react-native/commit/0646551d7690cd54847eb468f8e43d71ebebdda9) by [@sshic](https://github.com/sshic)) +- Update @react-native/eslint-plugin-specs to 0.70.0 ([d07fae9b23](https://github.com/facebook/react-native/commit/d07fae9b23c258a60045b666167efd5259b962ce), [afd76f69c7](https://github.com/facebook/react-native/commit/afd76f69c7d2408654ba67ac2ed4d612abfbe0ce) by [@dmytrorykun](https://github.com/dmytrorykun), [ea8d8e2f49](https://github.com/facebook/react-native/commit/ea8d8e2f49ea3ce15faeab500b661a1cacacf8a8) by [@cortinico](https://github.com/cortinico)) +- Do not depend on hermes-engine NPM package anymore ([78cd689f9a](https://github.com/facebook/react-native/commit/78cd689f9a634b152ea09ed6cb4fa858ee26e653) by [@cortinico](https://github.com/cortinico)) +- Add ability to pass `ItemSeparatorComponent` as React Element ([5854b11bf9](https://github.com/facebook/react-native/commit/5854b11bf9d42bab9dbe62b9152a3d3a94e42c13) by [@retyui](https://github.com/retyui)) +- Hermes version bump. ([0b4b7774e2](https://github.com/facebook/react-native/commit/0b4b7774e2d71259962ed36b7acb5c3989c3be9c) by [@dmytrorykun](https://github.com/dmytrorykun), [8c682ddd59](https://github.com/facebook/react-native/commit/8c682ddd599b75a547975104cb6f90eec8753daf) by [@dmytrorykun](https://github.com/dmytrorykun), [eb6767813a](https://github.com/facebook/react-native/commit/eb6767813a0efe04a9e79955b8f6ee909a4a76bf) by [@cortinico](https://github.com/cortinico)) +- Codemod `{...null}` to `{}` in xplat/js ([f392ba6725](https://github.com/facebook/react-native/commit/f392ba67254e95126974fafabf3e4ef0300e24e8) by [@gkz](https://github.com/gkz)) +- Fix TextInput dropping text when used as uncontrolled component with `defaultValue` ([51f49ca998](https://github.com/facebook/react-native/commit/51f49ca9982f24de08f5a5654a5210e547bb5b86)) +- Suppress errors ahead of launch ([67e12a19cb](https://github.com/facebook/react-native/commit/67e12a19cb236fbe0809fbbc9e516b37a5848a6a) by [@gkz](https://github.com/gkz)) +- Suppress missing 'this' annotations ([6c563a507f](https://github.com/facebook/react-native/commit/6c563a507fd8c41e04a1e62e2ba87993c6eb1e2f) by [@pieterv](https://github.com/pieterv)) +- Suppress missing annotations ([66c6a75650](https://github.com/facebook/react-native/commit/66c6a75650f91d61e7e87a8e661d87101e26cf9c) by [@pieterv](https://github.com/pieterv)) +- Use RuntimeConfig instead of VM Experiment Flag to set up the micro task queue. ([753038cf34](https://github.com/facebook/react-native/commit/753038cf345a45d95ab9b9343447f524e1b36840) by [@fbmal7](https://github.com/fbmal7)) +- Update direct Metro dependencies to 0.72.0 ([05dcebc211](https://github.com/facebook/react-native/commit/05dcebc21175a78c6533a8856aed644c45276169) by [@kelset](https://github.com/kelset), [64788cc9fe](https://github.com/facebook/react-native/commit/64788cc9fe42fbedc3e3b1c9c516a079cfa71cd1) by [@huntie](https://github.com/huntie), [bdeb4e0655](https://github.com/facebook/react-native/commit/bdeb4e065532dfb1bb4c9c1e87e8a869a737e48a) by [@jacdebug](https://github.com/jacdebug), [894f652639](https://github.com/facebook/react-native/commit/894f6526399098d825ef32c02eb201cd8ba41873) by [@robhogan](https://github.com/robhogan), [08ebc1cfd8](https://github.com/facebook/react-native/commit/08ebc1cfd88a629389c43abf23b40a2bdf1b1579) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- ECOSYSTEM.md: update Partner entries ([5471afeebf](https://github.com/facebook/react-native/commit/5471afeebf59853ce31df1ade6a4591414b6aa2f) by [@Simek](https://github.com/Simek)) +- Move ScrollView's contentOffset to common props ([7c581f3d30](https://github.com/facebook/react-native/commit/7c581f3d3007954413d68daf2e868ce93e120615) by [@genkikondo](https://github.com/genkikondo)) +- Upgrade react-native-gradle-plugin to 0.70.2 ([1518f838b7](https://github.com/facebook/react-native/commit/1518f838b70951882f7b414c90407d3eb584cab4), [2176173dcc](https://github.com/facebook/react-native/commit/2176173dcc029ab21bfcdfe5c9e150581db47409) by [@dmytrorykun](https://github.com/dmytrorykun)) +- Update a few metro deps as follow up from the commit from main ([7c7ba1babd](https://github.com/facebook/react-native/commit/7c7ba1babd41b6b60f0dc9f48c34d00235d2fef5) by [@kelset](https://github.com/kelset)) + +#### Android specific + +- Bump Android Gradle Plugin to 7.2.1 ([53c8fc9488](https://github.com/facebook/react-native/commit/53c8fc94882893dd8c337fd29543ae11fd467267) by [@leotm](https://github.com/leotm), [c274456e5b](https://github.com/facebook/react-native/commit/c274456e5b635825560852baa5787e96640800d8) by [@dulmandakh](https://github.com/dulmandakh)) +- Rename NativeModuleCallExceptionHandler to JSExceptionHandler for broader usage ([b6f7689d70](https://github.com/facebook/react-native/commit/b6f7689d701d0409c23ab364356aeb95710c20fa) by [@sshic](https://github.com/sshic)) +- Simplify the Android.mk file in the App Template ([7fb0bb40d2](https://github.com/facebook/react-native/commit/7fb0bb40d2206c734a1feb6b555c22d6d5f2436e) by [@cortinico](https://github.com/cortinico)) +- Make Hermes the default engine on Android ([a7db8df207](https://github.com/facebook/react-native/commit/a7db8df2076f68ae9451ce1c77d7eb09d8cfeb14) by [@cortinico](https://github.com/cortinico)) +- Revamp touch event dispatching methods ([089ff4555a](https://github.com/facebook/react-native/commit/089ff4555af27eec4561b1627298702b4ecee482) by [@sshic](https://github.com/sshic)) +- Demonstrating Dark Mode correctly in the `StatusBar` for the starter template App. ([763dc52387](https://github.com/facebook/react-native/commit/763dc5238721a21847b6d6670b5fa268e3bf2ed4) by [@mrbrentkelly](https://github.com/mrbrentkelly)) +- Bump Gradle to 7.5.0 ([5c8186623a](https://github.com/facebook/react-native/commit/5c8186623ae15388949cfc4143edae86863a447b) by [@leotm](https://github.com/leotm), [99e7373dd2](https://github.com/facebook/react-native/commit/99e7373dd2f20184153377109e0e8e48b5bf46f7) by [@dulmandakh](https://github.com/dulmandakh)) +- Generalized the return type of ViewManagerOnDemandReactPackage.getViewManagerNames ([51e029ec3c](https://github.com/facebook/react-native/commit/51e029ec3ce42ae8df3d367d8f553ec2148eeafc) by [@javache](https://github.com/javache)) +- Don't assert on current activity when call startActivityForResult ([bf6884dc90](https://github.com/facebook/react-native/commit/bf6884dc903154ae32daa50ce7983a9f014be781) by [@sshic](https://github.com/sshic)) +- Adapt template to new architecture autolinking on Android ([9ad7cbc3eb](https://github.com/facebook/react-native/commit/9ad7cbc3eb365190e0bfe290e1025553a807b298) by [@thymikee](https://github.com/thymikee)) +- Replaced reactnativeutilsjni with reactnativejni in the build process to reduce size ([54a4fcbfdc](https://github.com/facebook/react-native/commit/54a4fcbfdcc8111b3010b2c31ed3c1d48632ce4c) by [@SparshaSaha](https://github.com/SparshaSaha)) +- Bump Soloader to 0.10.4 ([b9adf2db20](https://github.com/facebook/react-native/commit/b9adf2db20bf9e1436fa58182d886fd9461df9af) by [@mikehardy](https://github.com/mikehardy)) +- Update the new app template to use CMake instead of Android.mk ([dfd7f70eff](https://github.com/facebook/react-native/commit/dfd7f70effeacfeb06d9c2d4762a279a079ee004) by [@cortinico](https://github.com/cortinico)) +- Refactored usage of kotlin plugin ([be35c6dafb](https://github.com/facebook/react-native/commit/be35c6dafbdb46d2ec165460d4bb12f34de6e878) by [@hurali97](https://github.com/hurali97)) +- Bump Gradle to 7.5.1 ([7a911e0730](https://github.com/facebook/react-native/commit/7a911e073094b533cb5a7ce76932c02f83f4fe5d) by [@AlexanderEggers](https://github.com/AlexanderEggers)) +- Fix error of release builds with Hermes enabled for Windows users ([7fcdb9d9d8](https://github.com/facebook/react-native/commit/7fcdb9d9d8f964d24a5ec3d423c67f49b7650ed8) by [@JoseLion](https://github.com/JoseLion)) + +#### iOS specific + +- Move and test Hermes setup from react_native_pods script into a dedicated file ([468b86bd37](https://github.com/facebook/react-native/commit/468b86bd3710b1d43a492c94fb314cc472f03b86) by [@cipolleschi](https://github.com/cipolleschi)) +- Use the correct operator to decide whether Hermes is enabled or not. ([61488449b9](https://github.com/facebook/react-native/commit/61488449b996da5881e4711e0813e9c90b6e57a1) by [@cipolleschi](https://github.com/cipolleschi)) +- Hermes is now the default engine on iOS. This setting is controlled via `flags[:hermes_enabled]` in the Podfile. ([1115bc77db](https://github.com/facebook/react-native/commit/1115bc77db1090042effc021837f70b28694fa09) by [@hramos](https://github.com/hramos)) +- Move LocalPodspecPatch to dedicated file ([8fe2b591c7](https://github.com/facebook/react-native/commit/8fe2b591c7e073d629e95cd7b67aa1dfa96ece38) by [@cipolleschi](https://github.com/cipolleschi)) +- Move the `modify_flags_for_new_architecture` method to separate ruby file ([71da21243c](https://github.com/facebook/react-native/commit/71da21243c85283445c6cefa64d1ace13823ab69) by [@cipolleschi](https://github.com/cipolleschi)) +- Refactoring part of the react_native_pods.rb script ([4f732ba9ee](https://github.com/facebook/react-native/commit/4f732ba9ee2a1e162729c97d5c12ea771b3a424a), [7a2704455f](https://github.com/facebook/react-native/commit/7a2704455f3edf203d2ecc8135fabf2667f718d8) by [@cipolleschi](https://github.com/cipolleschi)) +- When Hermes is enabled, it will use the same copy of JSI as React Native ([340612a200](https://github.com/facebook/react-native/commit/340612a200505ca829bae1f9bce800d3673dac04) by [@hramos](https://github.com/hramos)) +- Move `use_flipper` logic inside `use_react_native` and simplify the Flipper dependencies logic ([0bd5239553](https://github.com/facebook/react-native/commit/0bd523955385a3b1e622077b7ee4ea0df3c5c158) by [@f-meloni](https://github.com/f-meloni)) +- Export `flipper.rb` script file ([e07a7eb16b](https://github.com/facebook/react-native/commit/e07a7eb16b97e1222e23f935a3d4bb3dac848ef2) by [@cipolleschi](https://github.com/cipolleschi)) +- Use `outputDir` as base directory for the codegen and remove the possibility to customize the intermediate path. The generated code requires specific paths in the `#include` directive. ([e4d0153a67](https://github.com/facebook/react-native/commit/e4d0153a675fbdd8718f433b2e9f8bfdccec4b2f) by [@cipolleschi](https://github.com/cipolleschi)) +- Refactor part of the codegen scripts and add tests. ([0465c3fd10](https://github.com/facebook/react-native/commit/0465c3fd102525b005826f3c68923d7e9851d6b8), [305a054865](https://github.com/facebook/react-native/commit/305a0548652a405d9f638fb2c054781951dfc996) by [@cipolleschi](https://github.com/cipolleschi)) +- CodeGen now supports the `"all"` library type. ([6718500eaa](https://github.com/facebook/react-native/commit/6718500eaaeb92b8a74320dcee961ac96f6f12fa) by [@cipolleschi](https://github.com/cipolleschi)) +- Fix the test_ios_unit test ([fdbe4719e2](https://github.com/facebook/react-native/commit/fdbe4719e2e2b599e86d42c49d42c4da97ef431a) by [@cipolleschi](https://github.com/cipolleschi)) +- Update Podfile to allow `PRODUCTION=1 pod install` ([77752fc403](https://github.com/facebook/react-native/commit/77752fc4037e66d5b0a5851bae79c4d3285ed334) by [@leotm](https://github.com/leotm)) +- Destruct use_reactnative parameters and ad ddocumentation ([79a37e5a88](https://github.com/facebook/react-native/commit/79a37e5a88e179090ade7145a453a46719c87b3f) by [@cipolleschi](https://github.com/cipolleschi)) +- Move codegen in separate files ([7d069b2583](https://github.com/facebook/react-native/commit/7d069b25835ad20654a46ebb1e09631d826598e0) by [@cipolleschi](https://github.com/cipolleschi)) +- Silence warning due to react-native internal details. ([a4599225f5](https://github.com/facebook/react-native/commit/a4599225f5a6a2d6801dd80b7728c1bbe5b2ec3a) by [@cipolleschi](https://github.com/cipolleschi)) + +### Removed + +- Remove previously deprecated Transform style-attribute props ([7cfd77debd](https://github.com/facebook/react-native/commit/7cfd77debd36f867f5ddfdb9cc44fbe6137aaeba) by [@Zachinquarantine](https://github.com/Zachinquarantine)) +- Remove deprecated `isTVOS` constant. ([6075d64acf](https://github.com/facebook/react-native/commit/6075d64acf6f8d74e18ef6568c9438f73fe56d44) by [@Zachinquarantine](https://github.com/Zachinquarantine)) +- The diffs renames the required variable which was causing conflicts in names with Apple core SDK's ([086c13dd5f](https://github.com/facebook/react-native/commit/086c13dd5fba3f77acbc70c9bdedc9299118b526) by [@arinjay](https://github.com/arinjay)) +- Removed `EventEmitter.prototype.removeSubscription` method. ([870755fa7e](https://github.com/facebook/react-native/commit/870755fa7e7011ac46d269d5fb66d2a1d1543442) by [@yungsters](https://github.com/yungsters)) +- Remove deprecated removeListener methods ([2596b2f695](https://github.com/facebook/react-native/commit/2596b2f6954362d2cd34a1be870810ab90cbb916) by [@matinzd](https://github.com/matinzd)) +- Remove APPLETVOS variants from BUCk targets. ([cf2e27c388](https://github.com/facebook/react-native/commit/cf2e27c3888ded6f851ba267597ef13f1d0cfd8c) by [@d16r](https://github.com/d16r)) + +#### iOS specific + +- Remove `emulateUnlessSupported` ([c73e021a4b](https://github.com/facebook/react-native/commit/c73e021a4b11bbae3a7868670d140fe3d5dac6ae) by [@ken0nek](https://github.com/ken0nek)) +- Remove USE_CODEGEN_DISCOVERY flag ([2e720c3610](https://github.com/facebook/react-native/commit/2e720c361001d996ed35d8bfbf4dc67c31fb895d) by [@cipolleschi](https://github.com/cipolleschi)) + +### Fixed + +- Throw JSINativeException from asHostObject ([ef6ab3f5ca](https://github.com/facebook/react-native/commit/ef6ab3f5cad968d7b2c9127d834429b0f4e1b2cf) by [@neildhar](https://github.com/neildhar)) +- Use new Babel parser instead of deprecated one ([97291bfa31](https://github.com/facebook/react-native/commit/97291bfa3157ac171a2754e19a52d006040961fb) by [@Kerumen](https://github.com/Kerumen)) +- Fixed a crash on deserialization of props when using 'px'/'em' units. ([70788313fe](https://github.com/facebook/react-native/commit/70788313fedd40fe2e6d1cf15980ce3cca5adaac) by [@nlutsenko](https://github.com/nlutsenko)) +- Fix nullability lost on readonly types in TurboModule specs ([c006722e6c](https://github.com/facebook/react-native/commit/c006722e6cdbe02711cb50ea7a739e0d4d81c7e7) by [@appden](https://github.com/appden)) +- Make tests pass for windows ([9596bf045d](https://github.com/facebook/react-native/commit/9596bf045d527e27608ac4b7b2990a4e6846fdeb) by [@cipolleschi](https://github.com/cipolleschi)) +- Handle possible null exception on ReactEditText with AppCompat 1.4.0 ([24a1f5c66c](https://github.com/facebook/react-native/commit/24a1f5c66c8633f9b41eef45df3297ffc1d2b606) by [@mikemasam](https://github.com/mikemasam)) +- Fixed the disappearance of items when scrolling after zooming VirtualizedList. ([13a72e0ccc](https://github.com/facebook/react-native/commit/13a72e0ccceb2db6aeacd03b4f429d200392c17b) by [@islandryu](https://github.com/islandryu)) +- Improved Flow type inference in Animated `.interpolate()` ([7b86fa2b79](https://github.com/facebook/react-native/commit/7b86fa2b795647f5c89e04e4c3ee4b83bc27ef77) by [@motiz88](https://github.com/motiz88)) +- Add Jest mock for Vibration module ([79529a1c77](https://github.com/facebook/react-native/commit/79529a1c77e7e1b174fdbe8103a2199c9ac924ff) by [@hduprat](https://github.com/hduprat)) +- Allow ReactInstrumentationTest to use custom JSIModules ([eb2a83b0be](https://github.com/facebook/react-native/commit/eb2a83b0be4658654fc6ca6f4671e45f1898798d) by [@christophpurrer](https://github.com/christophpurrer)) +- Working around Long paths limitation on Windows ([883a93871c](https://github.com/facebook/react-native/commit/883a93871cb1fbca4434600a322f63afbba333da) by [@mganandraj](https://github.com/mganandraj)) +- Fix eslint-plugin-specs prepack npm lifecycle hook now that we use npm 8 ([8441c4a6f7](https://github.com/facebook/react-native/commit/8441c4a6f7bfeda73f89f076fe7d8d1132e4b9be) by [@kelset](https://github.com/kelset)) +- Codegen should ignore `.d.ts` files ([0f0d52067c](https://github.com/facebook/react-native/commit/0f0d52067cb89fdb39a99021f0745282ce087fc2) by [@tido64](https://github.com/tido64)) +- Avoid full copy of large folly::dynamic objects in JSIExecutor#defaultTimeoutInvoker ([521011d4cc](https://github.com/facebook/react-native/commit/521011d4cc713dfce97dc8872fd0f5171e587b5d) by [@christophpurrer](https://github.com/christophpurrer)) + +#### Android specific + +- Fixed HorizontalScrollView API scrollToEnd causing NPE in side-effects. ([e5ba6ab7b4](https://github.com/facebook/react-native/commit/e5ba6ab7b482c380e35765b898e522e9d4e1d3b0) by [@ryancat](https://github.com/ryancat)) +- Fix InputAccessoryView crash on Android ([afa5df1764](https://github.com/facebook/react-native/commit/afa5df1764324f2574d102abeae7199d4b02d183) by [@hduprat](https://github.com/hduprat)) +- Bring back non-rootview touch handling based on reactTag ([8b837268b4](https://github.com/facebook/react-native/commit/8b837268b49fd4e72a05f955c20702c457a68fab) by [@fkgozali](https://github.com/fkgozali)) +- Make Text not focusable by default ([8ced165e53](https://github.com/facebook/react-native/commit/8ced165e53135d9d33cfdc55a9d4660f8eb5b3c5) by [@kacieb](https://github.com/kacieb)) +- Revert [PR 33924](https://github.com/facebook/react-native/pull/33924) because of issues with TextInputs with numeric keyboard types not respecting the secureTextEntry prop ([edb27e3aa1](https://github.com/facebook/react-native/commit/edb27e3aa1210ef33d55c1840065457c31b19cb0) by [@charlesbdudley](https://github.com/charlesbdudley)) +- Fix edge case when we enqueue a pending event to views on stopped surface ([ea7c9f2ad9](https://github.com/facebook/react-native/commit/ea7c9f2ad9a78b16234306932edc1d78b783ac27) by [@ryancat](https://github.com/ryancat)) +- Fix a bug where the keyboard, once set as email, won't change back to default. ([ec307e0167](https://github.com/facebook/react-native/commit/ec307e0167deca7f17640cd3c5a60f6be5f47b62) by [@larkox](https://github.com/larkox)) +- NPE in `ReactEditText.setInputType` when React Native is used with some versions of a AppCompat 1.4.x. (and possibly others) ([92ebb298e2](https://github.com/facebook/react-native/commit/92ebb298e2e5ad640754e09ce3a37d3de1d28f58)) +- Fix NPE on `ReactEditText` due to null mFabricViewStateManager ([ba6bf5a3ce](https://github.com/facebook/react-native/commit/ba6bf5a3ce7039a7e407a6632ee41aa3d504f833) by [@cortinico](https://github.com/cortinico)) +- Scroll views would still receive scroll events when nested in a view with `pointer-events: "none"` ([fced96bf52](https://github.com/facebook/react-native/commit/fced96bf5202e8b89b804ccc1004abacc9f91660) by [@javache](https://github.com/javache)) +- Fixed an edge case that event dispatching is failed after pre-allocation of a view and before the view is mounted. ([a093fe5f2f](https://github.com/facebook/react-native/commit/a093fe5f2fae4e9996b0cbffdfccdce8e58e8cf1) by [@ryancat](https://github.com/ryancat)) +- Avoid crash by handling missing views in dispatchViewManagerCommand ([ee1a191cb1](https://github.com/facebook/react-native/commit/ee1a191cb1c10085722d57fc276734f83e86a4f3) by [@hsource](https://github.com/hsource)) +- Pass react build dir to cmake ([6ab7a99518](https://github.com/facebook/react-native/commit/6ab7a99518f8ba0d53e62e35d230ebec78e50217) by [@janicduplessis](https://github.com/janicduplessis)) +- Fix missing space in ReactPropertyException message ([24560b6718](https://github.com/facebook/react-native/commit/24560b67184da00e05491af38289865c4b934ee8) by [@markv](https://github.com/markv)) +- Fix import path breakage ([2e1e62f2bf](https://github.com/facebook/react-native/commit/2e1e62f2bf043ea0bf9926e1f5786ca54a22005e) by [@aniketmathur](https://github.com/aniketmathur)) +- When `onEndReachedThreshold` is set to 0 `onEndReached` function on `VirtualizedList` properly fires once the user scrolls to the bottom of the list. ([b869680c11](https://github.com/facebook/react-native/commit/b869680c1196a6549154a4b9cb7ffa10eab1989c)) +- Fix rendering of transparent borders in RN Android ([a9659ce86d](https://github.com/facebook/react-native/commit/a9659ce86d94dd34768b067763740a5c41917e42) by [@mdvacca](https://github.com/mdvacca)) +- Exception with `Cannot load WebView` message will initialising WebView (along with existing checks) ([9e0d8696cc](https://github.com/facebook/react-native/commit/9e0d8696cc68436a0d309cafde252c55fc337be4) by [@rachitmishra](https://github.com/rachitmishra)) +- Fix accessibilityState overwriting view's disabled state on Android ([f35d18caa3](https://github.com/facebook/react-native/commit/f35d18caa302351319840ec85337182f4f148e5e) by [@okwasniewski](https://github.com/okwasniewski)) +- Make sure *.ts files are considered for task avoidance in the Gradle Plugin ([1a9fb6cb68](https://github.com/facebook/react-native/commit/1a9fb6cb682aa5ff83462e1e2869eb99f3b873fd) by [@cortinico](https://github.com/cortinico)) +- Fix missing import on New Architecture build script in template ([a22f30d2ce](https://github.com/facebook/react-native/commit/a22f30d2ce866cb1488b26bb18eee0620a0ac259) by [@cortinico](https://github.com/cortinico)) + +#### iOS specific + +- Use `NODE_BINARY` from `.xcode.env` when running packager from Xcode ([ff785dbcf5](https://github.com/facebook/react-native/commit/ff785dbcf5c464a4d850fa738e977702efd8abd3) by [@elsurudo](https://github.com/elsurudo)) +- Bug with error message formatting when bundle is missing ([f501979f3d](https://github.com/facebook/react-native/commit/f501979f3d1e5c053eed16967a3d3385eab8e15f) by [@BenLorantfy](https://github.com/BenLorantfy)) +- Fix the race condition when calling readAsDataURL after new Blob(blobs) ([bd12e41188](https://github.com/facebook/react-native/commit/bd12e41188c8d85c0acbd713f10f0bd34ea0edca) by [@wood1986](https://github.com/wood1986)) +- Fix the way the orientation events are published, to avoid false publish on orientation change when app changes state to inactive ([7d42106d4c](https://github.com/facebook/react-native/commit/7d42106d4ce20c644bda4d928fb0abc163580cee) by [@lbaldy](https://github.com/lbaldy)) +- Fix sed error when installing `glog` ([4a7e4b9ca6](https://github.com/facebook/react-native/commit/4a7e4b9ca6ef4fb52611b6c3cb788f624d1f81a4) by [@alphashuro](https://github.com/alphashuro)) +- Don't validate ENTRY_FILE in react-native-xcode.sh ([780fe80fca](https://github.com/facebook/react-native/commit/780fe80fcaf213d84d9d087132af933bd02d1349) by [@janicduplessis](https://github.com/janicduplessis)) +- `_scrollViewComponentView` is set to `RCTPullToRefreshViewComponentView's` superview ([4e4b9e2111](https://github.com/facebook/react-native/commit/4e4b9e2111faaf5652ae1f5b885730b378f3de98) by [@dmytrorykun](https://github.com/dmytrorykun)) +- Use `GCC_PREPROCESSOR_DEFINITIONS` to set `FB_SONARKIT_ENABLED` ([77e6bff629](https://github.com/facebook/react-native/commit/77e6bff629312f20cdacb1e798cd2464ac50db9e) by [@janicduplessis](https://github.com/janicduplessis)) +- Fix Hermes not being properly downloaded during pod install ([d5e0659fcc](https://github.com/facebook/react-native/commit/d5e0659fccf2767beb7aae55461e9690ba335c81) by [@cortinico](https://github.com/cortinico)) +- Typo in the documation for the `automaticallyAdjustKeyboardInsets` prop ([927b43d47c](https://github.com/facebook/react-native/commit/927b43d47c2cd42538265cb06154b12cb0be6816) by [@jeremybarbet](https://github.com/jeremybarbet)) +- Deprecate iOS/tvOS SDK 11.0 support now that 12.4+ is required ([f56d701e56](https://github.com/facebook/react-native/commit/f56d701e567af0c252a2e297bf81cd4add59378a) by [@leotm](https://github.com/leotm)) +- Fix blank spaces that don't recover as you scroll when in an RTL locale and e.nativeEvent.zoomScale is -1. ([bc7b5c3011](https://github.com/facebook/react-native/commit/bc7b5c3011460935614a47a03cd077cd1059de72), [2f491bfa9f](https://github.com/facebook/react-native/commit/2f491bfa9f86c3db2e459e331f39bc3cf12e7239)) +- Fixed paddingTop not being applied when using padding and paddingVertical in multiline textinput ([2fb107c9a6](https://github.com/facebook/react-native/commit/2fb107c9a63aacd2c880ad6abedaad67ffb6022b) by [@hetanthakkar1](https://github.com/hetanthakkar1)) +- Fixed the ability to pass the port to use for Metro when running `react-native run-ios --port `. ([7dc0b5153e](https://github.com/facebook/react-native/commit/7dc0b5153e4eb91c333238a58fe8c75a47cb5f81) by [@lindboe](https://github.com/lindboe)) +- Fix missing imports ([c78babac39](https://github.com/facebook/react-native/commit/c78babac39b7c64e03e137d8fddd91e783303426)) +- Fix React-bridging headers import not found ([c4b51e8d76](https://github.com/facebook/react-native/commit/c4b51e8d7679c3c20b843072581acd23a931fc83) by [@Kudo](https://github.com/Kudo)) +- Fix Hermes executor not available when `use_frameworks` is enabled ([88b7b640a7](https://github.com/facebook/react-native/commit/88b7b640a74bafd918b8b1cd5d58e1f5ddfb730a) by [@Kudo](https://github.com/Kudo)) + +### Security + +- Add GitHub token permissions for workflows ([3da3d82320](https://github.com/facebook/react-native/commit/3da3d82320bd035c6bd361a82ea12a70dba4e851) by [@varunsh-coder](https://github.com/varunsh-coder)) +- Bump RCT-Folly to 2021-07-22 ([68f3a42fc7](https://github.com/facebook/react-native/commit/68f3a42fc7380051714253f43b42175de361f8bd) by [@luissantana](https://github.com/luissantana)) + ## v0.69.5 ### Changed -- Bump react-native-codegen to 0.69.2 ([df3d52bfbf](https://github.com/facebook/react-native/commit/df3d52bfbf4254cd16e1dc0ca0af2743cd7e11c1) by [@dmitryrykun](https://github.com/dmitryrykun)) +- Bump react-native-codegen to 0.69.2 ([df3d52bfbf](https://github.com/facebook/react-native/commit/df3d52bfbf4254cd16e1dc0ca0af2743cd7e11c1) by [@dmytrorykun](https://github.com/dmytrorykun)) #### Android specific @@ -588,7 +803,7 @@ - Rename deprecated `Keyboard.removeEventListener` to `Keyboard.removeListener`. ([8880c09076](https://github.com/facebook/react-native/commit/8880c09076e4727768ace26a74766cbe6f64021c) by [@yungsters](https://github.com/yungsters)) - Update `Modal`'s mock to not render its children when it is not visible ([ec614c16b3](https://github.com/facebook/react-native/commit/ec614c16b331bf3f793fda5780fa273d181a8492) by [@AntoineDoubovetzky](https://github.com/AntoineDoubovetzky)) - Upgraded `react-devtools-core` dependency to 4.19.1 ([356236471a](https://github.com/facebook/react-native/commit/356236471abc6b5b8c139223e15388fd1eecd2d1) by [@jstejada](https://github.com/jstejada)) -- React-native/normalize-color now supports Node.js ([65e58f26e1](https://github.com/facebook/react-native/commit/65e58f26e1fbd06b1ae32e2ab3a2616c8eef08e0) by [@yungsters](https://github.com/yungsters)) +- React-native/normalize-colors now supports Node.js ([65e58f26e1](https://github.com/facebook/react-native/commit/65e58f26e1fbd06b1ae32e2ab3a2616c8eef08e0) by [@yungsters](https://github.com/yungsters)) - Updated to Contributor Covenant v2.1 ([19f8d2f7da](https://github.com/facebook/react-native/commit/19f8d2f7da13f4524f31acf7aa10cc0aa91b5da4)) diff --git a/Libraries/Alert/Alert.js.flow b/Libraries/Alert/Alert.js.flow new file mode 100644 index 00000000000000..be6f948f557add --- /dev/null +++ b/Libraries/Alert/Alert.js.flow @@ -0,0 +1,49 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +export type AlertType = + | 'default' + | 'plain-text' + | 'secure-text' + | 'login-password'; +export type AlertButtonStyle = 'default' | 'cancel' | 'destructive'; +export type Buttons = Array<{ + text?: string, + onPress?: ?Function, + isPreferred?: boolean, + style?: AlertButtonStyle, + ... +}>; +type Options = { + cancelable?: ?boolean, + userInterfaceStyle?: 'unspecified' | 'light' | 'dark', + onDismiss?: ?() => void, + ... +}; + +declare class Alert { + static alert( + title: ?string, + message?: ?string, + buttons?: Buttons, + options?: Options, + ): void; + static prompt( + title: ?string, + message?: ?string, + callbackOrButtons?: ?(((text: string) => void) | Buttons), + type?: ?AlertType, + defaultValue?: string, + keyboardType?: string, + options?: Options, + ): void; +} + +module.exports = Alert; diff --git a/Libraries/Animated/Animated.js b/Libraries/Animated/Animated.js index 88fd9dbb188dbe..4b2de95d3f109b 100644 --- a/Libraries/Animated/Animated.js +++ b/Libraries/Animated/Animated.js @@ -8,6 +8,8 @@ * @format */ +export type {CompositeAnimation, Numeric} from './AnimatedImplementation'; + import Platform from '../Utilities/Platform'; import typeof AnimatedFlatList from './components/AnimatedFlatList'; import typeof AnimatedImage from './components/AnimatedImage'; @@ -16,31 +18,31 @@ import typeof AnimatedSectionList from './components/AnimatedSectionList'; import typeof AnimatedText from './components/AnimatedText'; import typeof AnimatedView from './components/AnimatedView'; -import * as AnimatedMock from './AnimatedMock'; -import * as AnimatedImplementation from './AnimatedImplementation'; +import AnimatedMock from './AnimatedMock'; +import AnimatedImplementation from './AnimatedImplementation'; const Animated = ((Platform.isTesting ? AnimatedMock - : AnimatedImplementation): typeof AnimatedMock); + : AnimatedImplementation): typeof AnimatedImplementation); -module.exports = { +export default { get FlatList(): AnimatedFlatList { - return require('./components/AnimatedFlatList'); + return require('./components/AnimatedFlatList').default; }, get Image(): AnimatedImage { - return require('./components/AnimatedImage'); + return require('./components/AnimatedImage').default; }, get ScrollView(): AnimatedScrollView { - return require('./components/AnimatedScrollView'); + return require('./components/AnimatedScrollView').default; }, get SectionList(): AnimatedSectionList { - return require('./components/AnimatedSectionList'); + return require('./components/AnimatedSectionList').default; }, get Text(): AnimatedText { - return require('./components/AnimatedText'); + return require('./components/AnimatedText').default; }, get View(): AnimatedView { - return require('./components/AnimatedView'); + return require('./components/AnimatedView').default; }, ...Animated, }; diff --git a/Libraries/Animated/AnimatedEvent.js b/Libraries/Animated/AnimatedEvent.js index c1b221fbf703b4..bdbbb837a86558 100644 --- a/Libraries/Animated/AnimatedEvent.js +++ b/Libraries/Animated/AnimatedEvent.js @@ -10,14 +10,12 @@ 'use strict'; -const AnimatedValue = require('./nodes/AnimatedValue'); -const AnimatedValueXY = require('./nodes/AnimatedValueXY'); -const NativeAnimatedHelper = require('./NativeAnimatedHelper'); -const ReactNative = require('../Renderer/shims/ReactNative'); +import AnimatedValue from './nodes/AnimatedValue'; +import AnimatedValueXY from './nodes/AnimatedValueXY'; +import NativeAnimatedHelper from './NativeAnimatedHelper'; +import {findNodeHandle} from '../ReactNative/RendererProxy'; -const invariant = require('invariant'); - -const {shouldUseNativeDriver} = require('./NativeAnimatedHelper'); +import invariant from 'invariant'; import type {PlatformConfig} from './AnimatedPlatformConfig'; @@ -31,7 +29,7 @@ export type EventConfig = { platformConfig?: PlatformConfig, }; -function attachNativeEvent( +export function attachNativeEvent( viewRef: any, eventName: string, argMapping: $ReadOnlyArray, @@ -67,7 +65,7 @@ function attachNativeEvent( // Assume that the event containing `nativeEvent` is always the first argument. traverse(argMapping[0].nativeEvent, []); - const viewTag = ReactNative.findNodeHandle(viewRef); + const viewTag = findNodeHandle(viewRef); if (viewTag != null) { eventMappings.forEach(mapping => { NativeAnimatedHelper.API.addAnimatedEventToView( @@ -146,7 +144,7 @@ function validateMapping(argMapping: $ReadOnlyArray, args: any) { }); } -class AnimatedEvent { +export class AnimatedEvent { _argMapping: $ReadOnlyArray; _listeners: Array = []; _attachedEvent: ?{detach: () => void, ...}; @@ -165,7 +163,7 @@ class AnimatedEvent { this.__addListener(config.listener); } this._attachedEvent = null; - this.__isNative = shouldUseNativeDriver(config); + this.__isNative = NativeAnimatedHelper.shouldUseNativeDriver(config); this.__platformConfig = config.platformConfig; } @@ -257,5 +255,3 @@ class AnimatedEvent { this._listeners.forEach(listener => listener(...args)); }; } - -module.exports = {AnimatedEvent, attachNativeEvent}; diff --git a/Libraries/Animated/AnimatedImplementation.js b/Libraries/Animated/AnimatedImplementation.js index 5aaa29f336537f..33883c9494ecd3 100644 --- a/Libraries/Animated/AnimatedImplementation.js +++ b/Libraries/Animated/AnimatedImplementation.js @@ -10,23 +10,23 @@ 'use strict'; -const {AnimatedEvent, attachNativeEvent} = require('./AnimatedEvent'); -const AnimatedAddition = require('./nodes/AnimatedAddition'); -const AnimatedDiffClamp = require('./nodes/AnimatedDiffClamp'); -const AnimatedDivision = require('./nodes/AnimatedDivision'); -const AnimatedInterpolation = require('./nodes/AnimatedInterpolation'); -const AnimatedModulo = require('./nodes/AnimatedModulo'); -const AnimatedMultiplication = require('./nodes/AnimatedMultiplication'); -const AnimatedNode = require('./nodes/AnimatedNode'); -const AnimatedSubtraction = require('./nodes/AnimatedSubtraction'); -const AnimatedTracking = require('./nodes/AnimatedTracking'); -const AnimatedValue = require('./nodes/AnimatedValue'); -const AnimatedValueXY = require('./nodes/AnimatedValueXY'); -const DecayAnimation = require('./animations/DecayAnimation'); -const SpringAnimation = require('./animations/SpringAnimation'); -const TimingAnimation = require('./animations/TimingAnimation'); - -const createAnimatedComponent = require('./createAnimatedComponent'); +import {AnimatedEvent, attachNativeEvent} from './AnimatedEvent'; +import AnimatedAddition from './nodes/AnimatedAddition'; +import AnimatedDiffClamp from './nodes/AnimatedDiffClamp'; +import AnimatedDivision from './nodes/AnimatedDivision'; +import AnimatedInterpolation from './nodes/AnimatedInterpolation'; +import AnimatedModulo from './nodes/AnimatedModulo'; +import AnimatedMultiplication from './nodes/AnimatedMultiplication'; +import AnimatedNode from './nodes/AnimatedNode'; +import AnimatedSubtraction from './nodes/AnimatedSubtraction'; +import AnimatedTracking from './nodes/AnimatedTracking'; +import AnimatedValue from './nodes/AnimatedValue'; +import AnimatedValueXY from './nodes/AnimatedValueXY'; +import DecayAnimation from './animations/DecayAnimation'; +import SpringAnimation from './animations/SpringAnimation'; +import TimingAnimation from './animations/TimingAnimation'; + +import createAnimatedComponent from './createAnimatedComponent'; import type { AnimationConfig, @@ -575,7 +575,7 @@ export type {AnimatedNumeric as Numeric}; * * See https://reactnative.dev/docs/animated */ -module.exports = { +export default { /** * Standard value class for driving animations. Typically initialized with * `new Animated.Value(0);` diff --git a/Libraries/Animated/AnimatedMock.js b/Libraries/Animated/AnimatedMock.js index b7af8042fb90e5..28cc94bb4869a4 100644 --- a/Libraries/Animated/AnimatedMock.js +++ b/Libraries/Animated/AnimatedMock.js @@ -12,14 +12,14 @@ import type {EndResult} from './animations/Animation'; -const {AnimatedEvent, attachNativeEvent} = require('./AnimatedEvent'); -const AnimatedImplementation = require('./AnimatedImplementation'); -const AnimatedInterpolation = require('./nodes/AnimatedInterpolation'); -const AnimatedNode = require('./nodes/AnimatedNode'); -const AnimatedValue = require('./nodes/AnimatedValue'); -const AnimatedValueXY = require('./nodes/AnimatedValueXY'); +import {AnimatedEvent, attachNativeEvent} from './AnimatedEvent'; +import AnimatedImplementation from './AnimatedImplementation'; +import AnimatedInterpolation from './nodes/AnimatedInterpolation'; +import AnimatedNode from './nodes/AnimatedNode'; +import AnimatedValue from './nodes/AnimatedValue'; +import AnimatedValueXY from './nodes/AnimatedValueXY'; -const createAnimatedComponent = require('./createAnimatedComponent'); +import createAnimatedComponent from './createAnimatedComponent'; import type {EndCallback} from './animations/Animation'; import type {TimingAnimationConfig} from './animations/TimingAnimation'; @@ -168,7 +168,7 @@ const loop = function ( export type {AnimatedNumeric as Numeric}; -module.exports = { +export default { Value: AnimatedValue, ValueXY: AnimatedValueXY, Color: AnimatedColor, diff --git a/Libraries/Animated/AnimatedWeb.js b/Libraries/Animated/AnimatedWeb.js index e1c016b753241b..e23a04587a7061 100644 --- a/Libraries/Animated/AnimatedWeb.js +++ b/Libraries/Animated/AnimatedWeb.js @@ -10,9 +10,9 @@ 'use strict'; -const AnimatedImplementation = require('./AnimatedImplementation'); +import AnimatedImplementation from './AnimatedImplementation'; -module.exports = { +export default { ...AnimatedImplementation, /* $FlowFixMe[incompatible-call] createAnimatedComponent expects to receive * types. Plain intrinsic components can't be typed like this */ diff --git a/Libraries/Animated/Easing.js b/Libraries/Animated/Easing.js index f8b5bac2f30404..32819708a11d6b 100644 --- a/Libraries/Animated/Easing.js +++ b/Libraries/Animated/Easing.js @@ -214,7 +214,7 @@ const Easing = { x2: number, y2: number, ): (t: number) => number { - const _bezier = require('./bezier'); + const _bezier = require('./bezier').default; return _bezier(x1, y1, x2, y2); }, @@ -247,4 +247,4 @@ const Easing = { }, }; -module.exports = Easing; +export default Easing; diff --git a/Libraries/Animated/NativeAnimatedHelper.js b/Libraries/Animated/NativeAnimatedHelper.js index 255f6a3ee9ff55..811d5b998a831b 100644 --- a/Libraries/Animated/NativeAnimatedHelper.js +++ b/Libraries/Animated/NativeAnimatedHelper.js @@ -550,7 +550,7 @@ function transformDataType(value: number | string): number | string { } } -module.exports = { +export default { API, isSupportedColorStyleProp, isSupportedStyleProp, diff --git a/Libraries/Animated/SpringConfig.js b/Libraries/Animated/SpringConfig.js index c687f6b97126eb..2ed616eb87e671 100644 --- a/Libraries/Animated/SpringConfig.js +++ b/Libraries/Animated/SpringConfig.js @@ -24,7 +24,7 @@ function dampingFromOrigamiValue(oValue: number) { return (oValue - 8) * 3 + 25; } -function fromOrigamiTensionAndFriction( +export function fromOrigamiTensionAndFriction( tension: number, friction: number, ): SpringConfigType { @@ -34,7 +34,7 @@ function fromOrigamiTensionAndFriction( }; } -function fromBouncinessAndSpeed( +export function fromBouncinessAndSpeed( bounciness: number, speed: number, ): SpringConfigType { @@ -96,8 +96,3 @@ function fromBouncinessAndSpeed( damping: dampingFromOrigamiValue(bouncyFriction), }; } - -module.exports = { - fromOrigamiTensionAndFriction, - fromBouncinessAndSpeed, -}; diff --git a/Libraries/Animated/__tests__/Animated-test.js b/Libraries/Animated/__tests__/Animated-test.js index 8f62804c73b781..5b13e40b8118a8 100644 --- a/Libraries/Animated/__tests__/Animated-test.js +++ b/Libraries/Animated/__tests__/Animated-test.js @@ -5,10 +5,9 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ -import AnimatedProps from '../nodes/AnimatedProps'; import TestRenderer from 'react-test-renderer'; import * as React from 'react'; @@ -21,7 +20,8 @@ jest.mock('../../BatchedBridge/NativeModules', () => ({ }, })); -let Animated = require('../Animated'); +let AnimatedProps = require('../nodes/AnimatedProps').default; +let Animated = require('../Animated').default; describe('Animated tests', () => { beforeEach(() => { @@ -692,7 +692,7 @@ describe('Animated tests', () => { beforeEach(() => { jest.mock('../../Interaction/InteractionManager'); - Animated = require('../Animated'); + Animated = require('../Animated').default; InteractionManager = require('../../Interaction/InteractionManager'); }); diff --git a/Libraries/Animated/__tests__/AnimatedMock-test.js b/Libraries/Animated/__tests__/AnimatedMock-test.js index cc510feefefb33..107fa50919a126 100644 --- a/Libraries/Animated/__tests__/AnimatedMock-test.js +++ b/Libraries/Animated/__tests__/AnimatedMock-test.js @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; -const AnimatedMock = require('../AnimatedMock'); -const AnimatedImplementation = require('../AnimatedImplementation'); +import AnimatedMock from '../AnimatedMock'; +import AnimatedImplementation from '../AnimatedImplementation'; describe('Animated Mock', () => { it('matches implementation keys', () => { diff --git a/Libraries/Animated/__tests__/AnimatedNative-test.js b/Libraries/Animated/__tests__/AnimatedNative-test.js index 677527e22c9d15..b333c17fadf13f 100644 --- a/Libraries/Animated/__tests__/AnimatedNative-test.js +++ b/Libraries/Animated/__tests__/AnimatedNative-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ jest @@ -20,14 +20,14 @@ jest })) .mock('../NativeAnimatedModule') .mock('../../EventEmitter/NativeEventEmitter') - // findNodeHandle is imported from ReactNative so mock that whole module. - .setMock('../../Renderer/shims/ReactNative', {findNodeHandle: () => 1}); + // findNodeHandle is imported from RendererProxy so mock that whole module. + .setMock('../../ReactNative/RendererProxy', {findNodeHandle: () => 1}); import TestRenderer from 'react-test-renderer'; import * as React from 'react'; -const Animated = require('../Animated'); -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); +const Animated = require('../Animated').default; +const NativeAnimatedHelper = require('../NativeAnimatedHelper').default; describe('Native Animated', () => { const NativeAnimatedModule = require('../NativeAnimatedModule').default; diff --git a/Libraries/Animated/__tests__/Easing-test.js b/Libraries/Animated/__tests__/Easing-test.js index 8efeed00037d74..1447c0c60edd0e 100644 --- a/Libraries/Animated/__tests__/Easing-test.js +++ b/Libraries/Animated/__tests__/Easing-test.js @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; -const Easing = require('../Easing'); +import Easing from '../Easing'; describe('Easing', () => { it('should work with linear', () => { const easing = Easing.linear; diff --git a/Libraries/Animated/__tests__/Interpolation-test.js b/Libraries/Animated/__tests__/Interpolation-test.js index 64585ac683bd9a..21d796ed6d6082 100644 --- a/Libraries/Animated/__tests__/Interpolation-test.js +++ b/Libraries/Animated/__tests__/Interpolation-test.js @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; -const AnimatedInterpolation = require('../nodes/AnimatedInterpolation'); -const Easing = require('../Easing'); +import AnimatedInterpolation from '../nodes/AnimatedInterpolation'; +import Easing from '../Easing'; describe('Interpolation', () => { it('should work with defaults', () => { diff --git a/Libraries/Animated/__tests__/TimingAnimation-test.js b/Libraries/Animated/__tests__/TimingAnimation-test.js index e82407876a2d9c..b05a2ff3c76efe 100644 --- a/Libraries/Animated/__tests__/TimingAnimation-test.js +++ b/Libraries/Animated/__tests__/TimingAnimation-test.js @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; -const TimingAnimation = require('../animations/TimingAnimation'); +import TimingAnimation from '../animations/TimingAnimation'; describe('Timing Animation', () => { it('should return array of 61 items', () => { diff --git a/Libraries/Animated/__tests__/bezier-test.js b/Libraries/Animated/__tests__/bezier-test.js index 48bfdef0f2d605..da5303f9c5e8da 100644 --- a/Libraries/Animated/__tests__/bezier-test.js +++ b/Libraries/Animated/__tests__/bezier-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @emails oncall+react_native * @flow * @format + * @oncall react_native */ /** @@ -17,7 +17,7 @@ 'use strict'; -const bezier = require('../bezier'); +import bezier from '../bezier'; const identity = function (x: number) { return x; diff --git a/Libraries/Animated/__tests__/createAnimatedComponentInjection-test.js b/Libraries/Animated/__tests__/createAnimatedComponentInjection-test.js index 9d8fa9b1869d99..e2388fcd26ca7a 100644 --- a/Libraries/Animated/__tests__/createAnimatedComponentInjection-test.js +++ b/Libraries/Animated/__tests__/createAnimatedComponentInjection-test.js @@ -4,16 +4,16 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @emails oncall+react_native * @flow strict-local * @format + * @oncall react_native */ 'use strict'; -const createAnimatedComponent = require('../createAnimatedComponent'); +const createAnimatedComponent = require('../createAnimatedComponent').default; const createAnimatedComponentInjection = require('../createAnimatedComponentInjection'); -const React = require('react'); +import * as React from 'react'; function injected( Component: React.AbstractComponent, diff --git a/Libraries/Animated/animations/Animation.js b/Libraries/Animated/animations/Animation.js index f22c5e9e4adaa5..68d04566a9753a 100644 --- a/Libraries/Animated/animations/Animation.js +++ b/Libraries/Animated/animations/Animation.js @@ -10,7 +10,7 @@ 'use strict'; -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); +import NativeAnimatedHelper from '../NativeAnimatedHelper'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type AnimatedValue from '../nodes/AnimatedValue'; @@ -30,7 +30,7 @@ let startNativeAnimationNextId = 1; // Important note: start() and stop() will only be called at most once. // Once an animation has been stopped or finished its course, it will // not be reused. -class Animation { +export default class Animation { __active: boolean; __isInteraction: boolean; __nativeId: number; @@ -85,5 +85,3 @@ class Animation { } } } - -module.exports = Animation; diff --git a/Libraries/Animated/animations/DecayAnimation.js b/Libraries/Animated/animations/DecayAnimation.js index c53ff08ac0fea4..d365cd726f555b 100644 --- a/Libraries/Animated/animations/DecayAnimation.js +++ b/Libraries/Animated/animations/DecayAnimation.js @@ -10,9 +10,9 @@ 'use strict'; -const Animation = require('./Animation'); +import Animation from './Animation'; -const {shouldUseNativeDriver} = require('../NativeAnimatedHelper'); +import NativeAnimatedHelper from '../NativeAnimatedHelper'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type AnimatedValue from '../nodes/AnimatedValue'; @@ -36,7 +36,7 @@ export type DecayAnimationConfigSingle = { deceleration?: number, }; -class DecayAnimation extends Animation { +export default class DecayAnimation extends Animation { _startTime: number; _lastValue: number; _fromValue: number; @@ -51,7 +51,7 @@ class DecayAnimation extends Animation { super(); this._deceleration = config.deceleration ?? 0.998; this._velocity = config.velocity; - this._useNativeDriver = shouldUseNativeDriver(config); + this._useNativeDriver = NativeAnimatedHelper.shouldUseNativeDriver(config); this._platformConfig = config.platformConfig; this.__isInteraction = config.isInteraction ?? !this._useNativeDriver; this.__iterations = config.iterations ?? 1; @@ -123,5 +123,3 @@ class DecayAnimation extends Animation { this.__debouncedOnEnd({finished: false}); } } - -module.exports = DecayAnimation; diff --git a/Libraries/Animated/animations/SpringAnimation.js b/Libraries/Animated/animations/SpringAnimation.js index 0d0d6ada083025..1c0d919b67c551 100644 --- a/Libraries/Animated/animations/SpringAnimation.js +++ b/Libraries/Animated/animations/SpringAnimation.js @@ -14,12 +14,12 @@ import type AnimatedValue from '../nodes/AnimatedValue'; import type AnimatedValueXY from '../nodes/AnimatedValueXY'; import type AnimatedInterpolation from '../nodes/AnimatedInterpolation'; -const Animation = require('./Animation'); -const SpringConfig = require('../SpringConfig'); +import Animation from './Animation'; +import * as SpringConfig from '../SpringConfig'; -const invariant = require('invariant'); +import invariant from 'invariant'; -const {shouldUseNativeDriver} = require('../NativeAnimatedHelper'); +import NativeAnimatedHelper from '../NativeAnimatedHelper'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type {AnimationConfig, EndCallback} from './Animation'; @@ -83,7 +83,7 @@ export type SpringAnimationConfigSingle = { delay?: number, }; -class SpringAnimation extends Animation { +export default class SpringAnimation extends Animation { _overshootClamping: boolean; _restDisplacementThreshold: number; _restSpeedThreshold: number; @@ -116,7 +116,7 @@ class SpringAnimation extends Animation { this._lastVelocity = config.velocity ?? 0; this._toValue = config.toValue; this._delay = config.delay ?? 0; - this._useNativeDriver = shouldUseNativeDriver(config); + this._useNativeDriver = NativeAnimatedHelper.shouldUseNativeDriver(config); this._platformConfig = config.platformConfig; this.__isInteraction = config.isInteraction ?? !this._useNativeDriver; this.__iterations = config.iterations ?? 1; @@ -372,5 +372,3 @@ class SpringAnimation extends Animation { this.__debouncedOnEnd({finished: false}); } } - -module.exports = SpringAnimation; diff --git a/Libraries/Animated/animations/TimingAnimation.js b/Libraries/Animated/animations/TimingAnimation.js index 12606f85c5d41c..5262b9703868e1 100644 --- a/Libraries/Animated/animations/TimingAnimation.js +++ b/Libraries/Animated/animations/TimingAnimation.js @@ -14,9 +14,9 @@ import type AnimatedValue from '../nodes/AnimatedValue'; import type AnimatedValueXY from '../nodes/AnimatedValueXY'; import type AnimatedInterpolation from '../nodes/AnimatedInterpolation'; -const Animation = require('./Animation'); +import Animation from './Animation'; -const {shouldUseNativeDriver} = require('../NativeAnimatedHelper'); +import NativeAnimatedHelper from '../NativeAnimatedHelper'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type {AnimationConfig, EndCallback} from './Animation'; @@ -54,13 +54,13 @@ export type TimingAnimationConfigSingle = $ReadOnly<{ let _easeInOut; function easeInOut() { if (!_easeInOut) { - const Easing = require('../Easing'); + const Easing = require('../Easing').default; _easeInOut = Easing.inOut(Easing.ease); } return _easeInOut; } -class TimingAnimation extends Animation { +export default class TimingAnimation extends Animation { _startTime: number; _fromValue: number; _toValue: number; @@ -80,7 +80,7 @@ class TimingAnimation extends Animation { this._duration = config.duration ?? 500; this._delay = config.delay ?? 0; this.__iterations = config.iterations ?? 1; - this._useNativeDriver = shouldUseNativeDriver(config); + this._useNativeDriver = NativeAnimatedHelper.shouldUseNativeDriver(config); this._platformConfig = config.platformConfig; this.__isInteraction = config.isInteraction ?? !this._useNativeDriver; } @@ -173,5 +173,3 @@ class TimingAnimation extends Animation { this.__debouncedOnEnd({finished: false}); } } - -module.exports = TimingAnimation; diff --git a/Libraries/Animated/bezier.js b/Libraries/Animated/bezier.js index da60afa0ec32e5..f18cef48e2daea 100644 --- a/Libraries/Animated/bezier.js +++ b/Libraries/Animated/bezier.js @@ -92,7 +92,7 @@ function newtonRaphsonIterate( return aGuessT; } -module.exports = function bezier( +export default function bezier( mX1: number, mY1: number, mX2: number, @@ -161,4 +161,4 @@ module.exports = function bezier( } return calcBezier(getTForX(x), mY1, mY2); }; -}; +} diff --git a/Libraries/Animated/components/AnimatedFlatList.js b/Libraries/Animated/components/AnimatedFlatList.js index ebe160f12e7545..966f6b272c023f 100644 --- a/Libraries/Animated/components/AnimatedFlatList.js +++ b/Libraries/Animated/components/AnimatedFlatList.js @@ -10,8 +10,8 @@ import * as React from 'react'; -const FlatList = require('../../Lists/FlatList'); -const createAnimatedComponent = require('../createAnimatedComponent'); +import FlatList from '../../Lists/FlatList'; +import createAnimatedComponent from '../createAnimatedComponent'; import type {AnimatedComponentType} from '../createAnimatedComponent'; @@ -22,7 +22,7 @@ const FlatListWithEventThrottle = React.forwardRef((props, ref) => ( )); -module.exports = (createAnimatedComponent( +export default (createAnimatedComponent( FlatListWithEventThrottle, ): AnimatedComponentType< React.ElementConfig, diff --git a/Libraries/Animated/components/AnimatedImage.js b/Libraries/Animated/components/AnimatedImage.js index b0e7b9042020c2..823f6bcdbc804a 100644 --- a/Libraries/Animated/components/AnimatedImage.js +++ b/Libraries/Animated/components/AnimatedImage.js @@ -10,12 +10,12 @@ import * as React from 'react'; -const Image = require('../../Image/Image'); -const createAnimatedComponent = require('../createAnimatedComponent'); +import Image from '../../Image/Image'; +import createAnimatedComponent from '../createAnimatedComponent'; import type {AnimatedComponentType} from '../createAnimatedComponent'; -module.exports = (createAnimatedComponent( +export default (createAnimatedComponent( (Image: $FlowFixMe), ): AnimatedComponentType< React.ElementConfig, diff --git a/Libraries/Animated/components/AnimatedScrollView.js b/Libraries/Animated/components/AnimatedScrollView.js index 887948366ac849..7589a04cd7fba4 100644 --- a/Libraries/Animated/components/AnimatedScrollView.js +++ b/Libraries/Animated/components/AnimatedScrollView.js @@ -10,8 +10,8 @@ import * as React from 'react'; -const ScrollView = require('../../Components/ScrollView/ScrollView'); -const createAnimatedComponent = require('../createAnimatedComponent'); +import ScrollView from '../../Components/ScrollView/ScrollView'; +import createAnimatedComponent from '../createAnimatedComponent'; import type {AnimatedComponentType} from '../createAnimatedComponent'; @@ -22,7 +22,7 @@ const ScrollViewWithEventThrottle = React.forwardRef((props, ref) => ( )); -module.exports = (createAnimatedComponent( +export default (createAnimatedComponent( ScrollViewWithEventThrottle, ): AnimatedComponentType< React.ElementConfig, diff --git a/Libraries/Animated/components/AnimatedSectionList.js b/Libraries/Animated/components/AnimatedSectionList.js index 2c467a66998282..e5dd4c6613a2c0 100644 --- a/Libraries/Animated/components/AnimatedSectionList.js +++ b/Libraries/Animated/components/AnimatedSectionList.js @@ -11,7 +11,7 @@ import * as React from 'react'; import SectionList from '../../Lists/SectionList'; -const createAnimatedComponent = require('../createAnimatedComponent'); +import createAnimatedComponent from '../createAnimatedComponent'; import type {AnimatedComponentType} from '../createAnimatedComponent'; @@ -22,7 +22,7 @@ const SectionListWithEventThrottle = React.forwardRef((props, ref) => ( )); -module.exports = (createAnimatedComponent( +export default (createAnimatedComponent( SectionListWithEventThrottle, ): AnimatedComponentType< React.ElementConfig, diff --git a/Libraries/Animated/components/AnimatedText.js b/Libraries/Animated/components/AnimatedText.js index 0cd6cd5245d301..6329932413d1a5 100644 --- a/Libraries/Animated/components/AnimatedText.js +++ b/Libraries/Animated/components/AnimatedText.js @@ -10,12 +10,12 @@ import * as React from 'react'; -const Text = require('../../Text/Text'); -const createAnimatedComponent = require('../createAnimatedComponent'); +import Text from '../../Text/Text'; +import createAnimatedComponent from '../createAnimatedComponent'; import type {AnimatedComponentType} from '../createAnimatedComponent'; -module.exports = (createAnimatedComponent( +export default (createAnimatedComponent( (Text: $FlowFixMe), ): AnimatedComponentType< React.ElementConfig, diff --git a/Libraries/Animated/components/AnimatedView.js b/Libraries/Animated/components/AnimatedView.js index 75358b003d5dfc..da01bc17e0790e 100644 --- a/Libraries/Animated/components/AnimatedView.js +++ b/Libraries/Animated/components/AnimatedView.js @@ -10,12 +10,12 @@ import * as React from 'react'; -const View = require('../../Components/View/View'); -const createAnimatedComponent = require('../createAnimatedComponent'); +import View from '../../Components/View/View'; +import createAnimatedComponent from '../createAnimatedComponent'; import type {AnimatedComponentType} from '../createAnimatedComponent'; -module.exports = (createAnimatedComponent(View): AnimatedComponentType< +export default (createAnimatedComponent(View): AnimatedComponentType< React.ElementConfig, React.ElementRef, >); diff --git a/Libraries/Animated/createAnimatedComponent.js b/Libraries/Animated/createAnimatedComponent.js index be43a6ba65672b..ec815279266434 100644 --- a/Libraries/Animated/createAnimatedComponent.js +++ b/Libraries/Animated/createAnimatedComponent.js @@ -12,14 +12,14 @@ import * as createAnimatedComponentInjection from './createAnimatedComponentInjection'; -const View = require('../Components/View/View'); -const {AnimatedEvent} = require('./AnimatedEvent'); -const AnimatedProps = require('./nodes/AnimatedProps'); -const React = require('react'); -const NativeAnimatedHelper = require('./NativeAnimatedHelper'); +import View from '../Components/View/View'; +import {AnimatedEvent} from './AnimatedEvent'; +import AnimatedProps from './nodes/AnimatedProps'; +import * as React from 'react'; +import NativeAnimatedHelper from './NativeAnimatedHelper'; -const invariant = require('invariant'); -const setAndForwardRef = require('../Utilities/setAndForwardRef'); +import invariant from 'invariant'; +import setAndForwardRef from '../Utilities/setAndForwardRef'; let animatedComponentNextId = 1; @@ -277,5 +277,5 @@ function createAnimatedComponent( } // $FlowIgnore[incompatible-cast] - Will be compatible after refactors. -module.exports = (createAnimatedComponentInjection.recordAndRetrieve() ?? +export default (createAnimatedComponentInjection.recordAndRetrieve() ?? createAnimatedComponent: typeof createAnimatedComponent); diff --git a/Libraries/Animated/nodes/AnimatedAddition.js b/Libraries/Animated/nodes/AnimatedAddition.js index ea430c6cd72220..c5e35fce04e357 100644 --- a/Libraries/Animated/nodes/AnimatedAddition.js +++ b/Libraries/Animated/nodes/AnimatedAddition.js @@ -12,14 +12,14 @@ import type AnimatedNode from './AnimatedNode'; -const AnimatedInterpolation = require('./AnimatedInterpolation'); -const AnimatedValue = require('./AnimatedValue'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import AnimatedInterpolation from './AnimatedInterpolation'; +import AnimatedValue from './AnimatedValue'; +import AnimatedWithChildren from './AnimatedWithChildren'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type {InterpolationConfigType} from './AnimatedInterpolation'; -class AnimatedAddition extends AnimatedWithChildren { +export default class AnimatedAddition extends AnimatedWithChildren { _a: AnimatedNode; _b: AnimatedNode; @@ -63,5 +63,3 @@ class AnimatedAddition extends AnimatedWithChildren { }; } } - -module.exports = AnimatedAddition; diff --git a/Libraries/Animated/nodes/AnimatedDiffClamp.js b/Libraries/Animated/nodes/AnimatedDiffClamp.js index 98f070cb7fb40b..c543e8069f9576 100644 --- a/Libraries/Animated/nodes/AnimatedDiffClamp.js +++ b/Libraries/Animated/nodes/AnimatedDiffClamp.js @@ -12,13 +12,13 @@ import type AnimatedNode from './AnimatedNode'; -const AnimatedInterpolation = require('./AnimatedInterpolation'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import AnimatedInterpolation from './AnimatedInterpolation'; +import AnimatedWithChildren from './AnimatedWithChildren'; import type {InterpolationConfigType} from './AnimatedInterpolation'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; -class AnimatedDiffClamp extends AnimatedWithChildren { +export default class AnimatedDiffClamp extends AnimatedWithChildren { _a: AnimatedNode; _min: number; _max: number; @@ -71,5 +71,3 @@ class AnimatedDiffClamp extends AnimatedWithChildren { }; } } - -module.exports = AnimatedDiffClamp; diff --git a/Libraries/Animated/nodes/AnimatedDivision.js b/Libraries/Animated/nodes/AnimatedDivision.js index 3d77e2de6453e7..ee5e768d344590 100644 --- a/Libraries/Animated/nodes/AnimatedDivision.js +++ b/Libraries/Animated/nodes/AnimatedDivision.js @@ -10,15 +10,15 @@ 'use strict'; -const AnimatedInterpolation = require('./AnimatedInterpolation'); -const AnimatedNode = require('./AnimatedNode'); -const AnimatedValue = require('./AnimatedValue'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import AnimatedInterpolation from './AnimatedInterpolation'; +import AnimatedNode from './AnimatedNode'; +import AnimatedValue from './AnimatedValue'; +import AnimatedWithChildren from './AnimatedWithChildren'; import type {InterpolationConfigType} from './AnimatedInterpolation'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; -class AnimatedDivision extends AnimatedWithChildren { +export default class AnimatedDivision extends AnimatedWithChildren { _a: AnimatedNode; _b: AnimatedNode; _warnedAboutDivideByZero: boolean = false; @@ -78,5 +78,3 @@ class AnimatedDivision extends AnimatedWithChildren { }; } } - -module.exports = AnimatedDivision; diff --git a/Libraries/Animated/nodes/AnimatedInterpolation.js b/Libraries/Animated/nodes/AnimatedInterpolation.js index 911122c113a21d..e246cf2742ee7b 100644 --- a/Libraries/Animated/nodes/AnimatedInterpolation.js +++ b/Libraries/Animated/nodes/AnimatedInterpolation.js @@ -14,11 +14,11 @@ import type AnimatedNode from './AnimatedNode'; -const AnimatedWithChildren = require('./AnimatedWithChildren'); -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); +import AnimatedWithChildren from './AnimatedWithChildren'; +import NativeAnimatedHelper from '../NativeAnimatedHelper'; -const invariant = require('invariant'); -const normalizeColor = require('../../StyleSheet/normalizeColor'); +import invariant from 'invariant'; +import normalizeColor from '../../StyleSheet/normalizeColor'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; @@ -300,7 +300,7 @@ function checkInfiniteRange(name: string, arr: $ReadOnlyArray) { ); } -class AnimatedInterpolation< +export default class AnimatedInterpolation< OutputT: number | string, > extends AnimatedWithChildren { // Export for testing. @@ -369,5 +369,3 @@ class AnimatedInterpolation< }; } } - -module.exports = AnimatedInterpolation; diff --git a/Libraries/Animated/nodes/AnimatedModulo.js b/Libraries/Animated/nodes/AnimatedModulo.js index a05d4d694d5210..a465cf075f8620 100644 --- a/Libraries/Animated/nodes/AnimatedModulo.js +++ b/Libraries/Animated/nodes/AnimatedModulo.js @@ -12,13 +12,13 @@ import type AnimatedNode from './AnimatedNode'; -const AnimatedInterpolation = require('./AnimatedInterpolation'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import AnimatedInterpolation from './AnimatedInterpolation'; +import AnimatedWithChildren from './AnimatedWithChildren'; import type {InterpolationConfigType} from './AnimatedInterpolation'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; -class AnimatedModulo extends AnimatedWithChildren { +export default class AnimatedModulo extends AnimatedWithChildren { _a: AnimatedNode; _modulus: number; @@ -62,5 +62,3 @@ class AnimatedModulo extends AnimatedWithChildren { }; } } - -module.exports = AnimatedModulo; diff --git a/Libraries/Animated/nodes/AnimatedMultiplication.js b/Libraries/Animated/nodes/AnimatedMultiplication.js index 7053a5726a03aa..d16ddf38fb4e57 100644 --- a/Libraries/Animated/nodes/AnimatedMultiplication.js +++ b/Libraries/Animated/nodes/AnimatedMultiplication.js @@ -12,14 +12,14 @@ import type AnimatedNode from './AnimatedNode'; -const AnimatedInterpolation = require('./AnimatedInterpolation'); -const AnimatedValue = require('./AnimatedValue'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import AnimatedInterpolation from './AnimatedInterpolation'; +import AnimatedValue from './AnimatedValue'; +import AnimatedWithChildren from './AnimatedWithChildren'; import type {InterpolationConfigType} from './AnimatedInterpolation'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; -class AnimatedMultiplication extends AnimatedWithChildren { +export default class AnimatedMultiplication extends AnimatedWithChildren { _a: AnimatedNode; _b: AnimatedNode; @@ -62,5 +62,3 @@ class AnimatedMultiplication extends AnimatedWithChildren { }; } } - -module.exports = AnimatedMultiplication; diff --git a/Libraries/Animated/nodes/AnimatedNode.js b/Libraries/Animated/nodes/AnimatedNode.js index 159bf819a4a633..d753c2aa1720c0 100644 --- a/Libraries/Animated/nodes/AnimatedNode.js +++ b/Libraries/Animated/nodes/AnimatedNode.js @@ -10,20 +10,21 @@ 'use strict'; -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); +import NativeAnimatedHelper from '../NativeAnimatedHelper'; -const NativeAnimatedAPI = NativeAnimatedHelper.API; -const invariant = require('invariant'); +import invariant from 'invariant'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; +const NativeAnimatedAPI = NativeAnimatedHelper.API; + type ValueListenerCallback = (state: {value: number, ...}) => mixed; let _uniqueId = 1; // Note(vjeux): this would be better as an interface but flow doesn't // support them yet -class AnimatedNode { +export default class AnimatedNode { _listeners: {[key: string]: ValueListenerCallback, ...}; _platformConfig: ?PlatformConfig; __nativeAnimatedValueListener: ?any; @@ -193,5 +194,3 @@ class AnimatedNode { this._platformConfig = platformConfig; } } - -module.exports = AnimatedNode; diff --git a/Libraries/Animated/nodes/AnimatedProps.js b/Libraries/Animated/nodes/AnimatedProps.js index d4ed70da8d6e9c..fffa6e496e8ae3 100644 --- a/Libraries/Animated/nodes/AnimatedProps.js +++ b/Libraries/Animated/nodes/AnimatedProps.js @@ -12,14 +12,15 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; -const ReactNative = require('../../Renderer/shims/ReactNative'); -const {AnimatedEvent} = require('../AnimatedEvent'); -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); -const AnimatedNode = require('./AnimatedNode'); -const AnimatedStyle = require('./AnimatedStyle'); -const invariant = require('invariant'); - -class AnimatedProps extends AnimatedNode { +import {AnimatedEvent} from '../AnimatedEvent'; +import NativeAnimatedHelper from '../NativeAnimatedHelper'; +import {findNodeHandle} from '../../ReactNative/RendererProxy'; +import invariant from 'invariant'; + +import AnimatedNode from './AnimatedNode'; +import AnimatedStyle from './AnimatedStyle'; + +export default class AnimatedProps extends AnimatedNode { _props: Object; _animatedView: any; _callback: () => void; @@ -134,9 +135,7 @@ class AnimatedProps extends AnimatedNode { __connectAnimatedView(): void { invariant(this.__isNative, 'Expected node to be marked as "native"'); - const nativeViewTag: ?number = ReactNative.findNodeHandle( - this._animatedView, - ); + const nativeViewTag: ?number = findNodeHandle(this._animatedView); invariant( nativeViewTag != null, 'Unable to locate attached view in the native tree', @@ -149,9 +148,7 @@ class AnimatedProps extends AnimatedNode { __disconnectAnimatedView(): void { invariant(this.__isNative, 'Expected node to be marked as "native"'); - const nativeViewTag: ?number = ReactNative.findNodeHandle( - this._animatedView, - ); + const nativeViewTag: ?number = findNodeHandle(this._animatedView); invariant( nativeViewTag != null, 'Unable to locate attached view in the native tree', @@ -187,5 +184,3 @@ class AnimatedProps extends AnimatedNode { }; } } - -module.exports = AnimatedProps; diff --git a/Libraries/Animated/nodes/AnimatedStyle.js b/Libraries/Animated/nodes/AnimatedStyle.js index 7ec61c77ce48a8..b523b41ba6e1ba 100644 --- a/Libraries/Animated/nodes/AnimatedStyle.js +++ b/Libraries/Animated/nodes/AnimatedStyle.js @@ -12,13 +12,13 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; -const flattenStyle = require('../../StyleSheet/flattenStyle'); -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); -const AnimatedNode = require('./AnimatedNode'); -const AnimatedTransform = require('./AnimatedTransform'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import flattenStyle from '../../StyleSheet/flattenStyle'; +import NativeAnimatedHelper from '../NativeAnimatedHelper'; +import AnimatedNode from './AnimatedNode'; +import AnimatedTransform from './AnimatedTransform'; +import AnimatedWithChildren from './AnimatedWithChildren'; -class AnimatedStyle extends AnimatedWithChildren { +export default class AnimatedStyle extends AnimatedWithChildren { _style: Object; constructor(style: any) { @@ -131,5 +131,3 @@ class AnimatedStyle extends AnimatedWithChildren { }; } } - -module.exports = AnimatedStyle; diff --git a/Libraries/Animated/nodes/AnimatedSubtraction.js b/Libraries/Animated/nodes/AnimatedSubtraction.js index 9cd15cec044125..111d720ae92fb5 100644 --- a/Libraries/Animated/nodes/AnimatedSubtraction.js +++ b/Libraries/Animated/nodes/AnimatedSubtraction.js @@ -12,14 +12,14 @@ import type AnimatedNode from './AnimatedNode'; -const AnimatedInterpolation = require('./AnimatedInterpolation'); -const AnimatedValue = require('./AnimatedValue'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import AnimatedInterpolation from './AnimatedInterpolation'; +import AnimatedValue from './AnimatedValue'; +import AnimatedWithChildren from './AnimatedWithChildren'; import type {InterpolationConfigType} from './AnimatedInterpolation'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; -class AnimatedSubtraction extends AnimatedWithChildren { +export default class AnimatedSubtraction extends AnimatedWithChildren { _a: AnimatedNode; _b: AnimatedNode; @@ -63,5 +63,3 @@ class AnimatedSubtraction extends AnimatedWithChildren { }; } } - -module.exports = AnimatedSubtraction; diff --git a/Libraries/Animated/nodes/AnimatedTracking.js b/Libraries/Animated/nodes/AnimatedTracking.js index 2275d3c6d14d7a..6099a23c29730d 100644 --- a/Libraries/Animated/nodes/AnimatedTracking.js +++ b/Libraries/Animated/nodes/AnimatedTracking.js @@ -12,16 +12,13 @@ import type AnimatedValue from './AnimatedValue'; -const AnimatedNode = require('./AnimatedNode'); -const { - generateNewAnimationId, - shouldUseNativeDriver, -} = require('../NativeAnimatedHelper'); +import AnimatedNode from './AnimatedNode'; +import NativeAnimatedHelper from '../NativeAnimatedHelper'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type {EndCallback} from '../animations/Animation'; -class AnimatedTracking extends AnimatedNode { +export default class AnimatedTracking extends AnimatedNode { _value: AnimatedValue; _parent: AnimatedNode; _callback: ?EndCallback; @@ -41,7 +38,8 @@ class AnimatedTracking extends AnimatedNode { this._parent = parent; this._animationClass = animationClass; this._animationConfig = animationConfig; - this._useNativeDriver = shouldUseNativeDriver(animationConfig); + this._useNativeDriver = + NativeAnimatedHelper.shouldUseNativeDriver(animationConfig); this._callback = callback; this.__attach(); } @@ -94,12 +92,10 @@ class AnimatedTracking extends AnimatedNode { const animationConfig = animation.__getNativeAnimationConfig(); return { type: 'tracking', - animationId: generateNewAnimationId(), + animationId: NativeAnimatedHelper.generateNewAnimationId(), animationConfig, toValue: this._parent.__getNativeTag(), value: this._value.__getNativeTag(), }; } } - -module.exports = AnimatedTracking; diff --git a/Libraries/Animated/nodes/AnimatedTransform.js b/Libraries/Animated/nodes/AnimatedTransform.js index c3d4175fc6f4cd..d68c844c31311d 100644 --- a/Libraries/Animated/nodes/AnimatedTransform.js +++ b/Libraries/Animated/nodes/AnimatedTransform.js @@ -12,11 +12,11 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); -const AnimatedNode = require('./AnimatedNode'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import NativeAnimatedHelper from '../NativeAnimatedHelper'; +import AnimatedNode from './AnimatedNode'; +import AnimatedWithChildren from './AnimatedWithChildren'; -class AnimatedTransform extends AnimatedWithChildren { +export default class AnimatedTransform extends AnimatedWithChildren { _transforms: $ReadOnlyArray; constructor(transforms: $ReadOnlyArray) { @@ -119,5 +119,3 @@ class AnimatedTransform extends AnimatedWithChildren { }; } } - -module.exports = AnimatedTransform; diff --git a/Libraries/Animated/nodes/AnimatedValue.js b/Libraries/Animated/nodes/AnimatedValue.js index 4d6f37b2f02591..dcb11e36e8343c 100644 --- a/Libraries/Animated/nodes/AnimatedValue.js +++ b/Libraries/Animated/nodes/AnimatedValue.js @@ -10,10 +10,10 @@ 'use strict'; -const AnimatedInterpolation = require('./AnimatedInterpolation'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); -const InteractionManager = require('../../Interaction/InteractionManager'); -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); +import AnimatedInterpolation from './AnimatedInterpolation'; +import AnimatedWithChildren from './AnimatedWithChildren'; +import InteractionManager from '../../Interaction/InteractionManager'; +import NativeAnimatedHelper from '../NativeAnimatedHelper'; import type AnimatedNode from './AnimatedNode'; import type Animation, {EndCallback} from '../animations/Animation'; @@ -84,7 +84,7 @@ function _executeAsAnimatedBatch(id: string, operation: () => void) { * * See https://reactnative.dev/docs/animatedvalue */ -class AnimatedValue extends AnimatedWithChildren { +export default class AnimatedValue extends AnimatedWithChildren { _value: number; _startingValue: number; _offset: number; @@ -304,5 +304,3 @@ class AnimatedValue extends AnimatedWithChildren { }; } } - -module.exports = AnimatedValue; diff --git a/Libraries/Animated/nodes/AnimatedValueXY.js b/Libraries/Animated/nodes/AnimatedValueXY.js index c54a9d9d6f55e5..4d554f15c04d27 100644 --- a/Libraries/Animated/nodes/AnimatedValueXY.js +++ b/Libraries/Animated/nodes/AnimatedValueXY.js @@ -12,10 +12,10 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; -const AnimatedValue = require('./AnimatedValue'); -const AnimatedWithChildren = require('./AnimatedWithChildren'); +import AnimatedValue from './AnimatedValue'; +import AnimatedWithChildren from './AnimatedWithChildren'; -const invariant = require('invariant'); +import invariant from 'invariant'; export type AnimatedValueXYConfig = $ReadOnly<{ useNativeDriver: boolean, @@ -34,7 +34,7 @@ let _uniqueId = 1; * * See https://reactnative.dev/docs/animatedvaluexy */ -class AnimatedValueXY extends AnimatedWithChildren { +export default class AnimatedValueXY extends AnimatedWithChildren { x: AnimatedValue; y: AnimatedValue; _listeners: { @@ -249,5 +249,3 @@ class AnimatedValueXY extends AnimatedWithChildren { super.__makeNative(platformConfig); } } - -module.exports = AnimatedValueXY; diff --git a/Libraries/Animated/nodes/AnimatedWithChildren.js b/Libraries/Animated/nodes/AnimatedWithChildren.js index 435365d1f6ee6d..d60df641e9c09b 100644 --- a/Libraries/Animated/nodes/AnimatedWithChildren.js +++ b/Libraries/Animated/nodes/AnimatedWithChildren.js @@ -11,10 +11,10 @@ 'use strict'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; -const AnimatedNode = require('./AnimatedNode'); -const NativeAnimatedHelper = require('../NativeAnimatedHelper'); +import AnimatedNode from './AnimatedNode'; +import NativeAnimatedHelper from '../NativeAnimatedHelper'; -class AnimatedWithChildren extends AnimatedNode { +export default class AnimatedWithChildren extends AnimatedNode { _children: Array; constructor() { @@ -85,5 +85,3 @@ class AnimatedWithChildren extends AnimatedNode { } } } - -module.exports = AnimatedWithChildren; diff --git a/Libraries/BatchedBridge/NativeModules.js b/Libraries/BatchedBridge/NativeModules.js index 30259e79b9fdec..0ea6b7c5c4a83e 100644 --- a/Libraries/BatchedBridge/NativeModules.js +++ b/Libraries/BatchedBridge/NativeModules.js @@ -155,6 +155,7 @@ function genMethod(moduleID: number, methodID: number, type: MethodType) { } }; } + // $FlowFixMe[prop-missing] fn.type = type; return fn; } diff --git a/Libraries/BatchedBridge/__tests__/MessageQueue-test.js b/Libraries/BatchedBridge/__tests__/MessageQueue-test.js index e80e024b6fedb9..46304de89ad7ac 100644 --- a/Libraries/BatchedBridge/__tests__/MessageQueue-test.js +++ b/Libraries/BatchedBridge/__tests__/MessageQueue-test.js @@ -4,8 +4,8 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @emails oncall+react_native * @format + * @oncall react_native */ 'use strict'; diff --git a/Libraries/BatchedBridge/__tests__/NativeModules-test.js b/Libraries/BatchedBridge/__tests__/NativeModules-test.js index f4d4aa7a93a6c8..570c95127940f8 100644 --- a/Libraries/BatchedBridge/__tests__/NativeModules-test.js +++ b/Libraries/BatchedBridge/__tests__/NativeModules-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Blob/__tests__/Blob-test.js b/Libraries/Blob/__tests__/Blob-test.js index 5e406f024dd084..9fdabab67ef530 100644 --- a/Libraries/Blob/__tests__/Blob-test.js +++ b/Libraries/Blob/__tests__/Blob-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Blob/__tests__/BlobManager-test.js b/Libraries/Blob/__tests__/BlobManager-test.js index e03dd87d9d1c85..856eac1ad869d5 100644 --- a/Libraries/Blob/__tests__/BlobManager-test.js +++ b/Libraries/Blob/__tests__/BlobManager-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Blob/__tests__/File-test.js b/Libraries/Blob/__tests__/File-test.js index 21b50650a99879..b6d6c31ec2fe72 100644 --- a/Libraries/Blob/__tests__/File-test.js +++ b/Libraries/Blob/__tests__/File-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Blob/__tests__/FileReader-test.js b/Libraries/Blob/__tests__/FileReader-test.js index 8ae1c81a31f8a8..1e1ac1ab7a4dd6 100644 --- a/Libraries/Blob/__tests__/FileReader-test.js +++ b/Libraries/Blob/__tests__/FileReader-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Blob/__tests__/URL-test.js b/Libraries/Blob/__tests__/URL-test.js index 28e89950b267db..c317217c8fe724 100644 --- a/Libraries/Blob/__tests__/URL-test.js +++ b/Libraries/Blob/__tests__/URL-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js index 556db6835801d5..be45c92c6f4172 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js @@ -9,7 +9,7 @@ */ import RCTDeviceEventEmitter from '../../EventEmitter/RCTDeviceEventEmitter'; -import {sendAccessibilityEvent} from '../../Renderer/shims/ReactNative'; +import {sendAccessibilityEvent} from '../../ReactNative/RendererProxy'; import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import Platform from '../../Utilities/Platform'; import type {EventSubscription} from '../../vendor/emitter/EventEmitter'; diff --git a/Libraries/Components/ActivityIndicator/__tests__/ActivityIndicator-test.js b/Libraries/Components/ActivityIndicator/__tests__/ActivityIndicator-test.js index 91cb7bd6e29291..a08495457e2b28 100644 --- a/Libraries/Components/ActivityIndicator/__tests__/ActivityIndicator-test.js +++ b/Libraries/Components/ActivityIndicator/__tests__/ActivityIndicator-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format - * @emails oncall+react_native * @flow strict-local + * @format + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/Button.flow.js b/Libraries/Components/Button.flow.js index 614c36af83f1e8..abf6d00538fd35 100644 --- a/Libraries/Components/Button.flow.js +++ b/Libraries/Components/Button.flow.js @@ -119,7 +119,11 @@ type ButtonProps = $ReadOnly<{| Text to display for blindness accessibility features. */ accessibilityLabel?: ?string, - + /** + * Alias for accessibilityLabel https://reactnative.dev/docs/view#accessibilitylabel + * https://github.com/facebook/react-native/issues/34424 + */ + 'aria-label'?: ?string, /** If `true`, disable all interactions for this component. diff --git a/Libraries/Components/Button.js b/Libraries/Components/Button.js index d396acebf5e59f..08723a7e2f9715 100644 --- a/Libraries/Components/Button.js +++ b/Libraries/Components/Button.js @@ -126,7 +126,11 @@ type ButtonProps = $ReadOnly<{| Text to display for blindness accessibility features. */ accessibilityLabel?: ?string, - + /** + * Alias for accessibilityLabel https://reactnative.dev/docs/view#accessibilitylabel + * https://github.com/facebook/react-native/issues/34424 + */ + 'aria-label'?: ?string, /** If `true`, disable all interactions for this component. @@ -147,6 +151,17 @@ type ButtonProps = $ReadOnly<{| onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, accessibilityState?: ?AccessibilityState, + /** + * alias for accessibilityState + * + * see https://reactnative.dev/docs/accessibility#accessibilitystate + */ + 'aria-busy'?: ?boolean, + 'aria-checked'?: ?boolean, + 'aria-disabled'?: ?boolean, + 'aria-expanded'?: ?boolean, + 'aria-selected'?: ?boolean, + /** * [Android] Controlling if a view fires accessibility events and if it is reported to accessibility services. */ @@ -270,6 +285,13 @@ class Button extends React.Component { render(): React.Node { const { accessibilityLabel, + accessibilityState, + 'aria-busy': ariaBusy, + 'aria-checked': ariaChecked, + 'aria-disabled': ariaDisabled, + 'aria-expanded': ariaExpanded, + 'aria-label': ariaLabel, + 'aria-selected': ariaSelected, importantForAccessibility, color, onPress, @@ -298,15 +320,23 @@ class Button extends React.Component { } } + let _accessibilityState = { + busy: ariaBusy ?? accessibilityState?.busy, + checked: ariaChecked ?? accessibilityState?.checked, + disabled: ariaDisabled ?? accessibilityState?.disabled, + expanded: ariaExpanded ?? accessibilityState?.expanded, + selected: ariaSelected ?? accessibilityState?.selected, + }; + const disabled = this.props.disabled != null ? this.props.disabled - : this.props.accessibilityState?.disabled; + : _accessibilityState?.disabled; - const accessibilityState = - disabled !== this.props.accessibilityState?.disabled - ? {...this.props.accessibilityState, disabled} - : this.props.accessibilityState; + _accessibilityState = + disabled !== _accessibilityState?.disabled + ? {..._accessibilityState, disabled} + : _accessibilityState; if (disabled) { buttonStyles.push(styles.buttonDisabled); @@ -333,11 +363,11 @@ class Button extends React.Component { accessible={accessible} accessibilityActions={accessibilityActions} onAccessibilityAction={onAccessibilityAction} - accessibilityLabel={accessibilityLabel} + accessibilityLabel={ariaLabel || accessibilityLabel} accessibilityHint={accessibilityHint} accessibilityLanguage={accessibilityLanguage} accessibilityRole="button" - accessibilityState={accessibilityState} + accessibilityState={_accessibilityState} importantForAccessibility={_importantForAccessibility} hasTVPreferredFocus={hasTVPreferredFocus} nextFocusDown={nextFocusDown} diff --git a/Libraries/Components/DatePicker/__tests__/DatePickerIOS-test.js b/Libraries/Components/DatePicker/__tests__/DatePickerIOS-test.js index 4fdcf8f8ca2727..d6c34e12fa91cf 100644 --- a/Libraries/Components/DatePicker/__tests__/DatePickerIOS-test.js +++ b/Libraries/Components/DatePicker/__tests__/DatePickerIOS-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format - * @emails oncall+react_native * @flow + * @format + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/DrawerAndroid/__tests__/DrawerAndroid-test.js b/Libraries/Components/DrawerAndroid/__tests__/DrawerAndroid-test.js index bc1b173de0a343..db9c10fe8752a5 100644 --- a/Libraries/Components/DrawerAndroid/__tests__/DrawerAndroid-test.js +++ b/Libraries/Components/DrawerAndroid/__tests__/DrawerAndroid-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format - * @emails oncall+react_native * @flow strict-local + * @format + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/Keyboard/__tests__/Keyboard-test.js b/Libraries/Components/Keyboard/__tests__/Keyboard-test.js index 3094781e2cc201..d3192afc7c7ded 100644 --- a/Libraries/Components/Keyboard/__tests__/Keyboard-test.js +++ b/Libraries/Components/Keyboard/__tests__/Keyboard-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format * @flow strict-local - * @emails oncall+react_native + * @format + * @oncall react_native */ const LayoutAnimation = require('../../../LayoutAnimation/LayoutAnimation'); diff --git a/Libraries/Components/Pressable/Pressable.js b/Libraries/Components/Pressable/Pressable.js index aab4f21d33ed89..47498ac37f102b 100644 --- a/Libraries/Components/Pressable/Pressable.js +++ b/Libraries/Components/Pressable/Pressable.js @@ -50,8 +50,30 @@ type Props = $ReadOnly<{| accessibilityRole?: ?AccessibilityRole, accessibilityState?: ?AccessibilityState, accessibilityValue?: ?AccessibilityValue, + 'aria-valuemax'?: AccessibilityValue['max'], + 'aria-valuemin'?: AccessibilityValue['min'], + 'aria-valuenow'?: AccessibilityValue['now'], + 'aria-valuetext'?: AccessibilityValue['text'], accessibilityViewIsModal?: ?boolean, + 'aria-modal'?: ?boolean, accessible?: ?boolean, + + /** + * alias for accessibilityState + * + * see https://reactnative.dev/docs/accessibility#accessibilitystate + */ + 'aria-busy'?: ?boolean, + 'aria-checked'?: ?boolean, + 'aria-disabled'?: ?boolean, + 'aria-expanded'?: ?boolean, + 'aria-selected'?: ?boolean, + /** + * A value indicating whether the accessibility elements contained within + * this accessibility element are hidden. + */ + 'aria-hidden'?: ?boolean, + 'aria-live'?: ?('polite' | 'assertive' | 'off'), focusable?: ?boolean, importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, @@ -164,6 +186,11 @@ type Props = $ReadOnly<{| * Duration to wait after press down before calling `onPressIn`. */ unstable_pressDelay?: ?number, + /** + * Web to Native Accessibilty props + * https://github.com/facebook/react-native/issues/34424 + */ + 'aria-label'?: ?string, |}>; /** @@ -175,8 +202,16 @@ type Props = $ReadOnly<{| function Pressable(props: Props, forwardedRef): React.Node { const { accessible, + accessibilityState, + 'aria-live': ariaLive, android_disableSound, android_ripple, + 'aria-busy': ariaBusy, + 'aria-checked': ariaChecked, + 'aria-disabled': ariaDisabled, + 'aria-expanded': ariaExpanded, + 'aria-label': ariaLabel, + 'aria-selected': ariaSelected, cancelable, children, delayHoverIn, @@ -205,17 +240,39 @@ function Pressable(props: Props, forwardedRef): React.Node { const [pressed, setPressed] = usePressState(testOnly_pressed === true); - const accessibilityState = - disabled != null - ? {...props.accessibilityState, disabled} - : props.accessibilityState; + let _accessibilityState = { + busy: ariaBusy ?? accessibilityState?.busy, + checked: ariaChecked ?? accessibilityState?.checked, + disabled: ariaDisabled ?? accessibilityState?.disabled, + expanded: ariaExpanded ?? accessibilityState?.expanded, + selected: ariaSelected ?? accessibilityState?.selected, + }; + + _accessibilityState = + disabled != null ? {..._accessibilityState, disabled} : _accessibilityState; + const accessibilityValue = { + max: props['aria-valuemax'] ?? props.accessibilityValue?.max, + min: props['aria-valuemin'] ?? props.accessibilityValue?.min, + now: props['aria-valuenow'] ?? props.accessibilityValue?.now, + text: props['aria-valuetext'] ?? props.accessibilityValue?.text, + }; + + const accessibilityLiveRegion = + ariaLive === 'off' ? 'none' : ariaLive ?? props.accessibilityLiveRegion; + + const accessibilityLabel = ariaLabel ?? props.accessibilityLabel; const restPropsWithDefaults: React.ElementConfig = { ...restProps, ...android_rippleConfig?.viewProps, accessible: accessible !== false, - accessibilityState, + accessibilityViewIsModal: + restProps['aria-modal'] ?? restProps.accessibilityViewIsModal, + accessibilityLiveRegion, + accessibilityLabel, + accessibilityState: _accessibilityState, focusable: focusable !== false, + accessibilityValue, hitSlop, }; diff --git a/Libraries/Components/Pressable/__tests__/Pressable-test.js b/Libraries/Components/Pressable/__tests__/Pressable-test.js index 09bb7ac8f336ca..29a3071d8bce89 100644 --- a/Libraries/Components/Pressable/__tests__/Pressable-test.js +++ b/Libraries/Components/Pressable/__tests__/Pressable-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format - * @emails oncall+react_native * @flow strict-local + * @format + * @oncall react_native */ import * as React from 'react'; diff --git a/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap b/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap index 821d4f41ea56e5..e348e02347e52b 100644 --- a/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap +++ b/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap @@ -2,6 +2,23 @@ exports[` should render as expected: should deep render when mocked (please verify output manually) 1`] = ` should render as expected: should deep render when mocked exports[` should render as expected: should deep render when not mocked (please verify output manually) 1`] = ` should be disabled when disabled is true: should be disabled when disabled is true: should be disable should be disable shou shou sh sh { }; getScrollableNode: () => ?number = () => { - return ReactNative.findNodeHandle(this._scrollViewRef); + return findNodeHandle(this._scrollViewRef); }; getInnerViewNode: () => ?number = () => { - return ReactNative.findNodeHandle(this._innerViewRef); + return findNodeHandle(this._innerViewRef); }; getInnerViewRef: () => ?React.ElementRef = () => { @@ -996,7 +999,7 @@ class ScrollView extends React.Component { if (typeof nodeHandle === 'number') { UIManager.measureLayout( nodeHandle, - ReactNative.findNodeHandle(this), + findNodeHandle(this), // $FlowFixMe[method-unbinding] added when improving typing for this parameters this._textInputFocusError, this._inputMeasureAndScrollToKeyboard, diff --git a/Libraries/Components/ScrollView/__tests__/ScrollView-test.js b/Libraries/Components/ScrollView/__tests__/ScrollView-test.js index 656017185ddefe..7711562fff2da1 100644 --- a/Libraries/Components/ScrollView/__tests__/ScrollView-test.js +++ b/Libraries/Components/ScrollView/__tests__/ScrollView-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format - * @emails oncall+react_native * @flow-strict + * @format + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/StatusBar/__tests__/StatusBar-test.js b/Libraries/Components/StatusBar/__tests__/StatusBar-test.js index 976af8aa6985a9..bb2689d5d6aea4 100644 --- a/Libraries/Components/StatusBar/__tests__/StatusBar-test.js +++ b/Libraries/Components/StatusBar/__tests__/StatusBar-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/TextInput/TextInput.flow.js b/Libraries/Components/TextInput/TextInput.flow.js new file mode 100644 index 00000000000000..6ab10861b68530 --- /dev/null +++ b/Libraries/Components/TextInput/TextInput.flow.js @@ -0,0 +1,1051 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import * as React from 'react'; + +import { + type TextStyleProp, + type ViewStyleProp, + type ColorValue, +} from '../../StyleSheet/StyleSheet'; +import type {ViewProps} from '../View/ViewPropTypes'; +import type { + SyntheticEvent, + ScrollEvent, + PressEvent, +} from '../../Types/CoreEventTypes'; +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +type ComponentRef = React.ElementRef>; + +type ReactRefSetter = {current: null | T, ...} | ((ref: null | T) => mixed); + +export type ChangeEvent = SyntheticEvent< + $ReadOnly<{| + eventCount: number, + target: number, + text: string, + |}>, +>; + +export type TextInputEvent = SyntheticEvent< + $ReadOnly<{| + eventCount: number, + previousText: string, + range: $ReadOnly<{| + start: number, + end: number, + |}>, + target: number, + text: string, + |}>, +>; + +export type ContentSizeChangeEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + contentSize: $ReadOnly<{| + width: number, + height: number, + |}>, + |}>, +>; + +type TargetEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, +>; + +export type BlurEvent = TargetEvent; +export type FocusEvent = TargetEvent; + +type Selection = $ReadOnly<{| + start: number, + end: number, +|}>; + +export type SelectionChangeEvent = SyntheticEvent< + $ReadOnly<{| + selection: Selection, + target: number, + |}>, +>; + +export type KeyPressEvent = SyntheticEvent< + $ReadOnly<{| + key: string, + target?: ?number, + eventCount?: ?number, + |}>, +>; + +export type EditingEvent = SyntheticEvent< + $ReadOnly<{| + eventCount: number, + text: string, + target: number, + |}>, +>; + +type DataDetectorTypesType = + | 'phoneNumber' + | 'link' + | 'address' + | 'calendarEvent' + | 'none' + | 'all'; + +export type KeyboardType = + // Cross Platform + | 'default' + | 'email-address' + | 'numeric' + | 'phone-pad' + | 'number-pad' + | 'decimal-pad' + | 'url' + // iOS-only + | 'ascii-capable' + | 'numbers-and-punctuation' + | 'name-phone-pad' + | 'twitter' + | 'web-search' + // iOS 10+ only + | 'ascii-capable-number-pad' + // Android-only + | 'visible-password'; + +export type InputMode = + | 'none' + | 'text' + | 'decimal' + | 'numeric' + | 'tel' + | 'search' + | 'email' + | 'url'; + +export type ReturnKeyType = + // Cross Platform + | 'done' + | 'go' + | 'next' + | 'search' + | 'send' + // Android-only + | 'none' + | 'previous' + // iOS-only + | 'default' + | 'emergency-call' + | 'google' + | 'join' + | 'route' + | 'yahoo'; + +export type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline'; + +export type AutoCapitalize = 'none' | 'sentences' | 'words' | 'characters'; + +export type TextContentType = + | 'none' + | 'URL' + | 'addressCity' + | 'addressCityAndState' + | 'addressState' + | 'countryName' + | 'creditCardNumber' + | 'emailAddress' + | 'familyName' + | 'fullStreetAddress' + | 'givenName' + | 'jobTitle' + | 'location' + | 'middleName' + | 'name' + | 'namePrefix' + | 'nameSuffix' + | 'nickname' + | 'organizationName' + | 'postalCode' + | 'streetAddressLine1' + | 'streetAddressLine2' + | 'sublocality' + | 'telephoneNumber' + | 'username' + | 'password' + | 'newPassword' + | 'oneTimeCode'; + +export type enterKeyHintType = + | 'enter' + | 'done' + | 'go' + | 'next' + | 'previous' + | 'search' + | 'send'; + +type PasswordRules = string; + +type IOSProps = $ReadOnly<{| + /** + * Give the keyboard and the system information about the + * expected semantic meaning for the content that users enter. + * @platform ios + */ + autoComplete?: ?( + | 'address-line1' + | 'address-line2' + | 'cc-number' + | 'current-password' + | 'country' + | 'email' + | 'name' + | 'additional-name' + | 'family-name' + | 'given-name' + | 'nickname' + | 'honorific-prefix' + | 'honorific-suffix' + | 'new-password' + | 'off' + | 'one-time-code' + | 'organization' + | 'organization-title' + | 'postal-code' + | 'street-address' + | 'tel' + | 'url' + | 'username' + ), + /** + * When the clear button should appear on the right side of the text view. + * This property is supported only for single-line TextInput component. + * @platform ios + */ + clearButtonMode?: ?('never' | 'while-editing' | 'unless-editing' | 'always'), + + /** + * If `true`, clears the text field automatically when editing begins. + * @platform ios + */ + clearTextOnFocus?: ?boolean, + + /** + * Determines the types of data converted to clickable URLs in the text input. + * Only valid if `multiline={true}` and `editable={false}`. + * By default no data types are detected. + * + * You can provide one type or an array of many types. + * + * Possible values for `dataDetectorTypes` are: + * + * - `'phoneNumber'` + * - `'link'` + * - `'address'` + * - `'calendarEvent'` + * - `'none'` + * - `'all'` + * + * @platform ios + */ + dataDetectorTypes?: + | ?DataDetectorTypesType + | $ReadOnlyArray, + + /** + * If `true`, the keyboard disables the return key when there is no text and + * automatically enables it when there is text. The default value is `false`. + * @platform ios + */ + enablesReturnKeyAutomatically?: ?boolean, + + /** + * An optional identifier which links a custom InputAccessoryView to + * this text input. The InputAccessoryView is rendered above the + * keyboard when this text input is focused. + * @platform ios + */ + inputAccessoryViewID?: ?string, + + /** + * Determines the color of the keyboard. + * @platform ios + */ + keyboardAppearance?: ?('default' | 'light' | 'dark'), + + /** + * Provide rules for your password. + * For example, say you want to require a password with at least eight characters consisting of a mix of uppercase and lowercase letters, at least one number, and at most two consecutive characters. + * "required: upper; required: lower; required: digit; max-consecutive: 2; minlength: 8;" + * @platform ios + */ + passwordRules?: ?PasswordRules, + + /* + * If `true`, allows TextInput to pass touch events to the parent component. + * This allows components to be swipeable from the TextInput on iOS, + * as is the case on Android by default. + * If `false`, TextInput always asks to handle the input (except when disabled). + * @platform ios + */ + rejectResponderTermination?: ?boolean, + + /** + * If `false`, scrolling of the text view will be disabled. + * The default value is `true`. Does only work with 'multiline={true}'. + * @platform ios + */ + scrollEnabled?: ?boolean, + + /** + * If `false`, disables spell-check style (i.e. red underlines). + * The default value is inherited from `autoCorrect`. + * @platform ios + */ + spellCheck?: ?boolean, + + /** + * Give the keyboard and the system information about the + * expected semantic meaning for the content that users enter. + * @platform ios + */ + textContentType?: ?TextContentType, +|}>; + +type AndroidProps = $ReadOnly<{| + /** + * Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content. + * To disable autocomplete, set `autoComplete` to `off`. + * + * *Android Only* + * + * Possible values for `autoComplete` are: + * + * - `birthdate-day` + * - `birthdate-full` + * - `birthdate-month` + * - `birthdate-year` + * - `cc-csc` + * - `cc-exp` + * - `cc-exp-day` + * - `cc-exp-month` + * - `cc-exp-year` + * - `cc-number` + * - `email` + * - `gender` + * - `name` + * - `name-family` + * - `name-given` + * - `name-middle` + * - `name-middle-initial` + * - `name-prefix` + * - `name-suffix` + * - `password` + * - `password-new` + * - `postal-address` + * - `postal-address-country` + * - `postal-address-extended` + * - `postal-address-extended-postal-code` + * - `postal-address-locality` + * - `postal-address-region` + * - `postal-code` + * - `street-address` + * - `sms-otp` + * - `tel` + * - `tel-country-code` + * - `tel-national` + * - `tel-device` + * - `username` + * - `username-new` + * - `off` + * + * @platform android + */ + autoComplete?: ?( + | 'birthdate-day' + | 'birthdate-full' + | 'birthdate-month' + | 'birthdate-year' + | 'cc-csc' + | 'cc-exp' + | 'cc-exp-day' + | 'cc-exp-month' + | 'cc-exp-year' + | 'cc-number' + | 'email' + | 'gender' + | 'name' + | 'name-family' + | 'name-given' + | 'name-middle' + | 'name-middle-initial' + | 'name-prefix' + | 'name-suffix' + | 'password' + | 'password-new' + | 'postal-address' + | 'postal-address-country' + | 'postal-address-extended' + | 'postal-address-extended-postal-code' + | 'postal-address-locality' + | 'postal-address-region' + | 'postal-code' + | 'street-address' + | 'sms-otp' + | 'tel' + | 'tel-country-code' + | 'tel-national' + | 'tel-device' + | 'username' + | 'username-new' + | 'off' + // additional HTML autocomplete values + | 'address-line1' + | 'address-line2' + | 'bday' + | 'bday-day' + | 'bday-month' + | 'bday-year' + | 'country' + | 'current-password' + | 'honorific-prefix' + | 'honorific-suffix' + | 'additional-name' + | 'family-name' + | 'given-name' + | 'new-password' + | 'one-time-code' + | 'sex' + ), + + /** + * When provided it will set the color of the cursor (or "caret") in the component. + * Unlike the behavior of `selectionColor` the cursor color will be set independently + * from the color of the text selection box. + * @platform android + */ + cursorColor?: ?ColorValue, + + /** + * When `false`, if there is a small amount of space available around a text input + * (e.g. landscape orientation on a phone), the OS may choose to have the user edit + * the text inside of a full screen text input mode. When `true`, this feature is + * disabled and users will always edit the text directly inside of the text input. + * Defaults to `false`. + * @platform android + */ + disableFullscreenUI?: ?boolean, + + importantForAutofill?: ?( + | 'auto' + | 'no' + | 'noExcludeDescendants' + | 'yes' + | 'yesExcludeDescendants' + ), + + /** + * If defined, the provided image resource will be rendered on the left. + * The image resource must be inside `/android/app/src/main/res/drawable` and referenced + * like + * ``` + * + * ``` + * @platform android + */ + inlineImageLeft?: ?string, + + /** + * Padding between the inline image, if any, and the text input itself. + * @platform android + */ + inlineImagePadding?: ?number, + + /** + * Sets the number of lines for a `TextInput`. Use it with multiline set to + * `true` to be able to fill the lines. + * @platform android + */ + numberOfLines?: ?number, + + /** + * Sets the return key to the label. Use it instead of `returnKeyType`. + * @platform android + */ + returnKeyLabel?: ?string, + + /** + * Sets the number of rows for a `TextInput`. Use it with multiline set to + * `true` to be able to fill the lines. + * @platform android + */ + rows?: ?number, + + /** + * When `false`, it will prevent the soft keyboard from showing when the field is focused. + * Defaults to `true`. + */ + showSoftInputOnFocus?: ?boolean, + + /** + * Set text break strategy on Android API Level 23+, possible values are `simple`, `highQuality`, `balanced` + * The default value is `simple`. + * @platform android + */ + textBreakStrategy?: ?('simple' | 'highQuality' | 'balanced'), + + /** + * The color of the `TextInput` underline. + * @platform android + */ + underlineColorAndroid?: ?ColorValue, +|}>; + +export type Props = $ReadOnly<{| + ...$Diff>, + ...IOSProps, + ...AndroidProps, + + /** + * Can tell `TextInput` to automatically capitalize certain characters. + * + * - `characters`: all characters. + * - `words`: first letter of each word. + * - `sentences`: first letter of each sentence (*default*). + * - `none`: don't auto capitalize anything. + */ + autoCapitalize?: ?AutoCapitalize, + + /** + * If `false`, disables auto-correct. The default value is `true`. + */ + autoCorrect?: ?boolean, + + /** + * If `true`, focuses the input on `componentDidMount`. + * The default value is `false`. + */ + autoFocus?: ?boolean, + + /** + * Specifies whether fonts should scale to respect Text Size accessibility settings. The + * default is `true`. + */ + allowFontScaling?: ?boolean, + + /** + * If `true`, caret is hidden. The default value is `false`. + * + * On Android devices manufactured by Xiaomi with Android Q, + * when keyboardType equals 'email-address'this will be set + * in native to 'true' to prevent a system related crash. This + * will cause cursor to be diabled as a side-effect. + * + */ + caretHidden?: ?boolean, + + /* + * If `true`, contextMenuHidden is hidden. The default value is `false`. + */ + contextMenuHidden?: ?boolean, + + /** + * Provides an initial value that will change when the user starts typing. + * Useful for simple use-cases where you do not want to deal with listening + * to events and updating the value prop to keep the controlled state in sync. + */ + defaultValue?: ?Stringish, + + /** + * If `false`, text is not editable. The default value is `true`. + */ + editable?: ?boolean, + + forwardedRef?: ?ReactRefSetter< + React.ElementRef> & ImperativeMethods, + >, + + /** + * `enterKeyHint` defines what action label (or icon) to present for the enter key on virtual keyboards. + * + * The following values is supported: + * + * - `enter` + * - `done` + * - `go` + * - `next` + * - `previous` + * - `search` + * - `send` + */ + enterKeyHint?: ?enterKeyHintType, + + /** + * `inputMode` works like the `inputmode` attribute in HTML, it determines which + * keyboard to open, e.g.`numeric` and has precedence over keyboardType + * + * Support the following values: + * + * - `none` + * - `text` + * - `decimal` + * - `numeric` + * - `tel` + * - `search` + * - `email` + * - `url` + */ + inputMode?: ?InputMode, + + /** + * Determines which keyboard to open, e.g.`numeric`. + * + * The following values work across platforms: + * + * - `default` + * - `numeric` + * - `number-pad` + * - `decimal-pad` + * - `email-address` + * - `phone-pad` + * - `url` + * + * *iOS Only* + * + * The following values work on iOS only: + * + * - `ascii-capable` + * - `numbers-and-punctuation` + * - `name-phone-pad` + * - `twitter` + * - `web-search` + * + * *Android Only* + * + * The following values work on Android only: + * + * - `visible-password` + * + */ + keyboardType?: ?KeyboardType, + + /** + * Specifies largest possible scale a font can reach when `allowFontScaling` is enabled. + * Possible values: + * `null/undefined` (default): inherit from the parent node or the global default (0) + * `0`: no max, ignore parent/global default + * `>= 1`: sets the maxFontSizeMultiplier of this node to this value + */ + maxFontSizeMultiplier?: ?number, + + /** + * Limits the maximum number of characters that can be entered. Use this + * instead of implementing the logic in JS to avoid flicker. + */ + maxLength?: ?number, + + /** + * If `true`, the text input can be multiple lines. + * The default value is `false`. + */ + multiline?: ?boolean, + + /** + * Callback that is called when the text input is blurred. + */ + onBlur?: ?(e: BlurEvent) => mixed, + + /** + * Callback that is called when the text input's text changes. + */ + onChange?: ?(e: ChangeEvent) => mixed, + + /** + * DANGER: this API is not stable and will change in the future. + * + * Callback will be called on the main thread and may result in dropped frames. + * Callback that is called when the text input's text changes. + * + * @platform ios + */ + unstable_onChangeSync?: ?(e: ChangeEvent) => mixed, + + /** + * Callback that is called when the text input's text changes. + * Changed text is passed as an argument to the callback handler. + */ + onChangeText?: ?(text: string) => mixed, + + /** + * DANGER: this API is not stable and will change in the future. + * + * Callback will be called on the main thread and may result in dropped frames. + * Callback that is called when the text input's text changes. + * Changed text is passed as an argument to the callback handler. + * + * @platform ios + */ + unstable_onChangeTextSync?: ?(text: string) => mixed, + + /** + * Callback that is called when the text input's content size changes. + * This will be called with + * `{ nativeEvent: { contentSize: { width, height } } }`. + * + * Only called for multiline text inputs. + */ + onContentSizeChange?: ?(e: ContentSizeChangeEvent) => mixed, + + /** + * Callback that is called when text input ends. + */ + onEndEditing?: ?(e: EditingEvent) => mixed, + + /** + * Callback that is called when the text input is focused. + */ + onFocus?: ?(e: FocusEvent) => mixed, + + /** + * Callback that is called when a key is pressed. + * This will be called with `{ nativeEvent: { key: keyValue } }` + * where `keyValue` is `'Enter'` or `'Backspace'` for respective keys and + * the typed-in character otherwise including `' '` for space. + * Fires before `onChange` callbacks. + */ + onKeyPress?: ?(e: KeyPressEvent) => mixed, + + /** + * DANGER: this API is not stable and will change in the future. + * + * Callback will be called on the main thread and may result in dropped frames. + * + * Callback that is called when a key is pressed. + * This will be called with `{ nativeEvent: { key: keyValue } }` + * where `keyValue` is `'Enter'` or `'Backspace'` for respective keys and + * the typed-in character otherwise including `' '` for space. + * Fires before `onChange` callbacks. + * + * @platform ios + */ + unstable_onKeyPressSync?: ?(e: KeyPressEvent) => mixed, + + /** + * Called when a touch is engaged. + */ + onPressIn?: ?(event: PressEvent) => mixed, + + /** + * Called when a touch is released. + */ + onPressOut?: ?(event: PressEvent) => mixed, + + /** + * Callback that is called when the text input selection is changed. + * This will be called with + * `{ nativeEvent: { selection: { start, end } } }`. + */ + onSelectionChange?: ?(e: SelectionChangeEvent) => mixed, + + /** + * Callback that is called when the text input's submit button is pressed. + * Invalid if `multiline={true}` is specified. + */ + onSubmitEditing?: ?(e: EditingEvent) => mixed, + + /** + * Invoked on content scroll with `{ nativeEvent: { contentOffset: { x, y } } }`. + * May also contain other properties from ScrollEvent but on Android contentSize + * is not provided for performance reasons. + */ + onScroll?: ?(e: ScrollEvent) => mixed, + + /** + * The string that will be rendered before text input has been entered. + */ + placeholder?: ?Stringish, + + /** + * The text color of the placeholder string. + */ + placeholderTextColor?: ?ColorValue, + + /** `readOnly` works like the `readonly` attribute in HTML. + * If `true`, text is not editable. The default value is `false`. + * See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly + * for more details. + */ + readOnly?: ?boolean, + + /** + * Determines how the return key should look. On Android you can also use + * `returnKeyLabel`. + * + * *Cross platform* + * + * The following values work across platforms: + * + * - `done` + * - `go` + * - `next` + * - `search` + * - `send` + * + * *Android Only* + * + * The following values work on Android only: + * + * - `none` + * - `previous` + * + * *iOS Only* + * + * The following values work on iOS only: + * + * - `default` + * - `emergency-call` + * - `google` + * - `join` + * - `route` + * - `yahoo` + */ + returnKeyType?: ?ReturnKeyType, + + /** + * If `true`, the text input obscures the text entered so that sensitive text + * like passwords stay secure. The default value is `false`. Does not work with 'multiline={true}'. + */ + secureTextEntry?: ?boolean, + + /** + * The start and end of the text input's selection. Set start and end to + * the same value to position the cursor. + */ + selection?: ?$ReadOnly<{| + start: number, + end?: ?number, + |}>, + + /** + * The highlight and cursor color of the text input. + */ + selectionColor?: ?ColorValue, + + /** + * If `true`, all text will automatically be selected on focus. + */ + selectTextOnFocus?: ?boolean, + + /** + * If `true`, the text field will blur when submitted. + * The default value is true for single-line fields and false for + * multiline fields. Note that for multiline fields, setting `blurOnSubmit` + * to `true` means that pressing return will blur the field and trigger the + * `onSubmitEditing` event instead of inserting a newline into the field. + * + * @deprecated + * Note that `submitBehavior` now takes the place of `blurOnSubmit` and will + * override any behavior defined by `blurOnSubmit`. + * @see submitBehavior + */ + blurOnSubmit?: ?boolean, + + /** + * When the return key is pressed, + * + * For single line inputs: + * + * - `'newline`' defaults to `'blurAndSubmit'` + * - `undefined` defaults to `'blurAndSubmit'` + * + * For multiline inputs: + * + * - `'newline'` adds a newline + * - `undefined` defaults to `'newline'` + * + * For both single line and multiline inputs: + * + * - `'submit'` will only send a submit event and not blur the input + * - `'blurAndSubmit`' will both blur the input and send a submit event + */ + submitBehavior?: ?SubmitBehavior, + + /** + * Note that not all Text styles are supported, an incomplete list of what is not supported includes: + * + * - `borderLeftWidth` + * - `borderTopWidth` + * - `borderRightWidth` + * - `borderBottomWidth` + * - `borderTopLeftRadius` + * - `borderTopRightRadius` + * - `borderBottomRightRadius` + * - `borderBottomLeftRadius` + * + * see [Issue#7070](https://github.com/facebook/react-native/issues/7070) + * for more detail. + * + * [Styles](docs/style.html) + */ + style?: ?TextStyleProp, + + /** + * The value to show for the text input. `TextInput` is a controlled + * component, which means the native value will be forced to match this + * value prop if provided. For most uses, this works great, but in some + * cases this may cause flickering - one common cause is preventing edits + * by keeping value the same. In addition to simply setting the same value, + * either set `editable={false}`, or set/update `maxLength` to prevent + * unwanted edits without flicker. + */ + value?: ?Stringish, +|}>; + +type ImperativeMethods = $ReadOnly<{| + clear: () => void, + isFocused: () => boolean, + getNativeRef: () => ?React.ElementRef>, + setSelection: (start: number, end: number) => void, +|}>; + +/** + * A foundational component for inputting text into the app via a + * keyboard. Props provide configurability for several features, such as + * auto-correction, auto-capitalization, placeholder text, and different keyboard + * types, such as a numeric keypad. + * + * The simplest use case is to plop down a `TextInput` and subscribe to the + * `onChangeText` events to read the user input. There are also other events, + * such as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple + * example: + * + * ```ReactNativeWebPlayer + * import React, { Component } from 'react'; + * import { AppRegistry, TextInput } from 'react-native'; + * + * export default class UselessTextInput extends Component { + * constructor(props) { + * super(props); + * this.state = { text: 'Useless Placeholder' }; + * } + * + * render() { + * return ( + * this.setState({text})} + * value={this.state.text} + * /> + * ); + * } + * } + * + * // skip this line if using Create React Native App + * AppRegistry.registerComponent('AwesomeProject', () => UselessTextInput); + * ``` + * + * Two methods exposed via the native element are .focus() and .blur() that + * will focus or blur the TextInput programmatically. + * + * Note that some props are only available with `multiline={true/false}`. + * Additionally, border styles that apply to only one side of the element + * (e.g., `borderBottomColor`, `borderLeftWidth`, etc.) will not be applied if + * `multiline=false`. To achieve the same effect, you can wrap your `TextInput` + * in a `View`: + * + * ```ReactNativeWebPlayer + * import React, { Component } from 'react'; + * import { AppRegistry, View, TextInput } from 'react-native'; + * + * class UselessTextInput extends Component { + * render() { + * return ( + * + * ); + * } + * } + * + * export default class UselessTextInputMultiline extends Component { + * constructor(props) { + * super(props); + * this.state = { + * text: 'Useless Multiline Placeholder', + * }; + * } + * + * // If you type something in the text box that is a color, the background will change to that + * // color. + * render() { + * return ( + * + * this.setState({text})} + * value={this.state.text} + * /> + * + * ); + * } + * } + * + * // skip these lines if using Create React Native App + * AppRegistry.registerComponent( + * 'AwesomeProject', + * () => UselessTextInputMultiline + * ); + * ``` + * + * `TextInput` has by default a border at the bottom of its view. This border + * has its padding set by the background image provided by the system, and it + * cannot be changed. Solutions to avoid this is to either not set height + * explicitly, case in which the system will take care of displaying the border + * in the correct position, or to not display the border by setting + * `underlineColorAndroid` to transparent. + * + * Note that on Android performing text selection in input can change + * app's activity `windowSoftInputMode` param to `adjustResize`. + * This may cause issues with components that have position: 'absolute' + * while keyboard is active. To avoid this behavior either specify `windowSoftInputMode` + * in AndroidManifest.xml ( https://developer.android.com/guide/topics/manifest/activity-element.html ) + * or control this param programmatically with native code. + * + */ +type InternalTextInput = (props: Props) => React.Node; + +export type TextInputComponentStatics = $ReadOnly<{| + State: $ReadOnly<{| + currentlyFocusedInput: () => ?ComponentRef, + currentlyFocusedField: () => ?number, + focusTextInput: (textField: ?ComponentRef) => void, + blurTextInput: (textField: ?ComponentRef) => void, + |}>, +|}>; + +export type TextInputType = React.AbstractComponent< + React.ElementConfig, + $ReadOnly<{| + ...React.ElementRef>, + ...ImperativeMethods, + |}>, +> & + TextInputComponentStatics; diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 59cb7f8e8bdc44..b212d07fa69eb3 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -22,6 +22,7 @@ import TextInputState from './TextInputState'; import invariant from 'invariant'; import nullthrows from 'nullthrows'; import setAndForwardRef from '../../Utilities/setAndForwardRef'; +import type {TextInputType} from './TextInput.flow'; import usePressability from '../../Pressability/usePressability'; @@ -229,6 +230,36 @@ export type enterKeyHintType = type PasswordRules = string; type IOSProps = $ReadOnly<{| + /** + * Give the keyboard and the system information about the + * expected semantic meaning for the content that users enter. + * @platform ios + */ + autoComplete?: ?( + | 'address-line1' + | 'address-line2' + | 'cc-number' + | 'current-password' + | 'country' + | 'email' + | 'name' + | 'additional-name' + | 'family-name' + | 'given-name' + | 'nickname' + | 'honorific-prefix' + | 'honorific-suffix' + | 'new-password' + | 'off' + | 'one-time-code' + | 'organization' + | 'organization-title' + | 'postal-code' + | 'street-address' + | 'tel' + | 'url' + | 'username' + ), /** * When the clear button should appear on the right side of the text view. * This property is supported only for single-line TextInput component. @@ -411,6 +442,23 @@ type AndroidProps = $ReadOnly<{| | 'username' | 'username-new' | 'off' + // additional HTML autocomplete values + | 'address-line1' + | 'address-line2' + | 'bday' + | 'bday-day' + | 'bday-month' + | 'bday-year' + | 'country' + | 'current-password' + | 'honorific-prefix' + | 'honorific-suffix' + | 'additional-name' + | 'family-name' + | 'given-name' + | 'new-password' + | 'one-time-code' + | 'sex' ), /** @@ -1339,6 +1387,14 @@ function InternalTextInput(props: Props): React.Node { // so omitting onBlur and onFocus pressability handlers here. const {onBlur, onFocus, ...eventHandlers} = usePressability(config) || {}; + const _accessibilityState = { + busy: props['aria-busy'] ?? props.accessibilityState?.busy, + checked: props['aria-checked'] ?? props.accessibilityState?.checked, + disabled: props['aria-disabled'] ?? props.accessibilityState?.disabled, + expanded: props['aria-expanded'] ?? props.accessibilityState?.expanded, + selected: props['aria-selected'] ?? props.accessibilityState?.selected, + }; + if (Platform.OS === 'ios') { const RCTTextInputView = props.multiline === true @@ -1360,6 +1416,7 @@ function InternalTextInput(props: Props): React.Node { {...props} {...eventHandlers} accessible={accessible} + accessibilityState={_accessibilityState} submitBehavior={submitBehavior} caretHidden={caretHidden} dataDetectorTypes={props.dataDetectorTypes} @@ -1407,6 +1464,7 @@ function InternalTextInput(props: Props): React.Node { {...props} {...eventHandlers} accessible={accessible} + accessibilityState={_accessibilityState} autoCapitalize={autoCapitalize} submitBehavior={submitBehavior} caretHidden={caretHidden} @@ -1460,6 +1518,67 @@ const inputModeToKeyboardTypeMap = { url: 'url', }; +// Map HTML autocomplete values to Android autoComplete values +const autoCompleteWebToAutoCompleteAndroidMap = { + 'address-line1': 'postal-address-region', + 'address-line2': 'postal-address-locality', + bday: 'birthdate-full', + 'bday-day': 'birthdate-day', + 'bday-month': 'birthdate-month', + 'bday-year': 'birthdate-year', + 'cc-csc': 'cc-csc', + 'cc-exp': 'cc-exp', + 'cc-exp-month': 'cc-exp-month', + 'cc-exp-year': 'cc-exp-year', + 'cc-number': 'cc-number', + country: 'postal-address-country', + 'current-password': 'password', + email: 'email', + 'honorific-prefix': 'name-prefix', + 'honorific-suffix': 'name-suffix', + name: 'name', + 'additional-name': 'name-middle', + 'family-name': 'name-family', + 'given-name': 'name-given', + 'new-password': 'password-new', + off: 'off', + 'one-time-code': 'sms-otp', + 'postal-code': 'postal-code', + sex: 'gender', + 'street-address': 'street-address', + tel: 'tel', + 'tel-country-code': 'tel-country-code', + 'tel-national': 'tel-national', + username: 'username', +}; + +// Map HTML autocomplete values to iOS textContentType values +const autoCompleteWebToTextContentTypeMap = { + 'address-line1': 'streetAddressLine1', + 'address-line2': 'streetAddressLine2', + 'cc-number': 'creditCardNumber', + 'current-password': 'password', + country: 'countryName', + email: 'emailAddress', + name: 'name', + 'additional-name': 'middleName', + 'family-name': 'familyName', + 'given-name': 'givenName', + nickname: 'nickname', + 'honorific-prefix': 'namePrefix', + 'honorific-suffix': 'nameSuffix', + 'new-password': 'newPassword', + off: 'none', + 'one-time-code': 'oneTimeCode', + organization: 'organizationName', + 'organization-title': 'jobTitle', + 'postal-code': 'postalCode', + 'street-address': 'fullStreetAddress', + tel: 'telephoneNumber', + url: 'URL', + username: 'username', +}; + const ExportedForwardRef: React.AbstractComponent< React.ElementConfig, React.ElementRef> & ImperativeMethods, @@ -1468,6 +1587,8 @@ const ExportedForwardRef: React.AbstractComponent< allowFontScaling = true, rejectResponderTermination = true, underlineColorAndroid = 'transparent', + autoComplete, + textContentType, readOnly, editable, enterKeyHint, @@ -1492,6 +1613,21 @@ const ExportedForwardRef: React.AbstractComponent< keyboardType={ inputMode ? inputModeToKeyboardTypeMap[inputMode] : keyboardType } + autoComplete={ + Platform.OS === 'android' + ? // $FlowFixMe + autoCompleteWebToAutoCompleteAndroidMap[autoComplete] ?? + autoComplete + : undefined + } + textContentType={ + Platform.OS === 'ios' && + autoComplete && + autoComplete in autoCompleteWebToTextContentTypeMap + ? // $FlowFixMe + autoCompleteWebToTextContentTypeMap[autoComplete] + : textContentType + } {...restProps} forwardedRef={forwardedRef} /> @@ -1526,11 +1662,4 @@ const styles = StyleSheet.create({ }); // $FlowFixMe[unclear-type] Unclear type. Using `any` type is not safe. -module.exports = ((ExportedForwardRef: any): React.AbstractComponent< - React.ElementConfig, - $ReadOnly<{| - ...React.ElementRef>, - ...ImperativeMethods, - |}>, -> & - TextInputComponentStatics); +module.exports = ((ExportedForwardRef: any): TextInputType); diff --git a/Libraries/Components/TextInput/TextInputState.js b/Libraries/Components/TextInput/TextInputState.js index 87cb3ccf787012..10c300bed1b58f 100644 --- a/Libraries/Components/TextInput/TextInputState.js +++ b/Libraries/Components/TextInput/TextInputState.js @@ -14,7 +14,7 @@ const React = require('react'); const Platform = require('../../Utilities/Platform'); -const {findNodeHandle} = require('../../Renderer/shims/ReactNative'); +const {findNodeHandle} = require('../../ReactNative/RendererProxy'); import {Commands as AndroidTextInputCommands} from '../../Components/TextInput/AndroidTextInputNativeComponent'; import {Commands as iOSTextInputCommands} from '../../Components/TextInput/RCTSingelineTextInputNativeComponent'; diff --git a/Libraries/Components/TextInput/__tests__/InputAccessoryView-test.js b/Libraries/Components/TextInput/__tests__/InputAccessoryView-test.js index f1a2d643651a8c..72b3136e6046bf 100644 --- a/Libraries/Components/TextInput/__tests__/InputAccessoryView-test.js +++ b/Libraries/Components/TextInput/__tests__/InputAccessoryView-test.js @@ -4,9 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format - * @emails oncall+react_native * @flow strict-local + * @format + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/TextInput/__tests__/TextInput-test.js b/Libraries/Components/TextInput/__tests__/TextInput-test.js index 18992428a64612..e1b028ed97e139 100644 --- a/Libraries/Components/TextInput/__tests__/TextInput-test.js +++ b/Libraries/Components/TextInput/__tests__/TextInput-test.js @@ -4,15 +4,15 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @emails oncall+react_native - * @format * @flow-strict + * @format + * @oncall react_native */ const React = require('react'); const ReactTestRenderer = require('react-test-renderer'); const TextInput = require('../TextInput'); -const ReactNative = require('../../../Renderer/shims/ReactNative'); +const ReactNative = require('../../../ReactNative/RendererProxy'); const { enter, diff --git a/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap b/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap index d83ac32fe9bf88..ea3b4c1f062744 100644 --- a/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap +++ b/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap @@ -2,6 +2,15 @@ exports[`TextInput tests should render as expected: should deep render when mocked (please verify output manually) 1`] = ` { // adopting `Pressability`, so preserve that behavior. const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} = this.state.pressability.getEventHandlers(); + const accessibilityLiveRegion = + this.props['aria-live'] === 'off' + ? 'none' + : this.props['aria-live'] ?? this.props.accessibilityLiveRegion; + const _accessibilityState = { + busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy, + checked: + this.props['aria-checked'] ?? this.props.accessibilityState?.checked, + disabled: + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled, + expanded: + this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, + selected: + this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + }; + + const accessibilityValue = { + max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max, + min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min, + now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now, + text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text, + }; + const accessibilityLabel = + this.props['aria-label'] ?? this.props.accessibilityLabel; return ( { } : this.props.accessibilityState; + const accessibilityValue = { + max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max, + min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min, + now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now, + text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text, + }; + + const accessibilityLiveRegion = + this.props['aria-live'] === 'off' + ? 'none' + : this.props['aria-live'] ?? this.props.accessibilityLiveRegion; + + const accessibilityLabel = + this.props['aria-label'] ?? this.props.accessibilityLabel; return ( { }; _createPressabilityConfig(): PressabilityConfig { + const accessibilityStateDisabled = + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled; return { cancelable: !this.props.rejectResponderTermination, disabled: this.props.disabled != null ? this.props.disabled - : this.props.accessibilityState?.disabled, + : accessibilityStateDisabled, hitSlop: this.props.hitSlop, delayLongPress: this.props.delayLongPress, delayPressIn: this.props.delayPressIn, @@ -204,7 +206,7 @@ class TouchableNativeFeedback extends React.Component { _dispatchPressedStateChange(pressed: boolean): void { if (Platform.OS === 'android') { - const hostComponentRef = ReactNative.findHostInstance_DEPRECATED(this); + const hostComponentRef = findHostInstance_DEPRECATED(this); if (hostComponentRef == null) { console.warn( 'Touchable: Unable to find HostComponent instance. ' + @@ -219,7 +221,7 @@ class TouchableNativeFeedback extends React.Component { _dispatchHotspotUpdate(event: PressEvent): void { if (Platform.OS === 'android') { const {locationX, locationY} = event.nativeEvent; - const hostComponentRef = ReactNative.findHostInstance_DEPRECATED(this); + const hostComponentRef = findHostInstance_DEPRECATED(this); if (hostComponentRef == null) { console.warn( 'Touchable: Unable to find HostComponent instance. ' + @@ -251,14 +253,40 @@ class TouchableNativeFeedback extends React.Component { const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} = this.state.pressability.getEventHandlers(); - const accessibilityState = + let _accessibilityState = { + busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy, + checked: + this.props['aria-checked'] ?? this.props.accessibilityState?.checked, + disabled: + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled, + expanded: + this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, + selected: + this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + }; + + _accessibilityState = this.props.disabled != null ? { - ...this.props.accessibilityState, + ..._accessibilityState, disabled: this.props.disabled, } - : this.props.accessibilityState; + : _accessibilityState; + + const accessibilityValue = { + max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max, + min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min, + now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now, + text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text, + }; + + const accessibilityLiveRegion = + this.props['aria-live'] === 'off' + ? 'none' + : this.props['aria-live'] ?? this.props.accessibilityLiveRegion; + const accessibilityLabel = + this.props['aria-label'] ?? this.props.accessibilityLabel; return React.cloneElement( element, { @@ -272,16 +300,21 @@ class TouchableNativeFeedback extends React.Component { accessible: this.props.accessible !== false, accessibilityHint: this.props.accessibilityHint, accessibilityLanguage: this.props.accessibilityLanguage, - accessibilityLabel: this.props.accessibilityLabel, + accessibilityLabel: accessibilityLabel, accessibilityRole: this.props.accessibilityRole, - accessibilityState: accessibilityState, + accessibilityState: _accessibilityState, accessibilityActions: this.props.accessibilityActions, onAccessibilityAction: this.props.onAccessibilityAction, - accessibilityValue: this.props.accessibilityValue, - importantForAccessibility: this.props.importantForAccessibility, - accessibilityLiveRegion: this.props.accessibilityLiveRegion, - accessibilityViewIsModal: this.props.accessibilityViewIsModal, - accessibilityElementsHidden: this.props.accessibilityElementsHidden, + accessibilityValue: accessibilityValue, + importantForAccessibility: + this.props['aria-hidden'] === true + ? 'no-hide-descendants' + : this.props.importantForAccessibility, + accessibilityViewIsModal: + this.props['aria-modal'] ?? this.props.accessibilityViewIsModal, + accessibilityLiveRegion: accessibilityLiveRegion, + accessibilityElementsHidden: + this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden, hasTVPreferredFocus: this.props.hasTVPreferredFocus, hitSlop: this.props.hitSlop, focusable: diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 67e18c06d54c83..d9de2b3c2b6fcc 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -137,7 +137,10 @@ class TouchableOpacity extends React.Component { _createPressabilityConfig(): PressabilityConfig { return { cancelable: !this.props.rejectResponderTermination, - disabled: this.props.disabled ?? this.props.accessibilityState?.disabled, + disabled: + this.props.disabled ?? + this.props['aria-disabled'] ?? + this.props.accessibilityState?.disabled, hitSlop: this.props.hitSlop, delayLongPress: this.props.delayLongPress, delayPressIn: this.props.delayPressIn, @@ -212,29 +215,63 @@ class TouchableOpacity extends React.Component { const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} = this.state.pressability.getEventHandlers(); - const accessibilityState = + let _accessibilityState = { + busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy, + checked: + this.props['aria-checked'] ?? this.props.accessibilityState?.checked, + disabled: + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled, + expanded: + this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, + selected: + this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + }; + + _accessibilityState = this.props.disabled != null ? { - ...this.props.accessibilityState, + ..._accessibilityState, disabled: this.props.disabled, } - : this.props.accessibilityState; + : _accessibilityState; + + const accessibilityValue = { + max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max, + min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min, + now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now, + text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text, + }; + const accessibilityLiveRegion = + this.props['aria-live'] === 'off' + ? 'none' + : this.props['aria-live'] ?? this.props.accessibilityLiveRegion; + + const accessibilityLabel = + this.props['aria-label'] ?? this.props.accessibilityLabel; return ( mixed, @@ -79,7 +98,12 @@ const PASSTHROUGH_PROPS = [ 'accessibilityLiveRegion', 'accessibilityRole', 'accessibilityValue', + 'aria-valuemax', + 'aria-valuemin', + 'aria-valuenow', + 'aria-valuetext', 'accessibilityViewIsModal', + 'aria-modal', 'hitSlop', 'importantForAccessibility', 'nativeID', @@ -98,6 +122,8 @@ class TouchableWithoutFeedback extends React.Component { render(): React.Node { const element = React.Children.only(this.props.children); const children = [element.props.children]; + const ariaLive = this.props['aria-live']; + if (__DEV__) { if (element.type === View) { children.push( @@ -106,6 +132,18 @@ class TouchableWithoutFeedback extends React.Component { } } + let _accessibilityState = { + busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy, + checked: + this.props['aria-checked'] ?? this.props.accessibilityState?.checked, + disabled: + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled, + expanded: + this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, + selected: + this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + }; + // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before // adopting `Pressability`, so preserve that behavior. const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} = @@ -117,12 +155,24 @@ class TouchableWithoutFeedback extends React.Component { accessibilityState: this.props.disabled != null ? { - ...this.props.accessibilityState, + ..._accessibilityState, disabled: this.props.disabled, } - : this.props.accessibilityState, + : _accessibilityState, focusable: this.props.focusable !== false && this.props.onPress !== undefined, + + accessibilityElementsHidden: + this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden, + importantForAccessibility: + this.props['aria-hidden'] === true + ? 'no-hide-descendants' + : this.props.importantForAccessibility, + accessibilityLiveRegion: + ariaLive === 'off' + ? 'none' + : ariaLive ?? this.props.accessibilityLiveRegion, + nativeID: this.props.id ?? this.props.nativeID, }; for (const prop of PASSTHROUGH_PROPS) { if (this.props[prop] !== undefined) { @@ -142,13 +192,16 @@ class TouchableWithoutFeedback extends React.Component { } } -function createPressabilityConfig(props: Props): PressabilityConfig { +function createPressabilityConfig({ + 'aria-disabled': ariaDisabled, + ...props +}: Props): PressabilityConfig { + const accessibilityStateDisabled = + ariaDisabled ?? props.accessibilityState?.disabled; return { cancelable: !props.rejectResponderTermination, disabled: - props.disabled !== null - ? props.disabled - : props.accessibilityState?.disabled, + props.disabled !== null ? props.disabled : accessibilityStateDisabled, hitSlop: props.hitSlop, delayLongPress: props.delayLongPress, delayPressIn: props.delayPressIn, diff --git a/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js b/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js index d1ae224b220613..e760fc27f4eafd 100644 --- a/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js +++ b/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js b/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js index dca7e508cc647a..50c453c746134c 100644 --- a/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js +++ b/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/Touchable/__tests__/TouchableOpacity-test.js b/Libraries/Components/Touchable/__tests__/TouchableOpacity-test.js index 30aa9b656aa24b..a3178b3f035a93 100644 --- a/Libraries/Components/Touchable/__tests__/TouchableOpacity-test.js +++ b/Libraries/Components/Touchable/__tests__/TouchableOpacity-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/Touchable/__tests__/TouchableWithoutFeedback-test.js b/Libraries/Components/Touchable/__tests__/TouchableWithoutFeedback-test.js index bbf3483ec8b033..15e1ce66f3da14 100644 --- a/Libraries/Components/Touchable/__tests__/TouchableWithoutFeedback-test.js +++ b/Libraries/Components/Touchable/__tests__/TouchableWithoutFeedback-test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @emails oncall+react_native + * @oncall react_native */ 'use strict'; diff --git a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap index 70eaabe704a1f0..35c845e97493fc 100644 --- a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap +++ b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap @@ -2,6 +2,14 @@ exports[`TouchableHighlight renders correctly 1`] = ` should render as expected 1`] = ` + - Touchable - +/> `; -exports[` should render as expected 1`] = ` +exports[` should overwrite accessibilityState with value of disabled prop 1`] = ` should render as expected 1`] = ` /> `; -exports[` should be disabled when disabled is true 1`] = ` +exports[` should be disabled when disabled is true and accessibilityState is empty 1`] = ` should be disabled when disab /> `; -exports[` should be disabled when disabled is true and accessibilityState is empty 1`] = ` +exports[` should keep accessibilityState when disabled is true 1`] = ` shoul /> `; -exports[` should keep accessibilityState when disabled is true 1`] = ` +exports[` should overwrite accessibilityState with value of disabled prop 1`] = ` `; -exports[` should overwrite accessibilityState with value of disabled prop 1`] = ` +exports[` should be disabled when disabled is true 1`] = ` `; -exports[` should overwrite accessibilityState with value of disabled prop 1`] = ` - +> + Touchable + `; diff --git a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap index 4d3f11bc92ef35..17f2e7f6f764e0 100644 --- a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap +++ b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap @@ -2,6 +2,23 @@ exports[`TouchableOpacity renders correctly 1`] = ` , > = React.forwardRef( - ({tabIndex, focusable, ...otherProps}: ViewProps, forwardedRef) => { + ( + { + accessibilityElementsHidden, + accessibilityLiveRegion, + 'aria-live': ariaLive, + accessibilityLabel, + accessibilityRole, + 'aria-label': ariaLabel, + 'aria-hidden': ariaHidden, + focusable, + id, + importantForAccessibility, + nativeID, + pointerEvents, + role, + style, + tabIndex, + ...otherProps + }: ViewProps, + forwardedRef, + ) => { + const { + accessibilityState, + 'aria-busy': ariaBusy, + 'aria-checked': ariaChecked, + 'aria-disabled': ariaDisabled, + 'aria-expanded': ariaExpanded, + 'aria-selected': ariaSelected, + ...restProps + } = otherProps; + + const _accessibilityState = { + busy: ariaBusy ?? accessibilityState?.busy, + checked: ariaChecked ?? accessibilityState?.checked, + disabled: ariaDisabled ?? accessibilityState?.disabled, + expanded: ariaExpanded ?? accessibilityState?.expanded, + selected: ariaSelected ?? accessibilityState?.selected, + }; + + // Map role values to AccessibilityRole values + const roleToAccessibilityRoleMapping = { + alert: 'alert', + alertdialog: undefined, + application: undefined, + article: undefined, + banner: undefined, + button: 'button', + cell: undefined, + checkbox: 'checkbox', + columnheader: undefined, + combobox: 'combobox', + complementary: undefined, + contentinfo: undefined, + definition: undefined, + dialog: undefined, + directory: undefined, + document: undefined, + feed: undefined, + figure: undefined, + form: undefined, + grid: 'grid', + group: undefined, + heading: 'header', + img: 'image', + link: 'link', + list: 'list', + listitem: undefined, + log: undefined, + main: undefined, + marquee: undefined, + math: undefined, + menu: 'menu', + menubar: 'menubar', + menuitem: 'menuitem', + meter: undefined, + navigation: undefined, + none: 'none', + note: undefined, + presentation: 'none', + progressbar: 'progressbar', + radio: 'radio', + radiogroup: 'radiogroup', + region: undefined, + row: undefined, + rowgroup: undefined, + rowheader: undefined, + scrollbar: 'scrollbar', + searchbox: 'search', + separator: undefined, + slider: 'adjustable', + spinbutton: 'spinbutton', + status: undefined, + summary: 'summary', + switch: 'switch', + tab: 'tab', + table: undefined, + tablist: 'tablist', + tabpanel: undefined, + term: undefined, + timer: 'timer', + toolbar: 'toolbar', + tooltip: undefined, + tree: undefined, + treegrid: undefined, + treeitem: undefined, + }; + + const accessibilityValue = { + max: otherProps['aria-valuemax'] ?? otherProps.accessibilityValue?.max, + min: otherProps['aria-valuemin'] ?? otherProps.accessibilityValue?.min, + now: otherProps['aria-valuenow'] ?? otherProps.accessibilityValue?.now, + text: otherProps['aria-valuetext'] ?? otherProps.accessibilityValue?.text, + }; + const restWithDefaultProps = {...otherProps, accessibilityValue}; + + const flattenedStyle = flattenStyle(style); + const newPointerEvents = flattenedStyle?.pointerEvents || pointerEvents; + return ( diff --git a/Libraries/Components/View/ViewAccessibility.js b/Libraries/Components/View/ViewAccessibility.js index 8ed64ae335aa60..729e5e0a32e5b8 100644 --- a/Libraries/Components/View/ViewAccessibility.js +++ b/Libraries/Components/View/ViewAccessibility.js @@ -46,6 +46,73 @@ export type AccessibilityRole = | 'toolbar' | 'grid'; +// Role types for web +export type Role = + | 'alert' + | 'alertdialog' + | 'application' + | 'article' + | 'banner' + | 'button' + | 'cell' + | 'checkbox' + | 'columnheader' + | 'combobox' + | 'complementary' + | 'contentinfo' + | 'definition' + | 'dialog' + | 'directory' + | 'document' + | 'feed' + | 'figure' + | 'form' + | 'grid' + | 'group' + | 'heading' + | 'img' + | 'link' + | 'list' + | 'listitem' + | 'log' + | 'main' + | 'marquee' + | 'math' + | 'menu' + | 'menubar' + | 'menuitem' + | 'meter' + | 'navigation' + | 'none' + | 'note' + | 'presentation' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'region' + | 'row' + | 'rowgroup' + | 'rowheader' + | 'scrollbar' + | 'searchbox' + | 'separator' + | 'slider' + | 'spinbutton' + | 'status' + | 'summary' + | 'switch' + | 'tab' + | 'table' + | 'tablist' + | 'tabpanel' + | 'term' + | 'timer' + | 'toolbar' + | 'tooltip' + | 'tree' + | 'treegrid' + | 'treeitem'; + // the info associated with an accessibility action export type AccessibilityActionInfo = $ReadOnly<{ name: string, diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index effed17622cfda..c9939c3ed398ef 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -23,6 +23,7 @@ import type {EdgeInsetsOrSizeProp} from '../../StyleSheet/EdgeInsetsPropType'; import type {Node} from 'react'; import type {ViewStyleProp} from '../../StyleSheet/StyleSheet'; import type { + Role, AccessibilityRole, AccessibilityState, AccessibilityValue, @@ -292,6 +293,16 @@ type AndroidViewProps = $ReadOnly<{| */ accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), + /** + * Indicates to accessibility services whether the user should be notified + * when this view changes. Works for Android API >= 19 only. + * + * @platform android + * + * See https://reactnative.dev/docs/view#accessibilityliveregion + */ + 'aria-live'?: ?('polite' | 'assertive' | 'off'), + /** * Controls how view is important for accessibility which is if it * fires accessibility events and if it is reported to accessibility services @@ -392,6 +403,15 @@ type IOSViewProps = $ReadOnly<{| */ accessibilityViewIsModal?: ?boolean, + /** + * The aria-modal attribute indicates content contained within a modal with aria-modal="true" + * should be accessible to the user. + * Default is `false`. + * + * @platform ios + */ + 'aria-modal'?: ?boolean, + /** * A value indicating whether the accessibility elements contained within * this accessibility element are hidden. @@ -452,6 +472,12 @@ export type ViewProps = $ReadOnly<{| */ accessibilityHint?: ?Stringish, + /** + * Alias for accessibilityLabel https://reactnative.dev/docs/view#accessibilitylabel + * https://github.com/facebook/react-native/issues/34424 + */ + 'aria-label'?: ?Stringish, + /** * Indicates to the accessibility services that the UI component is in * a specific language. The provided string should be formatted following @@ -466,12 +492,26 @@ export type ViewProps = $ReadOnly<{| */ accessibilityRole?: ?AccessibilityRole, + /** + * Alias for accessibilityRole + */ + role?: ?Role, + /** * Indicates to accessibility services that UI Component is in a specific State. */ accessibilityState?: ?AccessibilityState, accessibilityValue?: ?AccessibilityValue, + /** + * alias for accessibilityState + * It represents textual description of a component's value, or for range-based components, such as sliders and progress bars. + */ + 'aria-valuemax'?: ?AccessibilityValue['max'], + 'aria-valuemin'?: ?AccessibilityValue['min'], + 'aria-valuenow'?: ?AccessibilityValue['now'], + 'aria-valuetext'?: ?AccessibilityValue['text'], + /** * Provides an array of custom actions available for accessibility. * @@ -485,6 +525,23 @@ export type ViewProps = $ReadOnly<{| */ accessibilityLabelledBy?: ?string | ?Array, + /** + * alias for accessibilityState + * + * see https://reactnative.dev/docs/accessibility#accessibilitystate + */ + 'aria-busy'?: ?boolean, + 'aria-checked'?: ?boolean, + 'aria-disabled'?: ?boolean, + 'aria-expanded'?: ?boolean, + 'aria-selected'?: ?boolean, + /** A value indicating whether the accessibility elements contained within + * this accessibility element are hidden. + * + * See https://reactnative.dev/docs/view#aria-hidden + */ + 'aria-hidden'?: ?boolean, + /** * Views that are only used to layout their children or otherwise don't draw * anything may be automatically removed from the native hierarchy as an @@ -498,6 +555,15 @@ export type ViewProps = $ReadOnly<{| */ collapsable?: ?boolean, + /** + * Used to locate this view from native classes. + * + * > This disables the 'layout-only view removal' optimization for this view! + * + * See https://reactnative.dev/docs/view#id + */ + id?: string, + /** * Used to locate this view in end-to-end tests. * diff --git a/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap b/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap index fb87db9320e845..5b4294e0e8c850 100644 --- a/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap +++ b/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap @@ -5,7 +5,19 @@ exports[`