Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38529
VirtualizedList internally represents metrics along the scrolling axis using `offset` (x, y), and `length` (width, height). This one dimensional representation allows the list to be generic to being horizontal or vertical.
Right now offset conversion directly takes the `x` or `y` axis value, but this is not correct when we are using a horizontal FlatList in RTL.
This change converts most VirtualizedList code handling `offset,length` coordinates consistently flow from start to end, including in horizontal RTL and in inverted FlatList.
This is paired with a fix to Android native code in D47627115. With these together, basic Horizontal FlatList scenarios should work correctly when laid out in RTL.
Changelog:
[General][Fixed] - Fix virtualization logic with horizontal RTL lists
Reviewed By: vincentriemer
Differential Revision: D46586420
fbshipit-source-id: 79594e197d21871bb493399999e91fc0d6c7b050
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38526
This changes the logic we use to correct scroll position on RTL ScrollView content change, to a new more generalized strategy of keeping a constant right-edge offset on layout change. This includes first layout, so that the initial scroll position is correct.
Changelog:
[Android][Fixed] - Generalize RTL Scroll Correction Logic
Reviewed By: yungsters
Differential Revision: D47627115
fbshipit-source-id: 33b2aae0cb603b7f7f2e2e6c127622fd531230e8
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38328
This diff adds the two extra markers `initializeRuntimeStart` and `initializeRuntimeEnd` to the startup performance API. The runtime start time matches the existing android marker `GET_REACT_INSTANCE_MANAGER_START`, which is the first marker we have on the RN android app.
Changelog:
[Android][Added] - Add `performance.reactNativeStartupTiming.initializeRuntimeStart` and` `performance.reactNativeStartupTiming.initializeRuntimeEnd` API
Reviewed By: mdvacca
Differential Revision: D43863974
fbshipit-source-id: 277d35e14dbb5e3def8d440b717b3cf0215b4f47
Summary:
X-link: https://github.com/facebook/metro/pull/1024
Pull Request resolved: https://github.com/facebook/react-native/pull/38228
Changelog: [General][Changed] - Move react-native-babel-transformer and react-native-babel-preset from Metro to React Native repo.
Metro Changelog: **[Breaking]** - Remove `metro-react-native-babel-transformer` and `metro-react-native-babel-preset`, to be published as `react-native/metro-babel-transformer` and `react-native/babel-preset` instead.
This diff does the following:
- Move `metro/packages/metro-react-native-babel-preset` to `react-native/packages/react-native-babel-preset`.
- Rename `metro-react-native-babel-preset` package to `react-native/babel-preset`.
- Move `metro/packages/metro-react-native-babel-transformer` to `react-native/packages/react-native-babel-transformer`.
- Rename `metro-react-native-babel-transformer` package to `react-native/metro-babel-transformer`.
- Upadate dependencies.
Reviewed By: robhogan
Differential Revision: D46977466
fbshipit-source-id: 32478f63a0442b61a1804f12ef814c8b29d7f8bb
Summary:
The React Native community almost exclusively adds `mjs` support with something like: `config.resolver.sourceExts.push("mjs");` which causes `js` to be resolved before `mjs`. Mainstream bundlers will do the opposite, resolving `mjs` then `js`, unless bundling for Node.js environments.
`event-target-shim` has a `.js` and `.mjs` entry, when we [attempt to implement _community-standard_ resolution in Metro](https://github.com/expo/expo/pull/23528) the app fails to open on iOS––providing no indication of what failed. The issue here is that the `mjs` exports for `event-target-shim` don't support `module.exports = function() {}`, so we need to update some of the imports in `react-native` (note that one of the imports to `event-target-shim` already uses `import/export`).
### Discovery
For future readers––to discover this bug, I wrote a custom Metro resolver which printed a list of any `mjs` file that was resolved. In a basic app we observe the following:
```
/node_modules/react-native/Libraries/Core/setUpXHR.js > /node_modules/abort-controller/dist/abort-controller.mjs
/node_modules/react-native/Libraries/Network/XMLHttpRequest.js > /node_modules/event-target-shim/dist/event-target-shim.mjs
/node_modules/react-native/Libraries/WebSocket/WebSocket.js > /node_modules/event-target-shim/dist/event-target-shim.mjs
/node_modules/react-native/Libraries/Blob/FileReader.js > /node_modules/event-target-shim/dist/event-target-shim.mjs
/node_modules/abort-controller/dist/abort-controller.mjs > /node_modules/event-target-shim/dist/event-target-shim.mjs
```
In all cases the mjs files are resolved via `react-native` importing third-party packages, specifically `abort-controller` and `event-target-shim`. I modified the custom Metro resolver to ignore mjs resolution in different files until I found the problematic imports. This revealed that the exports were changing in `event-target-shim` between mjs and js.
Further, this was difficult to discover because the code that attempts to invoke an object as a function (error) is happening during the React Native networking setup. Ideally this JS code would be isolated from the user's bundler configuration and therefore impossible to break.
## Changelog:
[GENERAL] [FIXED] - Update `event-target-shim` import to support Metro resolving `mjs` modules before `js`.
<!-- Help reviewers and the release process by writing your own changelog entry.
Pick one each for the category and type tags:
[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message
For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
Pull Request resolved: https://github.com/facebook/react-native/pull/38628
Test Plan:
- If you add `mjs` support to the `metro.config.js` file **before** js (`config.resolver.sourceExts.unshift("mjs");`), the project should be capable of starting.
- Usage with the default `metro.config.js` setup works as well.
- https://github.com/expo/expo/pull/23528 works.
Reviewed By: NickGerleman
Differential Revision: D47816854
Pulled By: TheSavior
fbshipit-source-id: ebaf2e7a3ec02ae61effa004058589053601b766
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38637
ComponentDescriptor and ConcreteComponentDescriptor expose a virtual method to interpolate props for LayoutAnimation. The implementation of this virtual method in ConcreteComponentDescriptor calls ViewPropsInterpolation, creating a circular dependency between react/renderer/core and react/renderer/components/view.
To break this circular dependency, this change lifts the props interpolation functionality out of ComponentDescriptor into LayoutAnimationKeyFrameManager.
Please note, while this is technically a "breaking" change, as component descriptors for 3p components may have overridden this method, it's not supported because LayoutAnimation only works on View props.
## Changelog:
[General] [Breaking] - Remove interpolateProps functionality from ComponentDescriptor to fix circular dependency between react/renderer/core and react/renderer/components/view
Reviewed By: christophpurrer
Differential Revision: D47797967
fbshipit-source-id: 5285da7cc9de29f21ce14c96b850a3c58c579e94
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38642
isHighlighted is only used for iOS. Even macOS disables it (see https://github.com/microsoft/react-native-macos/pull/1346).
This change ensures that the isHighlighted prop is only updated for iOS.
## Changelog:
[General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS
Reviewed By: lenaic, sammy-SC
Differential Revision: D47800845
fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38638
A new stable version of Android Gradle Plugin has just been released which I'm bumping over here, and applying all the required changes.
Changelog:
[Internal] [Changed] - Bump AGP to 8.1.0
Reviewed By: cipolleschi
Differential Revision: D47798273
fbshipit-source-id: 57672b10444ffb6079aa5881ff09d033d2a5e895
Summary:
The `Request` interface provided by `types/react-native` doesn't have a `signal` property when it should as this is something that is accessible on the `Request` object.

For example, running the following:
#### Without providing a `signal`
```ts
console.log(new Request('https://www.facebook.com'));
```
will result in the following:
```ts
{"_bodyInit": undefined, "_bodyText": "", "bodyUsed": false, "credentials": "same-origin", "headers": {"map": {}}, "method": "GET", "mode": null, "referrer": null, "signal": {}, "url": "https://www.facebook.com"}
```
## Changelog:
[GENERAL] [FIXED] - Fixed missing property `signal` for the `Request` interface
## Reproduce
1. Add `new Request('https://www.facebook.com').signal` to a typescript file
2. TS will error `Property 'signal' does not exist on type 'Request'`
Pull Request resolved: https://github.com/facebook/react-native/pull/38536
Test Plan:
Adding to `global.d.ts` in a file will resolve the problem, demonstrating that this works.
```ts
interface Request {
readonly signal: AbortSignal | undefined
}
```
Reviewed By: NickGerleman
Differential Revision: D47660506
Pulled By: jacdebug
fbshipit-source-id: ef1459fbaca5d8f31bf8539bd61ac5e447111fec
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38613
The `value` string of the ReactAccessibilityDelegate's `fromValue` method is marked as `Nullable`, however the `null` case is not handled.
This change handle the `null` case setting the accesssibility role to NONE.
## Changelog:
[Android][Fixed] - Set the accessibility role to `NONE` when a `null` string is passed to `fromValue`
Reviewed By: cortinico
Differential Revision: D47752098
fbshipit-source-id: e8a44bdd8874e996d8127cb2ee29e5135210b196
Summary:
Currently, `metro-config` does not have `hermes-parser` enabled by default. This is because `hermes-parser` does not yet support parsing all of TypeScript's syntax nodes.
However, this also means we cannot yet utilize any Flow langauge features that require the use of `hermes-parser` (and are unsupported by Babel). Mapped types falls into this category, so we cannot use them.
This backs out a recent change that tried to adopt Flow mapped types in `EventEmitter`, for now. We can revisit after making the necessary changes to `metro-config`.
Changelog:
[Internal]
Reviewed By: pieterv
Differential Revision: D47729818
fbshipit-source-id: ec90b38e113a9c3ad952f33777fabbd82519cffb
Summary:
Migrates `EventEmitter` in React Native to use the newly introduced mapped types in Flow, instead of `$ObjMap`.
Changelog:
[Internal]
Reviewed By: jbrown215
Differential Revision: D47296240
fbshipit-source-id: 435d0a19242dcd13a4a6c7824daf0e894445cfa7
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38554
@public
Upgrades React Native, Relay, and Metro to use `hermes-parser@0.14.0`.
This also changes the repository's Jest configuration to now use `hermes-parser`.
Changelog:
[Internal]
Reviewed By: SamChou19815
Differential Revision: D47522140
fbshipit-source-id: 207ccd0c4e4489d486731d0c847d8089abc1cc72
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38322
As title, so that we can keep the format
```#import <ReactCommon/RCTHost.h>```
Changelog:
[iOS][Changed] - ] Re-orgnize BridgelessApple files to keep proper header file include structure
Reviewed By: cipolleschi, dmytrorykun
Differential Revision: D47421732
fbshipit-source-id: af14807d20676e8732c66fa7f792580819c33f33
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38107
This change makes bridgeless build with JSC and with all the frameworks settings.
## Changelog:
[iOS][Added] Support bridgeless with JSC and frameworks
Reviewed By: philIip
Differential Revision: D47025704
fbshipit-source-id: 5779d3ffd9ed037e6f6dee6c64cc65835f370a5b
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38547
Before this change, when a turbomodule was registered using the `RCT_EXPORT_MODULE()` function using a custom name, the TM was not found in the registry.
With this change, we are adding a fallback that looks in the list of registered TM, asking for the name used by the user to register it.
This fallback is executed only if no other method was successful before as it is more expensive.
## CHANGELOG
[iOS][Fixed] - Honor the custom name choosen by the user to register the module.
Reviewed By: philIip
Differential Revision: D47666848
fbshipit-source-id: 545855de1c398726b9449a0d77af7f1756cca233
Summary:
There was a typo in App.test.tsx, that I noticed when tried to upgrade from 0.71 to 0.72
## Changelog:
Fixed small typo from *shiped* to *shipped*
Pick one each for the category and type tags:
[GENERAL] [FIXED]
Pull Request resolved: https://github.com/facebook/react-native/pull/38524
Reviewed By: cortinico
Differential Revision: D47695088
Pulled By: NickGerleman
fbshipit-source-id: 9f74c7f891927be6c0c0f522f0cd51b022fb54f1
Summary:
The change in D47554161 is breaking builds for iOS 17 as the `addEntriesFromDictionary` method returns void and the code tries to assign the returned value to another dictionary.
## Changelog:
[iOS][Fixed] - Use `addEntriesFromDictionary` properly in RCTBaseTextInputView.
Reviewed By: sammy-SC
Differential Revision: D47696854
fbshipit-source-id: 49e01fdc63b3f0478762994d5cafdceb16830c74
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38527
This fixes a bug that got reported for the Fabric Interop for Android with Command dispatching.
(See https://github.com/terrylinla/react-native-sketch-canvas/issues/236)
The problem is that libraries that were receiving commands as ints with:
```
public void receiveCommand(
int surfaceId, int reactTag, int commandId, Nullable ReadableArray commandArgs) {
```
would not receive command with the Fabric Interop for Android.
The problem is that with Fabric, events are dispatched as string always.
cipolleschi took care of this for iOS, but we realized that the Android part was missing. I'm adding it here.
The logic is, if the event is dispatched as a string that represents a number (say `"42"`) and the user has Fabric Interop enabled, then we dispatch the event as `int` (so libraries will keep on working).
Changelog:
[Android] [Fixed] - Fabric Interop - Properly dispatch integer commands
Reviewed By: cipolleschi
Differential Revision: D47600094
fbshipit-source-id: c35f0509e6c6c0cddc7090a069882f92dd95532e
Summary:
While setting up a credit card form in RN, I discovered that iOS 17 supports a number of new content types ([`UITextContentType` docs](https://developer.apple.com/documentation/uikit/uitextcontenttype?language=objc)). In the docs these are marked with the `Beta` flag.
Setting up the new content types is relatively straightforward, but a change is required in https://github.com/facebook/react-native-deprecated-modules to update the `TextInput` prop types. ~~I will open a PR in that repo shortly.~~ I have [opened a PR](https://github.com/facebook/react-native-deprecated-modules/pull/23) to update the prop types. ~~Once that PR is merged, a version bump for that dependency will need to be added to this PR.~~ The PR is merged and the dependency in this PR has been updated.
## Changelog:
<!-- Help reviewers and the release process by writing your own changelog entry.
Pick one each for the category and type tags:
[IOS] [ADDED] - Added support for iOS 17+ text content types
For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
Pull Request resolved: https://github.com/facebook/react-native/pull/38354
Test Plan: The `rn-tester` app builds and runs successfully. I have added a few new examples of inputs using the new text content types.
Reviewed By: javache
Differential Revision: D47554161
Pulled By: philIip
fbshipit-source-id: 8d4414dc6229063f81164f2d8727921c8294c92e
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38474
Changelog: [Internal] - Add basics of pointer event interception
This diff adds the scaffolding for intercepting Pointer Events (without actually doing anything with them yet). Most notably introduces the logic of determining which events are of the PointerEvent type and downcasting to the type so the interceptor can properly work with the typed properties.
Originally my plan was to leverage `dynamic_cast` but sandcastle's signals let me know that there exists internal apps (particularly VR ones) which don't have RTTI enabled — so to avoid that usage I introduced an additional abstract method on EventPayload which lets subclasses identify themselves cheaply and then subsequently leverage `static_cast`.
Reviewed By: NickGerleman
Differential Revision: D47443773
fbshipit-source-id: 3671285c0413a60475d51318e209376f8a2790ed
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38521
`HermesRuntimeImpl::setValueAtIndexImpl` directly called
`setElementAt`, which meant that it would not handle index-like
properties properly. Use `putComputed_RJS` instead, which will check
for such properties.
Reviewed By: avp
Differential Revision: D47617445
fbshipit-source-id: c3505670960bd6223bd014f138cee191267a5315
Summary:
From the video below, we can see that the UI thread has dropped many frames, and it would become worse if there are multiple images.
If an image is located in the sandbox of the disk, we cannot load it using `RCTLocalAssetImageLoader` because `RCTLocalAssetImageLoader.requiresScheduling` is set to true, which loads the data on the UI thread and causes main thread stuttering. This will affect libraries such as `react-native-code-push` and others that save images to the sandbox of the disk.
Therefore, we should replace `RCTLocalAssetImageLoader.canLoadImageURL` from `RCTIsLocalAssetURL(url)` to `RCTIsBundleAssetURL(url)`. Similarly, we should rename the entire `RCTLocalAssetImageLoader` file with `RCTBundleAssetImageLoader`, which ignores images in the disk sandbox. And finally these images will be loaded from `NSURLRequest`, and our UI thread will run smoothly again.
https://user-images.githubusercontent.com/20135674/236368418-8933a2c6-549c-40d3-a551-81b492fe41d5.mp4
## Changelog:
<!-- Help reviewers and the release process by writing your own changelog entry.
Pick one each for the category and type tags:
[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message
For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[IOS] [Breaking] - Replace `RCTLocalAssetImageLoader` to `RCTBundleAssetImageLoader`
Pull Request resolved: https://github.com/facebook/react-native/pull/37232
Test Plan:
Test Code:
```javascript
constructor(props) {
super(props)
this.state = {
bundle_image: require('./large_image.png'),
sandbox_image: '',
source: null,
isLoading: false,
}
}
render() {
console.log('render', this.state)
return (
<View style={{ flex: 1, padding: 50, backgroundColor: 'white'}}>
<View style={{ flexDirection: 'row', alignItems: 'center', height: 70}}>
{
[{ title: 'Save Image To SandBox', onPress: () => {
let image = Image.resolveAssetSource(this.state.bundle_image)
console.log(image.uri)
this.setState({ isLoading: true })
RNFetchBlob.config({ fileCache: true, appendExt: "png" }).fetch("GET", image.uri).then(response => {
let path = response.path()
path = /^file:\/\//.test(path) ? path : 'file://' + path
console.log(path)
this.state.sandbox_image = path
}).finally(() => this.setState({ isLoading: false }))
}}, { title: 'Load From SandBox', onPress: () => {
this.setState({ source: { uri: this.state.sandbox_image } })
}}, { title: 'Clear', onPress: () => {
this.setState({
source: null,
isLoading: false
})
}}, { title: 'Load From Bundle', onPress: () => {
this.setState({ source: this.state.bundle_image })
}}].map((item, index) => {
return (
<Pressable
key={index}
style={{ height: '100%', justifyContent: 'center', flex: 1, borderWidth: 1, borderColor: 'black', marginLeft: index > 0 ? 15 : 0 }}
onPress={item.onPress}
>
<Text style={{ textAlign: 'center' }}>{item.title}</Text>
</Pressable>
)
})
}
</View>
<ActivityIndicator style={{ marginTop: 10 }} animating={this.state.isLoading} />
<Image
key={`${this.state.source}`}
style={{ marginTop: 20, width: 200, height: 200 }}
source={this.state.source}
onProgress={({ nativeEvent }) => console.log(nativeEvent)}
onLoadStart={() => this.setState({ isLoading: true })}
onLoadEnd={() => this.setState({ isLoading: false })}
/>
</View>
)
}
```
It needs to be tested in three environments: [Simulator_Debug, RealDevice_Debug, RealDevice_Release]
1. Open `Perf Monitor` (RealDevice_Release can be skipped)
2. Click `Save Image to SandBox`
3. Wait for the loading to end and click `Load From SandBox`
4. Verify that the image can be loaded successfully
5. Verify that the `UI thread` keeps `60 FPS` (RealDevice_Release can be skipped)
6. Click `Clear`
7. Repeat steps [3, 4, 5, 6] several times
8. Click `Load From Bundle` to verify that the bundle image can be loaded successfully
Simulator_Debug
https://user-images.githubusercontent.com/20135674/236369344-ee1b8ff1-2d49-49f3-a322-d973f4adf3e7.mp4
RealDevice_Debug
https://user-images.githubusercontent.com/20135674/236369356-fe440b2b-f72a-49be-b63c-b4bf709dac8c.mp4
RealDevice_Release
https://user-images.githubusercontent.com/20135674/236369365-8a6a5c2f-09ad-4c90-b6bd-41e8a5e3aa7f.mp4
Reviewed By: rshest
Differential Revision: D46441513
Pulled By: dmytrorykun
fbshipit-source-id: 652febd4147dbff6c1ceef03d84ce125b8c66770
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37730
This diff makes unschematized native components available in bridgeless mode. In case there is no static view config, `BridgelessUIManager` calls `RN$LegacyInterop_UIManager_getConstants`, and gets native view config form the constants.
Changelog: [Internal] - Use RN$LegacyInterop_UIManager_getConstants in BridgelessUIManager
Reviewed By: sammy-SC
Differential Revision: D45154396
fbshipit-source-id: 32b3718841b59a8b6fb22022c9d9edc17dad877f