Compare commits

...
Author SHA1 Message Date
React Native Bot b35291cbb8 Release 0.80.0-rc.2
#publish-packages-to-npm&next
2025-05-19 18:06:14 +00:00
Dawid Małecki 1cc46014d6 Fix generated types base on __typetests__ (#51383)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51383

This diff is a set of alignments/improvements in generated TS types. It includes:
- extending `AppStateStatus` with `extension` and `unknown`,
- exporting `AnimatedProps` under `Animated` namespace,
- resolving issue with discriminated unions in `ProgressBarAndroidTypes`,
- fixing `StyleSheet.create` type to accept only specified style properties,
- extending `TextProps` with `AccessibilityProps`,
extending Fn Args generic with `$ReadOnlyArray` in `ErrorUtils`,
- small `__typetests__` adjustments,
- removing type test `styleDimensionValueValidAnimated` as `DimensionValue` no longer accepts `AnimatedNode`,
- removing `styleDimensionValueInvalid` as `DimensionValue` accepts any string now - template literal types in Flow are not supported,
- changing `overlayColor` type to `ColorValue` to align with manual types,
- fixing `AnimatedPropsAllowList` type which wasn't correct in TS because index signature type was different from style type,
- using `DeviceEventEmitter` instead of `DeviceEventEmitterStatic` in type tests which is equivalent in both new and old types - `DeviceEventEmitterStatic` was only a type of `DeviceEventEmitter`,
- removing type test for checking forwarded key type - doesn't work with new types and that shouldn't be supported,
- removing `Animated.legacyRef` type test - not included in new types,
- adding `DOMRect` from "dom" lib to `globals.d.ts` to not include "dom" lib in the tsconfig - tries to compare globals with `lib.dom.d.ts` and produces many errors,
- exporting `SectionListData`,

Changelog:
[Internal]

Reviewed By: huntie

Differential Revision: D74807552

fbshipit-source-id: c5254ea0f701f3602b9d716faeb50ca1ab21b013
2025-05-19 16:59:19 +01:00
Alan Lee 5b630d224a migrate deprecated KEYCODE_BACK in Modal (#51097)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51097

**Problem:** `Event.KEYCODE_BACK`has been deprecated with targetSdk 36, predictive back will be enforced and KEYCODE_BACK no longer triggered. We need to migrate to backward compatible `OnBackPressedCallback`.
- https://developer.android.com/about/versions/16/behavior-changes-16#predictive-back.

**Solution:**
Use `OnBackPressedCallback` to handle BACK. Logic for ESC key handling still remains.
To support the callback mechanism, we are using AndroidX ComponentDialog ([src](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity/src/main/java/androidx/activity/ComponentDialog.kt)) which is a thin wrapper on the existing Dialog.

Changelog:
[Internal]

Reviewed By: mdvacca

Differential Revision: D74162844

fbshipit-source-id: ebd0e89c29999d3dd99431a4359c442e42d23911
2025-05-19 15:52:23 +00:00
Christian Falch a49bf3722b adding accessor for backing map (#51386)
Summary:
Expo is using the backingmap to be able to update properties in a fast and performant way in two overridden view manager subclasses (ViewGroupManager subclass is one of them).

This diff exposes the backing field via JvmName using the `internal_` prefix.

So Expo can keep on accessing the field as they were doing before. In the long run we should prevent them from accessing this property altogether but this would require a different API.

## Changelog:

[INTERNAL] -

Pull Request resolved: https://github.com/facebook/react-native/pull/51386

Test Plan: Build with Expo modules

Reviewed By: cipolleschi

Differential Revision: D74884533

Pulled By: cortinico

fbshipit-source-id: e76673c794a6a125059633d29445d991d867b770
2025-05-19 15:43:31 +00:00
Dawid Małecki 9858e1e1dc Align ImageStyle overflow prop type and compose function type (#51285)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51285

The `composeStyles` function should correctly determine the type of the input styles (`ViewStyle`, `ImageStyle`, `TextStyle`) base on the output type:

```ts
const combinedStyle8: StyleProp<ImageStyle> = StyleSheet.compose(
  // ts-expect-error
  composeTextStyle,
  composeTextStyle,
);
```

This diff adds generic type checking for `compose` function and fixes `ImageStyle` overflow prop type which accepted `scroll` property (which wasn't previously accepted in manual types) and which enables type system to distinguish `ImageStyle` from `ViewStyle` and `TextStyle`:

previous:
```ts
overflow?: 'visible' | 'hidden' | 'scroll'
```

current:
```t
overflow?: 'visible' | 'hidden'
```

Changelog:
[Internal]

Reviewed By: huntie

Differential Revision: D74574293

fbshipit-source-id: 751a44f2d3cd43055d93031343995f16ef87b185
2025-05-19 15:41:17 +00:00
Jakub Piasecki 7749879647 Add a custom Jest resolver to opt out from handling "exports" in tests (#51307)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51307

D72228547 added the `exports` field to the main `react-native` package, in which all imports from `./src/*` are explicitly disallowed. This was expected to be a breaking change and to limit the surface area of it, this diff will allow using all imports in jest tests.

Changelog: [General][Added] Added a custom Jest resolver to opt out from handling "exports" in tests

Reviewed By: huntie

Differential Revision: D74708701

fbshipit-source-id: 9a2714f4e6f78ffbad9e56b5bb92657c9ea908ef
2025-05-19 15:39:22 +00:00
Alex Hunt 2374d0ab36 Explicitly exclude types_generated/ from "exports" (#51121)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51121

Previously could match via the `"./*"` subpath when `"react-native-strict-api"` is not set. Only the entry point `./types_generated/index.d.ts` should be exposed.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D74242716

fbshipit-source-id: 232c90f34fafe8fdf1a5a7ef1fec4acc191525b4
2025-05-19 15:33:35 +00:00
Alan Lee 0e3764c8aa migrate deprecated onBackPressed() (#51096)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51096

**Problem:** `Activity.onBackPressed()` has been deprecated and with targetSdk 36, predictive back will be enforced and the API no longer called. We need to migrate to backward compatible AndroidX `OnBackPressedCallback`.
- https://developer.android.com/about/versions/16/behavior-changes-16#predictive-back.

**Solution:**
`OnBackPressedCallback` is registered conditionally only if it is `targetSdk` 36 or greater.
If the callback in enabled, `onBackPressed()` is not called and callback is used regardless of `android:enableOnBackInvokedCallback` property in <application> or <activity> set in AndroidManifest.xml.

As a workaround callback is manually calling existing `onBackPressed()`.

This is done rather than removing onBackPressed() completely and using only `OnBackPressedCallback` as we are not sure of the impact of removing the implementation entirely. Once we determine it is safe to do so then, we should remove the workaround and fully transition to `OnBackPressedCallback`

* I also surveyed child classes extending ReactActivity for overridden `onPressedBack()` usage and found only one usage which will be handled later.

NOTE: `ReactDelegate.onHostResume()` sets up the `DefaultHardwareBackBtnHandler` using `ReactActivity` (https://fburl.com/ul47tbeo) and will be called from JS `BackHanderl.exitApp` (https://fburl.com/code/a4l2pjsw). Calling `BackHanderl.exitApp` enables predictive back to work.

Changelog:
[Internal]

Reviewed By: mdvacca

Differential Revision: D74161428

fbshipit-source-id: 2e081ba6922b315e9d1746e83a41bab5277fa62e
2025-05-19 15:32:24 +00:00
Christian Falch 84cf4d8869 make DevServerHelper open (#51323)
Summary:
Expo inherits from the DevServerHelper class, and needs it to be declared as open, the same goes for its public interface.

Expo is using this in `DevLauncherDevServerHelper` and overrides the methods:

- getDevServerBundleURL
- getDevServerSplitBundleURL
- getSourceUrl
- getSourceMapUrl
- isPackagerRunning

This PR fixes this by adding the open to the class and to the methods that should be open

## Changelog:

[ANDROID] [FIXED] - Made DevServerHelper and its method open so that they can be overridden.

Pull Request resolved: https://github.com/facebook/react-native/pull/51323

Test Plan: Verify that we can build against Expo.

Reviewed By: cipolleschi

Differential Revision: D74876479

Pulled By: cortinico

fbshipit-source-id: 0037d6f7cee190a690ec3ec59896df04f46797b2
2025-05-16 15:22:12 +00:00
Jakub Piasecki 77021b600e Restore legacy semantics of modulesConformingToProtocol (#51381)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51381

Changelog: [General][Fixed] Fixed codegen breaking when a subset of `modulesConformingToProtocol` fields was specified or when the value was string

D70822061 introduced a new way of defininf modules and components in codegen, but accidentally introduced two breaking changes to the legacy syntax:
- before that diff, in case of 1:1 mapping, the value of the fileds could be a string, while after, it required it to be an array
- before that diff, not all of the fields on `modulesConformingToProtocol` had to be defined in `package.json`, while after, it required all fields to be defined even if unused

Reviewed By: cipolleschi

Differential Revision: D74875251

fbshipit-source-id: 610103b508f1462b4de01725f9b0a87341571197
2025-05-16 14:52:41 +00:00
Christian Falch 0a76d9fb87 fix adding children (#51213)
Summary:
See https://github.com/facebook/react-native/issues/51212 - children aren't updated correctly in an old arch native view using the interop layer under Fabric.

This is caused by the mountChildComponentView method not updating the view, only adding the new view to a list that will be used on the next update to mount the child.

This commit fixes this by adding the same pattern as in unmountChildComponentView where children are inserted directly if the underlying paperview is available in the adapter - otherwise it uses the mounting list as before.

#Closes 51212

bypass-github-export-checks

## Changelog:

[IOS] [FIXED] - fixed adding child views to a native view using the interop layer

Pull Request resolved: https://github.com/facebook/react-native/pull/51213

Test Plan:
**Previous output**:

<image src="https://github.com/user-attachments/assets/472b95e7-0921-46c9-be6a-f31759c0cd26" width="200px" />

**After fix**:

<image src="https://github.com/user-attachments/assets/554387cd-c264-483e-9c52-d9cd40b42601" width="200px" />

Reviewed By: sammy-SC

Differential Revision: D74471278

Pulled By: cipolleschi

fbshipit-source-id: 798f9e7be389359bd6e3aa1b6a6e9fb799fcb369
2025-05-16 14:15:12 +00:00
Ritesh Shukla af85c4c810 Fixed borderBottomEndRadius on RTL (#51229)
Summary:
Fixes https://github.com/facebook/react-native/issues/51193
## Changelog:
[ANDROID][FIXED] Wrong borderBottomEndRadius on RTL

Pull Request resolved: https://github.com/facebook/react-native/pull/51229

Test Plan:
Tested with Arabic (RTL) and English(LTR)

English
<img src="https://github.com/user-attachments/assets/5bd1eca9-194c-4d83-b75f-689bc13d827b" width=200>

Arabic
<img src="https://github.com/user-attachments/assets/459320a0-6bb2-4585-97bb-bd4ded6ec399" width=200>

Reviewed By: cortinico

Differential Revision: D74709219

Pulled By: NickGerleman

fbshipit-source-id: 885bb84d97d73324983d044fd2874a457b40f646
2025-05-16 10:14:04 +00:00
Christian Falch 51d10578dc make removeView open in ViewGroupManager (#51322)
Summary:
After conversion to Kotlin we could no longer override the removeView function since it is no longer open. The rest of this class can be overridden as before, but since functions are final by default this doesn't work for the new `removeView` function.

Expo is overriding the `removeView` functions in `GroupViewManagerWrapper.kt` (a lot of other ViewManager methods are also overridden here, but the `removeView` is introduced in `ViewGroupManager` and needs to be open as well. `GroupViewManagerWrapper.kt` is a replacement view manager that adds support for a delegate that will receive callbacks whenever one of the methods in the view manager are called.

This commit fixes this by making the removeView function explicitly open.

## Changelog:

[ANDROID] [FIXED] - Made function `removeView` open in Kotlin class

Pull Request resolved: https://github.com/facebook/react-native/pull/51322

Test Plan: Verify that Expo can build against this class.

Reviewed By: javache

Differential Revision: D74807744

Pulled By: cortinico

fbshipit-source-id: 55f4b9deccb7d82ceb78be1d56c2b99a6f7e3ce9
2025-05-16 10:07:16 +00:00
React Native Bot 033e6b1f9c [LOCAL] Bump Podfile.lock 2025-05-12 17:41:07 +00:00
React Native Bot d2168e9415 Release 0.80.0-rc.1
#publish-packages-to-npm&next
2025-05-12 16:16:21 +00:00
Riccardo Cipolleschi 79e2298230 [RN][Release] Fix set-rn-version to consider also the codegen snapshot tests (#51156) 2025-05-12 15:17:36 +01:00
Jakub Piasecki 619a0db17f Update transform types to preserve behavior in TypeScript (#51115)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51115

Changelog: [Internal]

Reviewed By: huntie

Differential Revision: D74229819

fbshipit-source-id: 08e363ae58c29ca910601b2f078153b8ff30103c
2025-05-12 14:14:01 +00:00
Dawid Małecki 241b1a6462 Add transform that moves comments for default exported variable declarations (#51135)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51135

In generated types default exported variables are re-declared which shadows attached tags and doc blocks. This transform moves necessary comments on top of re-declarations to keep them accessible.

Example output for SafeAreaView:

```ts
import type { ViewProps } from "../View/ViewPropTypes";
import View from "../View/View";
import * as React from "react";
declare const exported: (props: Omit<ViewProps, keyof {
  ref?: React.Ref<React.ComponentRef<typeof View>>;
}> & {
  ref?: React.Ref<React.ComponentRef<typeof View>>;
}) => React.ReactNode;
/**
 * Renders nested content and automatically applies paddings reflect the portion
 * of the view that is not covered by navigation bars, tab bars, toolbars, and
 * other ancestor views.
 *
 * Moreover, and most importantly, Safe Area's paddings reflect physical
 * limitation of the screen, such as rounded corners or camera notches (aka
 * sensor housing area on iPhone X).
 */
declare const SafeAreaView_DEFAULT: typeof exported;
declare type SafeAreaView_DEFAULT = typeof SafeAreaView_DEFAULT;
export default SafeAreaView_DEFAULT;
```

Changelog:
[Internal]

Reviewed By: huntie

Differential Revision: D74249424

fbshipit-source-id: 5cdd1c746e7fed99e3d3427d6ebf4c0e7ba3f3fd
2025-05-12 13:52:49 +00:00
Dawid Małecki e8b14c7b06 Attach @deprecated tag and doc block to ProgressBarAndroid (#51136)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51136

This diff attaches doc block to ProgressBarAndroid copied from the manual TS types.

Generated types result:

```ts
import * as React from "react";
import type $$IMPORT_TYPEOF_1$$ from "./ProgressBarAndroidNativeComponent";
type ProgressBarAndroidNativeComponentType = typeof $$IMPORT_TYPEOF_1$$;
import type { ProgressBarAndroidProps } from "./ProgressBarAndroidTypes";
export type { ProgressBarAndroidProps };
declare let ProgressBarAndroid: (props: Omit<ProgressBarAndroidProps, keyof {
  ref?: React.Ref<React.ComponentRef<ProgressBarAndroidNativeComponentType>>;
}> & {
  ref?: React.Ref<React.ComponentRef<ProgressBarAndroidNativeComponentType>>;
}) => React.ReactNode;
/**
 * ProgressBarAndroid has been extracted from react-native core and will be removed in a future release.
 * It can now be installed and imported from `react-native-community/progress-bar-android` instead of 'react-native'.
 * see https://github.com/react-native-community/progress-bar-android
 * deprecated
 */
declare const $$ProgressBarAndroid: typeof ProgressBarAndroid;
declare type $$ProgressBarAndroid = typeof $$ProgressBarAndroid;
export default $$ProgressBarAndroid;

```

Changelog:
[Internal]

Reviewed By: robhogan

Differential Revision: D73855212

fbshipit-source-id: c6c09ea68c9f61f305f96c0954370bb938fc59d9
2025-05-12 13:51:37 +00:00
Dawid Małecki 8b8e1055ae Move imported types from @react-native/assets-registry and @react-native/js-polyfills to react-native repo (#51192)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51192

The `build-types` script cannot currently resolve `react-native/assets-registry` and `react-native/js-polyfills`. This diff moves imported types from these packages to `react-native` to include them in generated types.

Changelog:
[Internal]

Reviewed By: huntie

Differential Revision: D74392568

fbshipit-source-id: cbce977b710f54dc53ce1b0fc080704b420490d4
2025-05-12 13:50:13 +00:00
Riccardo Cipolleschi cdf7d76101 [RN][Releases] Fix draft creation (#51158) 2025-05-12 14:49:17 +01:00
Kacper Rożniata 1c22a46cf6 fix(iOS): enable DEFINES_MODULE in React-jsc (#51160)
Summary:
Enables `DEFINES_MODULE` in `React-jsc.podspec`

After upgrading app to RN `0.79`, when installing pods with JSC enabled there is an error being thrown that

`The following Swift pods cannot yet be integrated as static libraries`
`The Swift pod 'RNFlashList' depends upon 'React-jsc', which does not define modules. ...`
when installing packages that use Swift

## Changelog:

[IOS] [CHANGED] -  enable `DEFINES_MODULE` in `React-jsc.podspec`

Pull Request resolved: https://github.com/facebook/react-native/pull/51160

Test Plan: RNTester runs and builds correctly

Reviewed By: huntie

Differential Revision: D74325357

Pulled By: cipolleschi

fbshipit-source-id: b994b7e678633440d5e362ae6965b2d5188d34f1
2025-05-12 13:41:22 +00:00
ismarbesic 7ce8f12549 Exclude selectively disabled libraries from codegen generation (#51078)
Summary:
Selectively disabling autolinking of a native dependency with components registered in the codegen configuration in react-native.config.js causes builds to crash upon launch on iOS. This is because the generated `RCTThirdPartyComponentsProvider.mm` file contains references to the excluded library using `NSClassFromString` causing the returned NSDictionary from `+[RCTThirdPartyComponentsProvider thirdPartyFabricComponents]` to be populated with nil values and therefore crashing the app. This has been confirmed in 0.78.2 and 0.79.2 but probably exists in 0.77.x as well.

The issue has been further described in https://github.com/facebook/react-native/issues/51077.

## Changelog:

[IOS][FIXED] - Skip codegen for selectively disabled libraries in react-native.config.js

Pull Request resolved: https://github.com/facebook/react-native/pull/51078

Test Plan:
1. Install a library that has the componentProvider field set in the codegen config (see reproducer) and install the iOS pods.
2. Build the app.
3. App should run successfully without any crashes.

Reviewed By: cortinico

Differential Revision: D74248371

Pulled By: cipolleschi

fbshipit-source-id: 1ff7b477ed3d94ca45616ae243d3d2d30bd897db
2025-05-12 13:39:24 +00:00
Jakub Piasecki ce4d7e5d52 Fix generated types in @react-native/virtualized-lists being used without opt-in (#51246)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51246

Changelog: [General][Fixed] Fix generated types in react-native/virtualized-lists being used without opt-in

D71969602 introduces `exports` field to `package.json` files in `react-native` and `virtualized-lists`. In that diff, the `types` in `virtualized-lists` by default pointed to the new generated types without requiring the opt-in.

This fixes that by requiring the opt-in before using the generated types.

Reviewed By: huntie

Differential Revision: D74573321

fbshipit-source-id: fe05b0204a7200c1c91aac2614aa786bbbced2a5
2025-05-12 13:34:50 +00:00
Dawid Małecki d5c6afaae0 Fix suggesting components from types_generated directory (#51101)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51101

TS LSP suggests importing/using components from `types_generated` directory which are exported under slightly different name than root exports. Prefixing default exports with `$$` fixes the issue.

Changelog:
[Internal]

Reviewed By: huntie

Differential Revision: D74177107

fbshipit-source-id: 86a6869c2aa7a113915184e4857a7882710b1db4
2025-05-12 13:18:20 +00:00
React Native Bot f70a146699 [LOCAL] Bump Podfile.lock 2025-05-07 11:41:41 +00:00
React Native Bot d9c2857e59 Release 0.80.0-rc.0
#publish-packages-to-npm&next
2025-05-07 10:17:06 +00:00
Jorge Cohen cbf1710fd5 Bump hermes version 2025-05-06 11:21:57 +01:00
92 changed files with 1847 additions and 768 deletions
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
with:
script: |
const {createDraftRelease} = require('./.github/workflow-scripts/createDraftRelease.js');
const version = ${{ github.ref_name }}';
const version = '${{ github.ref_name }}';
const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js');
await createDraftRelease(version, isLatest(), '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}');
+10
View File
@@ -0,0 +1,10 @@
## Summary:
This change fixes the script that updates the RN Version to also update the Codegen snapshots so that they are in sync with the current version of React Native.
It also updates the Snapshot as it was failing in rc.0
## Changelog:
[Internal] - Fixed script that updates the react native versions
## Test Plan:
Tested locally by running `node ./scripts/releases/set-rn-artifacts-version --built-type release --to-version 0.80.0-rc.0` and verifying that the snapshot file was getting updated. I then run the `yarn test
generate-artifacts-executor-test.js` command to verify that the tests were passing.
+2 -2
View File
@@ -52,8 +52,8 @@
"@babel/preset-flow": "^7.24.7",
"@definitelytyped/dtslint": "^0.0.127",
"@jest/create-cache-key-function": "^29.7.0",
"@react-native/metro-babel-transformer": "0.80.0-main",
"@react-native/metro-config": "0.80.0-main",
"@react-native/metro-babel-transformer": "0.80.0-rc.2",
"@react-native/metro-config": "0.80.0-rc.2",
"@tsconfig/node18": "1.0.1",
"@types/react": "^19.0.0",
"@typescript-eslint/parser": "^7.1.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/assets-registry",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Asset support code for React Native.",
"license": "MIT",
"repository": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/babel-plugin-codegen",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Babel plugin to generate native module and view manager code for React Native.",
"license": "MIT",
"repository": {
@@ -26,7 +26,7 @@
],
"dependencies": {
"@babel/traverse": "^7.25.3",
"@react-native/codegen": "0.80.0-main"
"@react-native/codegen": "0.80.0-rc.2"
},
"devDependencies": {
"@babel/core": "^7.25.2"
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/community-cli-plugin",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Core CLI commands for React Native",
"keywords": [
"react-native",
@@ -22,7 +22,7 @@
"dist"
],
"dependencies": {
"@react-native/dev-middleware": "0.80.0-main",
"@react-native/dev-middleware": "0.80.0-rc.2",
"chalk": "^4.0.0",
"debug": "^4.4.0",
"invariant": "^2.2.4",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/core-cli-utils",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "React Native CLI library for Frameworks to build on",
"license": "MIT",
"main": "./src/index.flow.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/debugger-frontend",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Debugger frontend for React Native based on Chrome DevTools",
"keywords": [
"react-native",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/dev-middleware",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Dev server middleware for React Native",
"keywords": [
"react-native",
@@ -23,7 +23,7 @@
],
"dependencies": {
"@isaacs/ttlcache": "^1.4.1",
"@react-native/debugger-frontend": "0.80.0-main",
"@react-native/debugger-frontend": "0.80.0-rc.2",
"chrome-launcher": "^0.15.2",
"chromium-edge-launcher": "^0.2.0",
"connect": "^3.6.5",
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-config",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "ESLint config for React Native",
"license": "MIT",
"repository": {
@@ -22,7 +22,7 @@
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.25.1",
"@react-native/eslint-plugin": "0.80.0-main",
"@react-native/eslint-plugin": "0.80.0-rc.2",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"eslint-config-prettier": "^8.5.0",
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "ESLint rules for @react-native/eslint-config",
"license": "MIT",
"repository": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin-specs",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "ESLint rules to validate NativeModule and Component Specs",
"license": "MIT",
"repository": {
@@ -26,7 +26,7 @@
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-transform-flow-strip-types": "^7.25.2",
"@react-native/codegen": "0.80.0-main",
"@react-native/codegen": "0.80.0-rc.2",
"make-dir": "^2.1.0",
"pirates": "^4.0.1",
"source-map-support": "0.5.0"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/gradle-plugin",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Gradle Plugin for React Native",
"license": "MIT",
"repository": {
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "helloworld",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"private": true,
"scripts": {
"bootstrap": "node ./cli.js bootstrap",
@@ -13,16 +13,16 @@
},
"dependencies": {
"react": "19.1.0",
"react-native": "1000.0.0"
"react-native": "0.80.0-rc.2"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native/babel-preset": "0.80.0-main",
"@react-native/core-cli-utils": "0.80.0-main",
"@react-native/eslint-config": "0.80.0-main",
"@react-native/metro-config": "0.80.0-main",
"@react-native/babel-preset": "0.80.0-rc.2",
"@react-native/core-cli-utils": "0.80.0-rc.2",
"@react-native/eslint-config": "0.80.0-rc.2",
"@react-native/metro-config": "0.80.0-rc.2",
"chalk": "^4.1.2",
"commander": "^12.0.0",
"eslint": "^8.19.0",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/metro-config",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Metro configuration for React Native.",
"license": "MIT",
"repository": {
@@ -26,8 +26,8 @@
"dist"
],
"dependencies": {
"@react-native/js-polyfills": "0.80.0-main",
"@react-native/metro-babel-transformer": "0.80.0-main",
"@react-native/js-polyfills": "0.80.0-rc.2",
"@react-native/metro-babel-transformer": "0.80.0-rc.2",
"metro-config": "^0.82.2",
"metro-runtime": "^0.82.2"
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/new-app-screen",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "NewAppScreen component for React Native",
"keywords": [
"react-native"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/normalize-colors",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Color normalization for React Native.",
"license": "MIT",
"repository": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/js-polyfills",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Polyfills for React Native.",
"license": "MIT",
"repository": {
@@ -1,6 +1,6 @@
{
"name": "@react-native/babel-preset",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Babel preset for React Native applications",
"repository": {
"type": "git",
@@ -66,7 +66,7 @@
"@babel/plugin-transform-typescript": "^7.25.2",
"@babel/plugin-transform-unicode-regex": "^7.24.7",
"@babel/template": "^7.25.0",
"@react-native/babel-plugin-codegen": "0.80.0-main",
"@react-native/babel-plugin-codegen": "0.80.0-rc.2",
"babel-plugin-syntax-hermes-parser": "0.28.1",
"babel-plugin-transform-flow-enums": "^0.0.2",
"react-refresh": "^0.14.0"
@@ -1,6 +1,6 @@
{
"name": "@react-native/metro-babel-transformer",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Babel transformer for React Native applications.",
"repository": {
"type": "git",
@@ -27,7 +27,7 @@
],
"dependencies": {
"@babel/core": "^7.25.2",
"@react-native/babel-preset": "0.80.0-main",
"@react-native/babel-preset": "0.80.0-rc.2",
"hermes-parser": "0.28.1",
"nullthrows": "^1.1.1"
},
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@react-native/bots",
"description": "React Native Bots",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"private": true,
"license": "MIT",
"repository": {
@@ -1,6 +1,6 @@
{
"name": "@react-native/codegen-typescript-test",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"private": true,
"description": "TypeScript related unit test for @react-native/codegen",
"license": "MIT",
@@ -19,7 +19,7 @@
"prepare": "yarn run build"
},
"dependencies": {
"@react-native/codegen": "0.80.0-main"
"@react-native/codegen": "0.80.0-rc.2"
},
"devDependencies": {
"@babel/core": "^7.25.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/codegen",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Code generation tools for React Native",
"license": "MIT",
"repository": {
@@ -1,6 +1,6 @@
{
"name": "@react-native/compatibility-check",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Check a React Native app's boundary between JS and Native for incompatibilities",
"license": "MIT",
"repository": {
@@ -29,7 +29,7 @@
"dist"
],
"dependencies": {
"@react-native/codegen": "0.80.0-main"
"@react-native/codegen": "0.80.0-rc.2"
},
"devDependencies": {
"flow-remove-types": "^2.237.2",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@react-native/fantom",
"private": true,
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"main": "src/index.js",
"description": "Internal integration testing and benchmarking tool for React Native",
"peerDependencies": {
@@ -1,6 +1,6 @@
{
"name": "@react-native/popup-menu-android",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "PopupMenu for the Android platform",
"main": "index.js",
"files": [
@@ -21,7 +21,7 @@
},
"license": "MIT",
"devDependencies": {
"@react-native/codegen": "0.80.0-main"
"@react-native/codegen": "0.80.0-rc.2"
},
"peerDependencies": {
"@types/react": "^19.0.0",
@@ -1,6 +1,6 @@
{
"name": "@react-native/oss-library-example",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"private": true,
"description": "Package that includes native module exapmle, native component example, targets both the old and the new architecture. It should serve as an example of a real-world OSS library.",
"license": "MIT",
@@ -26,8 +26,8 @@
],
"devDependencies": {
"@babel/core": "^7.25.2",
"@react-native/babel-preset": "0.80.0-main",
"react-native": "1000.0.0"
"@react-native/babel-preset": "0.80.0-rc.2",
"react-native": "0.80.0-rc.2"
},
"peerDependencies": {
"react": "*",
@@ -37,7 +37,7 @@ export type {default as AnimatedDivision} from './nodes/AnimatedDivision';
export type {default as AnimatedModulo} from './nodes/AnimatedModulo';
export type {default as AnimatedMultiplication} from './nodes/AnimatedMultiplication';
export type {default as AnimatedSubtraction} from './nodes/AnimatedSubtraction';
export type {WithAnimatedValue} from './createAnimatedComponent';
export type {WithAnimatedValue, AnimatedProps} from './createAnimatedComponent';
export type {AnimatedComponentType as AnimatedComponent} from './createAnimatedComponent';
/**
@@ -22,7 +22,7 @@ import invariant from 'invariant';
export type AnimatedPropsAllowlist = $ReadOnly<{
style?: ?AnimatedStyleAllowlist,
[string]: true,
[key: string]: true | AnimatedStyleAllowlist,
}>;
type TargetView = {
+6 -1
View File
@@ -22,7 +22,12 @@ import NativeAppState from './NativeAppState';
* - @platform android - on another Activity (even if it was launched by your app)
* @platform ios - inactive - This is a state that occurs when transitioning between foreground & background, and during periods of inactivity such as entering the multitasking view, opening the Notification Center or in the event of an incoming call.
*/
export type AppStateStatus = 'inactive' | 'background' | 'active';
export type AppStateStatus =
| 'inactive'
| 'background'
| 'active'
| 'extension'
| 'unknown';
/**
* change - This even is received when the app state has changed.
@@ -110,6 +110,7 @@ const ActivityIndicator = (
style={StyleSheet.compose(styles.container, style)}>
{Platform.OS === 'android' ? (
// $FlowFixMe[prop-missing] Flow doesn't know when this is the android component
// $FlowFixMe[incompatible-type]
<PlatformActivityIndicator {...nativeProps} {...androidProps} />
) : (
/* $FlowFixMe[incompatible-type] (>=0.106.0 site=react_native_android_fb) This comment
@@ -17,11 +17,23 @@ import Platform from '../../Utilities/Platform';
export type {ProgressBarAndroidProps};
// A utility type to preserve the semantics of the union uses in the definition
// of ProgressBarAndroidProps. TS's Omit does not distribute over unions, so
// we define our own version which does. This does not affect Flow.
// $FlowExpectedError[unclear-type]
type Omit<T, K> = T extends any ? Pick<T, Exclude<$Keys<T>, K>> : T;
/**
* ProgressBarAndroid has been extracted from react-native core and will be removed in a future release.
* It can now be installed and imported from `@react-native-community/progress-bar-android` instead of 'react-native'.
* @see https://github.com/react-native-community/progress-bar-android
* @deprecated
*/
let ProgressBarAndroid: component(
ref?: React.RefSetter<
React.ElementRef<ProgressBarAndroidNativeComponentType>,
>,
...props: ProgressBarAndroidProps
...props: Omit<ProgressBarAndroidProps, empty>
);
if (Platform.OS === 'android') {
@@ -17,28 +17,25 @@ import type {ViewProps} from '../View/ViewPropTypes';
* `indeterminate` can only be false if `styleAttr` is Horizontal, and requires a
* `progress` value.
*/
type ProgressBarAndroidStyleAttrProp =
| {
styleAttr: 'Horizontal',
indeterminate: false,
progress: number,
}
| {
styleAttr:
| 'Horizontal'
| 'Normal'
| 'Small'
| 'Large'
| 'Inverse'
| 'SmallInverse'
| 'LargeInverse',
indeterminate: true,
};
type DeterminateProgressBarAndroidStyleAttrProp = {
styleAttr: 'Horizontal',
indeterminate: false,
progress: number,
};
export type ProgressBarAndroidProps = $ReadOnly<{
...ViewProps,
...ProgressBarAndroidStyleAttrProp,
type IndeterminateProgressBarAndroidStyleAttrProp = {
styleAttr:
| 'Horizontal'
| 'Normal'
| 'Small'
| 'Large'
| 'Inverse'
| 'SmallInverse'
| 'LargeInverse',
indeterminate: true,
};
type ProgressBarAndroidBaseProps = $ReadOnly<{
/**
* Whether to show the ProgressBar (true, the default) or hide it (false).
*/
@@ -52,3 +49,15 @@ export type ProgressBarAndroidProps = $ReadOnly<{
*/
testID?: ?string,
}>;
export type ProgressBarAndroidProps =
| $ReadOnly<{
...ViewProps,
...ProgressBarAndroidBaseProps,
...DeterminateProgressBarAndroidStyleAttrProp,
}>
| $ReadOnly<{
...ViewProps,
...ProgressBarAndroidBaseProps,
...IndeterminateProgressBarAndroidStyleAttrProp,
}>;
+3 -3
View File
@@ -14,8 +14,8 @@ export const version: $ReadOnly<{
patch: number,
prerelease: string | null,
}> = {
major: 1000,
minor: 0,
major: 0,
minor: 80,
patch: 0,
prerelease: null,
prerelease: 'rc.2',
};
@@ -52,7 +52,7 @@ export default class NativeEventEmitter<
{
_nativeModule: ?NativeModule;
constructor(nativeModule: ?NativeModule) {
constructor(nativeModule?: ?NativeModule) {
if (Platform.OS === 'ios') {
invariant(
nativeModule != null,
@@ -18,10 +18,23 @@ export type ResolvedAssetSource = {
+scale: number,
};
import type {
AssetDestPathResolver,
PackagerAsset,
} from '@react-native/assets-registry/registry';
// From @react-native/assets-registry
type AssetDestPathResolver = 'android' | 'generic';
// From @react-native/assets-registry
type PackagerAsset = $ReadOnly<{
__packager_asset: boolean,
fileSystemLocation: string,
httpServerLocation: string,
width: ?number,
height: ?number,
scales: Array<number>,
hash: string,
name: string,
type: string,
resolver?: AssetDestPathResolver,
...
}>;
const PixelRatio = require('../Utilities/PixelRatio').default;
const Platform = require('../Utilities/Platform').default;
@@ -107,4 +107,6 @@ declare export const setStyleAttributePreprocessor: (
* An identity function for creating style sheets.
*/
// $FlowFixMe[unsupported-variance-annotation]
declare export const create: <+S: ____Styles_Internal>(obj: S) => $ReadOnly<S>;
declare export const create: <+S: ____Styles_Internal>(
obj: S & ____Styles_Internal,
) => $ReadOnly<S>;
@@ -21,6 +21,7 @@ import type {
____ViewStyle_InternalOverrides,
} from './private/_StyleSheetTypesOverrides';
import type {____TransformStyle_Internal} from './private/_TransformStyle';
import type {ColorValue} from './StyleSheet';
export type {____TransformStyle_Internal};
@@ -1001,7 +1002,8 @@ export type ____ImageStyle_InternalCore = $ReadOnly<{
resizeMode?: ImageResizeMode,
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none',
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
overlayColor?: ColorValue,
overflow?: 'visible' | 'hidden',
}>;
export type ____ImageStyle_Internal = $ReadOnly<{
@@ -1014,7 +1016,7 @@ export type ____DangerouslyImpreciseStyle_InternalCore = $ReadOnly<{
resizeMode?: ImageResizeMode,
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none',
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
overlayColor?: ColorValue,
}>;
export type ____DangerouslyImpreciseStyle_Internal = $ReadOnly<{
@@ -10,6 +10,25 @@
import type AnimatedNode from '../../Animated/nodes/AnimatedNode';
// Helper types to enforce that a single key is used in a transform object
// after generating a TypeScript definition file from the Flow types.
// $FlowExpectedError[unclear-type]
type KeysOfUnion<T> = T extends any ? $Keys<T> : empty;
// $FlowExpectedError[unclear-type]
type ValueOfUnion<T, K> = T extends any
? K extends $Keys<T>
? T[K]
: empty
: empty;
type MergeUnion<T> = {
[K in KeysOfUnion<T>]?: ValueOfUnion<T, K>,
};
type MaximumOneOf<T: {...}> = $Values<{
[K in keyof T]: $Exact<{
[P in keyof T]?: P extends K ? T[P] : empty,
}>,
}>;
export type ____TransformStyle_Internal = $ReadOnly<{
/**
* `transform` accepts an array of transformation objects. Each object specifies
@@ -29,27 +48,36 @@ export type ____TransformStyle_Internal = $ReadOnly<{
*/
transform?:
| $ReadOnlyArray<
| {+perspective: number | AnimatedNode}
| {+rotate: string | AnimatedNode}
| {+rotateX: string | AnimatedNode}
| {+rotateY: string | AnimatedNode}
| {+rotateZ: string | AnimatedNode}
| {+scale: number | AnimatedNode}
| {+scaleX: number | AnimatedNode}
| {+scaleY: number | AnimatedNode}
| {+translateX: number | string | AnimatedNode}
| {+translateY: number | string | AnimatedNode}
| {
+translate:
| [number | string | AnimatedNode, number | string | AnimatedNode]
| AnimatedNode,
}
| {+skewX: string | AnimatedNode}
| {+skewY: string | AnimatedNode}
// TODO: what is the actual type it expects?
| {
+matrix: $ReadOnlyArray<number | AnimatedNode> | AnimatedNode,
},
$ReadOnly<
MaximumOneOf<
MergeUnion<
| {+perspective: number | AnimatedNode}
| {+rotate: string | AnimatedNode}
| {+rotateX: string | AnimatedNode}
| {+rotateY: string | AnimatedNode}
| {+rotateZ: string | AnimatedNode}
| {+scale: number | AnimatedNode}
| {+scaleX: number | AnimatedNode}
| {+scaleY: number | AnimatedNode}
| {+translateX: number | string | AnimatedNode}
| {+translateY: number | string | AnimatedNode}
| {
+translate:
| [
number | string | AnimatedNode,
number | string | AnimatedNode,
]
| AnimatedNode,
}
| {+skewX: string | AnimatedNode}
| {+skewY: string | AnimatedNode}
// TODO: what is the actual type it expects?
| {
+matrix: $ReadOnlyArray<number | AnimatedNode> | AnimatedNode,
},
>,
>,
>,
>
| string,
/**
+2 -31
View File
@@ -13,6 +13,7 @@
import type {
AccessibilityActionEvent,
AccessibilityActionInfo,
AccessibilityProps,
AccessibilityRole,
AccessibilityState,
Role,
@@ -124,20 +125,7 @@ export type TextPropsAndroid = {
};
type TextBaseProps = $ReadOnly<{
/**
* Indicates whether the view is an accessibility element.
*
* See https://reactnative.dev/docs/text#accessible
*/
accessible?: ?boolean,
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
accessibilityHint?: ?Stringish,
accessibilityLanguage?: ?Stringish,
accessibilityLabel?: ?Stringish,
accessibilityRole?: ?AccessibilityRole,
accessibilityState?: ?AccessibilityState,
'aria-label'?: ?string,
/**
* Whether fonts should scale to respect Text Size accessibility settings.
@@ -152,24 +140,6 @@ type TextBaseProps = $ReadOnly<{
*
*/
android_hyphenationFrequency?: ?('normal' | 'none' | 'full'),
/**
* alias for accessibilityState
*
* see https://reactnative.dev/docs/accessibility#accessibilitystate
*/
'aria-busy'?: ?boolean,
'aria-checked'?: ?boolean | 'mixed',
'aria-disabled'?: ?boolean,
'aria-expanded'?: ?boolean,
'aria-selected'?: ?boolean,
/**
* Represents the nativeID of the associated label text. When the assistive technology focuses on the component with this props, the text is read aloud.
* This prop is listed for cross-platform reasons and has no real effect on Android or iOS.
*/
'aria-labelledby'?: ?string,
children?: ?React.Node,
/**
@@ -306,4 +276,5 @@ export type TextProps = $ReadOnly<{
...TextPropsIOS,
...TextPropsAndroid,
...TextBaseProps,
...AccessibilityProps,
}>;
@@ -190,7 +190,10 @@ export type { default as AnimatedDivision } from \\"./nodes/AnimatedDivision\\";
export type { default as AnimatedModulo } from \\"./nodes/AnimatedModulo\\";
export type { default as AnimatedMultiplication } from \\"./nodes/AnimatedMultiplication\\";
export type { default as AnimatedSubtraction } from \\"./nodes/AnimatedSubtraction\\";
export type { WithAnimatedValue } from \\"./createAnimatedComponent\\";
export type {
WithAnimatedValue,
AnimatedProps,
} from \\"./createAnimatedComponent\\";
export type { AnimatedComponentType as AnimatedComponent } from \\"./createAnimatedComponent\\";
declare export const add: typeof AnimatedImplementation.add;
declare export const attachNativeEvent: typeof AnimatedImplementation.attachNativeEvent;
@@ -904,7 +907,7 @@ declare export default class AnimatedObject extends AnimatedWithChildren {
exports[`public API should not change unintentionally Libraries/Animated/nodes/AnimatedProps.js 1`] = `
"export type AnimatedPropsAllowlist = $ReadOnly<{
style?: ?AnimatedStyleAllowlist,
[string]: true,
[key: string]: true | AnimatedStyleAllowlist,
}>;
type TargetViewInstance = React.ElementRef<React.ElementType>;
declare export default class AnimatedProps extends AnimatedNode {
@@ -1077,7 +1080,12 @@ exports[`public API should not change unintentionally Libraries/Animated/useAnim
`;
exports[`public API should not change unintentionally Libraries/AppState/AppState.js 1`] = `
"export type AppStateStatus = \\"inactive\\" | \\"background\\" | \\"active\\";
"export type AppStateStatus =
| \\"inactive\\"
| \\"background\\"
| \\"active\\"
| \\"extension\\"
| \\"unknown\\";
type AppStateEventDefinitions = {
change: [AppStateStatus],
memoryWarning: [],
@@ -1818,11 +1826,12 @@ declare export default function useAndroidRippleForView(
exports[`public API should not change unintentionally Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.js 1`] = `
"export type { ProgressBarAndroidProps };
type Omit<T, K> = T extends any ? Pick<T, Exclude<$Keys<T>, K>> : T;
declare let ProgressBarAndroid: component(
ref?: React.RefSetter<
React.ElementRef<ProgressBarAndroidNativeComponentType>,
>,
...props: ProgressBarAndroidProps
...props: Omit<ProgressBarAndroidProps, empty>
);
declare export default typeof ProgressBarAndroid;
"
@@ -1835,30 +1844,38 @@ declare export default typeof ProgressBarAndroidNativeComponent;
`;
exports[`public API should not change unintentionally Libraries/Components/ProgressBarAndroid/ProgressBarAndroidTypes.js 1`] = `
"type ProgressBarAndroidStyleAttrProp =
| {
styleAttr: \\"Horizontal\\",
indeterminate: false,
progress: number,
}
| {
styleAttr:
| \\"Horizontal\\"
| \\"Normal\\"
| \\"Small\\"
| \\"Large\\"
| \\"Inverse\\"
| \\"SmallInverse\\"
| \\"LargeInverse\\",
indeterminate: true,
};
export type ProgressBarAndroidProps = $ReadOnly<{
...ViewProps,
...ProgressBarAndroidStyleAttrProp,
"type DeterminateProgressBarAndroidStyleAttrProp = {
styleAttr: \\"Horizontal\\",
indeterminate: false,
progress: number,
};
type IndeterminateProgressBarAndroidStyleAttrProp = {
styleAttr:
| \\"Horizontal\\"
| \\"Normal\\"
| \\"Small\\"
| \\"Large\\"
| \\"Inverse\\"
| \\"SmallInverse\\"
| \\"LargeInverse\\",
indeterminate: true,
};
type ProgressBarAndroidBaseProps = $ReadOnly<{
animating?: ?boolean,
color?: ?ColorValue,
testID?: ?string,
}>;
export type ProgressBarAndroidProps =
| $ReadOnly<{
...ViewProps,
...ProgressBarAndroidBaseProps,
...DeterminateProgressBarAndroidStyleAttrProp,
}>
| $ReadOnly<{
...ViewProps,
...ProgressBarAndroidBaseProps,
...IndeterminateProgressBarAndroidStyleAttrProp,
}>;
"
`;
@@ -4152,7 +4169,7 @@ declare export default class NativeEventEmitter<
> = $ReadOnly<Record<string, $ReadOnlyArray<UnsafeObject>>>,
> implements IEventEmitter<TEventToArgsMap>
{
constructor(nativeModule: ?NativeModule): void;
constructor(nativeModule?: ?NativeModule): void;
addListener<TEvent: $Keys<TEventToArgsMap>>(
eventType: TEvent,
listener: (...args: TEventToArgsMap[TEvent]) => mixed,
@@ -4202,6 +4219,19 @@ exports[`public API should not change unintentionally Libraries/Image/AssetSourc
+uri: string,
+scale: number,
};
type AssetDestPathResolver = \\"android\\" | \\"generic\\";
type PackagerAsset = $ReadOnly<{
fileSystemLocation: string,
httpServerLocation: string,
width: ?number,
height: ?number,
scales: Array<number>,
hash: string,
name: string,
type: string,
resolver?: AssetDestPathResolver,
...
}>;
declare class AssetSourceResolver {
serverUrl: ?string;
jsbundleUrl: ?string;
@@ -7080,7 +7110,9 @@ declare export const setStyleAttributePreprocessor: (
property: string,
process: (nextProp: any) => any
) => void;
declare export const create: <+S: ____Styles_Internal>(obj: S) => $ReadOnly<S>;
declare export const create: <+S: ____Styles_Internal>(
obj: S & ____Styles_Internal
) => $ReadOnly<S>;
"
`;
@@ -7485,7 +7517,8 @@ export type ____ImageStyle_InternalCore = $ReadOnly<{
resizeMode?: ImageResizeMode,
objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\" | \\"none\\",
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
overlayColor?: ColorValue,
overflow?: \\"visible\\" | \\"hidden\\",
}>;
export type ____ImageStyle_Internal = $ReadOnly<{
...____ImageStyle_InternalCore,
@@ -7496,7 +7529,7 @@ export type ____DangerouslyImpreciseStyle_InternalCore = $ReadOnly<{
resizeMode?: ImageResizeMode,
objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\" | \\"none\\",
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
overlayColor?: ColorValue,
}>;
export type ____DangerouslyImpreciseStyle_Internal = $ReadOnly<{
...____DangerouslyImpreciseStyle_InternalCore,
@@ -7580,29 +7613,52 @@ export type ____ViewStyle_InternalOverrides = $ReadOnly<{}>;
`;
exports[`public API should not change unintentionally Libraries/StyleSheet/private/_TransformStyle.js 1`] = `
"export type ____TransformStyle_Internal = $ReadOnly<{
"type KeysOfUnion<T> = T extends any ? $Keys<T> : empty;
type ValueOfUnion<T, K> = T extends any
? K extends $Keys<T>
? T[K]
: empty
: empty;
type MergeUnion<T> = {
[K in KeysOfUnion<T>]?: ValueOfUnion<T, K>,
};
type MaximumOneOf<T: { ... }> = $Values<{
[K in keyof T]: $Exact<{
[P in keyof T]?: P extends K ? T[P] : empty,
}>,
}>;
export type ____TransformStyle_Internal = $ReadOnly<{
transform?:
| $ReadOnlyArray<
| { +perspective: number | AnimatedNode }
| { +rotate: string | AnimatedNode }
| { +rotateX: string | AnimatedNode }
| { +rotateY: string | AnimatedNode }
| { +rotateZ: string | AnimatedNode }
| { +scale: number | AnimatedNode }
| { +scaleX: number | AnimatedNode }
| { +scaleY: number | AnimatedNode }
| { +translateX: number | string | AnimatedNode }
| { +translateY: number | string | AnimatedNode }
| {
+translate:
| [number | string | AnimatedNode, number | string | AnimatedNode]
| AnimatedNode,
}
| { +skewX: string | AnimatedNode }
| { +skewY: string | AnimatedNode }
| {
+matrix: $ReadOnlyArray<number | AnimatedNode> | AnimatedNode,
},
$ReadOnly<
MaximumOneOf<
MergeUnion<
| { +perspective: number | AnimatedNode }
| { +rotate: string | AnimatedNode }
| { +rotateX: string | AnimatedNode }
| { +rotateY: string | AnimatedNode }
| { +rotateZ: string | AnimatedNode }
| { +scale: number | AnimatedNode }
| { +scaleX: number | AnimatedNode }
| { +scaleY: number | AnimatedNode }
| { +translateX: number | string | AnimatedNode }
| { +translateY: number | string | AnimatedNode }
| {
+translate:
| [
number | string | AnimatedNode,
number | string | AnimatedNode,
]
| AnimatedNode,
}
| { +skewX: string | AnimatedNode }
| { +skewY: string | AnimatedNode }
| {
+matrix: $ReadOnlyArray<number | AnimatedNode> | AnimatedNode,
},
>,
>,
>,
>
| string,
transformOrigin?:
@@ -7818,23 +7874,9 @@ export type TextPropsAndroid = {
minimumFontScale?: ?number,
};
type TextBaseProps = $ReadOnly<{
accessible?: ?boolean,
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
accessibilityHint?: ?Stringish,
accessibilityLanguage?: ?Stringish,
accessibilityLabel?: ?Stringish,
accessibilityRole?: ?AccessibilityRole,
accessibilityState?: ?AccessibilityState,
\\"aria-label\\"?: ?string,
allowFontScaling?: ?boolean,
android_hyphenationFrequency?: ?(\\"normal\\" | \\"none\\" | \\"full\\"),
\\"aria-busy\\"?: ?boolean,
\\"aria-checked\\"?: ?boolean | \\"mixed\\",
\\"aria-disabled\\"?: ?boolean,
\\"aria-expanded\\"?: ?boolean,
\\"aria-selected\\"?: ?boolean,
\\"aria-labelledby\\"?: ?string,
children?: ?React.Node,
ellipsizeMode?: ?(\\"clip\\" | \\"head\\" | \\"middle\\" | \\"tail\\"),
id?: string,
@@ -7865,6 +7907,7 @@ export type TextProps = $ReadOnly<{
...TextPropsIOS,
...TextPropsAndroid,
...TextBaseProps,
...AccessibilityProps,
}>;
"
`;
@@ -8892,8 +8935,33 @@ declare export default typeof rejectionTrackingOptions;
`;
exports[`public API should not change unintentionally Libraries/vendor/core/ErrorUtils.js 1`] = `
"export type ErrorUtils = ErrorUtilsT;
declare export default ErrorUtilsT;
"type ErrorHandler = (error: mixed, isFatal: boolean) => void;
type Fn<Args: $ReadOnlyArray<mixed>, Return> = (...Args) => Return;
export type ErrorUtils = {
applyWithGuard<TArgs: $ReadOnlyArray<mixed>, TOut>(
fun: Fn<TArgs, TOut>,
context?: mixed,
args?: ?TArgs,
unused_onError?: null,
unused_name?: ?string
): ?TOut,
applyWithGuardIfNeeded<TArgs: $ReadOnlyArray<mixed>, TOut>(
fun: Fn<TArgs, TOut>,
context?: mixed,
args?: ?TArgs
): ?TOut,
getGlobalHandler(): ErrorHandler,
guard<TArgs: $ReadOnlyArray<mixed>, TOut>(
fun: Fn<TArgs, TOut>,
name?: ?string,
context?: mixed
): ?(...TArgs) => ?TOut,
inGuard(): boolean,
reportError(error: mixed): void,
reportFatalError(error: mixed): void,
setGlobalHandler(fun: ErrorHandler): void,
};
declare export default ErrorUtils;
"
`;
@@ -9010,6 +9078,7 @@ export type {
SectionListProps,
SectionListRenderItem,
SectionListRenderItemInfo,
SectionListData,
} from \\"./Libraries/Lists/SectionList\\";
export { default as SectionList } from \\"./Libraries/Lists/SectionList\\";
export type {
+28 -4
View File
@@ -8,9 +8,33 @@
* @flow strict
*/
import type {ErrorUtilsT} from '@react-native/js-polyfills/error-guard';
export type ErrorUtils = ErrorUtilsT;
// From @react-native/js-polyfills
type ErrorHandler = (error: mixed, isFatal: boolean) => void;
type Fn<Args: $ReadOnlyArray<mixed>, Return> = (...Args) => Return;
export type ErrorUtils = {
applyWithGuard<TArgs: $ReadOnlyArray<mixed>, TOut>(
fun: Fn<TArgs, TOut>,
context?: mixed,
args?: ?TArgs,
unused_onError?: null,
unused_name?: ?string,
): ?TOut,
applyWithGuardIfNeeded<TArgs: $ReadOnlyArray<mixed>, TOut>(
fun: Fn<TArgs, TOut>,
context?: mixed,
args?: ?TArgs,
): ?TOut,
getGlobalHandler(): ErrorHandler,
guard<TArgs: $ReadOnlyArray<mixed>, TOut>(
fun: Fn<TArgs, TOut>,
name?: ?string,
context?: mixed,
): ?(...TArgs) => ?TOut,
inGuard(): boolean,
reportError(error: mixed): void,
reportFatalError(error: mixed): void,
setGlobalHandler(fun: ErrorHandler): void,
};
/**
* The particular require runtime that we are using looks for a global
@@ -24,4 +48,4 @@ export type ErrorUtils = ErrorUtilsT;
* that use it aren't just using a global variable, so simply export the global
* variable here. ErrorUtils is originally defined in a file named error-guard.js.
*/
export default (global.ErrorUtils: ErrorUtilsT);
export default global.ErrorUtils as ErrorUtils;
@@ -21,10 +21,10 @@ NSDictionary* RCTGetReactNativeVersion(void)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^(void){
__rnVersion = @{
RCTVersionMajor: @(1000),
RCTVersionMinor: @(0),
RCTVersionMajor: @(0),
RCTVersionMinor: @(80),
RCTVersionPatch: @(0),
RCTVersionPrerelease: [NSNull null],
RCTVersionPrerelease: @"rc.2",
};
});
return __rnVersion;
@@ -170,10 +170,24 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[_viewsToBeMounted addObject:@{
kRCTLegacyInteropChildIndexKey : [NSNumber numberWithInteger:index],
kRCTLegacyInteropChildComponentKey : childComponentView
}];
if (_adapter && index == _adapter.paperView.reactSubviews.count) {
// This is a new child view that is being added to the end of the children array.
// After the children is added, we need to call didUpdateReactSubviews to make sure that it is rendered.
// Without this change, the new child will not be rendered right away because the didUpdateReactSubviews is not
// called and the `finalizeUpdate` is not invoked.
if ([childComponentView isKindOfClass:[RCTLegacyViewManagerInteropComponentView class]]) {
UIView *target = ((RCTLegacyViewManagerInteropComponentView *)childComponentView).contentView;
[_adapter.paperView insertReactSubview:target atIndex:index];
} else {
[_adapter.paperView insertReactSubview:childComponentView atIndex:index];
}
[_adapter.paperView didUpdateReactSubviews];
} else {
[_viewsToBeMounted addObject:@{
kRCTLegacyInteropChildIndexKey : [NSNumber numberWithInteger:index],
kRCTLegacyInteropChildComponentKey : childComponentView
}];
}
}
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
@@ -2006,7 +2006,7 @@ public final class com/facebook/react/devsupport/DefaultDevLoadingViewImplementa
public final fun setDevLoadingEnabled (Z)V
}
public final class com/facebook/react/devsupport/DevServerHelper {
public class com/facebook/react/devsupport/DevServerHelper {
public fun <init> (Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;Landroid/content/Context;Lcom/facebook/react/packagerconnection/PackagerConnectionSettings;)V
public final fun closeInspectorConnection ()V
public final fun closePackagerConnection ()V
@@ -2015,12 +2015,12 @@ public final class com/facebook/react/devsupport/DevServerHelper {
public final fun downloadBundleFromURL (Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;Ljava/io/File;Ljava/lang/String;Lcom/facebook/react/devsupport/BundleDownloader$BundleInfo;Lokhttp3/Request$Builder;)V
public static synthetic fun downloadBundleFromURL$default (Lcom/facebook/react/devsupport/DevServerHelper;Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;Ljava/io/File;Ljava/lang/String;Lcom/facebook/react/devsupport/BundleDownloader$BundleInfo;Lokhttp3/Request$Builder;ILjava/lang/Object;)V
public final fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public final fun getDevServerBundleURL (Ljava/lang/String;)Ljava/lang/String;
public final fun getDevServerSplitBundleURL (Ljava/lang/String;)Ljava/lang/String;
public final fun getSourceMapUrl (Ljava/lang/String;)Ljava/lang/String;
public final fun getSourceUrl (Ljava/lang/String;)Ljava/lang/String;
public fun getDevServerBundleURL (Ljava/lang/String;)Ljava/lang/String;
public fun getDevServerSplitBundleURL (Ljava/lang/String;)Ljava/lang/String;
public fun getSourceMapUrl (Ljava/lang/String;)Ljava/lang/String;
public fun getSourceUrl (Ljava/lang/String;)Ljava/lang/String;
public final fun getWebsocketProxyURL ()Ljava/lang/String;
public final fun isPackagerRunning (Lcom/facebook/react/devsupport/interfaces/PackagerStatusCallback;)V
public fun isPackagerRunning (Lcom/facebook/react/devsupport/interfaces/PackagerStatusCallback;)V
public final fun openDebugger (Lcom/facebook/react/bridge/ReactContext;Ljava/lang/String;)V
public final fun openInspectorConnection ()V
public final fun openPackagerConnection (Ljava/lang/String;Lcom/facebook/react/devsupport/DevServerHelper$PackagerCommandListener;)V
@@ -4656,7 +4656,7 @@ public abstract class com/facebook/react/uimanager/ViewGroupManager : com/facebo
public fun getShadowNodeClass ()Ljava/lang/Class;
public static final fun getViewZIndex (Landroid/view/View;)Ljava/lang/Integer;
public fun needsCustomLayoutForChildren ()Z
public final fun removeView (Landroid/view/ViewGroup;Landroid/view/View;)V
public fun removeView (Landroid/view/ViewGroup;Landroid/view/View;)V
public synthetic fun removeViewAt (Landroid/view/View;I)V
public fun removeViewAt (Landroid/view/ViewGroup;I)V
public static final fun setViewZIndex (Landroid/view/View;I)V
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0
VERSION_NAME=0.80.0-rc.2
react.internal.publishingGroup=com.facebook.react
android.useAndroidX=true
@@ -11,11 +11,13 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.KeyEvent;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.PermissionAwareActivity;
import com.facebook.react.modules.core.PermissionListener;
import com.facebook.react.util.AndroidVersion;
import org.jetbrains.annotations.NotNull;
/** Base Activity for React Native applications. */
@@ -24,6 +26,18 @@ public abstract class ReactActivity extends AppCompatActivity
private final ReactActivityDelegate mDelegate;
// Due to enforced predictive back on targetSdk 36, 'onBackPressed()' is disabled by default.
// Using a workaround to trigger it manually.
private final OnBackPressedCallback mBackPressedCallback =
new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setEnabled(false);
onBackPressed();
setEnabled(true);
}
};
protected ReactActivity() {
mDelegate = createReactActivityDelegate();
}
@@ -45,6 +59,9 @@ public abstract class ReactActivity extends AppCompatActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
if (AndroidVersion.isAtLeastTargetSdk36(this)) {
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
}
}
@Override
@@ -103,6 +120,9 @@ public abstract class ReactActivity extends AppCompatActivity
@Override
public void invokeDefaultOnBackPressed() {
// Disabling callback so the fallback logic (finish activity) can run
// as super.onBackPressed() will call all enabled callbacks in the dispatcher.
mBackPressedCallback.setEnabled(false);
super.onBackPressed();
}
@@ -59,7 +59,7 @@ import okio.Okio
*/
@SuppressLint(
"StaticFieldLeak") // TODO: This entire class should be rewritten to don't use AsyncTask
public class DevServerHelper(
public open class DevServerHelper(
private val settings: DeveloperSettings,
private val applicationContext: Context,
private val packagerConnectionSettings: PackagerConnectionSettings
@@ -287,20 +287,20 @@ public class DevServerHelper(
additionalOptionsBuilder.toString())
}
public fun getDevServerBundleURL(jsModulePath: String): String =
public open fun getDevServerBundleURL(jsModulePath: String): String =
createBundleURL(jsModulePath, BundleType.BUNDLE, packagerConnectionSettings.debugServerHost)
public fun getDevServerSplitBundleURL(jsModulePath: String): String =
public open fun getDevServerSplitBundleURL(jsModulePath: String): String =
createSplitBundleURL(jsModulePath, packagerConnectionSettings.debugServerHost)
public fun isPackagerRunning(callback: PackagerStatusCallback) {
public open fun isPackagerRunning(callback: PackagerStatusCallback) {
packagerStatusCheck.run(packagerConnectionSettings.debugServerHost, callback)
}
public fun getSourceMapUrl(mainModuleName: String): String =
public open fun getSourceMapUrl(mainModuleName: String): String =
createBundleURL(mainModuleName, BundleType.MAP)
public fun getSourceUrl(mainModuleName: String): String =
public open fun getSourceUrl(mainModuleName: String): String =
createBundleURL(mainModuleName, BundleType.BUNDLE)
/**
@@ -12,9 +12,9 @@ package com.facebook.react.modules.systeminfo
public object ReactNativeVersion {
@JvmField
public val VERSION: Map<String, Any?> = mapOf(
"major" to 1000,
"minor" to 0,
"major" to 0,
"minor" to 80,
"patch" to 0,
"prerelease" to null
"prerelease" to "rc.2"
)
}
@@ -462,9 +462,9 @@ public class NativeViewHierarchyOptimizer {
return false;
}
ReadableMapKeySetIterator keyIterator = props.backingMap.keySetIterator();
ReadableMapKeySetIterator keyIterator = props.internal_backingMap().keySetIterator();
while (keyIterator.hasNextKey()) {
if (!ViewProps.isLayoutOnly(props.backingMap, keyIterator.nextKey())) {
if (!ViewProps.isLayoutOnly(props.internal_backingMap(), keyIterator.nextKey())) {
return false;
}
}
@@ -31,7 +31,12 @@ import com.facebook.react.bridge.ReadableMap
*/
public class ReactStylesDiffMap(props: ReadableMap) {
@JvmField internal val backingMap: ReadableMap = props
/**
* This backing map is annotated as JvmName("internal_backingMap") so can be accessed by Java
* consumers. This is used in Expo to override setting properties in some subclassed view-manager
* as this provides faster access to the underlying values.
*/
@get:JvmName("internal_backingMap") internal val backingMap: ReadableMap = props
public fun toMap(): Map<String, Any?> = backingMap.toHashMap()
@@ -49,7 +49,12 @@ constructor(reactContext: ReactApplicationContext? = null) :
parent.removeViewAt(index)
}
public fun removeView(parent: T, view: View) {
/**
* Expo overrides this function GroupViewManagerWrapper.kt`, which is a replacement view manager
* adding support for delegates receiving callbacks whenever one of the methods in the view
* manager are called.
*/
public open fun removeView(parent: T, view: View) {
UiThreadUtil.assertOnUiThread()
for (i in 0 until getChildCount(parent)) {
@@ -97,7 +97,7 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
*/
public void updateProperties(@NonNull T viewToUpdate, ReactStylesDiffMap props) {
ViewManagerDelegate<T> delegate = getOrCreateViewManagerDelegate();
Iterator<Map.Entry<String, Object>> iterator = props.backingMap.getEntryIterator();
Iterator<Map.Entry<String, Object>> iterator = props.internal_backingMap().getEntryIterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
delegate.setProperty(viewToUpdate, entry.getKey(), entry.getValue());
@@ -143,11 +143,11 @@ internal data class BorderRadiusStyle(
CornerRadii(it, width, height)
} ?: zeroRadii,
bottomLeft =
(endEnd ?: bottomStart ?: bottomRight ?: uniform)?.let {
(endEnd ?: bottomEnd ?: bottomRight ?: uniform)?.let {
CornerRadii(it, width, height)
} ?: zeroRadii,
bottomRight =
(startEnd ?: bottomEnd ?: bottomLeft ?: uniform)?.let {
(startEnd ?: bottomStart ?: bottomLeft ?: uniform)?.let {
CornerRadii(it, width, height)
} ?: zeroRadii,
width = width,
@@ -0,0 +1,30 @@
/*
* 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.
*/
package com.facebook.react.util
import android.content.Context
import android.os.Build
/** Helper class for checking Android version-related information. */
internal object AndroidVersion {
/**
* This is the version code for Android 16 (SDK Level 36). Delete it once we bump up the default
* compile SDK version to 36.
*/
private const val VERSION_CODE_BAKLAVA: Int = 36
/**
* This method is used to check if the current device is running Android 16 (SDK Level 36) or
* higher and the app is targeting Android 16 (SDK Level 36) or higher.
*/
@JvmStatic
fun isAtLeastTargetSdk36(context: Context): Boolean =
Build.VERSION.SDK_INT >= VERSION_CODE_BAKLAVA &&
context.applicationInfo.targetSdkVersion >= VERSION_CODE_BAKLAVA
}
@@ -20,11 +20,12 @@ import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewStructure
import android.view.Window
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.FrameLayout
import androidx.activity.ComponentDialog
import androidx.activity.OnBackPressedCallback
import androidx.annotation.UiThread
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
@@ -49,10 +50,10 @@ import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.common.ContextUtils
import com.facebook.react.views.modal.ReactModalHostView.DialogRootViewGroup
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.view.setStatusBarTranslucency
import com.facebook.react.views.view.setSystemBarsTranslucency
import java.util.Objects
/**
* ReactModalHostView is a view that sits in the view hierarchy representing a Modal view.
@@ -71,7 +72,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
ViewGroup(context), LifecycleEventListener {
@get:VisibleForTesting
public var dialog: Dialog? = null
public var dialog: ComponentDialog? = null
private set
public var transparent: Boolean = false
@@ -260,17 +261,34 @@ public class ReactModalHostView(context: ThemedReactContext) :
}
val currentActivity = getCurrentActivity()
val newDialog = Dialog(currentActivity ?: context, theme)
val newDialog = ComponentDialog(currentActivity ?: context, theme)
dialog = newDialog
Objects.requireNonNull<Window>(newDialog.window)
.setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
val window = requireNotNull(newDialog.window)
window.setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
newDialog.setContentView(contentView)
updateProperties()
newDialog.setOnShowListener(onShowListener)
val handleCloseAction: () -> Unit = {
val listener =
checkNotNull(onRequestCloseListener) {
"onRequestClose callback must be set if back key is expected to close the modal"
}
listener.onRequestClose(newDialog)
}
val backPressedCallback: OnBackPressedCallback =
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
handleCloseAction()
}
}
newDialog.onBackPressedDispatcher.addCallback(newDialog, backPressedCallback)
newDialog.setOnKeyListener(
object : DialogInterface.OnKeyListener {
override fun onKey(dialog: DialogInterface, keyCode: Int, event: KeyEvent): Boolean {
@@ -280,11 +298,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
// to whether or not to allow the back/escape key to close the dialog. If it chooses
// to, it can just set visible to false on the Modal and the Modal will go away
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
val listener =
checkNotNull(onRequestCloseListener) {
"onRequestClose callback must be set if back key is expected to close the modal"
}
listener.onRequestClose(dialog)
handleCloseAction()
return true
} else {
// We redirect the rest of the key events to the current activity, since the
@@ -301,19 +315,19 @@ public class ReactModalHostView(context: ThemedReactContext) :
}
})
newDialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
if (hardwareAccelerated) {
newDialog.window?.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
window.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
}
val flagSecureSet = isFlagSecureSet(currentActivity)
if (flagSecureSet) {
newDialog.window?.setFlags(
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
}
if (currentActivity?.isFinishing == false) {
newDialog.show()
updateSystemAppearance()
newDialog.window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
}
@@ -95,13 +95,13 @@ class BorderRadiusStyleTest {
arrayOf(
BorderRadiusProp.BORDER_RADIUS,
BorderRadiusProp.BORDER_BOTTOM_RIGHT_RADIUS,
BorderRadiusProp.BORDER_BOTTOM_START_RADIUS,
BorderRadiusProp.BORDER_BOTTOM_END_RADIUS,
BorderRadiusProp.BORDER_END_END_RADIUS),
ComputedBorderRadiusProp.COMPUTED_BORDER_BOTTOM_RIGHT_RADIUS to
arrayOf(
BorderRadiusProp.BORDER_RADIUS,
BorderRadiusProp.BORDER_BOTTOM_LEFT_RADIUS,
BorderRadiusProp.BORDER_BOTTOM_END_RADIUS,
BorderRadiusProp.BORDER_BOTTOM_START_RADIUS,
BorderRadiusProp.BORDER_START_END_RADIUS),
)
@@ -12,17 +12,17 @@
#include <cstdint>
#include <string_view>
#define REACT_NATIVE_VERSION_MAJOR 1000
#define REACT_NATIVE_VERSION_MINOR 0
#define REACT_NATIVE_VERSION_MAJOR 0
#define REACT_NATIVE_VERSION_MINOR 80
#define REACT_NATIVE_VERSION_PATCH 0
namespace facebook::react {
constexpr struct {
int32_t Major = 1000;
int32_t Minor = 0;
int32_t Major = 0;
int32_t Minor = 80;
int32_t Patch = 0;
std::string_view Prerelease = "";
std::string_view Prerelease = "rc.2";
} ReactNativeVersion;
} // namespace facebook::react
@@ -32,6 +32,6 @@ Pod::Spec.new do |s|
s.dependency "React-jsi", version
s.subspec "Fabric" do |ss|
ss.pod_target_xcconfig = { "OTHER_CFLAGS" => "$(inherited)" }
ss.pod_target_xcconfig = { "OTHER_CFLAGS" => "$(inherited)", "DEFINES_MODULE" => "YES" }
end
end
+1
View File
@@ -106,6 +106,7 @@ export type {
SectionListProps,
SectionListRenderItem,
SectionListRenderItemInfo,
SectionListData,
} from './Libraries/Lists/SectionList';
export {default as SectionList} from './Libraries/Lists/SectionList';
+1
View File
@@ -14,6 +14,7 @@ module.exports = {
defaultPlatform: 'ios',
platforms: ['android', 'ios', 'native'],
},
resolver: require.resolve('./jest/resolver.js'),
transform: {
'^.+\\.(js|ts|tsx)$': 'babel-jest',
'^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp)$': require.resolve(
+31
View File
@@ -0,0 +1,31 @@
/**
* 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
*/
'use strict';
module.exports = (path, options) => {
const originalPackageFilter = options.packageFilter;
return options.defaultResolver(path, {
...options,
packageFilter: pkg => {
const filteredPkg = originalPackageFilter
? originalPackageFilter(pkg)
: pkg;
// Temporarily allow any react-native subpaths to be resolved and
// mocked by Jest (backwards compatibility around RFC0894)
if (filteredPkg.name === 'react-native') {
delete filteredPkg.exports;
}
return filteredPkg;
},
});
};
+9 -8
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "1000.0.0",
"version": "0.80.0-rc.2",
"description": "A framework for building native apps using React",
"license": "MIT",
"repository": {
@@ -64,6 +64,7 @@
"./src/*": null,
"./third-party-podspecs/*": null,
"./types/*": null,
"./types_generated/*": null,
"./package.json": "./package.json"
},
"jest-junit": {
@@ -154,13 +155,13 @@
},
"dependencies": {
"@jest/create-cache-key-function": "^29.7.0",
"@react-native/assets-registry": "0.80.0-main",
"@react-native/codegen": "0.80.0-main",
"@react-native/community-cli-plugin": "0.80.0-main",
"@react-native/gradle-plugin": "0.80.0-main",
"@react-native/js-polyfills": "0.80.0-main",
"@react-native/normalize-colors": "0.80.0-main",
"@react-native/virtualized-lists": "0.80.0-main",
"@react-native/assets-registry": "0.80.0-rc.2",
"@react-native/codegen": "0.80.0-rc.2",
"@react-native/community-cli-plugin": "0.80.0-rc.2",
"@react-native/gradle-plugin": "0.80.0-rc.2",
"@react-native/js-polyfills": "0.80.0-rc.2",
"@react-native/normalize-colors": "0.80.0-rc.2",
"@react-native/virtualized-lists": "0.80.0-rc.2",
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
"ansi-regex": "^5.0.0",
@@ -0,0 +1,37 @@
{
"name": "test-app-legacy",
"version": "0.0.0",
"private": true,
"scripts": {
},
"dependencies": {
},
"devDependencies": {
},
"codegenConfig": {
"name": "TestAppConfig",
"type": "all",
"android": {
"javaPackageName": "com.testApp"
},
"ios": {
"modulesConformingToProtocol": {
"RCTImageURLLoader": "RCTTestAppDeprecatedImageURLLoader",
"RCTURLRequestHandler": "RCTTestAppDeprecatedURLRequestHandler"
},
"modulesProvider": {
"TestAppDeprecatedImageURLLoader": "RCTTestAppDeprecatedImageURLLoader",
"TestAppDeprecatedURLRequestHandler": "RCTTestAppDeprecatedURLRequestHandler",
"TestAppDeprecatedImageDataDecoder": "RCTTestAppDeprecatedImageDataDecoder"
},
"componentProvider": {
"TestAppDeprecatedComponent": "RCTTestAppDeprecatedComponentClass"
},
"unstableModulesRequiringMainQueueSetup": [
"RCTTestAppDeprecatedImageURLLoader",
"RCTTestAppDeprecatedURLRequestHandler",
"RCTTestAppDeprecatedImageDataDecoder"
]
}
}
}
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`execute "RCTAppDependencyProvider.h" should match snapshot 1`] = `
exports[`execute test-app "RCTAppDependencyProvider.h" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_END
"
`;
exports[`execute "RCTAppDependencyProvider.mm" should match snapshot 1`] = `
exports[`execute test-app "RCTAppDependencyProvider.mm" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -73,7 +73,7 @@ exports[`execute "RCTAppDependencyProvider.mm" should match snapshot 1`] = `
"
`;
exports[`execute "RCTModuleProviders.h" should match snapshot 1`] = `
exports[`execute test-app "RCTModuleProviders.h" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -93,7 +93,7 @@ exports[`execute "RCTModuleProviders.h" should match snapshot 1`] = `
"
`;
exports[`execute "RCTModuleProviders.mm" should match snapshot 1`] = `
exports[`execute test-app "RCTModuleProviders.mm" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -159,7 +159,7 @@ exports[`execute "RCTModuleProviders.mm" should match snapshot 1`] = `
"
`;
exports[`execute "RCTModulesConformingToProtocolsProvider.h" should match snapshot 1`] = `
exports[`execute test-app "RCTModulesConformingToProtocolsProvider.h" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -181,7 +181,7 @@ exports[`execute "RCTModulesConformingToProtocolsProvider.h" should match snapsh
"
`;
exports[`execute "RCTModulesConformingToProtocolsProvider.mm" should match snapshot 1`] = `
exports[`execute test-app "RCTModulesConformingToProtocolsProvider.mm" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -248,7 +248,7 @@ exports[`execute "RCTModulesConformingToProtocolsProvider.mm" should match snaps
"
`;
exports[`execute "RCTThirdPartyComponentsProvider.h" should match snapshot 1`] = `
exports[`execute test-app "RCTThirdPartyComponentsProvider.h" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -268,7 +268,7 @@ exports[`execute "RCTThirdPartyComponentsProvider.h" should match snapshot 1`] =
"
`;
exports[`execute "RCTThirdPartyComponentsProvider.mm" should match snapshot 1`] = `
exports[`execute test-app "RCTThirdPartyComponentsProvider.mm" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -305,7 +305,7 @@ exports[`execute "RCTThirdPartyComponentsProvider.mm" should match snapshot 1`]
"
`;
exports[`execute "RCTUnstableModulesRequiringMainQueueSetupProvider.h" should match snapshot 1`] = `
exports[`execute test-app "RCTUnstableModulesRequiringMainQueueSetupProvider.h" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -323,7 +323,7 @@ exports[`execute "RCTUnstableModulesRequiringMainQueueSetupProvider.h" should ma
"
`;
exports[`execute "RCTUnstableModulesRequiringMainQueueSetupProvider.mm" should match snapshot 1`] = `
exports[`execute test-app "RCTUnstableModulesRequiringMainQueueSetupProvider.mm" should match snapshot 1`] = `
"/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
@@ -357,13 +357,13 @@ exports[`execute "RCTUnstableModulesRequiringMainQueueSetupProvider.mm" should m
"
`;
exports[`execute "ReactAppDependencyProvider.podspec" should match snapshot 1`] = `
exports[`execute test-app "ReactAppDependencyProvider.podspec" should match snapshot 1`] = `
"# 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.
version = \\"1000.0.0\\"
version = \\"0.80.0-rc.2\\"
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
@@ -395,13 +395,13 @@ end
"
`;
exports[`execute "ReactCodegen.podspec" should match snapshot 1`] = `
exports[`execute test-app "ReactCodegen.podspec" should match snapshot 1`] = `
"# 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.
version = \\"1000.0.0\\"
version = \\"0.80.0-rc.2\\"
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
@@ -504,3 +504,478 @@ SCRIPT
end
"
`;
exports[`execute test-app-legacy "RCTAppDependencyProvider.h" should match snapshot 1`] = `
"/*
* 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.
*/
#import <Foundation/Foundation.h>
#if __has_include(<React-RCTAppDelegate/RCTDependencyProvider.h>)
#import <React-RCTAppDelegate/RCTDependencyProvider.h>
#elif __has_include(<React_RCTAppDelegate/RCTDependencyProvider.h>)
#import <React_RCTAppDelegate/RCTDependencyProvider.h>
#else
#import \\"RCTDependencyProvider.h\\"
#endif
NS_ASSUME_NONNULL_BEGIN
@interface RCTAppDependencyProvider : NSObject <RCTDependencyProvider>
@end
NS_ASSUME_NONNULL_END
"
`;
exports[`execute test-app-legacy "RCTAppDependencyProvider.mm" should match snapshot 1`] = `
"/*
* 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.
*/
#import \\"RCTAppDependencyProvider.h\\"
#import <ReactCodegen/RCTModulesConformingToProtocolsProvider.h>
#import <ReactCodegen/RCTThirdPartyComponentsProvider.h>
#import <ReactCodegen/RCTUnstableModulesRequiringMainQueueSetupProvider.h>
#import <ReactCodegen/RCTModuleProviders.h>
@implementation RCTAppDependencyProvider
- (nonnull NSArray<NSString *> *)URLRequestHandlerClassNames {
return RCTModulesConformingToProtocolsProvider.URLRequestHandlerClassNames;
}
- (nonnull NSArray<NSString *> *)imageDataDecoderClassNames {
return RCTModulesConformingToProtocolsProvider.imageDataDecoderClassNames;
}
- (nonnull NSArray<NSString *> *)imageURLLoaderClassNames {
return RCTModulesConformingToProtocolsProvider.imageURLLoaderClassNames;
}
- (nonnull NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup {
return RCTUnstableModulesRequiringMainQueueSetupProvider.modules;
}
- (nonnull NSDictionary<NSString *,Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents {
return RCTThirdPartyComponentsProvider.thirdPartyFabricComponents;
}
- (nonnull NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders {
return RCTModuleProviders.moduleProviders;
}
@end
"
`;
exports[`execute test-app-legacy "RCTModuleProviders.h" should match snapshot 1`] = `
"/*
* 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.
*/
#import <Foundation/Foundation.h>
@protocol RCTModuleProvider;
@interface RCTModuleProviders: NSObject
+ (NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders;
@end
"
`;
exports[`execute test-app-legacy "RCTModuleProviders.mm" should match snapshot 1`] = `
"/*
* 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.
*/
#import <Foundation/Foundation.h>
#import \\"RCTModuleProviders.h\\"
#import <ReactCommon/RCTTurboModule.h>
#import <React/RCTLog.h>
@implementation RCTModuleProviders
+ (NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders
{
static NSDictionary<NSString *, id<RCTModuleProvider>> *providers = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSDictionary<NSString *, NSString *> * moduleMapping = @{
@\\"TestAppDeprecatedImageURLLoader\\": @\\"RCTTestAppDeprecatedImageURLLoader\\", // test-app-legacy
@\\"TestAppDeprecatedURLRequestHandler\\": @\\"RCTTestAppDeprecatedURLRequestHandler\\", // test-app-legacy
@\\"TestAppDeprecatedImageDataDecoder\\": @\\"RCTTestAppDeprecatedImageDataDecoder\\", // test-app-legacy
};
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:moduleMapping.count];
for (NSString *key in moduleMapping) {
NSString * moduleProviderName = moduleMapping[key];
Class klass = NSClassFromString(moduleProviderName);
if (!klass) {
RCTLogError(@\\"Module provider %@ cannot be found in the runtime\\", moduleProviderName);
continue;
}
id instance = [klass new];
if (![instance respondsToSelector:@selector(getTurboModule:)]) {
RCTLogError(@\\"Module provider %@ does not conform to RCTModuleProvider\\", moduleProviderName);
continue;
}
[dict setObject:instance forKey:key];
}
providers = dict;
});
return providers;
}
@end
"
`;
exports[`execute test-app-legacy "RCTModulesConformingToProtocolsProvider.h" should match snapshot 1`] = `
"/*
* 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.
*/
#import <Foundation/Foundation.h>
@interface RCTModulesConformingToProtocolsProvider: NSObject
+(NSArray<NSString *> *)imageURLLoaderClassNames;
+(NSArray<NSString *> *)imageDataDecoderClassNames;
+(NSArray<NSString *> *)URLRequestHandlerClassNames;
@end
"
`;
exports[`execute test-app-legacy "RCTModulesConformingToProtocolsProvider.mm" should match snapshot 1`] = `
"/*
* 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.
*/
#import \\"RCTModulesConformingToProtocolsProvider.h\\"
@implementation RCTModulesConformingToProtocolsProvider
+(NSArray<NSString *> *)imageURLLoaderClassNames
{
static NSArray<NSString *> *classNames = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
classNames = @[
@\\"RCTTestAppDeprecatedImageURLLoader\\"
];
});
return classNames;
}
+(NSArray<NSString *> *)imageDataDecoderClassNames
{
static NSArray<NSString *> *classNames = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
classNames = @[
];
});
return classNames;
}
+(NSArray<NSString *> *)URLRequestHandlerClassNames
{
static NSArray<NSString *> *classNames = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
classNames = @[
@\\"RCTTestAppDeprecatedURLRequestHandler\\"
];
});
return classNames;
}
@end
"
`;
exports[`execute test-app-legacy "RCTThirdPartyComponentsProvider.h" should match snapshot 1`] = `
"/*
* 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.
*/
#import <Foundation/Foundation.h>
@protocol RCTComponentViewProtocol;
@interface RCTThirdPartyComponentsProvider: NSObject
+ (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
@end
"
`;
exports[`execute test-app-legacy "RCTThirdPartyComponentsProvider.mm" should match snapshot 1`] = `
"/*
* 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.
*/
#import <Foundation/Foundation.h>
#import \\"RCTThirdPartyComponentsProvider.h\\"
#import <React/RCTComponentViewProtocol.h>
@implementation RCTThirdPartyComponentsProvider
+ (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
static NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *thirdPartyComponents = nil;
static dispatch_once_t nativeComponentsToken;
dispatch_once(&nativeComponentsToken, ^{
thirdPartyComponents = @{
};
});
return thirdPartyComponents;
}
@end
"
`;
exports[`execute test-app-legacy "RCTUnstableModulesRequiringMainQueueSetupProvider.h" should match snapshot 1`] = `
"/*
* 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.
*/
#import <Foundation/Foundation.h>
@interface RCTUnstableModulesRequiringMainQueueSetupProvider: NSObject
+(NSArray<NSString *> *)modules;
@end
"
`;
exports[`execute test-app-legacy "RCTUnstableModulesRequiringMainQueueSetupProvider.mm" should match snapshot 1`] = `
"/*
* 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.
*/
#import \\"RCTUnstableModulesRequiringMainQueueSetupProvider.h\\"
@implementation RCTUnstableModulesRequiringMainQueueSetupProvider
+(NSArray<NSString *> *)modules
{
return @[
@\\"RCTTestAppDeprecatedImageURLLoader\\",
@\\"RCTTestAppDeprecatedURLRequestHandler\\",
@\\"RCTTestAppDeprecatedImageDataDecoder\\"
];
}
@end
"
`;
exports[`execute test-app-legacy "ReactAppDependencyProvider.podspec" should match snapshot 1`] = `
"# 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.
version = \\"0.80.0-rc.2\\"
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = \`git rev-parse HEAD\`.strip if system(\\"git rev-parse --git-dir > /dev/null 2>&1\\")
else
source[:tag] = \\"v#{version}\\"
end
Pod::Spec.new do |s|
s.name = \\"ReactAppDependencyProvider\\"
s.version = version
s.summary = \\"The third party dependency provider for the app\\"
s.homepage = \\"https://reactnative.dev/\\"
s.documentation_url = \\"https://reactnative.dev/\\"
s.license = \\"MIT\\"
s.author = \\"Meta Platforms, Inc. and its affiliates\\"
s.platforms = min_supported_versions
s.source = source
s.source_files = \\"**/RCTAppDependencyProvider.{h,mm}\\"
# This guard prevent to install the dependencies when we run \`pod install\` in the old architecture.
s.pod_target_xcconfig = {
\\"CLANG_CXX_LANGUAGE_STANDARD\\" => rct_cxx_language_standard(),
\\"DEFINES_MODULE\\" => \\"YES\\"
}
s.dependency \\"ReactCodegen\\"
end
"
`;
exports[`execute test-app-legacy "ReactCodegen.podspec" should match snapshot 1`] = `
"# 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.
version = \\"0.80.0-rc.2\\"
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = \`git rev-parse HEAD\`.strip if system(\\"git rev-parse --git-dir > /dev/null 2>&1\\")
else
source[:tag] = \\"v#{version}\\"
end
use_frameworks = ENV['USE_FRAMEWORKS'] != nil
folly_compiler_flags = Helpers::Constants.folly_config[:compiler_flags]
boost_compiler_flags = Helpers::Constants.boost_config[:compiler_flags]
header_search_paths = [
\\"\\\\\\"$(PODS_ROOT)/ReactNativeDependencies\\\\\\"\\",
\\"\\\\\\"\${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\\\\\\"\\",
\\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-Fabric\\\\\\"\\",
\\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\\\\\\"\\",
\\"\\\\\\"$(PODS_ROOT)/Headers/Private/Yoga\\\\\\"\\",
\\"\\\\\\"$(PODS_TARGET_SRCROOT)\\\\\\"\\",
]
framework_search_paths = []
if use_frameworks
ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-Fabric\\", \\"React_Fabric\\", [\\"react/renderer/components/view/platform/cxx\\"])
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-FabricImage\\", \\"React_FabricImage\\", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-graphics\\", \\"React_graphics\\", [\\"react/renderer/graphics/platform/ios\\"]))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"ReactCommon\\", \\"ReactCommon\\", [\\"react/nativemodule/core\\"]))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-NativeModulesApple\\", \\"React_NativeModulesApple\\", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-RCTFabric\\", \\"RCTFabric\\", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-debug\\", \\"React_debug\\", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-rendererdebug\\", \\"React_rendererdebug\\", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-utils\\", \\"React_utils\\", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-featureflags\\", \\"React_featureflags\\", []))
.each { |search_path|
header_search_paths << \\"\\\\\\"#{search_path}\\\\\\"\\"
}
end
Pod::Spec.new do |s|
s.name = \\"ReactCodegen\\"
s.version = version
s.summary = 'Temp pod for generated files for React Native'
s.homepage = 'https://facebook.com/'
s.license = 'Unlicense'
s.authors = 'Facebook'
s.compiler_flags = \\"#{folly_compiler_flags} #{boost_compiler_flags} -Wno-nullability-completeness -std=c++20\\"
s.source = { :git => '' }
s.header_mappings_dir = './'
s.platforms = min_supported_versions
s.source_files = \\"**/*.{h,mm,cpp}\\"
s.exclude_files = \\"RCTAppDependencyProvider.{h,mm}\\" # these files are generated in the same codegen path but needs to belong to a different pod
s.pod_target_xcconfig = {
\\"HEADER_SEARCH_PATHS\\" => header_search_paths.join(' '),
\\"FRAMEWORK_SEARCH_PATHS\\" => framework_search_paths,
\\"OTHER_CPLUSPLUSFLAGS\\" => \\"$(inherited) #{folly_compiler_flags} #{boost_compiler_flags}\\"
}
s.dependency \\"React-jsiexecutor\\"
s.dependency \\"RCTRequired\\"
s.dependency \\"RCTTypeSafety\\"
s.dependency \\"React-Core\\"
s.dependency \\"React-jsi\\"
s.dependency \\"ReactCommon/turbomodule/bridging\\"
s.dependency \\"ReactCommon/turbomodule/core\\"
s.dependency \\"React-NativeModulesApple\\"
s.dependency 'React-graphics'
s.dependency 'React-rendererdebug'
s.dependency 'React-Fabric'
s.dependency 'React-FabricImage'
s.dependency 'React-debug'
s.dependency 'React-utils'
s.dependency 'React-featureflags'
s.dependency 'React-RCTAppDelegate'
depend_on_js_engine(s)
add_rn_third_party_dependencies(s)
s.script_phases = {
'name' => 'Generate Specs',
'execution_position' => :before_compile,
'input_files' => [],
'show_env_vars_in_log' => true,
'output_files' => [\\"\${DERIVED_FILE_DIR}/react-codegen.log\\"],
'script': <<-SCRIPT
pushd \\"$PODS_ROOT/../\\" > /dev/null
RCT_SCRIPT_POD_INSTALLATION_ROOT=$(pwd)
popd >/dev/null
export RCT_SCRIPT_RN_DIR=\\"$RCT_SCRIPT_POD_INSTALLATION_ROOT/../../../../..\\"
export RCT_SCRIPT_APP_PATH=\\"$RCT_SCRIPT_POD_INSTALLATION_ROOT/..\\"
export RCT_SCRIPT_OUTPUT_DIR=\\"$RCT_SCRIPT_POD_INSTALLATION_ROOT\\"
export RCT_SCRIPT_TYPE=\\"withCodegenDiscovery\\"
SCRIPT_PHASES_SCRIPT=\\"$RCT_SCRIPT_RN_DIR/scripts/react_native_pods_utils/script_phases.sh\\"
WITH_ENVIRONMENT=\\"$RCT_SCRIPT_RN_DIR/scripts/xcode/with-environment.sh\\"
/bin/sh -c \\"$WITH_ENVIRONMENT $SCRIPT_PHASES_SCRIPT\\"
SCRIPT
}
end
"
`;
@@ -28,105 +28,107 @@ const packageJson = JSON.stringify({
name: 'react-native',
});
describe('execute', () => {
const appDir = path.join(__dirname, '../__fixtures__/test-app');
const outputDir = path.join(appDir, 'temp');
['test-app', 'test-app-legacy'].forEach(appName => {
describe(`execute ${appName}`, () => {
const appDir = path.join(__dirname, '../__fixtures__', appName);
const outputDir = path.join(appDir, 'temp');
beforeAll(() => {
execute(appDir, 'ios', outputDir, 'app', false);
});
afterAll(() => {
fs.rmdirSync(outputDir, {recursive: true});
});
[
'RCTAppDependencyProvider.h',
'RCTAppDependencyProvider.mm',
'RCTModuleProviders.h',
'RCTModuleProviders.mm',
'RCTModulesConformingToProtocolsProvider.h',
'RCTModulesConformingToProtocolsProvider.mm',
'RCTThirdPartyComponentsProvider.h',
'RCTThirdPartyComponentsProvider.mm',
'ReactAppDependencyProvider.podspec',
'ReactCodegen.podspec',
'RCTUnstableModulesRequiringMainQueueSetupProvider.h',
'RCTUnstableModulesRequiringMainQueueSetupProvider.mm',
].forEach(file => {
it(`"${file}" should match snapshot`, () => {
const generatedFileDir = path.join(outputDir, 'build/generated/ios');
const generatedFile = path.join(generatedFileDir, file);
expect(fs.existsSync(generatedFile)).toBe(true);
expect(fs.readFileSync(generatedFile, 'utf8')).toMatchSnapshot();
beforeAll(() => {
execute(appDir, 'ios', outputDir, 'app', false);
});
});
});
describe('extractLibrariesFromJSON', () => {
it('extracts a single dependency when config has no libraries', () => {
let configFile = fixtures.noLibrariesConfigFile;
let libraries = extractLibrariesFromJSON(configFile, '.');
expect(libraries.length).toBe(1);
expect(libraries[0]).toEqual({
config: {
name: 'AppModules',
type: 'all',
jsSrcsDir: '.',
},
libraryPath: '.',
afterAll(() => {
fs.rmdirSync(outputDir, {recursive: true});
});
[
'RCTAppDependencyProvider.h',
'RCTAppDependencyProvider.mm',
'RCTModuleProviders.h',
'RCTModuleProviders.mm',
'RCTModulesConformingToProtocolsProvider.h',
'RCTModulesConformingToProtocolsProvider.mm',
'RCTThirdPartyComponentsProvider.h',
'RCTThirdPartyComponentsProvider.mm',
'ReactAppDependencyProvider.podspec',
'ReactCodegen.podspec',
'RCTUnstableModulesRequiringMainQueueSetupProvider.h',
'RCTUnstableModulesRequiringMainQueueSetupProvider.mm',
].forEach(file => {
it(`"${file}" should match snapshot`, () => {
const generatedFileDir = path.join(outputDir, 'build/generated/ios');
const generatedFile = path.join(generatedFileDir, file);
expect(fs.existsSync(generatedFile)).toBe(true);
expect(fs.readFileSync(generatedFile, 'utf8')).toMatchSnapshot();
});
});
});
it("doesn't extract libraries when they are present but empty", () => {
const configFile = {codegenConfig: {libraries: []}};
let libraries = extractLibrariesFromJSON(configFile, rootPath);
expect(libraries.length).toBe(0);
});
describe('extractLibrariesFromJSON', () => {
it('extracts a single dependency when config has no libraries', () => {
let configFile = fixtures.noLibrariesConfigFile;
let libraries = extractLibrariesFromJSON(configFile, '.');
expect(libraries.length).toBe(1);
expect(libraries[0]).toEqual({
config: {
name: 'AppModules',
type: 'all',
jsSrcsDir: '.',
},
libraryPath: '.',
});
});
it('extracts libraries when they are present and not empty', () => {
const configFile = fixtures.singleLibraryCodegenConfig;
let libraries = extractLibrariesFromJSON(configFile, rootPath);
expect(libraries.length).toBe(1);
expect(libraries[0]).toEqual({
config: {
name: 'react-native',
type: 'all',
jsSrcsDir: '.',
},
libraryPath: rootPath,
it("doesn't extract libraries when they are present but empty", () => {
const configFile = {codegenConfig: {libraries: []}};
let libraries = extractLibrariesFromJSON(configFile, rootPath);
expect(libraries.length).toBe(0);
});
});
it('extract codegenConfig with multiple dependencies', () => {
const configFile = fixtures.multipleLibrariesCodegenConfig;
const myDependency = 'my-dependency';
const myDependencyPath = path.join(__dirname, myDependency);
let libraries = extractLibrariesFromJSON(configFile, myDependencyPath);
expect(libraries.length).toBe(3);
expect(libraries[0]).toEqual({
config: {
name: 'react-native',
type: 'all',
jsSrcsDir: '.',
},
libraryPath: myDependencyPath,
it('extracts libraries when they are present and not empty', () => {
const configFile = fixtures.singleLibraryCodegenConfig;
let libraries = extractLibrariesFromJSON(configFile, rootPath);
expect(libraries.length).toBe(1);
expect(libraries[0]).toEqual({
config: {
name: 'react-native',
type: 'all',
jsSrcsDir: '.',
},
libraryPath: rootPath,
});
});
expect(libraries[1]).toEqual({
config: {
name: 'my-component',
type: 'components',
jsSrcsDir: 'component/js',
},
libraryPath: myDependencyPath,
});
expect(libraries[2]).toEqual({
config: {
name: 'my-module',
type: 'module',
jsSrcsDir: 'module/js',
},
libraryPath: myDependencyPath,
it('extract codegenConfig with multiple dependencies', () => {
const configFile = fixtures.multipleLibrariesCodegenConfig;
const myDependency = 'my-dependency';
const myDependencyPath = path.join(__dirname, myDependency);
let libraries = extractLibrariesFromJSON(configFile, myDependencyPath);
expect(libraries.length).toBe(3);
expect(libraries[0]).toEqual({
config: {
name: 'react-native',
type: 'all',
jsSrcsDir: '.',
},
libraryPath: myDependencyPath,
});
expect(libraries[1]).toEqual({
config: {
name: 'my-component',
type: 'components',
jsSrcsDir: 'component/js',
},
libraryPath: myDependencyPath,
});
expect(libraries[2]).toEqual({
config: {
name: 'my-module',
type: 'module',
jsSrcsDir: 'module/js',
},
libraryPath: myDependencyPath,
});
});
});
});
@@ -30,6 +30,8 @@ function generateCustomURLHandlers(libraries, outputDir) {
const imageDataDecoderModules = new Set();
const urlRequestHandlersModules = new Set();
const wrapInArrayIfNecessary = value =>
Array.isArray(value) || value == null ? value : [value];
// Old API
for (const library of libraries) {
const modulesConformingToProtocol =
@@ -38,13 +40,19 @@ function generateCustomURLHandlers(libraries, outputDir) {
continue;
}
modulesConformingToProtocol.RCTImageURLLoader.forEach(moduleName => {
wrapInArrayIfNecessary(
modulesConformingToProtocol.RCTImageURLLoader,
)?.forEach(moduleName => {
imageURLLoaderModules.add(moduleName);
});
modulesConformingToProtocol.RCTImageDataDecoder.forEach(moduleName => {
wrapInArrayIfNecessary(
modulesConformingToProtocol.RCTImageDataDecoder,
)?.forEach(moduleName => {
imageDataDecoderModules.add(moduleName);
});
modulesConformingToProtocol.RCTURLRequestHandler.forEach(moduleName => {
wrapInArrayIfNecessary(
modulesConformingToProtocol.RCTURLRequestHandler,
)?.forEach(moduleName => {
urlRequestHandlersModules.add(moduleName);
});
}
@@ -35,8 +35,10 @@ const {
cleanupEmptyFilesAndFolders,
codegenLog,
findCodegenEnabledLibraries,
findDisabledLibrariesByPlatform,
pkgJsonIncludesGeneratedCode,
readPkgJsonInDirectory,
readReactNativeConfig,
} = require('./utils');
const path = require('path');
@@ -83,9 +85,14 @@ function execute(
buildCodegenIfNeeded();
}
const libraries = findCodegenEnabledLibraries(pkgJson, projectRoot);
const reactNativeConfig = readReactNativeConfig(projectRoot);
const codegenEnabledLibraries = findCodegenEnabledLibraries(
pkgJson,
projectRoot,
reactNativeConfig,
);
if (libraries.length === 0) {
if (codegenEnabledLibraries.length === 0) {
codegenLog('No codegen-enabled libraries found.', true);
return;
}
@@ -94,6 +101,18 @@ function execute(
targetPlatform === 'all' ? supportedPlatforms : [targetPlatform];
for (const platform of platforms) {
const disabledLibraries = findDisabledLibrariesByPlatform(
reactNativeConfig,
platform,
);
const libraries = codegenEnabledLibraries.filter(
({name}) => !disabledLibraries.includes(name),
);
if (!libraries.length) {
continue;
}
const outputPath = computeOutputPath(
projectRoot,
baseOutputPath,
@@ -94,10 +94,20 @@ function cleanupEmptyFilesAndFolders(filepath) {
}
}
function readReactNativeConfig(projectRoot) {
const rnConfigFilePath = path.resolve(projectRoot, 'react-native.config.js');
if (!fs.existsSync(rnConfigFilePath)) {
return {};
}
return require(rnConfigFilePath);
}
/**
* Finding libraries!
*/
function findCodegenEnabledLibraries(pkgJson, projectRoot) {
function findCodegenEnabledLibraries(pkgJson, projectRoot, reactNativeConfig) {
const projectLibraries = findProjectRootLibraries(pkgJson, projectRoot);
if (pkgJsonIncludesGeneratedCode(pkgJson)) {
return projectLibraries;
@@ -105,7 +115,7 @@ function findCodegenEnabledLibraries(pkgJson, projectRoot) {
return [
...projectLibraries,
...findExternalLibraries(pkgJson, projectRoot),
...findLibrariesFromReactNativeConfig(projectRoot),
...findLibrariesFromReactNativeConfig(projectRoot, reactNativeConfig),
];
}
}
@@ -128,22 +138,13 @@ function findProjectRootLibraries(pkgJson, projectRoot) {
return extractLibrariesFromJSON(pkgJson, projectRoot);
}
function findLibrariesFromReactNativeConfig(projectRoot) {
const rnConfigFileName = 'react-native.config.js';
function findLibrariesFromReactNativeConfig(projectRoot, rnConfig) {
codegenLog(
`Searching for codegen-enabled libraries in ${rnConfigFileName}`,
`Searching for codegen-enabled libraries in react-native.config.js`,
true,
);
const rnConfigFilePath = path.resolve(projectRoot, rnConfigFileName);
if (!fs.existsSync(rnConfigFilePath)) {
return [];
}
const rnConfig = require(rnConfigFilePath);
if (rnConfig.dependencies == null) {
if (!rnConfig.dependencies) {
return [];
}
return Object.keys(rnConfig.dependencies).flatMap(name => {
@@ -366,6 +367,19 @@ function getLibraryName(library) {
).name;
}
/**
* Finds all disabled libraries by platform based the react native config.
*
* This is needed when selectively disabling libraries in react-native.config.js since codegen should exclude those libraries as well.
*/
function findDisabledLibrariesByPlatform(reactNativeConfig, platform) {
const dependencies = reactNativeConfig.dependencies ?? {};
return Object.keys(dependencies).filter(
dependency => dependencies[dependency].platforms?.[platform] === null,
);
}
module.exports = {
buildCodegenIfNeeded,
pkgJsonIncludesGeneratedCode,
@@ -377,4 +391,6 @@ module.exports = {
findProjectRootLibraries,
extractLibrariesFromJSON,
parseiOSAnnotations,
readReactNativeConfig,
findDisabledLibrariesByPlatform,
};
@@ -0,0 +1 @@
hermes-2025-05-06-RNv0.80.0-4eb6132a5bf0450bf4c6c91987675381d7ac8bca
+12 -5
View File
@@ -4,19 +4,26 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @format
*/
import type {
ImageStyle,
TextStyle,
ViewStyle,
} from '../../../Libraries/StyleSheet/StyleSheet';
import type {StyleProp} from '../../../Libraries/StyleSheet/StyleSheetTypes';
/**
* Combines two styles such that `style2` will override any styles in `style1`.
* If either style is null or undefined, the other one is returned without
* allocating an array, saving allocations and enabling memoization.
*/
export default function composeStyles<T1, T2>(
style1: ?T1,
style2: ?T2,
): ?(T1 | T2 | $ReadOnlyArray<T1 | T2>) {
export default function composeStyles<
T: ViewStyle | ImageStyle | TextStyle,
U: T,
V: T,
>(style1: ?StyleProp<U>, style2: ?StyleProp<V>): ?StyleProp<T> {
if (style1 == null) {
return style2;
}
+42
View File
@@ -57,6 +57,48 @@ declare global {
const HermesInternal: null | {};
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) */
interface DOMRectReadOnly {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/bottom) */
readonly bottom: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/height) */
readonly height: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/left) */
readonly left: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/right) */
readonly right: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/top) */
readonly top: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/width) */
readonly width: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/x) */
readonly x: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/y) */
readonly y: number;
toJSON(): any;
}
interface DOMRect extends DOMRectReadOnly {
height: number;
width: number;
x: number;
y: number;
}
interface DOMRectInit {
height?: number | undefined;
width?: number | undefined;
x?: number | undefined;
y?: number | undefined;
}
var DOMRect: {
prototype: DOMRect;
new (x?: number, y?: number, width?: number, height?: number): DOMRect;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect/fromRect_static) */
fromRect(other?: DOMRectInit): DOMRect;
};
// #region Timer Functions
function clearInterval(handle: number): void;
@@ -14,7 +14,6 @@ import {
View,
NativeSyntheticEvent,
NativeScrollEvent,
StyleProp,
SectionListData,
} from 'react-native';
@@ -41,12 +40,6 @@ const ForwardComp = React.forwardRef<View, CompProps>(({width}, ref) => {
type X = React.PropsWithoutRef<React.ComponentProps<typeof ForwardComp>>;
type Props = React.ComponentPropsWithRef<typeof Animated.Text>;
const AnimatedWrapperComponent: React.FunctionComponent<Props> = ({
key, // $ExpectType string | number | null | undefined || Key | null | undefined
...props
}) => <Animated.Text {...props} />;
function TestAnimatedAPI() {
// Value
const v1 = new Animated.Value(0);
@@ -168,9 +161,7 @@ function TestAnimatedAPI() {
});
const AnimatedView = Animated.createAnimatedComponent(View);
const ref = React.useRef<View>(null);
const legacyRef = React.useRef<Animated.LegacyRef<View>>(null);
const ref = React.useRef<React.ComponentRef<typeof View>>(null);
return (
<View ref={ref}>
<Animated.View
@@ -185,8 +176,6 @@ function TestAnimatedAPI() {
<AnimatedView ref={ref} style={{top: 3}}>
i has children
</AnimatedView>
<Animated.View ref={legacyRef} />
<AnimatedView ref={legacyRef} />
<AnimatedComp ref={AnimatedCompRef} width={v1} />
<ForwardComp ref={ForwardCompRef} width={1} />
<AnimatedForwardComp ref={AnimatedForwardCompRef} width={10} />
@@ -34,7 +34,6 @@ import {
ColorValue,
DevSettings,
DeviceEventEmitter,
DeviceEventEmitterStatic,
Dimensions,
DrawerLayoutAndroid,
DrawerSlideEvent,
@@ -50,6 +49,7 @@ import {
ImageBackground,
ImageErrorEvent,
ImageLoadEvent,
// @ts-ignore
ImageResizeMode,
ImageResolvedAssetSource,
ImageStyle,
@@ -64,6 +64,7 @@ import {
Modal,
MouseEvent,
NativeEventEmitter,
// @ts-ignore
NativeModule, // Not actually exported, not sure why
NativeModules,
NativeScrollEvent,
@@ -75,6 +76,7 @@ import {
ProgressBarAndroid,
PushNotificationIOS,
RefreshControl,
// @ts-ignore
RegisteredStyle,
ScaledSize,
ScrollView,
@@ -97,6 +99,7 @@ import {
TextInputEndEditingEvent,
TextInputFocusEvent,
TextInputKeyPressEvent,
// @ts-ignore
TextInputScrollEvent,
TextInputSelectionChangeEvent,
TextInputSubmitEditingEvent,
@@ -116,12 +119,14 @@ import {
requireNativeComponent,
useColorScheme,
useWindowDimensions,
// @ts-ignore
SectionListData,
ToastAndroid,
Touchable,
LayoutAnimation,
processColor,
experimental_LayoutConformance as LayoutConformance,
ViewProps,
} from 'react-native';
declare module 'react-native' {
@@ -233,10 +238,10 @@ const fontVariantStyle: StyleProp<TextStyle> = {
fontVariant: ['tabular-nums'],
};
const viewProperty = StyleSheet.flatten(viewStyle).backgroundColor;
const textProperty = StyleSheet.flatten(textStyle).fontSize;
const imageProperty = StyleSheet.flatten(imageStyle).resizeMode;
const fontVariantProperty = StyleSheet.flatten(fontVariantStyle).fontVariant;
const viewProperty = StyleSheet.flatten(viewStyle)?.backgroundColor;
const textProperty = StyleSheet.flatten(textStyle)?.fontSize;
const imageProperty = StyleSheet.flatten(imageStyle)?.resizeMode;
const fontVariantProperty = StyleSheet.flatten(fontVariantStyle)?.fontVariant;
// correct use of the StyleSheet.flatten
const styleArray: StyleProp<ViewStyle>[] = [];
@@ -263,25 +268,6 @@ const styleDimensionValueValidPct: ViewStyle = {
width: '5%',
};
const styleDimensionValueValidAnimated: ViewStyle = {
width: new Animated.Value(5),
};
const styleDimensionValueInvalid1: ViewStyle = {
// @ts-expect-error
width: '5',
};
const styleDimensionValueInvalid2: ViewStyle = {
// @ts-expect-error
width: '5px',
};
const styleDimensionValueInvalid3: ViewStyle = {
// @ts-expect-error
width: 'A%',
};
// StyleSheet.compose
// It creates a new style object by composing two existing styles
const composeTextStyle: StyleProp<TextStyle> = {
@@ -401,10 +387,13 @@ const testNativeSyntheticEvent = <T extends {}>(
e.isTrusted;
e.nativeEvent;
e.target;
e.target.measure(() => {});
e.timeStamp;
e.type;
e.nativeEvent;
if (typeof e.target !== 'number') {
e.target?.measure(() => {});
}
};
function eventHandler<T extends React.BaseSyntheticEvent>(e: T) {}
@@ -427,7 +416,7 @@ class CustomView extends React.Component {
}
class Welcome extends React.Component<
ElementProps<View> & {color: string; bgColor?: null | undefined | string}
ViewProps & {color: string; bgColor?: null | undefined | string}
> {
rootViewRef = React.createRef<View>();
customViewRef = React.createRef<CustomView>();
@@ -637,7 +626,9 @@ export class TouchableNativeFeedbackTest extends React.Component {
// PressableTest
export class PressableTest extends React.Component<{}> {
private readonly myRef: React.RefObject<View | null> = React.createRef();
private readonly myRef: React.RefObject<React.ComponentRef<
typeof View
> | null> = React.createRef();
onPressButton = (e: GestureResponderEvent) => {
e.persist();
@@ -747,7 +738,7 @@ const AppStateExample = () => {
React.useEffect(() => {
const subscription = AppState.addEventListener('change', nextAppState => {
if (
appState.current.match(/inactive|background/) &&
appState.current?.match(/inactive|background/) &&
nextAppState === 'active'
) {
console.log('App has come to the foreground!');
@@ -1155,10 +1146,10 @@ class InputAccessoryViewTest extends React.Component {
}
}
// DeviceEventEmitterStatic
const deviceEventEmitterStatic: DeviceEventEmitterStatic = DeviceEventEmitter;
deviceEventEmitterStatic.addListener('keyboardWillShow', data => true);
deviceEventEmitterStatic.addListener('keyboardWillShow', data => true, {});
// DeviceEventEmitter
const deviceEventEmitter: typeof DeviceEventEmitter = DeviceEventEmitter;
deviceEventEmitter.addListener('keyboardWillShow', data => true);
deviceEventEmitter.addListener('keyboardWillShow', data => true, {});
// NativeEventEmitter - Android
const androidEventEmitter = new NativeEventEmitter();
@@ -1322,7 +1313,6 @@ class TextTest extends React.Component {
<Text
allowFontScaling={false}
ellipsizeMode="head"
lineBreakMode="clip"
numberOfLines={2}
onLayout={this.handleOnLayout}
onTextLayout={this.handleOnTextLayout}
@@ -1423,9 +1413,9 @@ export class ImageTest extends React.Component {
}
export class ImageBackgroundProps extends React.Component {
private _imageRef: Image | null = null;
private _imageRef: React.ComponentRef<typeof Image> | null = null;
setImageRef = (image: Image) => {
setImageRef = (image: React.ComponentRef<typeof Image>) => {
this._imageRef = image;
};
@@ -1854,7 +1844,9 @@ const PlatformTest = () => {
};
const PlatformConstantsTest = () => {
const testing: boolean = Platform.constants.isTesting;
if (Platform.OS !== 'web') {
const testing: boolean = Platform.constants.isTesting;
}
if (Platform.OS === 'ios') {
const hasForceTouch: boolean = Platform.constants.forceTouchAvailable;
} else if (Platform.OS === 'android') {
@@ -1993,6 +1985,7 @@ const ProgressBarAndroidTest = () => {
color="white"
styleAttr="Horizontal"
progress={0.42}
indeterminate={false}
/>;
};
@@ -2011,7 +2004,7 @@ const PushNotificationTest = () => {
alertTitle: 'Hello!',
applicationIconBadgeNumber: 999,
category: 'engagement',
fireDate: new Date().toISOString(),
fireDate: +new Date(),
isSilent: false,
repeatInterval: 'minute',
userInfo: {
@@ -8,6 +8,7 @@
*/
import * as React from 'react';
// @ts-ignore
import {TextInputProperties} from 'react-native';
class Test extends React.Component<TextInputProperties> {}
@@ -8,6 +8,7 @@
*/
import * as React from 'react';
// @ts-ignore
import {View, StyleSheet, type ShadowStyleIOS} from 'react-native';
export function App() {
File diff suppressed because it is too large Load Diff
@@ -34,6 +34,7 @@ function StaticViewAndImage(props: Props): React.Node {
<Text>Hello world!</Text>
</View>
</View>
{/* $FlowFixMe - ImageStyle is not compatible with ViewStyle */}
<Image
source={props.imageSource ?? hotdog}
style={[props.style, styles.commonImage]}
@@ -48,6 +48,7 @@ function LayeredImage(props: Props) {
<ImageBackground
source={require('../../assets/rainbow.jpeg')}
style={[styles.backdrop, {width: 200}]}>
{/* $FlowFixMe - ImageStyle is not compatible with ViewStyle */}
<Image
source={require('../../assets/alpha-hotdog.png')}
style={[styles.commonImage, props.style]}
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/tester",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"private": true,
"description": "React Native tester app.",
"license": "MIT",
@@ -26,9 +26,9 @@
"e2e-test-ios": "./scripts/maestro-test-ios.sh"
},
"dependencies": {
"@react-native/oss-library-example": "0.80.0-main",
"@react-native/new-app-screen": "0.80.0-main",
"@react-native/popup-menu-android": "0.80.0-main",
"@react-native/oss-library-example": "0.80.0-rc.2",
"@react-native/new-app-screen": "0.80.0-rc.2",
"@react-native/popup-menu-android": "0.80.0-rc.2",
"flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
"nullthrows": "^1.1.1"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/typescript-config",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Default TypeScript configuration for React Native apps",
"license": "MIT",
"repository": {
@@ -17,6 +17,7 @@ import invariant from 'invariant';
import * as React from 'react';
type DefaultSectionT = {
data: any,
[key: string]: any,
};
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/virtualized-lists",
"version": "0.80.0-main",
"version": "0.80.0-rc.2",
"description": "Virtualized lists for React Native.",
"license": "MIT",
"repository": {
@@ -21,7 +21,8 @@
},
"exports": {
".": {
"types": "./types_generated/index.d.ts",
"react-native-strict-api": "./types_generated/index.d.ts",
"types": "./index.d.ts",
"default": "./index.js"
},
"./*": {
@@ -0,0 +1,87 @@
/**
* 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
* @oncall react_native
*/
const reattachDocComments = require('../reattachDocComments.js');
const {parse, print} = require('hermes-transform');
const prettierOptions = {parser: 'babel'};
async function translate(code: string): Promise<string> {
const parsed = await parse(code);
const result = await reattachDocComments(parsed);
return print(result.ast, result.mutatedCode, prettierOptions);
}
describe('reattachDocComments', () => {
test('should move component doc block', async () => {
const code = `
import Bar from './Bar';
/**
* Foo documentation
*/
let Foo: component(
ref?: React.RefSetter<
React.ElementRef<FooType>,
>,
...props: FooProps
);
export default Foo;
`;
const result = await translate(code);
expect(result).toMatchInlineSnapshot(`
"import Bar from \\"./Bar\\";
let Foo: component(
ref?: React.RefSetter<React.ElementRef<FooType>>,
...props: FooProps
);
/**
* Foo documentation
*/
export default Foo;
"
`);
});
test('should move variable doc block', async () => {
const code = `
const bar = 'bar';
/**
* Foo documentation
*/
const Foo: component(
ref?: React.RefSetter<
React.ElementRef<FooType>,
>,
...props: FooProps
) = () => {};
export default Foo;
`;
const result = await translate(code);
expect(result).toMatchInlineSnapshot(`
"const bar = \\"bar\\";
const Foo: component(
ref?: React.RefSetter<React.ElementRef<FooType>>,
...props: FooProps
) = () => {};
/**
* Foo documentation
*/
export default Foo;
"
`);
});
});
@@ -35,9 +35,9 @@ describe('replaceDefaultExportName', () => {
const code = `export default Foo;`;
const result = await translate(code, 'mock/path/to/module/Foo.js');
expect(result).toMatchInlineSnapshot(`
"declare const Foo_DEFAULT: typeof Foo;
declare type Foo_DEFAULT = typeof Foo_DEFAULT;
export default Foo_DEFAULT;"
"declare const $$Foo: typeof Foo;
declare type $$Foo = typeof $$Foo;
export default $$Foo;"
`);
});
});
@@ -0,0 +1,66 @@
/**
* 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
* @oncall react_native
*/
import type {ExportDefaultDeclaration, Program} from 'hermes-estree/dist';
import type {TransformVisitor} from 'hermes-transform';
import type {ParseResult} from 'hermes-transform/dist/transform/parse';
import type {TransformASTResult} from 'hermes-transform/dist/transform/transformAST';
const {transformAST} = require('hermes-transform/dist/transform/transformAST');
const visitors: TransformVisitor = context => ({
Program(node): void {
const getExportDefaultDeclaration = (
programNode: Program,
): [ExportDefaultDeclaration, string] | null => {
for (const bodyNode of programNode.body) {
if (bodyNode.type === 'ExportDefaultDeclaration') {
if (bodyNode.declaration.type === 'Identifier') {
return [bodyNode, bodyNode.declaration.name];
}
}
}
return null;
};
const exportDefaultDeclResult = getExportDefaultDeclaration(node);
if (exportDefaultDeclResult == null) {
return;
}
const [exportDefaultDecl, exportDefaultDeclName] = exportDefaultDeclResult;
for (const bodyNode of node.body) {
if (bodyNode.type === 'VariableDeclaration') {
for (const decl of bodyNode.declarations) {
if (
decl.id.type === 'Identifier' &&
decl.id.name === exportDefaultDeclName
) {
const comments = context.getComments(bodyNode);
if (comments != null) {
context.addLeadingComments(exportDefaultDecl, comments);
context.removeComments(comments);
}
}
}
}
}
},
});
async function reattachDocComments(
source: ParseResult,
): Promise<TransformASTResult> {
return transformAST(source, visitors);
}
module.exports = reattachDocComments;
@@ -19,7 +19,10 @@ function createReplaceDefaultExportName(filePath: string): PluginObj<mixed> {
const moduleName = fileName.split('.')[0];
if (node.node.name === '$$EXPORT_DEFAULT_DECLARATION$$') {
node.node.name = `${moduleName}_DEFAULT`;
// Prefixing with $$ prevents the TS LSP server from (incorrectly)
// discovering identifiers outside of package.json "exports" in
// autocomplete.
node.node.name = `$$${moduleName}`;
}
},
},
@@ -27,6 +27,7 @@ const preTransforms: Array<PreTransformFn> = [
require('./transforms/replaceEmptyWithNever'),
require('./transforms/replaceStringishWithString'),
require('./transforms/replaceNullablePropertiesWithUndefined'),
require('./transforms/reattachDocComments'),
];
const postTransforms: Array<PluginObj<mixed>> = [];
const prettierOptions = {parser: 'babel'};
@@ -121,6 +121,12 @@ constexpr struct {
"
`;
exports[`updateReactNativeArtifacts should set nightly version: packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap 1`] = `
"version = \\"0.81.0-nightly-29282302-abcd1234\\\\
other text
version = \\"0.81.0-nightly-29282302-abcd1234\\\\"
`;
exports[`updateReactNativeArtifacts should set release version: packages/react-native/Libraries/Core/ReactNativeVersion.js 1`] = `
"/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -241,3 +247,9 @@ constexpr struct {
} // namespace facebook::react
"
`;
exports[`updateReactNativeArtifacts should set release version: packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap 1`] = `
"version = \\"0.81.0\\\\
other text
version = \\"0.81.0\\\\"
`;
@@ -1,5 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`setVersion updates monorepo for nightly: ../../../../packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap 1`] = `"[omitted]"`;
exports[`setVersion updates monorepo for nightly: set-version/package.json 1`] = `
"{
\\"name\\": \\"@react-native/monorepo\\",
@@ -81,6 +83,8 @@ exports[`setVersion updates monorepo for nightly: set-version/packages/react-nat
"
`;
exports[`setVersion updates monorepo for release-candidate: ../../../../packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap 1`] = `"[omitted]"`;
exports[`setVersion updates monorepo for release-candidate: set-version/package.json 1`] = `
"{
\\"name\\": \\"@react-native/monorepo\\",
@@ -162,6 +166,8 @@ exports[`setVersion updates monorepo for release-candidate: set-version/packages
"
`;
exports[`setVersion updates monorepo for stable version: ../../../../packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap 1`] = `"[omitted]"`;
exports[`setVersion updates monorepo for stable version: set-version/package.json 1`] = `
"{
\\"name\\": \\"@react-native/monorepo\\",
@@ -37,6 +37,20 @@ describe('updateReactNativeArtifacts', () => {
) {
return 'VERSION_NAME=1000.0.0\n';
}
if (
filePath ===
path.join(
REPO_ROOT,
'packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap',
)
) {
return `
version = "1000.0.0\\
other text
version = "1000.0.0\\
`;
}
});
});
@@ -79,6 +79,7 @@ async function updateReactNativeArtifacts(
const versionInfo = parseVersion(version, buildType);
await updateSourceFiles(versionInfo);
await updateTestFiles(versionInfo);
await updateGradleFile(versionInfo.version);
}
@@ -116,6 +117,40 @@ function updateSourceFiles(
]);
}
function updateTestFiles(
versionInfo /*: Version */,
) /*: Promise<Array<void>>*/ {
const oldVersion = /"\d+\.\d+\.\d+(-rc\.\d+)?\\/g;
const newVersion = `"${versionInfo.version}\\`;
const snapshotTestPath = path.join(
__dirname,
'..',
'..',
'packages',
'react-native',
'scripts',
'codegen',
'__tests__',
'__snapshots__',
'generate-artifacts-executor-test.js.snap',
);
const promise /*: Promise<void> */ = new Promise(async (resolve, reject) => {
try {
let snapshot = String(await fs.readFile(snapshotTestPath, 'utf8')).trim();
// Replace all occurrences of the old version pattern with the new version
snapshot = snapshot.replaceAll(oldVersion, newVersion);
await fs.writeFile(snapshotTestPath, snapshot, {encoding: 'utf8'});
resolve();
} catch (error) {
reject(error);
}
});
return Promise.all([promise]);
}
async function updateGradleFile(version /*: string */) /*: Promise<void> */ {
const contents = await fs.readFile(GRADLE_FILE_PATH, 'utf-8');