Compare commits

...
Author SHA1 Message Date
Distiller 57cc8e7f67 [0.74.0-rc.3] Bump version numbers 2024-03-11 14:59:31 +00:00
Alex Hunt 8a7c718ab3 Bump package versions
#publish-packages-to-npm&0.74-stable
2024-03-11 13:53:12 +00:00
Cedric van Putten 4efab59a1e feature(dev-middleware): add inspector proxy nativeNetworkInspection target capabilty flag (#43310)
Summary:
This adds the `nativeNetworkInspection` target capability flag, to enable/disable the proxy-side network inspection handling.

## 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
-->

[GENERAL][ADDED] Add inspector proxy `nativeNetworkInspection` target capability flag

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

Test Plan:
Once this lands, and is published through `react-native/dev-middleware`, we (Expo) can disable the proxy-side network inspection handling.

See https://github.com/expo/expo/pull/27425/commits/1a1b601a29fbc5766628238db7259121689f6cd6 on PR expo/expo#27425

Reviewed By: christophpurrer, motiz88

Differential Revision: D54486516

Pulled By: huntie

fbshipit-source-id: cc151349c816fb3866d3ec07af1a29a5f4ff9b00
2024-03-11 11:01:17 +00:00
Oskar Kwaśniewski e3da9b8c0a fix: add compiler conditional to hover style (#43331)
Summary:
Commit https://github.com/facebook/react-native/commit/73664f576aaa472d5c8fb2a02e0ddd017bbb2ea4 broke two jobs in CircleCI that we run using Xcode 14.3.1 because the commit introduced some types that are available only to iOS 17.
The code was wrapped around if(available()) statement, but this does not compile out the code. It is a runtime check and the code needs to build anyway.

This takes effect at compile time as well. However, unlike with #available, the method must type check and compile. The code will always be emitted into your binary: however, it will only be used when the binary is executed on platforms that meet the availability requirements.

source: [forums.swift.org/t/if-vs-available-vs-if-available/40266/2](https://forums.swift.org/t/if-vs-available-vs-if-available/40266/2)

This change should fix it, introducing some compile time pragmas that removes the code if we build with older versions of Xcode

## Changelog:

[IOS] [ADDED] - Compiler conditionals for hover style (cursor: pointer)

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

Test Plan: CI Green

Reviewed By: dmytrorykun

Differential Revision: D54540520

Pulled By: cipolleschi

fbshipit-source-id: 943ac479062e11969efa7645ec0ead26c6866374
2024-03-11 10:59:17 +00:00
Saad Najmi 7395765cf8 feat(iOS): Implement cursor style prop (#43078)
Summary:
Implement the cursor style prop for iOS (and consequently, visionOS), as described in this RFC: https://github.com/react-native-community/discussions-and-proposals/pull/750

See related PR in React Native macOS, where we target macOS and visionOS (not running in iPad compatibility mode) with the same change: https://github.com/microsoft/react-native-macos/pull/2080

Docs update: https://github.com/facebook/react-native-website/pull/4033

## Changelog:

[IOS] [ADDED] - Implement cursor style prop

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

Test Plan:
See the added example page, running on iOS with the new architecture enabled. This also runs the same on the old architecture.

https://github.com/facebook/react-native/assets/6722175/2af60a0c-1c1f-45c4-8d66-a20f6d5815df

See the example page running on all three apple platforms. The JS is slightly different because:
1. The "macOS Cursors" example is not part of this PR but the one in React Native macOS.
2. This PR (and exapmple) has went though a bunch of iterations and It got hard taking videos of every change 😅

https://github.com/facebook/react-native/assets/6722175/7775ba7c-8624-4873-a735-7665b94b7233

## Notes

- React Native macOS added the cursor prop to View with https://github.com/microsoft/react-native-macos/pull/760 and Text with https://github.com/microsoft/react-native-macos/pull/1469 . Much of the implementation comes from there.

- Due to an Apple bug, as of iOS 17.4 Beta 4, the shape of the iOS cursor hover effect doesn't render in the correct bounds (but it does on visionOS). I've worked around it with an ifdef. The result is that the hover effect will work on iOS and visionOS, but not iPad apps running in compatibility mode on visionOS.

Reviewed By: NickGerleman

Differential Revision: D54512945

Pulled By: vincentriemer

fbshipit-source-id: 699e3a01a901f55a466a2c1a19f667aede5aab80
2024-03-11 10:58:03 +00:00
Oskar Kwaśniewski 66b1cfee97 feat(RCTAppDelegate): Implement RCTRootViewFactory (#42263)
Summary:
This PR implements `RCTRootViewFactory` a utility class (suggested by cipolleschi) that returns proper RCTRootView based on the current environment state (new arch/old arch/bridgeless). This class aims to preserve background compatibility by implementing a configuration class forwarding necessary class to RCTAppDelegate.

This PR leverages the `RCTRootViewFactory` in `RCTAppDelegate` for the default initialization of React Native (greenfield).

Here is an example of creating a Brownfield integration (without RCTAppDelegate) using this class (can be later added to docs):

1. Store reference to `rootViewFactory` and to `UIWindow`

`AppDelegate.h`:
```objc
interface AppDelegate : UIResponder <UIApplicationDelegate>

property(nonatomic, strong) UIWindow* window;
property(nonatomic, strong) RCTRootViewFactory* rootViewFactory;

end
```

2. Create an initial configuration using `RCTRootViewFactoryConfiguration` and initialize `RCTRootViewFactory` using it. Then you can use the factory to create a new `RCTRootView` without worrying about old arch/new arch/bridgeless.

 `AppDelegate.mm`
```objc
implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions {

  // Create configuration
 RCTRootViewFactoryConfiguration *configuration = [[RCTRootViewFactoryConfiguration alloc] initWithBundleURL:self.bundleURL
                                                                                                 newArchEnabled:self.fabricEnabled
                                                                                             turboModuleEnabled:self.turboModuleEnabled
                                                                                              bridgelessEnabled:self.bridgelessEnabled];

  // Initialize RCTRootViewFactory
  self.rootViewFactory = [[RCTRootViewFactory alloc] initWithConfiguration:configuration];

  // Create main root view
  UIView *rootView = [self.rootViewFactory viewWithModuleName:@"RNTesterApp" initialProperties:@{} launchOptions:launchOptions];

  // Set main window as you prefer for your Brownfield integration.
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  // Later in the codebase you can initialize more rootView's using rootViewFactory.

  return YES;
}
end
```
bypass-github-export-checks

[INTERNAL] [ADDED] - Implement RCTRootViewFactory

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

Test Plan: Check if root view is properly created on app initialization

Reviewed By: dmytrorykun

Differential Revision: D53179625

Pulled By: cipolleschi

fbshipit-source-id: 9bc850965ba30d84ad3e67d91dd888f0547c2136
2024-03-11 10:54:06 +00:00
Tomek Zawadzki 6440e35bc7 Expose react_render_textlayoutmanager via prefab (#43381)
Summary:
The `react_render_textlayoutmanager` was not exposed via prefab. I'm adding it to make possible for react-native-live-markdown to integrate on top of React Native via prefab. Based on https://github.com/facebook/react-native/issues/36166.

## 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
-->

[ANDROID] [CHANGED] - Expose `react_render_textlayoutmanager` via prefab.

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

Reviewed By: javache

Differential Revision: D54676207

Pulled By: cortinico

fbshipit-source-id: 90e3b90ff842250bf1e3abcc0c54f057b68a82fd
2024-03-11 10:49:09 +00:00
Arushi Kesarwani 10d65924ee Support onActivityResult in Bridgeless (#43351)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43351

Implement `onActivityResult` on Bridgeless

Changelog:
[Internal] internal

Reviewed By: cortinico

Differential Revision: D54574139

fbshipit-source-id: f2369077199186ac6ef0187b5dfe7ed95f3b87fc
2024-03-11 10:43:48 +00:00
Rick Hanlon 31b62ab7f0 Fix component stacks for tsx, ts, and jsx files (#43370)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43370

Component stacks with files ending in .ts, .tsx, or .jsx were skipped in LogBox reporting. This diff fixes the regex.

Changelog:
[General][Fixed] - Support .tsx, .ts, and .jsx in component stacks

Reviewed By: yungsters

Differential Revision: D54638526

fbshipit-source-id: a5271daaa7b687e8e075be3f94ab9b9c03f79b66
2024-03-11 10:41:29 +00:00
Pieter De Baets 1151ea1247 Fix DefaultReactNativeHost assuming lazyViewManagers are always available (#43334)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43334

cortinico flagged that bridge + fabric regressed in 0.74, likely due to D53406841.

Changelog: [Android][Fixed] Fix registration of ViewManagers in new renderer when not using lazyViewManagers.

Reviewed By: fkgozali

Differential Revision: D54551645

fbshipit-source-id: 0783030cd0d2900a3a254ae04c9ea4e51035272a
2024-03-11 10:39:14 +00:00
Oskar Kwaśniewski a9ec4203e1 fix(iOS) [0.74]: RCTRedBox not appearing in Bridgeless when metro is not running (#43147)
Summary:
When testing out `0.74.0-rc0` I found that when the metro is not running we are not displaying RedBox which bumps users to start the packager and reload the app. It also fixes the case where users try to reload by clicking the "Reload" button on RedBox.

## Before

https://github.com/facebook/react-native/assets/52801365/086c557f-ea1f-4a97-b4c7-df8a945cc7a0

## After

https://github.com/facebook/react-native/assets/52801365/9f8421b3-5e83-466f-8cdb-38f97981275d

## Changelog:

[IOS] [FIXED] - RCTRedBox not appearing in Bridgeless when metro is not running

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

Test Plan: Build the app without metro running check if RedBox is shown

Reviewed By: javache

Differential Revision: D54632056

Pulled By: dmytrorykun

fbshipit-source-id: fb6742898d3bd82545bfffd9175208e1a5984cb6
2024-03-11 10:37:10 +00:00
Pieter De Baets bd39897abf Fix NullPointerException thrown on startup (#43293)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43293

Was debugging this, and found that this exception was being thrown due to `DefaultBindingsInstaller`, which was an invalid hybrid object. The ReactInstance initializer fully supports this being null, so let's use that as default.

Changelog: [Android][Fixed] NullPointerException is no longer ignored in MessageQueueThreadHandler

Reviewed By: sammy-SC

Differential Revision: D54434417

fbshipit-source-id: 52417b390061eface0f0578e32796d3a85303e03
2024-03-11 10:34:28 +00:00
Tomek Zawadzki 7c2fb7911a Expose rrc_text via prefab (#43275)
Summary:
The `rrc_text` was not exposed via prefab. I'm adding it to make possible for react-native-live-markdown to integrate on top of React Native via prefab. Based on https://github.com/facebook/react-native/issues/36166.

## 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
-->

[ANDROID] [CHANGED] - Expose `rrc_text` via prefab.

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

Reviewed By: cipolleschi

Differential Revision: D54536468

Pulled By: cortinico

fbshipit-source-id: 8c4ef983467bfc46930f10bf7bd95761c2d11788
2024-03-11 10:33:39 +00:00
Tomek Zawadzki 4dc9d54447 Expose rrc_textinput via prefab (#43274)
Summary:
The `rrc_textinput` was not exposed via prefab. I'm adding it to make possible for react-native-live-markdown to integrate on top of React Native via prefab. Based on https://github.com/facebook/react-native/issues/36166.

## 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
-->

[ANDROID] [CHANGED] - Expose `rrc_textinput` via prefab.

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

Reviewed By: cipolleschi

Differential Revision: D54482657

Pulled By: cortinico

fbshipit-source-id: ca7f4127f1808f841d88925238666e837de75bd0
2024-03-11 10:33:21 +00:00
Luna Wei 27b54bdcff local - podfile.lock update for rntester 2024-03-04 14:13:09 -08:00
Distiller c68669079a [0.74.0-rc.2] Bump version numbers 2024-03-04 19:42:11 +00:00
Luna Wei 1c1b03d6e8 bumped packages versions
#publish-packages-to-npm&0.74-stable
2024-03-04 11:29:35 -08:00
Luna Wei c7e704a0ef bumped packages versions
#publish-packages-to-npm&0.74-stable
2024-03-04 11:29:15 -08:00
Luna Wei 02d38e4eb5 bumped packages versions
#publish-packages-to-npm&0.74-stable
2024-03-04 11:28:55 -08:00
Luna Wei e063a1b0fb bumped packages versions
#publish-packages-to-npm&0.74-stable
2024-03-04 11:27:34 -08:00
Alex Hunt c09e4dacff Bump package versions
#publish-packages-to-npm&0.74-stable
2024-03-04 12:14:00 +00:00
Alex Hunt 011cb3a8d7 Update Podfile.lock 2024-03-04 12:11:28 +00:00
Riccardo Cipolleschi a5b5f6be78 Rename PopupMenuAndroidNativeComponent.js to PopupMenuAndroidNativeComponent.android.js to fix CI
Summary:
This change renames `PopupMenuAndroidNativeComponent.js` to `PopupMenuAndroidNativeComponent.android.js`.

The reason is that, without the suffix, Codegen was reading the NativeComponent spec also for iOS, generating some invalid specs and making RNTester fail.

## Changelog:
[Android][Changed] - Rename `PopupMenuAndroidNativeComponent.js` to `PopupMenuAndroidNativeComponent.android.js`

Reviewed By: cortinico, dmytrorykun

Differential Revision: D54199736

fbshipit-source-id: 7fd67c4d38a69fe3a84c800c8ee5dcbd8c4f9a6c
2024-03-04 11:02:58 +00:00
Ramanpreet Nara 29b34e70e3 Pull PopupMenuAndroid out of React Native core
Summary:
**History:** This component was originally introduced into React Native core in D52712758, to replace UIManagerModule.showPopupMenu().

**Problem:** But, React Native core should be lean. Adding this component to React Native bloats the core.

**Changes:** So, this diff pulls PopupMenuAndroid out into its own package in the react-native GitHub repository.

In the future, this will be migrated to a community package!

Changelog: [Android][Removed] Move PopupMenu out of React Native core

Reviewed By: NickGerleman

Differential Revision: D53328110

fbshipit-source-id: 469d8dc3e756c06040c72e08fa004aafa1bd6e18
2024-03-04 11:02:52 +00:00
Nicola Corti 6294453980 Undo moving of TurboModule to internal and expose utility function for TurboModule.class.isAssignableFrom (#43219)
Summary:
After discussing with mdvacca, we prefer to undo the change of `TurboModule` package to `.internal` as this is a quite aggressive breaking change for the ecosystem.

Moreover: users should not invoke `TurboModule.class.isAssignableFrom` because `TurboModule` is `.internal`. Therefore I'm exposing another API to check if a class is a TurboModule as a static field of `ReactModuleInfo`.

## Changelog:

[INTERNAL] - Do not use TurboModule.class.isAssignableFrom

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

Test Plan: Tests are attached

Reviewed By: mdvacca, cipolleschi

Differential Revision: D54280882

Pulled By: cortinico

fbshipit-source-id: 9443c8aa23cf70dd5cfe574fe573d83313134358
2024-03-04 11:02:03 +00:00
Oskar Kwaśniewski 7822a7796f fix(iOS) [0.74]: properly warn about createRootViewWithBridge (#43146)
Summary:
This PR fixes an issue that `_logWarnIfCreateRootViewWithBridgeIsOverridden` was called in wrong place.

Assuming user overrides this method and call to `[super]`:

```objc
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps {
  UIView *view = [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps];
  view.backgroundColor = [UIColor redColor];
  return view;
}
```

This method still wasn't called in bridgeless (and not showing the error).

Checking if user overrides this method in `appDidFinishWithLaunching` works every time

![simulator_screenshot_0E22557C-CE37-4617-A25A-F39A6ED4D3D0](https://github.com/facebook/react-native/assets/52801365/d7865f37-32f0-40ad-a252-74ab7c5b7757)

## Changelog:

[IOS] [FIXED] - Properly warn about `createRootViewWithBridge` being deprecated

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

Test Plan: Check if warning is shown when message is overridden

Reviewed By: huntie

Differential Revision: D54303506

Pulled By: cipolleschi

fbshipit-source-id: cf30555c791493f28b3015a189cf93b60cace8f8
2024-03-04 11:01:37 +00:00
Riccardo Cipolleschi 1ccc7a3e9e Deprecate getSurfacePresenter and getModuleRegistry in favor of their props
Summary:
This change align the `getSurfacePresenter` and `getModuleRegistry` to the iOS convention for which these should be computed properties with no `get` prefix in their name.

We want to land this change and to pick it in 0.74 so we can remove the `get` versions in 0.75.

## Changelog:
[iOS][Deprecated] - Deprecate `getSurfacePresenter` and `getModuleRegistry` for `surfacePresenter` and moduleRegistry` props.

Reviewed By: javache

Differential Revision: D54253805

fbshipit-source-id: e9ff7db744a73a3bd0f8ae1d87875e54ddd9a1a4
2024-03-04 11:01:15 +00:00
Dmitry Rykun 987c1f2880 Fix findLibrariesFromReactNativeConfig
Summary:
This diff removes extra argument from the `extractLibrariesFromJSON` call inside `findLibrariesFromReactNativeConfig`.
This should fix the iOS failurte discribed in https://github.com/facebook/react-native/issues/43204
Changelog: [iOS][Fixed] - Codegen correctly handles react-native.config.js.

Reviewed By: cipolleschi

Differential Revision: D54248400

fbshipit-source-id: 2ae5d0d29f49725877559a5b0edd7d59f8bdefaa
2024-03-04 10:56:27 +00:00
Moti Zilberman f6f3b5cb98 Restore Content-Length header in inspector-proxy JSON responses
Summary:
Changelog: [General][Fixed] Re-enable listing Hermes debugger targets in chrome://inspect, broken in 0.74 RC

Fixes https://github.com/facebook/react-native/issues/43259.

Reverts D52958725 and fixes the original `Content-Length` Unicode bug using a different approach.

Reviewed By: fabriziocucci

Differential Revision: D54409847

fbshipit-source-id: ed5bb464ab67f37535947646b124814d8bbf797c
2024-03-01 10:45:51 +00:00
Riccardo Cipolleschi f7644be6d4 [RN][iOS]Rename BUILD_FROM_SOURCE to RCT_BUILD_HERMES_FROM_SOURCE 2024-02-29 10:48:01 +00:00
Distiller ad3f6b5274 [0.74.0-rc.1] Bump version numbers 2024-02-27 01:08:06 +00:00
Nicola Corti ba3cf235f5 bumped packages versions
#publish-packages-to-npm&0.74-stable
2024-02-26 16:54:52 -08:00
Cedric van Putten d032e35f86 feat(cli): warn underlying command when using npx react-native init (#43127)
Summary:
This adds a new warning for React Native 0.74, implementing the [RFC 0759](https://github.com/react-native-community/discussions-and-proposals/blob/nc/rnf/proposals/0759-react-native-frameworks.md#the-init-command) init command changes.

- It's added inside `react-native/cli.js` to avoid warning users when actually executing `npx react-native-community/cli` commands.
- The check is fairly simple: `process.argv[2] === 'init'`. The first two args are the Node bin and the actual script bin paths.
- The message is sent over `console.warn` to avoid potentially mixing JSON with non-JSON output.

## Changelog:

[GENERAL] [ADDED] - Warn with future command when using `npx react-native init`

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

Test Plan:
Any command other than `init` must not warn.

- `$ node ./path/to/react-native/cli.js init`
- `$ node ./path/to/react-native/cli.js init --help`
  - Should warn with `Running: npx react-native-community/cli init`
    ![image](https://github.com/facebook/react-native/assets/1203991/a3f5e3d2-7b59-41fe-9a53-bc9ce5a21fd1)
- `$ node ./path/to/react-native/cli.js --help`
  - Must not warn
    ![image](https://github.com/facebook/react-native/assets/1203991/97679429-db35-47f8-bdeb-33187bb167cf)

Reviewed By: cipolleschi

Differential Revision: D54063131

Pulled By: cortinico

fbshipit-source-id: c60b8b6034087b584e98b51f5bedf68a46caf44c
2024-02-26 11:47:20 -08:00
Nicola Corti b33b80f51c Bump CLI to 13.6.1 (#43153)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43153

This contains an hotfix for the CLI needed for 0.74

Changelog:
[Internal] [Changed] - Bump CLI to 13.6.1

Reviewed By: huntie

Differential Revision: D54073715

fbshipit-source-id: a5fdf02f47c5e144efc58e6b7fd355669a21e07b
2024-02-26 11:15:57 -08:00
Nicola Corti b3300d77ea Remove accidental files included inside the template.
Summary:
Those files should not stay in the root `/app` folder but inside the `/app/gradle/wrapper` folder.
I've noticed this in the Upgrade Helper UI hence I'm removing them.

Changelog:
[Internal] [Changed] - Remove accidental files included inside the template

Reviewed By: mdvacca

Differential Revision: D54122995

fbshipit-source-id: 8873a91ffbea20f609c7aabd428a815c77a38db5
2024-02-26 11:10:30 -08:00
Nicola Corti fde94ce307 Do not crash on onJSBundleLoadedFromServer when fast-refreshing on bridgeless mode
Summary:
RN-Tester is currently instacrashing on fast-refresh (pressing r on Metro) as it ends up on `onJSBundleLoadedFromServer`
which throws an exception on Bridgeless mode. I'm fixing it by following the same logic as `onReloadWithJSDebugger`.

Changelog:
[Android] [Fixed] - Do not crash on onJSBundleLoadedFromServer when fast-refreshing on bridgeless mode

Reviewed By: huntie

Differential Revision: D54121838

fbshipit-source-id: 82d98ec0c5b2295f5751525368c956574dd7f3a0
2024-02-26 11:10:23 -08:00
Diego Segura 1f7ed063c9 fix flatlist props being undefined in ios (#43141)
Summary:
When using Flatlist on iOS and Android its failing because props are undefined

The problem is described on https://github.com/facebook/react-native/issues/34783

![Captura de pantalla 2024-02-22 a las 4 13 11](https://github.com/facebook/react-native/assets/1161455/325738d9-2e49-44a0-bb6a-077b2e02e9cd)

![Captura de pantalla 2024-02-22 a las 4 14 58](https://github.com/facebook/react-native/assets/1161455/118f76e1-a818-428e-938e-123b55536b49)

Fixed by setting constructor before any statement and removing unnecessary props declaration at the top of the class.

## 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
-->
[GENERAL] [FIXED] - Fix undefined props crash in FlatList

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

Reviewed By: javache

Differential Revision: D54069559

Pulled By: robhogan

fbshipit-source-id: b39cd9a273eb0279ed353f9efcb66a3c4ccf93b4
2024-02-26 11:09:34 -08:00
Nicola Corti 4def40ee33 Hook the default-app-setup OnLoad.cpp file with the cxxModuleProvider from RNCLI (#43049)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43049

This connects the OnLoad.cpp file used by OSS apps with the `rncli_cxxModuleProvider`.
This method is created by the CLI and takes care of querying all the TM CXX Modules discovered and returning them.

This PR is currently waiting on https://github.com/react-native-community/cli/pull/2296

Changelog:
[Internal] [Changed] - Hook the default-app-setup OnLoad.cpp file with the cxxModuleProvider from RNCLI

Reviewed By: cipolleschi

Differential Revision: D53812109

fbshipit-source-id: 47bc0ea699516993070cfa0127de97853acf8890
2024-02-22 11:01:50 +00:00
Riccardo Cipolleschi 341fbe5486 [RN][Release] Fix release testing script 2024-02-21 17:55:37 +00:00
Distiller 898e207bcf [0.74.0-rc.0] Bump version numbers 2024-02-21 16:33:24 +00:00
Alex Hunt 619b8eb4d0 Bump package versions
#publish-packages-to-npm&0.74-stable
2024-02-21 15:20:42 +00:00
Alex Hunt ebca982365 Update Hermes version 2024-02-20 15:24:28 +00:00
141 changed files with 2045 additions and 840 deletions
+2 -2
View File
@@ -35,11 +35,11 @@ executors:
xcode: *xcode_version
resource_class: macos.x86.medium.gen2
environment:
- BUILD_FROM_SOURCE: true
- RCT_BUILD_HERMES_FROM_SOURCE: true
reactnativeios-lts:
<<: *defaults
macos:
xcode: '14.3.1'
resource_class: macos.x86.medium.gen2
environment:
- BUILD_FROM_SOURCE: true
- RCT_BUILD_HERMES_FROM_SOURCE: true
+1 -1
View File
@@ -599,7 +599,7 @@ jobs:
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- HERMES_VERSION_FILE: "packages/react-native/sdks/.hermesversion"
- BUILD_FROM_SOURCE: true
- RCT_BUILD_HERMES_FROM_SOURCE: true
steps:
- run:
name: Install dependencies
+1
View File
@@ -42,6 +42,7 @@ project.xcworkspace
/packages/react-native/ReactAndroid/hermes-engine/.cxx/
/packages/react-native/template/android/app/build/
/packages/react-native/template/android/build/
/packages/react-native-popup-menu-android/android/build/
# Buck
.buckd
+2 -2
View File
@@ -59,8 +59,8 @@
"@definitelytyped/dtslint": "^0.0.127",
"@jest/create-cache-key-function": "^29.6.3",
"@pkgjs/parseargs": "^0.11.0",
"@react-native/metro-babel-transformer": "0.74.0",
"@react-native/metro-config": "0.74.0",
"@react-native/metro-babel-transformer": "0.74.2",
"@react-native/metro-config": "0.74.2",
"@tsconfig/node18": "1.0.1",
"@types/react": "^18.0.18",
"@typescript-eslint/parser": "^6.7.4",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/babel-plugin-codegen",
"version": "0.74.0",
"version": "0.74.2",
"description": "Babel plugin to generate native module and view manager code for React Native.",
"license": "MIT",
"repository": {
@@ -25,7 +25,7 @@
"index.js"
],
"dependencies": {
"@react-native/codegen": "0.74.0"
"@react-native/codegen": "0.74.2"
},
"devDependencies": {
"@babel/core": "^7.20.0"
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/community-cli-plugin",
"version": "0.74.0",
"version": "0.74.5",
"description": "Core CLI commands for React Native",
"keywords": [
"react-native",
@@ -22,10 +22,10 @@
"dist"
],
"dependencies": {
"@react-native-community/cli-server-api": "13.6.0",
"@react-native-community/cli-tools": "13.6.0",
"@react-native/dev-middleware": "0.74.0",
"@react-native/metro-babel-transformer": "0.74.0",
"@react-native-community/cli-server-api": "13.6.1",
"@react-native-community/cli-tools": "13.6.1",
"@react-native/dev-middleware": "0.74.3",
"@react-native/metro-babel-transformer": "0.74.2",
"chalk": "^4.0.0",
"execa": "^5.1.1",
"metro": "^0.80.3",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/debugger-frontend",
"version": "0.74.0",
"version": "0.74.1",
"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.74.0",
"version": "0.74.3",
"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.74.0",
"@react-native/debugger-frontend": "0.74.1",
"@rnx-kit/chromium-edge-launcher": "^1.0.0",
"chrome-launcher": "^0.15.2",
"connect": "^3.6.5",
@@ -14,11 +14,13 @@ import type {
JsonVersionResponse,
} from '../inspector-proxy/types';
import {fetchJson} from './FetchUtils';
import {fetchJson, fetchLocal} from './FetchUtils';
import {createDeviceMock} from './InspectorDeviceUtils';
import {withAbortSignalForEachTest} from './ResourceUtils';
import {withServerForEachTest} from './ServerUtils';
import nullthrows from 'nullthrows';
// Must be greater than or equal to PAGES_POLLING_INTERVAL in `InspectorProxy.js`.
const PAGES_POLLING_DELAY = 1000;
@@ -309,5 +311,67 @@ describe('inspector proxy HTTP API', () => {
}
});
});
test('handles Unicode data safely', async () => {
const device = await createDeviceMock(
`${serverRef.serverBaseWsUrl}/inspector/device?device=device1&name=foo&app=bar`,
autoCleanup.signal,
);
try {
device.getPages.mockImplementation(() => [
{
app: 'bar-app 📱',
id: 'page1 🛂',
title: 'bar-title 📰',
vm: 'bar-vm 🤖',
},
]);
jest.advanceTimersByTime(PAGES_POLLING_DELAY);
const json = await fetchJson<JsonPagesListResponse>(
`${serverRef.serverBaseUrl}${endpoint}`,
);
expect(json).toEqual([
expect.objectContaining({
description: 'bar-app 📱',
deviceName: 'foo',
id: 'device1-page1 🛂',
title: 'bar-title 📰',
vm: 'bar-vm 🤖',
}),
]);
} finally {
device.close();
}
});
test('includes a valid Content-Length header', async () => {
// NOTE: This test is needed because chrome://inspect's HTTP client is picky
// and doesn't accept responses without a Content-Length header.
const device = await createDeviceMock(
`${serverRef.serverBaseWsUrl}/inspector/device?device=device1&name=foo&app=bar`,
autoCleanup.signal,
);
try {
device.getPages.mockImplementation(() => [
{
app: 'bar-app',
id: 'page1',
title: 'bar-title',
vm: 'bar-vm',
},
]);
jest.advanceTimersByTime(PAGES_POLLING_DELAY);
const response = await fetchLocal(
`${serverRef.serverBaseUrl}${endpoint}`,
);
expect(response.headers.get('Content-Length')).not.toBeNull();
} finally {
device.close();
}
});
});
});
@@ -167,6 +167,7 @@ export default class InspectorProxy implements InspectorProxyQueries {
response.writeHead(200, {
'Content-Type': 'application/json; charset=UTF-8',
'Cache-Control': 'no-cache',
'Content-Length': Buffer.byteLength(data).toString(),
Connection: 'close',
});
response.end(data);
@@ -30,6 +30,13 @@ export type TargetCapabilityFlags = $ReadOnly<{
* In the proxy, this disables source fetching emulation and host rewrites.
*/
nativeSourceCodeFetching?: boolean,
/**
* The target supports native network inspection.
*
* In the proxy, this disables intercepting and storing network requests.
*/
nativeNetworkInspection?: boolean,
}>;
// Page information received from the device. New page is created for
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-config",
"version": "0.74.0",
"version": "0.74.1",
"description": "ESLint config for React Native",
"license": "MIT",
"repository": {
@@ -22,7 +22,7 @@
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.20.0",
"@react-native/eslint-plugin": "0.74.0",
"@react-native/eslint-plugin": "0.74.1",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"eslint-config-prettier": "^8.5.0",
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin",
"version": "0.74.0",
"version": "0.74.1",
"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.74.0",
"version": "0.74.2",
"description": "ESLint rules to validate NativeModule and Component Specs",
"license": "MIT",
"repository": {
@@ -31,7 +31,7 @@
"@babel/eslint-parser": "^7.20.0",
"@babel/plugin-transform-flow-strip-types": "^7.20.0",
"@babel/preset-flow": "^7.20.0",
"@react-native/codegen": "0.74.0",
"@react-native/codegen": "0.74.2",
"make-dir": "^2.1.0",
"pirates": "^4.0.1",
"source-map-support": "0.5.0"
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/metro-config",
"version": "0.74.0",
"version": "0.74.2",
"description": "Metro configuration for React Native.",
"license": "MIT",
"repository": {
@@ -27,7 +27,7 @@
],
"dependencies": {
"@react-native/js-polyfills": "0.74.0",
"@react-native/metro-babel-transformer": "0.74.0",
"@react-native/metro-babel-transformer": "0.74.2",
"metro-config": "^0.80.3",
"metro-runtime": "^0.80.3"
}
@@ -1,6 +1,6 @@
{
"name": "@react-native/babel-preset",
"version": "0.74.0",
"version": "0.74.2",
"description": "Babel preset for React Native applications",
"main": "src/index.js",
"repository": {
@@ -54,7 +54,7 @@
"@babel/plugin-transform-typescript": "^7.5.0",
"@babel/plugin-transform-unicode-regex": "^7.0.0",
"@babel/template": "^7.0.0",
"@react-native/babel-plugin-codegen": "0.74.0",
"@react-native/babel-plugin-codegen": "0.74.2",
"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.74.0",
"version": "0.74.2",
"description": "Babel transformer for React Native applications.",
"main": "src/index.js",
"repository": {
@@ -16,7 +16,7 @@
"license": "MIT",
"dependencies": {
"@babel/core": "^7.20.0",
"@react-native/babel-preset": "0.74.0",
"@react-native/babel-preset": "0.74.2",
"hermes-parser": "0.19.1",
"nullthrows": "^1.1.1"
},
@@ -19,7 +19,7 @@
"prepare": "yarn run build"
},
"dependencies": {
"@react-native/codegen": "0.74.0"
"@react-native/codegen": "0.74.2"
},
"devDependencies": {
"@babel/core": "^7.20.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/codegen",
"version": "0.74.0",
"version": "0.74.2",
"description": "Code generation tools for React Native",
"license": "MIT",
"repository": {
@@ -462,7 +462,7 @@ module.exports = {
'com.facebook.react.bridge.ReactApplicationContext',
'com.facebook.react.bridge.ReactContextBaseJavaModule',
'com.facebook.react.bridge.ReactMethod',
'com.facebook.react.internal.turbomodule.core.interfaces.TurboModule',
'com.facebook.react.turbomodule.core.interfaces.TurboModule',
'com.facebook.proguard.annotations.DoNotStrip',
'javax.annotation.Nonnull',
]);
@@ -20,7 +20,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaModule implements TurboModule {
@@ -66,7 +66,7 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -136,7 +136,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaModule implements TurboModule {
@@ -178,7 +178,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class AliasTurboModuleSpec extends ReactContextBaseJavaModule implements TurboModule {
@@ -224,7 +224,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class NativeCameraRollManagerSpec extends ReactContextBaseJavaModule implements TurboModule {
@@ -272,7 +272,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class NativeExceptionsManagerSpec extends ReactContextBaseJavaModule implements TurboModule {
@@ -338,7 +338,7 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
@@ -462,7 +462,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaModule implements TurboModule {
@@ -500,7 +500,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class NativeSampleTurboModule2Spec extends ReactContextBaseJavaModule implements TurboModule {
@@ -1,6 +1,6 @@
{
"name": "@react-native/gradle-plugin",
"version": "0.74.0",
"version": "0.74.1",
"description": "Gradle Plugin for React Native",
"license": "MIT",
"repository": {
@@ -0,0 +1,35 @@
/*
* 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.
*/
plugins {
id("com.facebook.react")
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
compileSdk = libs.versions.compileSdk.get().toInt()
buildToolsVersion = libs.versions.buildTools.get()
namespace = "com.facebook.react.popupmenu"
defaultConfig {
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions { jvmTarget = "17" }
}
dependencies {
// Build React Native from source
implementation(project(":packages:react-native:ReactAndroid"))
}
@@ -0,0 +1,3 @@
# We want to have more fine grained control on the Java version for
# ReactAndroid, therefore we disable RGNP Java version alignment mechanism
react.internal.disableJavaVersionAlignment=true
@@ -0,0 +1,20 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentDescriptorH.js
*/
#pragma once
#include "ShadowNodes.h"
#include <react/renderer/core/ConcreteComponentDescriptor.h>
namespace facebook::react {
using AndroidPopupMenuComponentDescriptor = ConcreteComponentDescriptor<AndroidPopupMenuShadowNode>;
} // namespace facebook::react
@@ -0,0 +1,24 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterCpp.js
*/
#include "EventEmitters.h"
namespace facebook::react {
void AndroidPopupMenuEventEmitter::onSelectionChange(OnSelectionChange $event) const {
dispatchEvent("selectionChange", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "item", $event.item);
return $payload;
});
}
} // namespace facebook::react
@@ -0,0 +1,25 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterH.js
*/
#pragma once
#include <react/renderer/components/view/ViewEventEmitter.h>
namespace facebook::react {
class AndroidPopupMenuEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
struct OnSelectionChange {
int item;
};
void onSelectionChange(OnSelectionChange value) const;
};
} // namespace facebook::react
@@ -0,0 +1,25 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsCpp.js
*/
#include "Props.h"
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
namespace facebook::react {
AndroidPopupMenuProps::AndroidPopupMenuProps(
const PropsParserContext &context,
const AndroidPopupMenuProps &sourceProps,
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
menuItems(convertRawProp(context, rawProps, "menuItems", sourceProps.menuItems, {}))
{}
} // namespace facebook::react
@@ -0,0 +1,28 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsH.js
*/
#pragma once
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/core/PropsParserContext.h>
#include <vector>
namespace facebook::react {
class AndroidPopupMenuProps final : public ViewProps {
public:
AndroidPopupMenuProps() = default;
AndroidPopupMenuProps(const PropsParserContext& context, const AndroidPopupMenuProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
std::vector<std::string> menuItems{};
};
} // namespace facebook::react
@@ -0,0 +1,17 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeCpp.js
*/
#include "ShadowNodes.h"
namespace facebook::react {
extern const char AndroidPopupMenuComponentName[] = "AndroidPopupMenu";
} // namespace facebook::react
@@ -0,0 +1,32 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeH.js
*/
#pragma once
#include "EventEmitters.h"
#include "Props.h"
#include "States.h"
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <jsi/jsi.h>
namespace facebook::react {
JSI_EXPORT extern const char AndroidPopupMenuComponentName[];
/*
* `ShadowNode` for <AndroidPopupMenu> component.
*/
using AndroidPopupMenuShadowNode = ConcreteViewShadowNode<
AndroidPopupMenuComponentName,
AndroidPopupMenuProps,
AndroidPopupMenuEventEmitter,
AndroidPopupMenuState>;
} // namespace facebook::react
@@ -0,0 +1,16 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateCpp.js
*/
#include "States.h"
namespace facebook::react {
} // namespace facebook::react
@@ -0,0 +1,34 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateH.js
*/
#pragma once
#ifdef ANDROID
#include <folly/dynamic.h>
#include <react/renderer/mapbuffer/MapBuffer.h>
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
#endif
namespace facebook::react {
class AndroidPopupMenuState {
public:
AndroidPopupMenuState() = default;
#ifdef ANDROID
AndroidPopupMenuState(AndroidPopupMenuState const &previousState, folly::dynamic data){};
folly::dynamic getDynamic() const {
return {};
};
MapBuffer getMapBuffer() const {
return MapBufferBuilder::EMPTY();
};
#endif
};
} // namespace facebook::react
@@ -0,0 +1,56 @@
/*
* 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.popupmenu
import com.facebook.react.BaseReactPackage
import com.facebook.react.ViewManagerOnDemandReactPackage
import com.facebook.react.bridge.ModuleSpec
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.annotations.ReactModuleList
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.uimanager.ViewManager
@ReactModuleList(nativeModules = arrayOf())
class PopupMenuPackage() : BaseReactPackage(), ViewManagerOnDemandReactPackage {
private var viewManagersMap: Map<String, ModuleSpec>? = null
override fun getModule(name: String, context: ReactApplicationContext): NativeModule? {
return null
}
private fun getViewManagersMap(): Map<String, ModuleSpec> {
val viewManagers =
viewManagersMap
?: mapOf(
ReactPopupMenuManager.REACT_CLASS to
ModuleSpec.viewManagerSpec({ ReactPopupMenuManager() }))
viewManagersMap = viewManagers
return viewManagers
}
protected override fun getViewManagers(context: ReactApplicationContext): List<ModuleSpec> {
return ArrayList(getViewManagersMap().values)
}
override fun getViewManagerNames(context: ReactApplicationContext): Collection<String> {
return getViewManagersMap().keys
}
override fun createViewManager(
reactContext: ReactApplicationContext,
viewManagerName: String
): ViewManager<*, *>? {
val spec: ModuleSpec? = getViewManagersMap().get(viewManagerName)
return if (spec != null) (spec.getProvider().get() as ViewManager<*, *>) else null
}
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
return ReactModuleInfoProvider { emptyMap() }
}
}
@@ -5,9 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
@file:Suppress("DEPRECATION") // We want to use RCTEventEmitter for interop purposes
package com.facebook.react.views.popupmenu
package com.facebook.react.popupmenu
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.popupmenu
package com.facebook.react.popupmenu
import android.content.Context
import android.os.Build
@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.popupmenu
package com.facebook.react.popupmenu
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.module.annotations.ReactModule
@@ -0,0 +1,41 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaDelegate.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.BaseViewManagerDelegate;
import com.facebook.react.uimanager.BaseViewManagerInterface;
public class AndroidPopupMenuManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & AndroidPopupMenuManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
public AndroidPopupMenuManagerDelegate(U viewManager) {
super(viewManager);
}
@Override
public void setProperty(T view, String propName, @Nullable Object value) {
switch (propName) {
case "menuItems":
mViewManager.setMenuItems(view, (ReadableArray) value);
break;
default:
super.setProperty(view, propName, value);
}
}
@Override
public void receiveCommand(T view, String commandName, ReadableArray args) {
switch (commandName) {
case "show":
mViewManager.show(view);
break;
}
}
}
@@ -0,0 +1,19 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaInterface.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReadableArray;
public interface AndroidPopupMenuManagerInterface<T extends View> {
void setMenuItems(T view, @Nullable ReadableArray value);
void show(T view);
}
+11
View File
@@ -0,0 +1,11 @@
/**
* 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
*/
export type {default} from './PopupMenuAndroid';
export type {PopupMenuAndroidInstance} from './PopupMenuAndroid';
+12
View File
@@ -0,0 +1,12 @@
/**
* 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
*/
export {default} from './js/PopupMenuAndroid';
export type {PopupMenuAndroidInstance} from './js/PopupMenuAndroid';
@@ -8,13 +8,13 @@
* @flow strict-local
*/
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
import type {RefObject} from 'react';
import type {HostComponent} from 'react-native';
import type {SyntheticEvent} from 'react-native/Libraries/Types/CoreEventTypes';
import PopupMenuAndroidNativeComponent, {
Commands,
} from './PopupMenuAndroidNativeComponent';
} from './PopupMenuAndroidNativeComponent.android';
import nullthrows from 'nullthrows';
import * as React from 'react';
import {useCallback, useImperativeHandle, useRef} from 'react';
@@ -8,7 +8,7 @@
*/
import type * as React from 'react';
import {HostComponent} from '../../../types/public/ReactNativeTypes';
import {HostComponent} from 'react-native';
type PopupMenuAndroidInstance = {
show: () => void;
@@ -12,8 +12,29 @@ import type {RefObject} from 'react';
import type {Node} from 'react';
import * as React from 'react';
import {StyleSheet, View} from 'react-native';
const UnimplementedView = require('../UnimplementedViews/UnimplementedView');
/**
* Common implementation for a simple stubbed view. Simply applies the view's styles to the inner
* View component and renders its children.
*/
class UnimplementedView extends React.Component<{children: Node}> {
render(): React.Node {
return (
<View style={[styles.unimplementedView]}>{this.props.children}</View>
);
}
}
const styles = StyleSheet.create({
unimplementedView: __DEV__
? {
alignSelf: 'flex-start',
borderColor: 'red',
borderWidth: 1,
}
: {},
});
export type PopupMenuAndroidInstance = {
+show: () => void,
@@ -27,7 +48,7 @@ type Props = {
};
function PopupMenuAndroid(props: Props): Node {
return <UnimplementedView />;
return <UnimplementedView>{props.children}</UnimplementedView>;
}
export default PopupMenuAndroid;
@@ -8,16 +8,16 @@
* @format
*/
import type {ViewProps} from '../../../../Libraries/Components/View/ViewPropTypes';
import type {HostComponent} from '../../../../Libraries/Renderer/shims/ReactNativeTypes';
import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes';
import type {
DirectEventHandler,
Int32,
} from '../../../../Libraries/Types/CodegenTypes';
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeCommands from '../../../../Libraries/Utilities/codegenNativeCommands';
import codegenNativeComponent from '../../../../Libraries/Utilities/codegenNativeComponent';
import * as React from 'react';
import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
type PopupMenuSelectionEvent = $ReadOnly<{
item: Int32,
@@ -0,0 +1,42 @@
{
"name": "@react-native/popup-menu-android",
"version": "0.74.1",
"description": "PopupMenu for the Android platform",
"react-native": "js/PopupMenuAndroid",
"source": "js/PopupMenuAndroid",
"files": [
"js",
"android",
"!android/build",
"!**/__tests__",
"!**/__fixtures__",
"!**/__mocks__"
],
"keywords": [
"react-native",
"android"
],
"license": "MIT",
"devDependencies": {
"@react-native/codegen": "*"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
},
"dependencies": {
"nullthrows": "^1.1.1"
},
"codegenConfig": {
"name": "ReactPopupMenuAndroidSpecs",
"type": "components",
"jsSrcsDir": "js",
"outputDir": {
"android": "android"
},
"includesGeneratedCode": true,
"android": {
"javaPackageName": "com.facebook.react.viewmanagers"
}
}
}
@@ -7,6 +7,7 @@
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import "RCTRootViewFactory.h"
@class RCTBridge;
@protocol RCTBridgeDelegate;
@@ -57,9 +58,12 @@ NS_ASSUME_NONNULL_BEGIN
/// The window object, used to render the UViewControllers
@property (nonatomic, strong, nonnull) UIWindow *window;
@property (nonatomic, strong, nullable) RCTBridge *bridge;
@property (nonatomic, nullable) RCTBridge *bridge;
@property (nonatomic, strong, nullable) NSString *moduleName;
@property (nonatomic, strong, nullable) NSDictionary *initialProps;
@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
/**
* It creates a `RCTBridge` using a delegate and some launch options.
@@ -126,13 +130,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setRootView:(UIView *)rootView toRootViewController:(UIViewController *)rootViewController;
/// This method controls whether the App will use RuntimeScheduler. Only applicable in the legacy architecture.
///
/// @return: `YES` to use RuntimeScheduler, `NO` to use JavaScript scheduler. The default value is `YES`.
- (BOOL)runtimeSchedulerEnabled;
@property (nonatomic, strong) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
/// This method returns a map of Component Descriptors and Components classes that needs to be registered in the
/// new renderer. The Component Descriptor is a string which represent the name used in JS to refer to the native
/// component. The default implementation returns an empty dictionary. Subclasses can override this method to register
@@ -39,84 +39,28 @@
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#import <react/runtime/JSRuntimeFactory.h>
@interface RCTAppDelegate () <
RCTTurboModuleManagerDelegate,
RCTComponentViewFactoryComponentProvider,
RCTContextContainerHandling> {
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
}
@interface RCTAppDelegate () <RCTComponentViewFactoryComponentProvider, RCTTurboModuleManagerDelegate>
@end
static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabricEnabled)
{
NSMutableDictionary *mutableProps = [initialProps mutableCopy] ?: [NSMutableDictionary new];
return mutableProps;
}
@interface RCTAppDelegate () <RCTCxxBridgeDelegate> {
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
}
@end
@implementation RCTAppDelegate {
RCTHost *_reactHost;
}
- (instancetype)init
{
if (self = [super init]) {
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
}
return self;
}
@implementation RCTAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTSetNewArchEnabled([self newArchEnabled]);
BOOL enableTM = self.turboModuleEnabled;
BOOL fabricEnabled = self.fabricEnabled;
BOOL enableBridgeless = self.bridgelessEnabled;
RCTAppSetupPrepareApp(application, self.turboModuleEnabled);
NSDictionary *initProps = updateInitialProps([self prepareInitialProps], fabricEnabled);
self.rootViewFactory = [self createRCTRootViewFactory];
RCTAppSetupPrepareApp(application, enableTM);
UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName
initialProperties:self.initialProps
launchOptions:launchOptions];
UIView *rootView;
if (enableBridgeless) {
// Enable native view config interop only if both bridgeless mode and Fabric is enabled.
RCTSetUseNativeViewConfigsInBridgelessMode(fabricEnabled);
// Enable TurboModule interop by default in Bridgeless mode
RCTEnableTurboModuleInterop(YES);
RCTEnableTurboModuleInteropBridgeProxy(YES);
[self createReactHost];
if (self.newArchEnabled || self.fabricEnabled) {
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
RCTFabricSurface *surface = [_reactHost createSurfaceWithModuleName:self.moduleName initialProperties:initProps];
RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView = [[RCTSurfaceHostingProxyRootView alloc]
initWithSurface:surface
sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];
rootView = (RCTRootView *)surfaceHostingProxyRootView;
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
if (!self.bridge) {
self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions];
}
if ([self newArchEnabled]) {
self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge
contextContainer:_contextContainer];
self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}
rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps];
}
[self _logWarnIfCreateRootViewWithBridgeIsOverridden];
[self customizeRootView:(RCTRootView *)rootView];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [self createRootViewController];
[self setRootView:rootView toRootViewController:rootViewController];
@@ -139,26 +83,15 @@ static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabri
return nil;
}
- (NSDictionary *)prepareInitialProps
{
return self.initialProps;
}
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
{
return [[RCTBridge alloc] initWithDelegate:delegate launchOptions:launchOptions];
}
- (void)customizeRootView:(RCTRootView *)rootView
{
// Override point for customization after application launch.
}
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initProps:(NSDictionary *)initProps
{
[self _logWarnIfCreateRootViewWithBridgeIsOverridden];
BOOL enableFabric = self.fabricEnabled;
UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric);
@@ -192,9 +125,9 @@ static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabri
rootViewController.view = rootView;
}
- (BOOL)runtimeSchedulerEnabled
- (void)customizeRootView:(RCTRootView *)rootView
{
return YES;
// Override point for customization after application launch.
}
#pragma mark - UISceneDelegate
@@ -207,25 +140,6 @@ static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabri
[[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self];
}
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
if ([self newArchEnabled]) {
std::shared_ptr<facebook::react::CallInvoker> callInvoker =
std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
RCTTurboModuleManager *turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:callInvoker];
_contextContainer->erase("RuntimeScheduler");
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
return RCTAppSetupDefaultJsExecutorFactory(bridge, turboModuleManager, _runtimeScheduler);
} else {
return RCTAppSetupJsExecutorFactoryForOldArch(bridge, _runtimeScheduler);
}
}
#pragma mark - New Arch Enabled settings
- (BOOL)newArchEnabled
@@ -252,11 +166,33 @@ static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabri
return [self newArchEnabled];
}
#pragma mark - RCTComponentViewFactoryComponentProvider
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
- (NSURL *)bundleURL
{
return @{};
[NSException raise:@"RCTAppDelegate::bundleURL not implemented"
format:@"Subclasses must implement a valid getBundleURL method"];
return nullptr;
}
#pragma mark - Bridge and Bridge Adapter properties
- (RCTBridge *)bridge
{
return self.rootViewFactory.bridge;
}
- (RCTSurfacePresenterBridgeAdapter *)bridgeAdapter
{
return self.rootViewFactory.bridgeAdapter;
}
- (void)setBridge:(RCTBridge *)bridge
{
self.rootViewFactory.bridge = bridge;
}
- (void)setBridgeAdapter:(RCTSurfacePresenterBridgeAdapter *)bridgeAdapter
{
self.rootViewFactory.bridgeAdapter = bridgeAdapter;
}
#pragma mark - RCTTurboModuleManagerDelegate
@@ -288,43 +224,33 @@ static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabri
return RCTAppSetupDefaultModuleFromClass(moduleClass);
}
#pragma mark - New Arch Utilities
#pragma mark - RCTComponentViewFactoryComponentProvider
- (void)createReactHost
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
return @{};
}
- (RCTRootViewFactory *)createRCTRootViewFactory
{
RCTRootViewFactoryConfiguration *configuration =
[[RCTRootViewFactoryConfiguration alloc] initWithBundleURL:self.bundleURL
newArchEnabled:self.fabricEnabled
turboModuleEnabled:self.turboModuleEnabled
bridgelessEnabled:self.bridgelessEnabled];
__weak __typeof(self) weakSelf = self;
_reactHost = [[RCTHost alloc] initWithBundleURL:[self bundleURL]
hostDelegate:nil
turboModuleManagerDelegate:self
jsEngineProvider:^std::shared_ptr<facebook::react::JSRuntimeFactory>() {
return [weakSelf createJSRuntimeFactory];
}];
[_reactHost setBundleURLProvider:^NSURL *() {
return [weakSelf bundleURL];
}];
[_reactHost setContextContainerHandler:self];
[_reactHost start];
}
configuration.createRootViewWithBridge = ^UIView *(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps)
{
return [weakSelf createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps];
};
- (std::shared_ptr<facebook::react::JSRuntimeFactory>)createJSRuntimeFactory
{
#if USE_HERMES
return std::make_shared<facebook::react::RCTHermesInstance>(_reactNativeConfig, nullptr);
#else
return std::make_shared<facebook::react::RCTJscInstance>();
#endif
}
configuration.createBridgeWithDelegate = ^RCTBridge *(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions)
{
return [weakSelf createBridgeWithDelegate:delegate launchOptions:launchOptions];
};
- (void)didCreateContextContainer:(std::shared_ptr<facebook::react::ContextContainer>)contextContainer
{
contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
}
- (NSURL *)bundleURL
{
[NSException raise:@"RCTAppDelegate::bundleURL not implemented"
format:@"Subclasses must implement a valid getBundleURL method"];
return nullptr;
return [[RCTRootViewFactory alloc] initWithConfiguration:configuration andTurboModuleManagerDelegate:self];
}
@end
@@ -0,0 +1,123 @@
/*
* 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 <React/RCTBridge.h>
#import <React/RCTRootView.h>
#import <React/RCTUtils.h>
@protocol RCTCxxBridgeDelegate;
@protocol RCTComponentViewFactoryComponentProvider;
@protocol RCTTurboModuleManagerDelegate;
@class RCTBridge;
@class RCTRootView;
@class RCTSurfacePresenterBridgeAdapter;
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Blocks' definitions
typedef UIView *_Nonnull (
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
typedef RCTBridge *_Nonnull (
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
#pragma mark - RCTRootViewFactory Configuration
@interface RCTRootViewFactoryConfiguration : NSObject
/// This property controls whether the App will use the Fabric renderer of the New Architecture or not.
@property (nonatomic, assign, readonly) BOOL fabricEnabled;
/// This property controls whether React Native's new initialization layer is enabled.
@property (nonatomic, assign, readonly) BOOL bridgelessEnabled;
/// This method controls whether the `turboModules` feature of the New Architecture is turned on or off
@property (nonatomic, assign, readonly) BOOL turboModuleEnabled;
/// Return the bundle URL for the main bundle.
@property (nonatomic) NSURL *bundleURL;
/**
* Use this method to initialize a new instance of `RCTRootViewFactoryConfiguration` by passing a `bundleURL`
*
* Which is the location of the JavaScript source file. When running from the packager
* this should be an absolute URL, e.g. `http://localhost:8081/index.ios.bundle`.
* When running from a locally bundled JS file, this should be a `file://` url
* pointing to a path inside the app resources, e.g. `file://.../main.jsbundle`.
*
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
newArchEnabled:(BOOL)newArchEnabled
turboModuleEnabled:(BOOL)turboModuleEnabled
bridgelessEnabled:(BOOL)bridgelessEnabled;
/**
* Block that allows to override logic of creating root view instance.
* It creates a `UIView` starting from a bridge, a module name and a set of initial properties.
* By default, it is invoked using the bridge created by `RCTCreateBridgeWithDelegateBlock` (or the default
* implementation) and the `moduleName` variable comes from `viewWithModuleName:initialProperties:launchOptions` of
* `RCTRootViewFactory`.
*
* @parameter: bridge - an instance of the `RCTBridge` object.
* @parameter: moduleName - the name of the app, used by Metro to resolve the module.
* @parameter: initProps - a set of initial properties.
*
* @returns: a UIView properly configured with a bridge for React Native.
*/
@property (nonatomic, nullable) RCTCreateRootViewWithBridgeBlock createRootViewWithBridge;
/**
* Block that allows to override default behavior of creating bridge.
* It should return `RCTBridge` using a delegate and some launch options.
*
* By default, it is invoked passing `self` as a delegate.
*
* @parameter: delegate - an object that implements the `RCTBridgeDelegate` protocol.
* @parameter: launchOptions - a dictionary with a set of options.
*
* @returns: a newly created instance of RCTBridge.
*/
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;
@end
#pragma mark - RCTRootViewFactory
/**
* The RCTRootViewFactory is an utility class that encapsulates the logic of creating a new RCTRootView based on the
* current state of the environment. It allows you to initialize your app root view for old architecture, new
* architecture and bridgless mode.
*
* This class is used to initalize rootView in RCTAppDelegate, but you can also use it separately.
*
* Create a new instance of this class (make sure to retain it) and call the
* `viewWithModuleName:initialProperties:launchOptions` method to create new RCTRootView.
*/
@interface RCTRootViewFactory : NSObject
@property (nonatomic, strong, nullable) RCTBridge *bridge;
@property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate;
/**
* This method can be used to create new RCTRootViews on demand.
*
* @parameter: moduleName - the name of the app, used by Metro to resolve the module.
* @parameter: initialProperties - a set of initial properties.
* @parameter: moduleName - a dictionary with a set of options.
*/
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *__nullable)initialProperties
launchOptions:(NSDictionary *__nullable)launchOptions;
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *__nullable)initialProperties;
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,253 @@
/*
* 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 "RCTRootViewFactory.h"
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTLog.h>
#import <React/RCTRootView.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <React/RCTUtils.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import "RCTAppDelegate.h"
#import "RCTAppSetupUtils.h"
#if RN_DISABLE_OSS_PLUGIN_HEADER
#import <RCTTurboModulePlugin/RCTTurboModulePlugin.h>
#else
#import <React/CoreModulesPlugins.h>
#endif
#import <React/RCTBundleURLProvider.h>
#import <React/RCTComponentViewFactory.h>
#import <React/RCTComponentViewProtocol.h>
#import <React/RCTFabricSurface.h>
#import <React/RCTSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <ReactCommon/RCTContextContainerHandling.h>
#if USE_HERMES
#import <ReactCommon/RCTHermesInstance.h>
#else
#import <ReactCommon/RCTJscInstance.h>
#endif
#import <ReactCommon/RCTHost+Internal.h>
#import <ReactCommon/RCTHost.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <react/config/ReactNativeConfig.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#import <react/runtime/JSRuntimeFactory.h>
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabricEnabled)
{
NSMutableDictionary *mutableProps = initialProps != NULL ? [initialProps mutableCopy] : [NSMutableDictionary new];
// Hardcoding the Concurrent Root as it it not recommended to
// have the concurrentRoot turned off when Fabric is enabled.
mutableProps[kRNConcurrentRoot] = @(isFabricEnabled);
return mutableProps;
}
@implementation RCTRootViewFactoryConfiguration
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
newArchEnabled:(BOOL)newArchEnabled
turboModuleEnabled:(BOOL)turboModuleEnabled
bridgelessEnabled:(BOOL)bridgelessEnabled
{
if (self = [super init]) {
_bundleURL = bundleURL;
_fabricEnabled = newArchEnabled;
_turboModuleEnabled = turboModuleEnabled;
_bridgelessEnabled = bridgelessEnabled;
}
return self;
}
@end
@interface RCTRootViewFactory () <RCTContextContainerHandling> {
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
}
@end
@interface RCTRootViewFactory () <RCTCxxBridgeDelegate> {
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
}
@end
@implementation RCTRootViewFactory {
RCTHost *_reactHost;
RCTRootViewFactoryConfiguration *_configuration;
__weak id<RCTTurboModuleManagerDelegate> _turboModuleManagerDelegate;
}
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
{
if (self = [super init]) {
_configuration = configuration;
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
_turboModuleManagerDelegate = turboModuleManagerDelegate;
}
return self;
}
- (UIView *)viewWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary *)initialProperties
{
return [self viewWithModuleName:moduleName initialProperties:initialProperties launchOptions:nil];
}
- (UIView *)viewWithModuleName:(NSString *)moduleName
{
return [self viewWithModuleName:moduleName initialProperties:nil launchOptions:nil];
}
- (UIView *)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions
{
NSDictionary *initProps = updateInitialProps(initialProperties, self->_configuration.fabricEnabled);
if (self->_configuration.bridgelessEnabled) {
// Enable native view config interop only if both bridgeless mode and Fabric is enabled.
RCTSetUseNativeViewConfigsInBridgelessMode(self->_configuration.fabricEnabled);
// Enable TurboModule interop by default in Bridgeless mode
RCTEnableTurboModuleInterop(YES);
RCTEnableTurboModuleInteropBridgeProxy(YES);
[self createReactHostIfNeeded];
RCTFabricSurface *surface = [_reactHost createSurfaceWithModuleName:moduleName initialProperties:initProps];
RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView = [[RCTSurfaceHostingProxyRootView alloc]
initWithSurface:surface
sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];
return surfaceHostingProxyRootView;
}
[self createBridgeIfNeeded:launchOptions];
[self createBridgeAdapterIfNeeded];
if (self->_configuration.createRootViewWithBridge != nil) {
return self->_configuration.createRootViewWithBridge(self.bridge, moduleName, initProps);
}
return [self createRootViewWithBridge:self.bridge moduleName:moduleName initProps:initProps];
}
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
{
return [[RCTBridge alloc] initWithDelegate:delegate launchOptions:launchOptions];
}
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initProps:(NSDictionary *)initProps
{
BOOL enableFabric = self->_configuration.fabricEnabled;
UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric);
rootView.backgroundColor = [UIColor systemBackgroundColor];
return rootView;
}
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
if (RCTIsNewArchEnabled()) {
std::shared_ptr<facebook::react::CallInvoker> callInvoker =
std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
RCTTurboModuleManager *turboModuleManager =
[[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:_turboModuleManagerDelegate
jsInvoker:callInvoker];
_contextContainer->erase("RuntimeScheduler");
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
return RCTAppSetupDefaultJsExecutorFactory(bridge, turboModuleManager, _runtimeScheduler);
} else {
return RCTAppSetupJsExecutorFactoryForOldArch(bridge, _runtimeScheduler);
}
}
- (void)createBridgeIfNeeded:(NSDictionary *)launchOptions
{
if (self.bridge != nil) {
return;
}
if (self->_configuration.createBridgeWithDelegate != nil) {
self.bridge = self->_configuration.createBridgeWithDelegate(self, launchOptions);
} else {
self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions];
}
}
- (void)createBridgeAdapterIfNeeded
{
if (!self->_configuration.fabricEnabled || self.bridgeAdapter) {
return;
}
self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge
contextContainer:_contextContainer];
self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;
}
#pragma mark - New Arch Utilities
- (void)createReactHostIfNeeded
{
if (_reactHost) {
return;
}
__weak __typeof(self) weakSelf = self;
_reactHost = [[RCTHost alloc] initWithBundleURL:[self bundleURL]
hostDelegate:nil
turboModuleManagerDelegate:_turboModuleManagerDelegate
jsEngineProvider:^std::shared_ptr<facebook::react::JSRuntimeFactory>() {
return [weakSelf createJSRuntimeFactory];
}];
[_reactHost setBundleURLProvider:^NSURL *() {
return [weakSelf bundleURL];
}];
[_reactHost setContextContainerHandler:self];
[_reactHost start];
}
- (std::shared_ptr<facebook::react::JSRuntimeFactory>)createJSRuntimeFactory
{
#if USE_HERMES
return std::make_shared<facebook::react::RCTHermesInstance>(_reactNativeConfig, nullptr);
#else
return std::make_shared<facebook::react::RCTJscInstance>();
#endif
}
- (void)didCreateContextContainer:(std::shared_ptr<facebook::react::ContextContainer>)contextContainer
{
contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
return [self bundleURL];
}
- (NSURL *)bundleURL
{
return self->_configuration.bundleURL;
}
@end
@@ -1,13 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
export * from '../../../src/private/specs/components/PopupMenuAndroidNativeComponent';
import PopupMenuAndroidNativeComponent from '../../../src/private/specs/components/PopupMenuAndroidNativeComponent';
export default PopupMenuAndroidNativeComponent;
@@ -144,6 +144,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
borderTopLeftRadius: true,
borderTopRightRadius: true,
borderTopStartRadius: true,
cursor: true,
opacity: true,
pointerEvents: true,
+3 -3
View File
@@ -14,10 +14,10 @@ const version: $ReadOnly<{
patch: number,
prerelease: string | null,
}> = {
major: 1000,
minor: 0,
major: 0,
minor: 74,
patch: 0,
prerelease: null,
prerelease: 'rc.3',
};
module.exports = {version};
-1
View File
@@ -308,7 +308,6 @@ export type Props<ItemT> = {
* Also inherits [ScrollView Props](docs/scrollview.html#props), unless it is nested in another FlatList of same orientation.
*/
class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
props: Props<ItemT>;
/**
* Scrolls to the end of the content. May be janky without `getItemLayout` prop.
*/
@@ -1020,6 +1020,54 @@ Please follow the instructions at: fburl.com/rn-remote-assets`,
});
});
it('detects a component stack for ts, tsx, jsx, and js files', () => {
expect(
parseLogBoxLog([
'Some kind of message\n in MyTSComponent (at MyTSXComponent.ts:1)\n in MyTSXComponent (at MyTSCComponent.tsx:1)\n in MyJSXComponent (at MyJSXComponent.jsx:1)\n in MyJSComponent (at MyJSComponent.js:1)',
]),
).toEqual({
componentStack: [
{
content: 'MyTSComponent',
fileName: 'MyTSXComponent.ts',
location: {
column: -1,
row: 1,
},
},
{
content: 'MyTSXComponent',
fileName: 'MyTSCComponent.tsx',
location: {
column: -1,
row: 1,
},
},
{
content: 'MyJSXComponent',
fileName: 'MyJSXComponent.jsx',
location: {
column: -1,
row: 1,
},
},
{
content: 'MyJSComponent',
fileName: 'MyJSComponent.js',
location: {
column: -1,
row: 1,
},
},
],
category: 'Some kind of message',
message: {
content: 'Some kind of message',
substitutions: [],
},
});
});
it('detects a component stack in the first argument (JSC)', () => {
expect(
parseLogBoxLog([
@@ -192,7 +192,7 @@ export function parseComponentStack(message: string): ComponentStack {
if (!s) {
return null;
}
const match = s.match(/(.*) \(at (.*\.js):([\d]+)\)/);
const match = s.match(/(.*) \(at (.*\.(?:js|jsx|ts|tsx)):([\d]+)\)/);
if (!match) {
return null;
}
@@ -27,6 +27,8 @@ export type DimensionValue =
type AnimatableNumericValue = number | Animated.AnimatedNode;
type AnimatableStringValue = string | Animated.AnimatedNode;
export type CursorValue = 'auto' | 'pointer';
/**
* Flex Prop Types
* @see https://reactnative.dev/docs/flexbox
@@ -274,6 +276,7 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
* Controls whether the View can be the target of touch events.
*/
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto' | undefined;
cursor?: CursorValue | undefined;
}
export type FontVariant =
@@ -403,4 +406,5 @@ export interface ImageStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
tintColor?: ColorValue | undefined;
opacity?: AnimatableNumericValue | undefined;
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | undefined;
cursor?: CursorValue | undefined;
}
@@ -37,6 +37,8 @@ export type EdgeInsetsValue = {
export type DimensionValue = number | string | 'auto' | AnimatedNode | null;
export type AnimatableNumericValue = number | AnimatedNode;
export type CursorValue = 'auto' | 'pointer';
/**
* React Native's layout system is based on Flexbox and is powered both
* on iOS and Android by an open source project called `Yoga`:
@@ -729,6 +731,7 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
opacity?: AnimatableNumericValue,
elevation?: number,
pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only',
cursor?: CursorValue,
}>;
export type ____ViewStyle_Internal = $ReadOnly<{
@@ -1773,41 +1773,6 @@ declare export default typeof NativeKeyboardObserver;
"
`;
exports[`public API should not change unintentionally Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.android.js 1`] = `
"export type PopupMenuAndroidInstance = {
+show: () => void,
};
type Props = {
menuItems: $ReadOnlyArray<string>,
onSelectionChange: (number) => void,
children: React.Node,
instanceRef: RefObject<?PopupMenuAndroidInstance>,
};
declare export default function PopupMenuAndroid(Props): React.Node;
"
`;
exports[`public API should not change unintentionally Libraries/Components/PopupMenuAndroid/PopupMenuAndroid.js 1`] = `
"export type PopupMenuAndroidInstance = {
+show: () => void,
};
type Props = {
menuItems: $ReadOnlyArray<string>,
onSelectionChange: (number) => void,
children: Node,
instanceRef: RefObject<?PopupMenuAndroidInstance>,
};
declare function PopupMenuAndroid(props: Props): Node;
declare export default typeof PopupMenuAndroid;
"
`;
exports[`public API should not change unintentionally Libraries/Components/PopupMenuAndroid/PopupMenuAndroidNativeComponent.js 1`] = `
"export * from \\"../../../src/private/specs/components/PopupMenuAndroidNativeComponent\\";
declare export default typeof PopupMenuAndroidNativeComponent;
"
`;
exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
@@ -7458,6 +7423,7 @@ export type EdgeInsetsValue = {
};
export type DimensionValue = number | string | \\"auto\\" | AnimatedNode | null;
export type AnimatableNumericValue = number | AnimatedNode;
export type CursorValue = \\"auto\\" | \\"pointer\\";
type ____LayoutStyle_Internal = $ReadOnly<{
display?: \\"none\\" | \\"flex\\",
width?: DimensionValue,
@@ -7608,6 +7574,7 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
opacity?: AnimatableNumericValue,
elevation?: number,
pointerEvents?: \\"auto\\" | \\"none\\" | \\"box-none\\" | \\"box-only\\",
cursor?: CursorValue,
}>;
export type ____ViewStyle_Internal = $ReadOnly<{
...____ViewStyle_InternalCore,
@@ -9026,7 +8993,6 @@ declare module.exports: {
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get PopupMenuAndroid(): PopupMenuAndroid,
get Modal(): Modal,
get Pressable(): Pressable,
get ProgressBarAndroid(): ProgressBarAndroid,
@@ -11,6 +11,7 @@
#import <React/RCTAnimationType.h>
#import <React/RCTBorderCurve.h>
#import <React/RCTBorderStyle.h>
#import <React/RCTCursor.h>
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
#import <React/RCTPointerEvents.h>
@@ -80,6 +81,8 @@ typedef NSURL RCTFileURL;
+ (UIBarStyle)UIBarStyle:(id)json __deprecated;
#endif
+ (RCTCursor)RCTCursor:(id)json;
+ (CGFloat)CGFloat:(id)json;
+ (CGPoint)CGPoint:(id)json;
+ (CGSize)CGSize:(id)json;
@@ -545,6 +545,15 @@ RCT_ENUM_CONVERTER(
UIBarStyleDefault,
integerValue)
RCT_ENUM_CONVERTER(
RCTCursor,
(@{
@"auto" : @(RCTCursorAuto),
@"pointer" : @(RCTCursorPointer),
}),
RCTCursorAuto,
integerValue)
static void convertCGStruct(const char *type, NSArray *fields, CGFloat *result, id json)
{
NSUInteger count = fields.count;
@@ -21,10 +21,10 @@ NSDictionary* RCTGetReactNativeVersion(void)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^(void){
__rnVersion = @{
RCTVersionMajor: @(1000),
RCTVersionMinor: @(0),
RCTVersionMajor: @(0),
RCTVersionMinor: @(74),
RCTVersionPatch: @(0),
RCTVersionPrerelease: [NSNull null],
RCTVersionPrerelease: @"rc.3",
};
});
return __rnVersion;
@@ -274,7 +274,13 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
- (void)reload
{
[_actionDelegate reloadFromRedBoxController:self];
if (_actionDelegate != nil) {
[_actionDelegate reloadFromRedBoxController:self];
} else {
// In bridgeless mode `RCTRedBox` gets deallocated, we need to notify listeners anyway.
RCTTriggerReloadCommandListeners(@"Redbox");
[self dismiss];
}
}
- (void)showExtraDataViewController
@@ -257,6 +257,11 @@ using namespace facebook::react;
self.layer.doubleSided = newViewProps.backfaceVisibility == BackfaceVisibility::Visible;
}
// `cursor`
if (oldViewProps.cursor != newViewProps.cursor) {
needsInvalidateLayer = YES;
}
// `shouldRasterize`
if (oldViewProps.shouldRasterize != newViewProps.shouldRasterize) {
self.layer.shouldRasterize = newViewProps.shouldRasterize;
@@ -592,6 +597,33 @@ static RCTBorderStyle RCTBorderStyleFromBorderStyle(BorderStyle borderStyle)
layer.shadowPath = nil;
}
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 170000 /* __IPHONE_17_0 */
// Stage 1.5. Cursor / Hover Effects
if (@available(iOS 17.0, *)) {
UIHoverStyle *hoverStyle = nil;
if (_props->cursor == Cursor::Pointer) {
const RCTCornerInsets cornerInsets =
RCTGetCornerInsets(RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), UIEdgeInsetsZero);
#if TARGET_OS_IOS
// Due to an Apple bug, it seems on iOS, UIShapes made with `[UIShape shapeWithBezierPath:]`
// evaluate their shape on the superviews' coordinate space. This leads to the hover shape
// rendering incorrectly on iOS, iOS apps in compatibility mode on visionOS, but not on visionOS.
// To work around this, for iOS, we can calculate the border path based on `view.frame` (the
// superview's coordinate space) instead of view.bounds.
CGPathRef borderPath = RCTPathCreateWithRoundedRect(self.frame, cornerInsets, NULL);
#else // TARGET_OS_VISION
CGPathRef borderPath = RCTPathCreateWithRoundedRect(self.bounds, cornerInsets, NULL);
#endif
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:borderPath];
CGPathRelease(borderPath);
UIShape *shape = [UIShape shapeWithBezierPath:bezierPath];
hoverStyle = [UIHoverStyle styleWithEffect:[UIHoverAutomaticEffect effect] shape:shape];
}
[self setHoverStyle:hoverStyle];
}
#endif
// Stage 2. Border Rendering
const bool useCoreAnimationBorderRendering =
borderMetrics.borderColors.isUniform() && borderMetrics.borderWidths.isUniform() &&
@@ -0,0 +1,13 @@
/*
* 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>
typedef NS_ENUM(NSInteger, RCTCursor) {
RCTCursorAuto,
RCTCursorPointer,
};
@@ -10,6 +10,7 @@
#import <React/RCTBorderCurve.h>
#import <React/RCTBorderStyle.h>
#import <React/RCTComponent.h>
#import <React/RCTCursor.h>
#import <React/RCTPointerEvents.h>
extern const UIAccessibilityTraits SwitchAccessibilityTrait;
@@ -120,6 +121,8 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
*/
@property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;
@property (nonatomic, assign) RCTCursor cursor;
/**
* (Experimental and unused for Paper) Pointer event handlers.
*/
@@ -136,6 +136,7 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
_borderCurve = RCTBorderCurveCircular;
_borderStyle = RCTBorderStyleSolid;
_hitTestEdgeInsets = UIEdgeInsetsZero;
_cursor = RCTCursorAuto;
_backgroundColor = super.backgroundColor;
}
@@ -796,6 +797,8 @@ static CGFloat RCTDefaultIfNegativeTo(CGFloat defaultValue, CGFloat x)
RCTUpdateShadowPathForView(self);
RCTUpdateHoverStyleForView(self);
const RCTCornerRadii cornerRadii = [self cornerRadii];
const UIEdgeInsets borderInsets = [self bordersAsInsets];
const RCTBorderColors borderColors = [self borderColorsWithTraitCollection:self.traitCollection];
@@ -891,6 +894,33 @@ static void RCTUpdateShadowPathForView(RCTView *view)
}
}
static void RCTUpdateHoverStyleForView(RCTView *view)
{
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 170000 /* __IPHONE_17_0 */
if (@available(iOS 17.0, *)) {
UIHoverStyle *hoverStyle = nil;
if ([view cursor] == RCTCursorPointer) {
const RCTCornerRadii cornerRadii = [view cornerRadii];
const RCTCornerInsets cornerInsets = RCTGetCornerInsets(cornerRadii, UIEdgeInsetsZero);
#if TARGET_OS_IOS
// Due to an Apple bug, it seems on iOS, `[UIShape shapeWithBezierPath:]` needs to
// be calculated in the superviews' coordinate space (view.frame). This is not true
// on other platforms like visionOS.
CGPathRef borderPath = RCTPathCreateWithRoundedRect(view.frame, cornerInsets, NULL);
#else // TARGET_OS_VISION
CGPathRef borderPath = RCTPathCreateWithRoundedRect(view.bounds, cornerInsets, NULL);
#endif
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:borderPath];
CGPathRelease(borderPath);
UIShape *shape = [UIShape shapeWithBezierPath:bezierPath];
hoverStyle = [UIHoverStyle styleWithEffect:[UIHoverHighlightEffect effect] shape:shape];
}
[view setHoverStyle:hoverStyle];
}
#endif
}
- (void)updateClippingForLayer:(CALayer *)layer
{
CALayer *mask = nil;
@@ -13,6 +13,7 @@
#import "RCTBridge.h"
#import "RCTConvert+Transform.h"
#import "RCTConvert.h"
#import "RCTCursor.h"
#import "RCTLog.h"
#import "RCTShadowView.h"
#import "RCTUIManager.h"
@@ -195,6 +196,7 @@ RCT_REMAP_VIEW_PROPERTY(testID, reactAccessibilityElement.accessibilityIdentifie
RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
RCT_REMAP_VIEW_PROPERTY(backfaceVisibility, layer.doubleSided, css_backface_visibility_t)
RCT_EXPORT_VIEW_PROPERTY(cursor, RCTCursor)
RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat)
RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor)
RCT_REMAP_VIEW_PROPERTY(shadowOffset, layer.shadowOffset, CGSize)
@@ -196,6 +196,7 @@ public abstract interface class com/facebook/react/ReactHost {
public abstract fun getJsEngineResolutionAlgorithm ()Lcom/facebook/react/JSEngineResolutionAlgorithm;
public abstract fun getLifecycleState ()Lcom/facebook/react/common/LifecycleState;
public abstract fun getReactQueueConfiguration ()Lcom/facebook/react/bridge/queue/ReactQueueConfiguration;
public abstract fun onActivityResult (Landroid/app/Activity;IILandroid/content/Intent;)V
public abstract fun onBackPressed ()Z
public abstract fun onHostDestroy ()V
public abstract fun onHostDestroy (Landroid/app/Activity;)V
@@ -322,7 +323,7 @@ public abstract class com/facebook/react/ReactPackageTurboModuleManagerDelegate
protected fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/util/List;Lcom/facebook/jni/HybridData;)V
public fun getEagerInitModuleNames ()Ljava/util/List;
public fun getLegacyModule (Ljava/lang/String;)Lcom/facebook/react/bridge/NativeModule;
public fun getModule (Ljava/lang/String;)Lcom/facebook/react/internal/turbomodule/core/interfaces/TurboModule;
public fun getModule (Ljava/lang/String;)Lcom/facebook/react/turbomodule/core/interfaces/TurboModule;
public fun unstable_enableSyncVoidMethods ()Z
public fun unstable_isLegacyModuleRegistered (Ljava/lang/String;)Z
public fun unstable_isModuleRegistered (Ljava/lang/String;)Z
@@ -2856,6 +2857,7 @@ public class com/facebook/react/module/model/ReactModuleInfo {
public fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZ)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZZ)V
public fun canOverrideExistingModule ()Z
public static fun classIsTurboModule (Ljava/lang/Class;)Z
public fun className ()Ljava/lang/String;
public fun hasConstants ()Z
public fun isCxxModule ()Z
@@ -3199,7 +3201,7 @@ public class com/facebook/react/modules/dialog/DialogModule : com/facebook/fbrea
public fun showAlert (Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V
}
public class com/facebook/react/modules/fresco/FrescoModule : com/facebook/react/bridge/ReactContextBaseJavaModule, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/internal/turbomodule/core/interfaces/TurboModule, com/facebook/react/modules/common/ModuleDataCleaner$Cleanable {
public class com/facebook/react/modules/fresco/FrescoModule : com/facebook/react/bridge/ReactContextBaseJavaModule, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/modules/common/ModuleDataCleaner$Cleanable, com/facebook/react/turbomodule/core/interfaces/TurboModule {
public static final field NAME Ljava/lang/String;
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/imagepipeline/core/ImagePipeline;Z)V
@@ -3440,7 +3442,7 @@ public class com/facebook/react/modules/systeminfo/AndroidInfoHelpers {
public static fun getServerHost (Ljava/lang/Integer;)Ljava/lang/String;
}
public class com/facebook/react/modules/systeminfo/AndroidInfoModule : com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec, com/facebook/react/internal/turbomodule/core/interfaces/TurboModule {
public class com/facebook/react/modules/systeminfo/AndroidInfoModule : com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec, com/facebook/react/turbomodule/core/interfaces/TurboModule {
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun getAndroidID ()Ljava/lang/String;
public fun getTypedExportedConstants ()Ljava/util/Map;
@@ -3601,6 +3603,7 @@ public class com/facebook/react/runtime/ReactHostImpl : com/facebook/react/React
public fun getLifecycleState ()Lcom/facebook/react/common/LifecycleState;
public fun getMemoryPressureRouter ()Lcom/facebook/react/MemoryPressureRouter;
public fun getReactQueueConfiguration ()Lcom/facebook/react/bridge/queue/ReactQueueConfiguration;
public fun onActivityResult (Landroid/app/Activity;IILandroid/content/Intent;)V
public fun onBackPressed ()Z
public fun onHostDestroy ()V
public fun onHostDestroy (Landroid/app/Activity;)V
@@ -3806,7 +3809,9 @@ public abstract interface class com/facebook/react/turbomodule/core/interfaces/C
public abstract interface class com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder {
}
public abstract interface class com/facebook/react/turbomodule/core/interfaces/TurboModule : com/facebook/react/internal/turbomodule/core/interfaces/TurboModule {
public abstract interface class com/facebook/react/turbomodule/core/interfaces/TurboModule {
public abstract fun initialize ()V
public abstract fun invalidate ()V
}
public abstract class com/facebook/react/uimanager/BaseViewManager : com/facebook/react/uimanager/ViewManager, android/view/View$OnLayoutChangeListener, com/facebook/react/uimanager/BaseViewManagerInterface {
@@ -5673,17 +5678,6 @@ public abstract interface class com/facebook/react/viewmanagers/AndroidHorizonta
public abstract fun setRemoveClippedSubviews (Landroid/view/View;Z)V
}
public class com/facebook/react/viewmanagers/AndroidPopupMenuManagerDelegate : com/facebook/react/uimanager/BaseViewManagerDelegate {
public fun <init> (Lcom/facebook/react/uimanager/BaseViewManagerInterface;)V
public fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public fun setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
}
public abstract interface class com/facebook/react/viewmanagers/AndroidPopupMenuManagerInterface {
public abstract fun setMenuItems (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V
public abstract fun show (Landroid/view/View;)V
}
public class com/facebook/react/viewmanagers/AndroidProgressBarManagerDelegate : com/facebook/react/uimanager/BaseViewManagerDelegate {
public fun <init> (Lcom/facebook/react/uimanager/BaseViewManagerInterface;)V
public fun setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
@@ -6153,47 +6147,6 @@ public abstract interface class com/facebook/react/views/modal/ReactModalHostVie
public abstract fun onRequestClose (Landroid/content/DialogInterface;)V
}
public final class com/facebook/react/views/popupmenu/PopupMenuSelectionEvent : com/facebook/react/uimanager/events/Event {
public static final field Companion Lcom/facebook/react/views/popupmenu/PopupMenuSelectionEvent$Companion;
public static final field EVENT_NAME Ljava/lang/String;
public fun <init> (III)V
public fun dispatch (Lcom/facebook/react/uimanager/events/RCTEventEmitter;)V
public fun getEventName ()Ljava/lang/String;
}
public final class com/facebook/react/views/popupmenu/PopupMenuSelectionEvent$Companion {
}
public final class com/facebook/react/views/popupmenu/ReactPopupMenuContainer : android/widget/FrameLayout {
public fun <init> (Landroid/content/Context;)V
public final fun setMenuItems (Lcom/facebook/react/bridge/ReadableArray;)V
public final fun showPopupMenu ()V
}
public final class com/facebook/react/views/popupmenu/ReactPopupMenuManager : com/facebook/react/uimanager/ViewGroupManager, com/facebook/react/viewmanagers/AndroidPopupMenuManagerInterface {
public static final field Companion Lcom/facebook/react/views/popupmenu/ReactPopupMenuManager$Companion;
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
public fun getName ()Ljava/lang/String;
public synthetic fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public fun receiveCommand (Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public synthetic fun setMenuItems (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V
public fun setMenuItems (Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;Lcom/facebook/react/bridge/ReadableArray;)V
public synthetic fun show (Landroid/view/View;)V
public fun show (Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;)V
}
public class com/facebook/react/views/popupmenu/ReactPopupMenuManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter {
public fun <init> ()V
public fun getProperties (Ljava/util/Map;)V
public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
public fun setProperty (Lcom/facebook/react/views/popupmenu/ReactPopupMenuManager;Lcom/facebook/react/views/popupmenu/ReactPopupMenuContainer;Ljava/lang/String;Ljava/lang/Object;)V
}
public final class com/facebook/react/views/popupmenu/ReactPopupMenuManager$Companion {
}
public class com/facebook/react/views/progressbar/ProgressBarShadowNode : com/facebook/react/uimanager/LayoutShadowNode, com/facebook/yoga/YogaMeasureFunction {
public fun <init> ()V
public fun getStyle ()Ljava/lang/String;
@@ -125,6 +125,16 @@ val preparePrefab by
"react/renderer/components/view/"),
Pair("../ReactCommon/react/renderer/components/view/platform/android/", ""),
)),
PrefabPreprocessingEntry(
"rrc_text",
Pair(
"../ReactCommon/react/renderer/components/text/",
"react/renderer/components/text/")),
PrefabPreprocessingEntry(
"rrc_textinput",
Pair(
"../ReactCommon/react/renderer/components/textinput/",
"react/renderer/components/androidtextinput/")),
PrefabPreprocessingEntry(
"rrc_legacyviewmanagerinterop",
Pair(
@@ -138,6 +148,14 @@ val preparePrefab by
PrefabPreprocessingEntry(
"react_render_mapbuffer",
Pair("../ReactCommon/react/renderer/mapbuffer/", "react/renderer/mapbuffer/")),
PrefabPreprocessingEntry(
"react_render_textlayoutmanager",
listOf(
Pair(
"../ReactCommon/react/renderer/textlayoutmanager/",
"react/renderer/textlayoutmanager/"),
Pair("../ReactCommon/react/renderer/textlayoutmanager/platform/android/", ""),
)),
PrefabPreprocessingEntry(
"yoga",
listOf(
@@ -538,11 +556,14 @@ android {
"rrc_image",
"rrc_root",
"rrc_view",
"rrc_text",
"rrc_textinput",
"rrc_legacyviewmanagerinterop",
"jsi",
"glog",
"fabricjni",
"react_render_mapbuffer",
"react_render_textlayoutmanager",
"yoga",
"folly_runtime",
"react_nativemodule_core",
@@ -662,6 +683,8 @@ android {
create("rrc_image") { headers = File(prefabHeadersDir, "rrc_image").absolutePath }
create("rrc_root") { headers = File(prefabHeadersDir, "rrc_root").absolutePath }
create("rrc_view") { headers = File(prefabHeadersDir, "rrc_view").absolutePath }
create("rrc_text") { headers = File(prefabHeadersDir, "rrc_text").absolutePath }
create("rrc_textinput") { headers = File(prefabHeadersDir, "rrc_textinput").absolutePath }
create("rrc_legacyviewmanagerinterop") {
headers = File(prefabHeadersDir, "rrc_legacyviewmanagerinterop").absolutePath
}
@@ -671,6 +694,9 @@ android {
create("react_render_mapbuffer") {
headers = File(prefabHeadersDir, "react_render_mapbuffer").absolutePath
}
create("react_render_textlayoutmanager") {
headers = File(prefabHeadersDir, "react_render_textlayoutmanager").absolutePath
}
create("yoga") { headers = File(prefabHeadersDir, "yoga").absolutePath }
create("folly_runtime") { headers = File(prefabHeadersDir, "folly_runtime").absolutePath }
create("react_nativemodule_core") {
@@ -74,10 +74,13 @@ add_library(react_cxxreactpackage ALIAS ReactAndroid::react_cxxreactpackage)
add_library(react_render_core ALIAS ReactAndroid::react_render_core)
add_library(react_render_graphics ALIAS ReactAndroid::react_render_graphics)
add_library(rrc_view ALIAS ReactAndroid::rrc_view)
add_library(rrc_text ALIAS ReactAndroid::rrc_text)
add_library(rrc_textinput ALIAS ReactAndroid::rrc_textinput)
add_library(jsi ALIAS ReactAndroid::jsi)
add_library(glog ALIAS ReactAndroid::glog)
add_library(fabricjni ALIAS ReactAndroid::fabricjni)
add_library(react_render_mapbuffer ALIAS ReactAndroid::react_render_mapbuffer)
add_library(react_render_textlayoutmanager ALIAS ReactAndroid::react_render_textlayoutmanager)
add_library(yoga ALIAS ReactAndroid::yoga)
add_library(folly_runtime ALIAS ReactAndroid::folly_runtime)
add_library(react_nativemodule_core ALIAS ReactAndroid::react_nativemodule_core)
@@ -106,8 +109,11 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
react_render_graphics # prefab ready
react_render_imagemanager # prefab ready
react_render_mapbuffer # prefab ready
react_render_textlayoutmanager # prefab ready
rrc_image # prefab ready
rrc_view # prefab ready
rrc_text # prefab ready
rrc_textinput # prefab ready
rrc_legacyviewmanagerinterop # prefab ready
runtimeexecutor # prefab ready
turbomodulejsijni # prefab ready
@@ -62,8 +62,16 @@ void registerComponents(
std::shared_ptr<TurboModule> cxxModuleProvider(
const std::string& name,
const std::shared_ptr<CallInvoker>& jsInvoker) {
// Not implemented yet: provide pure-C++ NativeModules here.
return nullptr;
// Here you can provide your CXX Turbo Modules coming from
// either your application or from external libraries. The approach to follow
// is similar to the following (for a module called `NativeCxxModuleExample`):
//
// if (name == NativeCxxModuleExample::kModuleName) {
// return std::make_shared<NativeCxxModuleExample>(jsInvoker);
// }
// And we fallback to the CXX module providers autolinked by RN CLI
return rncli_cxxModuleProvider(name, jsInvoker);
}
std::shared_ptr<TurboModule> javaModuleProvider(
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0
VERSION_NAME=0.74.0-rc.3
react.internal.publishingGroup=com.facebook.react
android.useAndroidX=true
@@ -17,7 +17,6 @@ import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.devsupport.LogBoxModule;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfo;
@@ -115,7 +114,7 @@ class CoreModulesPackage extends TurboReactPackage implements ReactPackageLogger
reactModule.canOverrideExistingModule(),
reactModule.needsEagerInit(),
reactModule.isCxxModule(),
TurboModule.class.isAssignableFrom(moduleClass)));
ReactModuleInfo.classIsTurboModule(moduleClass)));
}
return () -> reactModuleInfoMap;
@@ -12,7 +12,6 @@ import com.facebook.react.bridge.ModuleSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.devsupport.JSCHeapCapture;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfo;
@@ -74,7 +73,7 @@ class DebugCorePackage extends TurboReactPackage implements ViewManagerOnDemandR
reactModule.canOverrideExistingModule(),
reactModule.needsEagerInit(),
reactModule.isCxxModule(),
TurboModule.class.isAssignableFrom(moduleClass)));
ReactModuleInfo.classIsTurboModule(moduleClass)));
}
return () -> reactModuleInfoMap;
@@ -139,8 +139,7 @@ public class ReactDelegate {
public void onActivityResult(
int requestCode, int resultCode, Intent data, boolean shouldForwardToReactInstance) {
if (ReactFeatureFlags.enableBridgelessArchitecture) {
// TODO T156475655: Implement onActivityResult for Bridgeless
return;
mReactHost.onActivityResult(mActivity, requestCode, resultCode, data);
} else {
if (getReactNativeHost().hasInstance() && shouldForwardToReactInstance) {
getReactNativeHost()
@@ -9,6 +9,7 @@ package com.facebook.react
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.queue.ReactQueueConfiguration
@@ -111,6 +112,14 @@ public interface ReactHost {
*/
public fun destroy(reason: String, ex: Exception?): TaskInterface<Void>
/* To be called when the host activity receives an activity result. */
public fun onActivityResult(
activity: Activity,
requestCode: Int,
resultCode: Int,
data: Intent?,
)
public fun addBeforeDestroyListener(onBeforeDestroy: () -> Unit)
public fun removeBeforeDestroyListener(onBeforeDestroy: () -> Unit)
@@ -998,6 +998,11 @@ public class ReactInstanceManager {
if (names != null) {
uniqueNames.addAll(names);
}
} else {
FLog.w(
ReactConstants.TAG,
"Package %s is not a ViewManagerOnDemandReactPackage, view managers will not be loaded",
reactPackage.getClass().getSimpleName());
}
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
}
@@ -18,9 +18,9 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.internal.turbomodule.core.TurboModuleManagerDelegate;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -123,14 +123,14 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule
reactModule.canOverrideExistingModule(),
true,
reactModule.isCxxModule(),
TurboModule.class.isAssignableFrom(moduleClass))
ReactModuleInfo.classIsTurboModule(moduleClass))
: new ReactModuleInfo(
moduleName,
moduleClass.getName(),
module.canOverrideExistingModule(),
true,
CxxModuleWrapper.class.isAssignableFrom(moduleClass),
TurboModule.class.isAssignableFrom(moduleClass));
ReactModuleInfo.classIsTurboModule(moduleClass));
reactModuleInfoMap.put(moduleName, moduleInfo);
moduleMap.put(moduleName, module);
@@ -15,7 +15,7 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
import androidx.annotation.Nullable;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
import java.lang.reflect.Method;
@@ -20,7 +20,6 @@ import com.facebook.debug.tags.ReactDebugOverlayTags;
import com.facebook.infer.annotation.Assertions;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.systrace.SystraceMessage;
import java.util.concurrent.atomic.AtomicInteger;
@@ -73,7 +72,7 @@ public class ModuleHolder {
nativeModule.canOverrideExistingModule(),
true,
CxxModuleWrapper.class.isAssignableFrom(nativeModule.getClass()),
TurboModule.class.isAssignableFrom(nativeModule.getClass()));
ReactModuleInfo.classIsTurboModule(nativeModule.getClass()));
mModule = nativeModule;
PrinterHolder.getPrinter()
@@ -10,8 +10,6 @@ package com.facebook.react.bridge.queue;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.facebook.common.logging.FLog;
import com.facebook.react.common.ReactConstants;
/** Handler that can catch and dispatch Exceptions to an Exception handler. */
public class MessageQueueThreadHandler extends Handler {
@@ -28,15 +26,6 @@ public class MessageQueueThreadHandler extends Handler {
try {
super.dispatchMessage(msg);
} catch (Exception e) {
if (e instanceof NullPointerException) {
FLog.e(
ReactConstants.TAG,
"Caught NullPointerException when dispatching message in MessageQueueThreadHandler. This is likely caused by runnable"
+ "(msg.callback) being nulled in Android Handler after dispatching and before handling (see T170239922 for more details)."
+ "Currently we observe that it only happen once which is during initialisation. Due to fixing probably involve Android "
+ "System code, we decide to ignore here for now and print an error message for debugging purpose in case this cause more serious issues in future.");
return;
}
mExceptionHandler.handleException(e);
}
}
@@ -1,20 +0,0 @@
/*
* 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.defaults
import com.facebook.jni.annotations.DoNotStrip
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.runtime.BindingsInstaller
/**
* A utility class that provides users a default [BindingsInstaller] class that's used to initialize
* [ReactHostDelegate]
*/
@DoNotStrip
@UnstableReactNativeAPI
public class DefaultBindingsInstaller : BindingsInstaller(null) {}
@@ -43,7 +43,7 @@ public class DefaultReactHostDelegate(
override val jsBundleLoader: JSBundleLoader,
override val reactPackages: List<ReactPackage> = emptyList(),
override val jsRuntimeFactory: JSRuntimeFactory = HermesInstance(),
override val bindingsInstaller: BindingsInstaller = DefaultBindingsInstaller(),
override val bindingsInstaller: BindingsInstaller? = null,
private val reactNativeConfig: ReactNativeConfig = ReactNativeConfig.DEFAULT_CONFIG,
private val exceptionHandler: (Exception) -> Unit = {},
override val turboModuleManagerDelegateBuilder: ReactPackageTurboModuleManagerDelegate.Builder
@@ -49,13 +49,18 @@ protected constructor(
DefaultComponentsRegistry.register(componentFactory)
val viewManagerRegistry =
ViewManagerRegistry(
object : ViewManagerResolver {
override fun getViewManager(viewManagerName: String) =
reactInstanceManager.createViewManager(viewManagerName)
if (lazyViewManagersEnabled) {
ViewManagerRegistry(
object : ViewManagerResolver {
override fun getViewManager(viewManagerName: String) =
reactInstanceManager.createViewManager(viewManagerName)
override fun getViewManagerNames() = reactInstanceManager.viewManagerNames
})
override fun getViewManagerNames() = reactInstanceManager.viewManagerNames
})
} else {
ViewManagerRegistry(
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext))
}
FabricUIManagerProviderImpl(
componentFactory, ReactNativeConfig.DEFAULT_CONFIG, viewManagerRegistry)
@@ -18,7 +18,7 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
@@ -19,12 +19,12 @@ import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactNoCrashSoftException;
import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.RuntimeExecutor;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModuleRegistry;
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
import com.facebook.react.turbomodule.core.NativeMethodCallInvokerHolderImpl;
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHolder;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -12,7 +12,7 @@ import com.facebook.infer.annotation.Nullsafe;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.ArrayList;
import java.util.List;
@@ -1,19 +0,0 @@
/*
* 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.internal.turbomodule.core.interfaces
/** All turbo modules should inherit from this interface */
public interface TurboModule {
/** Initialize the TurboModule. */
public fun initialize()
/**
* Called during the turn down process of ReactHost. This method is called before React Native is
* stopped. Override this method to clean up resources used by the TurboModule.
*/
public fun invalidate()
}
@@ -7,6 +7,8 @@
package com.facebook.react.module.model;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
/**
* Data holder class holding native module specifications. {@link ReactModuleSpecProcessor} creates
* these so Java modules don't have to be instantiated at React Native start up.
@@ -80,4 +82,12 @@ public class ReactModuleInfo {
public boolean isTurboModule() {
return mIsTurboModule;
}
/**
* Checks if the passed class is a TurboModule. Useful to populate the parameter [isTurboModule]
* in the constructor of ReactModuleInfo.
*/
public static boolean classIsTurboModule(Class<?> clazz) {
return TurboModule.class.isAssignableFrom(clazz);
}
}
@@ -161,13 +161,13 @@ public class ReactModuleSpecProcessor extends ProcessorBase {
builder.addStatement("$T map = new $T()", MAP_TYPE, INSTANTIATED_MAP_TYPE);
String turboModuleInterfaceCanonicalName =
"com.facebook.react.internal.turbomodule.core.interfaces.TurboModule";
"com.facebook.react.turbomodule.core.interfaces.TurboModule";
TypeMirror turboModuleInterface =
mElements.getTypeElement(turboModuleInterfaceCanonicalName).asType();
if (turboModuleInterface == null) {
throw new RuntimeException(
"com.facebook.react.internal.turbomodule.core.interfaces.TurboModule interface not found.");
"com.facebook.react.turbomodule.core.interfaces.TurboModule interface not found.");
}
for (String nativeModule : nativeModules) {
@@ -19,12 +19,12 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.common.ModuleDataCleaner;
import com.facebook.react.modules.network.CookieJarContainer;
import com.facebook.react.modules.network.ForwardingCookieHandler;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.HashSet;
import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient;
@@ -18,8 +18,8 @@ import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativePlatformConstantsAndroidSpec;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.HashMap;
import java.util.Map;
@@ -15,8 +15,8 @@ import java.util.Map;
public class ReactNativeVersion {
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
"major", 1000,
"minor", 0,
"major", 0,
"minor", 74,
"patch", 0,
"prerelease", null);
"prerelease", "rc.3");
}
@@ -119,7 +119,7 @@ class BridgelessDevSupportManager extends DevSupportManagerBase {
@Override
public void onJSBundleLoadedFromServer() {
throw new IllegalStateException("Not implemented for bridgeless mode");
// Not implemented
}
@Override
@@ -14,7 +14,6 @@ import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.devsupport.LogBoxModule;
import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfo;
@@ -103,7 +102,7 @@ class CoreReactPackage extends TurboReactPackage {
reactModule.canOverrideExistingModule(),
reactModule.needsEagerInit(),
reactModule.isCxxModule(),
TurboModule.class.isAssignableFrom(moduleClass)));
ReactModuleInfo.classIsTurboModule(moduleClass)));
}
}
return () -> reactModuleInfoMap;
@@ -15,6 +15,7 @@ import static java.lang.Boolean.TRUE;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -600,6 +601,37 @@ public class ReactHostImpl implements ReactHost {
return null;
}
/**
* To be called when the host activity receives an activity result.
*
* @param activity The host activity
*/
@ThreadConfined(UI)
@Override
public void onActivityResult(
Activity activity, int requestCode, int resultCode, @Nullable Intent data) {
final String method =
"onActivityResult(activity = \""
+ activity
+ "\", requestCode = \""
+ requestCode
+ "\", resultCode = \""
+ resultCode
+ "\", data = \""
+ data
+ "\")";
log(method);
ReactContext currentContext = getCurrentReactContext();
if (currentContext != null) {
currentContext.onActivityResult(activity, requestCode, resultCode, data);
}
ReactSoftExceptionLogger.logSoftException(
TAG,
new ReactNoCrashSoftException(
"Tried to access onActivityResult while context is not ready"));
}
@Nullable
JavaScriptContextHolder getJavaScriptContextHolder() {
final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult();
@@ -15,7 +15,6 @@ import com.facebook.react.animated.NativeAnimatedModule;
import com.facebook.react.bridge.ModuleSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfo;
@@ -47,7 +46,6 @@ import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.views.drawer.ReactDrawerLayoutManager;
import com.facebook.react.views.image.ReactImageManager;
import com.facebook.react.views.modal.ReactModalHostManager;
import com.facebook.react.views.popupmenu.ReactPopupMenuManager;
import com.facebook.react.views.progressbar.ReactProgressBarViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollContainerViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager;
@@ -171,7 +169,6 @@ public class MainReactPackage extends TurboReactPackage implements ViewManagerOn
viewManagers.add(new ReactScrollViewManager());
viewManagers.add(new ReactSwitchManager());
viewManagers.add(new SwipeRefreshLayoutManager());
viewManagers.add(new ReactPopupMenuManager());
// Native equivalents
viewManagers.add(new FrescoBasedReactTextInlineImageViewManager());
@@ -213,7 +210,6 @@ public class MainReactPackage extends TurboReactPackage implements ViewManagerOn
appendMap(viewManagers, ReactSwitchManager.REACT_CLASS, ReactSwitchManager::new);
appendMap(
viewManagers, SwipeRefreshLayoutManager.REACT_CLASS, SwipeRefreshLayoutManager::new);
appendMap(viewManagers, ReactPopupMenuManager.REACT_CLASS, ReactPopupMenuManager::new);
appendMap(
viewManagers,
FrescoBasedReactTextInlineImageViewManager.REACT_CLASS,
@@ -300,7 +296,7 @@ public class MainReactPackage extends TurboReactPackage implements ViewManagerOn
reactModule.canOverrideExistingModule(),
reactModule.needsEagerInit(),
reactModule.isCxxModule(),
TurboModule.class.isAssignableFrom(moduleClass)));
ReactModuleInfo.classIsTurboModule(moduleClass)));
}
}
return () -> reactModuleInfoMap;
@@ -6,15 +6,14 @@
*/
package com.facebook.react.turbomodule.core.interfaces
/** All turbo modules should inherit from this interface */
public interface TurboModule {
/** Initialize the TurboModule. */
public fun initialize()
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture
/**
* This interface was introduced for backward compatibility purposes. This interface will be
* deprecated as part of the deprecation and removal of ReactModuleInfoProvider in the near future.
*
* See description of https://github.com/facebook/react-native/pull/41412 for more context.
*/
@DeprecatedInNewArchitecture
public interface TurboModule :
com.facebook.react.internal.turbomodule.core.interfaces.TurboModule {}
/**
* Called during the turn down process of ReactHost. This method is called before React Native is
* stopped. Override this method to clean up resources used by the TurboModule.
*/
public fun invalidate()
}
@@ -67,8 +67,6 @@ CoreComponentsRegistry::sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
AndroidPopupMenuComponentDescriptor>());
return providerRegistry;
}();

Some files were not shown because too many files have changed in this diff Show More