Compare commits

..
Author SHA1 Message Date
Simek 04ae39e603 fix C++ in-code docs comments to silence warnings 2025-09-18 10:50:03 +02:00
Alex Hunt fae11d58bd Replace trivial uses of string_view (#53775)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53775

A refactor to align our C++ code style within `jsinpector-modern`.

We prefer `std::string` and `const std::string&` everywhere (see [C++ Core Guidelines F.15](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-conventional)), except for when we are handing potentially very large strings — in which case we must use `string_view` all the way down.

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D82446939

fbshipit-source-id: 4b1c43068d1339f4b4a4c7eb06b392d0b0f624e1
2025-09-16 03:17:57 -07:00
Alex Hunt 6eb456bc4e Fix data race condition in NetworkHandler (#53788)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53788

Fix thread safety issue due to member variable  in `NetworkHandler` singleton without mutex.

Also intend to un-singleton this class in the imminent future.

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D82460574

fbshipit-source-id: c0c614f8f1bb5ffba22872ae5717fbd2ca01f2e9
2025-09-16 03:03:06 -07:00
Nicola Corti 27630d3106 Remove unused --otp property from release infrastructure (#53779)
Summary:
The `--otp` flag is completely unused now, therefore it can be removed.
We don't pass the `NPM_CONFIG_OTP` env variable either as this was done back in the days of CircleCI so I'm cleaning this up.

## Changelog:

[INTERNAL] - Remove unused --otp property from release infrastructure

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

Test Plan: CI

Reviewed By: lunaleaps

Differential Revision: D82453539

Pulled By: cortinico

fbshipit-source-id: 84a6b82a037c754165c21e17976dc534d9a7ba4c
2025-09-16 02:52:58 -07:00
Pieter De Baets 96c33a8b0b Update ws to 7.5.10 (#53781)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53781

Fixes deprecation warning printed when starting various `js1` tools

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D82449982

fbshipit-source-id: 852b5a6980badef146b4e194434f2f9c6dd9a1d5
2025-09-16 02:51:06 -07:00
Zeya Peng c9dcd64ed5 Clean up batchingControlledByJS in NativeAnimated kotlin (#53793)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53793

## Changelog:

[Android] [Deprecated] - Clean up batchingControlledByJS in NativeAnimated kotlin

`start/finishOperationBatch` will no longer be called on kotlin NativeAnimated since D78005971 (https://github.com/facebook/react-native/pull/52521), so `batchingControlledByJS` will remain false. Cleaning up some logic and TODO comments there

this feature was added in D23010844

Reviewed By: christophpurrer

Differential Revision: D82461457

fbshipit-source-id: a1208720b83e614c2a5f994ec1a5005189c5f197
2025-09-16 00:44:23 -07:00
generatedunixname537391475639613 15daa27871 xplat/js/react-native-github/packages/react-native/ReactCommon/react/renderer/components/view/LayoutConformanceShadowNode.h (#53772)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53772

Reviewed By: javache

Differential Revision: D82292073

fbshipit-source-id: 3a3f8e54b4217c8ce9432520e04c4f232b538687
2025-09-15 16:11:00 -07:00
nishan (o^▽^o) b365e26593 feat(iOS) - blur filter using SwiftUI (#52495)
Summary:
As per the discussion on the previous [PR thread](https://github.com/facebook/react-native/pull/52028#issuecomment-2979481948), this PR uses `SwiftUI` to implement blur filter on iOS.

## Approach:

To implement blur filter on iOS, we have two options:

1. Use `CAFilter` (private API, app can get rejected/API can break). Earlier [PR](https://github.com/facebook/react-native/pull/52028) was using that approach. Thanks to Nick for suggesting SwiftUI API.

2. Use `SwiftUI`. Wrap the view in a SwiftUI view and apply [blur](https://developer.apple.com/documentation/swiftui/view/blur(radius:opaque:)). This PR builds on top of that approach. This also enables a way to add `SwiftUI` only features like this one. Additional filters (grayscale, saturate, contrast, hueRotate) can also be added.

There are a few ways we can implement the SwiftUI approach:

1. Create a new `RCTSwiftUIComponentView` -> do style flattening in View -> check if `filter` is present and conditionally render the `RCTSwiftUIComponentView` on iOS, wrap children with a `SwiftUI` view. Tradeoff with this approach is that it adds `StyleSheet.flatten` overhead on JS side.
2. Add a `SwiftUI` container view inside of `RCTViewComponentView`. Tradeoff with this approach is that it complicates `RCTViewComponentView` a bit.

I decided to go with **2** to avoid the flattening tradeoff and try to minimize complicating `RCTViewComponentView`. it only adds the wrapper if it's required and removes if not (in this PR, blur filter style will add the wrapper, it will get removed if blur filter styling gets removed). It uses the existing container view pattern.

## Changelog:
[IOS][ADDED] - Filter blur

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests

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

Test Plan:
Test filter blur example on iOS. SwiftUI view should be added to the hierarchy.

<img src="https://github.com/user-attachments/assets/742539f4-a96d-45f4-94ba-5eb588d0ad5a" width="300px" />

## Aside:

- This PR also adds a new swift podspec. Creating a new podspec felt the right approach as adding swift in existing ones were adding some complexity. But open for changes here. Also, need some eyes on the podspec configs. cc - chrfalch  🙏   this might also affect the SPM migration.
- Unrelated: Existing brightness filter has some inconsistency compared to android and web, it uses [self.layer.opacity](https://github.com/facebook/react-native/blob/6892dde36373bbef2d0afe535ae818b1a7164f08/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm#L1008) so transparent background color do not blend well unless the view has an opacity. One solution would be to calculate true background color by using brightness or else use the `SwiftUI`'s [brightness](https://developer.apple.com/documentation/swiftui/view/brightness(_:)), which would be cleaner imo (tested and it works).

Reviewed By: cipolleschi

Differential Revision: D79666764

Pulled By: joevilches

fbshipit-source-id: 05e43d75ce7b6f25b67b4eed632524a559ea1c2e
2025-09-15 15:04:54 -07:00
generatedunixname537391475639613 7e85653c18 xplat/js/react-native-github/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PrepareGlogTaskTest.kt (#53750)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53750

Reviewed By: cortinico

Differential Revision: D82293987

fbshipit-source-id: 46bf93c7b8a2bf48a2246d9f5fc4ab8c1163badf
2025-09-15 13:04:17 -07:00
Ruslan Lesiutin 01b4749f6a Emit stashed trace to an active Fusebox client (#53771)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53771

# Changelog: [Internal]

Instead of opening DevTools every time we emit a background trace, we are going to check if there is an active session with Fusebox client and will send it to the first one registered.

Reviewed By: huntie

Differential Revision: D82321146

fbshipit-source-id: 46b4d090ae9a6f8b4fc98181b303ff552c561eb8
2025-09-15 12:45:53 -07:00
Ruslan Lesiutin 1b6d3c9ce1 refactor: emit the trace recoding on ReactNativeApplication domain initialization (#53760)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53760

# Changelog: [Internal]

This is a different approach from the one that I've introduced initially in [1].

This saves us from the scenario, where any local session could snatch the stashed trace recording. For example, if some session was created for a Runtime binding right after we've stashed the trace and before initializing real CDP session with the Frontend.

Reviewed By: huntie

Differential Revision: D82316584

fbshipit-source-id: 806a0f6dbdb4e4e928ce33af228cae86d43772e9
2025-09-15 12:45:53 -07:00
generatedunixname1395667395051502 fedad125bf Update React Native DevTools binaries
Summary:
Automated update of React Native DevTools binaries
bypass-github-export-checks
Changelog: [Internal]

Reviewed By: motiz88

Differential Revision: D82459089

fbshipit-source-id: 3ccf7a1f07da7e79732c785afda1b938ee585ea6
2025-09-15 11:54:30 -07:00
Pieter De Baets 64b30a9376 Fix newarch ignoring defaultfonthandler (#53755)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53755

Changelog: [iOS][Fixed] Make `RCTSetDefaultFontHandler` compatible with the new arch, and add a more powerful version as `RCTSetDefaultFontResolver`

Reviewed By: fkgozali

Differential Revision: D82207676

fbshipit-source-id: eeeaf708491de9156ef4f1e045864e4322213902
2025-09-15 11:31:30 -07:00
ismarbesic 07da2ff3e1 feat(ios): support condensed system font on fabric (#52259)
Summary:
This PR adds support for using the condensed system font on iOS when passing "SystemCondensed" as fontFamily. This behavior existed in the old architecture but was never ported to the new one, see [RCTFont.mm](https://github.com/facebook/react-native/blob/main/packages/react-native/React/Views/RCTFont.mm#L434) as reference. Fixes https://github.com/facebook/react-native/issues/52258.

## Changelog:

[IOS] [ADDED] - Add support for condensed system font when using the new react native architecture.

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

Test Plan:
Before:
<img width="275" src="https://github.com/user-attachments/assets/8744a5ae-252c-46db-b5f9-b803f3e1c671" />

After:
<img width="275" src="https://github.com/user-attachments/assets/69ec27a3-5c9a-46e3-a80a-0e02b76d8813" />

Reviewed By: cortinico

Differential Revision: D82208140

Pulled By: javache

fbshipit-source-id: b23a97c94bf45144c3f0860c30e35cae88c7dc2f
2025-09-15 11:31:30 -07:00
Alex Hunt 90ac3ac7bd Expose unstable_NativeText and unstable_NativeView components (#53777)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53777

Expose `unstable_NativeText` and `unstable_NativeView` components as root exports of the `react-native` package.

These are exposed as `unstable_` APIs which have no semver guarantee.

**Motivation**

There is significant community interest / dependance on the currently private `TextNativeComponent` and `ViewNativeComponent` deep imports, to access the faster-performing inner versions of these UI components.

Using `<Text>` and `<View>`, while recommended and stable, has led to measurable performance overhead in some apps when compared with these `<Native*>` counterparts.

Notably, these APIs are also referenced by low-level libraries such as React Strict DOM.

I am proposing this change in order to:
- Unblock libraries which safely use these.
- Meet users where they are at.
- Unblock us from enabling the Strict TypeScript API (no deep imports).

References:

- https://github.com/react-native-community/discussions-and-proposals/discussions/893#discussioncomment-13452047
- https://javascript.plainenglish.io/optimizing-text-component-rendering-in-react-native-b9d3565659d9
- https://github.com/search?type=code&q=react-native%2FLibraries%2FText%2FTextNativeComponent

**Ideal future state**

We are exposing these as unstable APIs because they should not be part of React Native's final API. The ideal end state is we improve the regular `<Text>` and `<View>` components to eliminate performance overhead and the need to access any lower level API.

Changelog:
[General][Added] - `unstable_NativeText` and `unstable_NativeView` are now exported from the `react-native` package

Reviewed By: javache

Differential Revision: D81588145

fbshipit-source-id: 2ea9b7f822286de85f49607944c6a484d1fcf242
2025-09-15 10:55:55 -07:00
Alex Hunt dba8dbdeeb Implement support for Network trace events (#53761)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53761

Updates `NetworkReporter` and `PerformanceEntryReporter` to populate (minimal) `"ResourceSendRequest"` and `"ResourceFinished"` events when a CDP performance trace is active. This allows the Chrome DevTools Performance panel to display the "Network" track.

**Notes**

- The trace events that Chrome requires need extra fields which aren't present on `PerformanceResourceTiming`, hence the new + optional `devtoolsRequestId`, `requestMethod`, `resourceType` params. We only populate these in debug builds.

**Limitations**

- We emit a *complete trace event set* within `reportResourceTiming`, implementing basic initial support in the Performance panel Network track. This means 1/ either all/no events are sent for a given request (rather than incrementally), 2/ we aren't yet handling failed/cancelled requests in this pipeline.

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D82212362

fbshipit-source-id: 4c6d5d2510cc98ddc819a2778222b835411295c8
2025-09-15 07:45:32 -07:00
Jakub Piasecki 0caf8e70d5 Add dependency on hermes-compiler (#53773)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53773

Changelog: [GENERAL][ADDED] - Added a dependency on hermes-compiler

Reviewed By: cortinico

Differential Revision: D82437752

fbshipit-source-id: 3b2d92b765f3a5ba949363ce7656e936403a1155
2025-09-15 06:16:25 -07:00
Luna Wei 56e5dff73f Hysteresis window for VirtualViewExperimental (#53765)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53765

Changelog: [Internal] Introduce hysteresis window for experimental VirtualView

Reviewed By: yungsters

Differential Revision: D82354142

fbshipit-source-id: 13ec0e3a46930d3bea0ea67060c5f0e1c137dec1
2025-09-13 21:41:49 -07:00
Luna Wei 4f20e4d0fc Subview clipping for VirtualViewExperiment (#53759)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53759

Changelog: [Internal] - Enable subview clipping for experimental version of VirtualView

Reviewed By: mdvacca

Differential Revision: D82313841

fbshipit-source-id: c6726fd5f443a55ec47c93ef13092fe8bb9297e0
2025-09-13 21:41:49 -07:00
Alex Hunt 09a7e0a0fc Restore NOT_FOCUSABLE flag on Perf Monitor overlay (#53754)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53754

Fix following D82302063.

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D82311593

fbshipit-source-id: 07305c8d3fdbd9199662e20a813ccfbf46e6491b
2025-09-13 06:23:56 -07:00
David Vacca 4fb42c84d8 Delete ScreenshotTestsManagerModule (#53746)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53746

ScreenshotTestsManagerModule and ReactAppScreenshotTestActivity are not in use anymore, let's delete them

changelog: [internal] internal

Reviewed By: javache

Differential Revision: D82249453

fbshipit-source-id: 73b0f2ef2e9a5370057c07c3bee03f9c0793d61a
2025-09-12 11:43:51 -07:00
generatedunixname89002005287564 ebe51d6ce8 Fix CQS signal readability-static-accessed-through-instance in xplat/js/react-native-github/packages (#53756)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53756

Reviewed By: javache

Differential Revision: D82289100

fbshipit-source-id: 432d9cdf4116aadbd6f21e8fdb994a91a163bfd5
2025-09-12 10:18:49 -07:00
vlad 81bbbe3c45 Fix deprecation message (#53751)
Summary:
This pull request fixes a small error in the deprecation message for `ReactContextBaseJavaModule#getCurrentActivity()`, where the reference to `getReactApplicationContext().getCurrentActivity()` contained a syntax error.

## Changelog:

[ANDROID] [FIXED] - Correct deprecation message for `ReactContextBaseJavaModule#getCurrentActivity()`

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

Reviewed By: javache

Differential Revision: D82302032

Pulled By: cortinico

fbshipit-source-id: 130991ef514663223165c30fccb920ce87403148
2025-09-12 09:11:04 -07:00
Alex Hunt 35f6ed1146 Update SectionList to accept React elements for separators (#53599)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53599

Runtime and types fix for the `ItemSeparatorComponent` prop on `virtualized-list` components (`FlatList`, `SectionList`, `VirtualizedList`).

- Docs source, where this prop (adjacent to other `*Component` props) is documented as accepting elements: https://reactnative.dev/docs/virtualizedlist#itemseparatorcomponent.
- Existing runtime behaviour matching this definition: https://github.com/facebook/react-native/blob/8d33e1c205b12fe27f4319e6566bb0c088197810/packages/virtualized-lists/Lists/VirtualizedListCellRenderer.js#L197-L203

**Changes**

- Update Flow, manual TS type defs.
- Align runtime behaviour in `VirtualizedSectionList` to add matching `React.isValidElement()` behaviour.

Resolves https://github.com/facebook/react-native/issues/53531.

Changelog:
[General][Fixed] - The `ItemSeparatorComponent` prop on list components now accepts a React element as well as a component function.

Reviewed By: cortinico

Differential Revision: D81675423

fbshipit-source-id: 3eed93b1bea89554988d6e20fa61b72e17be55df
2025-09-12 07:54:04 -07:00
Nicola Corti f59a6f9508 Do not crash inside getEncodedScreenSizeWithoutVerticalInsets if SurfaceMountingManager is null (#53752)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53752

Currently we `Objects.requireNotNull` on the `SurfaceMountingManager` inside the `getEncodedScreenSizeWithoutVerticalInsets`
function. However the `SurfaceMountingManager` could be null.
In that scenario, I'm returning 0 here (that will restore the old broken behavior, with the modal rendering on the top left corner for the first frame), instead of letting the app crash.

Changelog:
[Android] [Fixed] - Do not crash inside getEncodedScreenSizeWithoutVerticalInsets if SurfaceMountingManager is null

Reviewed By: javache

Differential Revision: D82225855

fbshipit-source-id: df84db612e77b6b981bc28afc0d293867b5d3b2e
2025-09-12 07:44:00 -07:00
Riccardo Cipolleschi 91d427fe52 Fix Switch layout with iOS26 (#53326)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53326

Apple changed the sizes of the UISwitchComponent and now, if you build an iOs app using the <Switch> component, the layout of the app will be broken because of wrong layout measurements.
This has been reported also by [https://github.com/facebook/react-native/issues/52823](https://github.com/facebook/react-native/issues/52823).

The `<Switch>` component was using hardcoded values for its size.
This change fixes the problem by:
- Using codegen for interface only
- Implementing a custom Sadow Node to ask the platform for the Switch measurements
- Updating the JS layout to wrap the size around the native component.

## Changelog:

[iOS][Fixed] - Fix Switch layout to work with iOS26

Reviewed By: sammy-SC

Differential Revision: D80454350

fbshipit-source-id: 1d468910276f7fde4559d2ae87cf60c8494caceb
2025-09-12 07:16:20 -07:00
Alex Hunt d28ee162e3 Restore background tracing touch target (#53753)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53753

Changelog: [Internal]

Reviewed By: rubennorte

Differential Revision: D82302063

fbshipit-source-id: 25c99c2449fd72b81ce3ac25473c41304993cbc1
2025-09-12 06:51:53 -07:00
Alex Hunt 136d795c22 Implement saved window positioning per target (#53743)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53743

As titled. A long awaited quality of life improvement that we can now deliver with our desktop shell.

Window arrangements are saved per [`windowKey`](https://github.com/facebook/react-native/blob/da7bf9c54567aae62ff355b79e66f511cb382065/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js#L193), mapping to each previously opened debugger target.

**Limitations**

- Does not save/restore macOS fullscreen app state.

Changelog: [Internal]

Reviewed By: vzaidman

Differential Revision: D82236159

fbshipit-source-id: e3c2f9c0cb05a3b8ef2208eb4a288e0be064489a
2025-09-12 05:26:27 -07:00
Alex Hunt 88f3452992 Add website links to Help menu (#53741)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53741

Adds a couple of web link options to populate the "Help" menu in the RNDT desktop app. The default menu is otherwise unchanged.

Changelog: [Internal]

Reviewed By: vzaidman

Differential Revision: D82231524

fbshipit-source-id: 9a57e6067854716691dc35938d6f27735b8c8448
2025-09-12 04:13:25 -07:00
Alex Hunt 408abf66d7 Fix user facing display name for debugger-shell (#53740)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53740

Adjusts user facing app name used by Electron, which previously used `package.json#name` and led to this leaking into unwanted parts of the UI — e.g. "[About|Hide|Quit] react-native/debugger-shell" in the macOS menu bar.

**Changes**

- Set the `productName` field in `package.json` ([docs](https://www.electronjs.org/docs/latest/api/app#appname:~:text=npm%20modules%20spec.-,You%20should%20usually%20also%20specify%20a%20productName%20field%2C%20which%20is%20your%20application%27s%20full%20capitalized%20name%2C%20and%20which%20will%20be%20preferred%20over%20name%20by%20Electron.,-app.userAgentFallback%E2%80%8B)).

**Notes**

- This **changes** the `User-Agent` header sent by the app, now of the form `"... ReactNativeDevTools/0.82.0-main-dev ..."`.

Changelog: [Internal]

Reviewed By: vzaidman

Differential Revision: D82228307

fbshipit-source-id: dd316ce5580a3ddf4138c7c3bf76aff99e4f4801
2025-09-12 04:13:25 -07:00
generatedunixname89002005287564 82708c775e Fix CQS signal readability-isolate-declaration in xplat/js/react-native-github/packages (#53747)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53747

Reviewed By: javache

Differential Revision: D82197859

fbshipit-source-id: e76e29754188ff15c7b4ebde8060c04f89aa3b52
2025-09-12 03:52:25 -07:00
Gabriel Donadel bcf9d5850a Add changelog for v0.81.3 (#53694)
Summary:
Add Changelog for 0.81.3

## Changelog:
[Internal] - Add Changelog for 0.81.3

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

Test Plan: N/A

Reviewed By: fabriziocucci

Differential Revision: D82111771

Pulled By: cortinico

fbshipit-source-id: a67f64e81afa794eb4ba260701a187cac9ca55bd
2025-09-12 03:49:52 -07:00
Vojtech Novak bc3503452f chore: improve codegen error when native project not found (#53726)
Summary:
While working on a somewhat non-standard library setup I ran into:

`[Codegen] TypeError [ERR_INVALID_ARG_TYPE]: The "from" argument must be of type string. Received undefined`

which was caused by `xcodeproj` file not found. The issue was on the project side rather than codegen, but the error message was rather unhelpful, so this improves it.

## Changelog:

[General][Changed] - improve codegen error when ios native project not found

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

Test Plan:
tested locally, received the improved error message:

`[Codegen] Error: Cannot find .xcodeproj file inside /Users/some_project. This is required to determine codegen spec paths relative to native project.`

Reviewed By: cortinico

Differential Revision: D82226931

Pulled By: cipolleschi

fbshipit-source-id: dd851205655048fc35ed9f5266cefdbfb067d211
2025-09-12 03:41:50 -07:00
Nicola Corti c4d2ac6401 Temporarily disable prebuilds for template e2e tests on main branch (#53715)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53715

This is a backport of https://github.com/facebook/react-native/commit/ee08261123ac513941189cf7566337156576d4dd
on `main` as otherwise 0.83 will also be affected by the same problem (CI broken for iOS on the release branch).

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D82119125

fbshipit-source-id: 6fbdcd42b446bd49ac71bbe834181ba91cc67990
2025-09-12 03:03:28 -07:00
107 changed files with 1911 additions and 532 deletions
+2 -1
View File
@@ -276,7 +276,8 @@ jobs:
NEW_ARCH_ENABLED=1
export RCT_USE_LOCAL_RN_DEP=/tmp/third-party/ReactNativeDependencies${{ matrix.flavor }}.xcframework.tar.gz
export RCT_TESTONLY_RNCORE_TARBALL_PATH="/tmp/ReactCore/ReactCore${{ matrix.flavor }}.xcframework.tar.gz"
# Disable prebuilds for now, as they are causing issues with E2E tests for 0.82-stable branch
# export RCT_TESTONLY_RNCORE_TARBALL_PATH="/tmp/ReactCore/ReactCore${{ matrix.flavor }}.xcframework.tar.gz"
HERMES_ENGINE_TARBALL_PATH=$HERMES_PATH RCT_NEW_ARCH_ENABLED=$NEW_ARCH_ENABLED bundle exec pod install
xcodebuild \
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## v0.81.3
### Fixed
#### iOS specific
- Reverted "Use autolinking-generated react-native-config output in second step of cocoapods linking that generates artifacts and generated source" ([537e3ad930](https://github.com/facebook/react-native/commit/537e3ad93041c0cef959f0d20586fe97818900a6) by [@gabrieldonadel](https://github.com/gabrieldonadel))
## v0.81.2
### Added
+41
View File
@@ -0,0 +1,41 @@
/**
* 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
* @format
*/
declare module 'electron-store' {
declare export type Schema = any;
declare export type Options = {
+name?: string,
defaults?: Object,
schema?: any,
migrations?: any,
beforeEachMigration?: any,
clearInvalidConfig?: boolean,
serialize?: any,
deserialize?: any,
accessPropertiesByDotNotation?: boolean,
watch?: boolean,
encryptionKey?: string | Buffer | $ReadOnlyArray<number>,
...
};
declare class ElectronStore {
constructor(options?: Options): this;
get(key: string): any;
get(key: string, defaultValue: any): any;
set(key: string, value: any): void;
set(object: Object): void;
has(key: string): boolean;
delete(key: string): void;
clear(): void;
}
declare module.exports: Class<ElectronStore>;
}
+1 -1
View File
@@ -117,7 +117,7 @@
"temp-dir": "^2.0.0",
"tinybench": "^4.1.0",
"typescript": "5.8.3",
"ws": "^6.2.3"
"ws": "^7.5.10"
},
"resolutions": {
"eslint-plugin-react-hooks": "6.1.0-canary-12bc60f5-20250613",
@@ -1,71 +1,71 @@
#!/usr/bin/env dotslash
// @generated SignedSource<<e93d55b5e28943e44271f5d3738083e0>>
// @generated SignedSource<<9df662721aea6e3774a8677e2a6065e4>>
{
"name": "React Native DevTools",
"platforms": {
"linux-aarch64": {
"size": 116060647,
"size": 116056584,
"hash": "sha256",
"digest": "4352f1c9848ca919101ec628bd08b87a72a828d1ab55fa43a02098329fa452fa",
"digest": "fac3912f10e3c373c874be6c4696f11e05cbaa754c116db6ea72189afae5efe6",
"providers": [
{
"type": "http",
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQM24LW0nPZRk0ypuIG9prz_72YjBJNcVlGSIEpO4zdlLXgw4dFNodH7MKg9eKNTnx7wrVDDBNACrnEPt_OfXOjZyZsV9Oaqu0-vNFRdlEyis4YqmpqGLtz3LvD-9R6fzcWxJI9zrhdPvOvlXP-3Syt1UNITaxXDVqIwAAYpCaAh0oLpupAFCc2yvYw"
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQPdlYV_w4y_wxd5Rs8c_F-soLMbY1zwXJjD-JM4TkOtOELyxZGyreTb6dTehp_X6e3qVFZUT05ETRs0MbvqYr4mqdb6dkG9DqNQEVv3TBoHwl7TYSygtHJEs3gXTAtMLYEKW9xXODJlVF-9II7fdTdHU7x7Pyf6NR6S3nv7sKUVD-zKpxF50L2TwUQ"
}
],
"format": "tar.gz",
"path": "React Native DevTools-linux-arm64/React Native DevTools"
},
"linux-x86_64": {
"size": 115930333,
"size": 115929093,
"hash": "sha256",
"digest": "11c7b07942928a6301b07fbf2bc77ce1229b2a52891f23541cdd9858b5250e64",
"digest": "06bbaeb62ae2e0081d184eba42b9f15be0d0b3f4901142b08a8a1430ff83e722",
"providers": [
{
"type": "http",
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQNDwm7HZRhtNxHqMr1FfSb0afHFGrn1OHxH0gOiggrLrht9QRUgJ3GG5jj7huhQzMRogE-LCMsnxh1ioOZks-YYX4KRt6Kj1-whdWsGFc7lBhPOpk1ssbYFGN1NNyuyFRmH-3nCY3lBC4AmbCUkbDTUeCi9DidCtJeyc73CZJEu7M62rIzxR2yV"
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQPENbrxrg0RF_TiyxSY_YVYqC1UfRKj_bMfKb3qHUsIhBlya8n3FkbfJqTXTNdqL4riFRulXS5ecXZprtvk_9kao-zY59r3kiTRwobzF0jnjM507_9UOnEHWzG5ZJYzQyOtS3kQmT0HwZabVj9qw38OB9mk-MPVCZIPZay2PRnIThBzpKDoOOP9"
}
],
"format": "tar.gz",
"path": "React Native DevTools-linux-x64/React Native DevTools"
},
"macos-aarch64": {
"size": 110891041,
"size": 110891603,
"hash": "sha256",
"digest": "3cbe8b1b3d17e433347f1601435bb9a6cb758528a5c176a66fc52d9977223175",
"digest": "eeb9cc1399c0c38c429848dbf622f1b46e88d7d97788dcdc4c30a9fcce37705c",
"providers": [
{
"type": "http",
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQOmC2cqqSv4OrSJKJroYVg_NE8OE4O73AXqY7wXiYqiWQVkDt0Xnyw3ZeUpQT_Qb0-OoT5F8REKoFrB6eqwat8Ovkyina30peYTTwNUzmwnnGQEg7J0fOHNxLF4dkmU1FagXtsoWgex4dKgsK_VpcMsHj3Vp7diomkYvWBVTf_gPVEseYSN9oKq92qa"
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQN9bd7nbXi-uF_MooJEiUL2jJVifMqgQxZ236aqbSdiJe5Uzjud5ANf0LDAl8GDVVRShd6x4B-gsZ-qRowH0qJikoGatQIkBgyzp4i8ors52etGOIIwdAxdNIng5Vtp441j2_N__btkJqlHcMMbbqvO8fg9oeYTlhMpOx3MLLWXIlG7ix5IFUDiYChf"
}
],
"format": "tar.gz",
"path": "React Native DevTools.app/Contents/MacOS/React Native DevTools"
},
"macos-x86_64": {
"size": 117766158,
"size": 117770388,
"hash": "sha256",
"digest": "6fb79bc2ba3008401b4c9c128248657b95b98581ccde60f8fadb622163779775",
"digest": "a65e446e526502b267cbe6800ae031e4e1b5b0aca21412152a66ffe1d3a29410",
"providers": [
{
"type": "http",
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQMMtGn-YGdfLfTVWC8zbQkQx65Asq6iArKt1t__cjZ8UY_s6-sX5XBHr8k1SaexAO21dFZENQVZ1jW_wn_gJ9ENvosQDG1KfWMViKsHli0xRzZ1HVsgPIj_KVXe907QZwwtJf2XhgH0HT8dfH-AQdDcd0_TB5DFUwOsHzhH0nBrHet7YFkbJtPTaA"
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQN29ukKLZS48QcCU-gms06YFnG-fxxDfrWTup-Z6KoIAP-QEu3sFzrpqeZz4g-jFsh3o-IIoHJsdbu4a2U7ROjPfWGguGJrPK8fdc3iV67Qw1_VAPU13dm0dI1DbSY50ah05wh43jdBG3LGCAYYJ-W8_mZMC3HqM2v-8KVd-DoPT4hOh1s9CCFgEQ"
}
],
"format": "tar.gz",
"path": "React Native DevTools.app/Contents/MacOS/React Native DevTools"
},
"windows-x86_64": {
"size": 125527537,
"size": 125526370,
"hash": "sha256",
"digest": "579a5b0944c51c3b1b541ad5af66c1ffedf93cae2a891ecdf88cb7219fd9b096",
"digest": "26b190c0f85249dee91999e020b8fe7ffd5c007458a2103ed3822558861dbe87",
"providers": [
{
"type": "http",
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQOQ3E8lBXqdVHbDPyVb5AOQMrDWjFrFV8fnLLBsygQvLWdpu6ixyG9PgWdwpi5jM-XcDdCHkhBdhaq-5dwT_tgRWKCAMsEBoAIUk0Xg77mGyHG2VF7bNfQ2qFBMuObrsTmrKy1nJ-UFDDm29pJD4GkFQW5NesiBwndJj8t3B8Ur8cczh_XR8rF5"
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQO0mdIJx1eYiSDJNiAZ2soaeECILayWnvOeiey-fpS4ydDTreAMfwL4QZ5GZo4-AsGwOXCSdF3hBMM2ufnvw6BDFg5UEiTc4DALJu7o6YBBG4wlVZbI-2kkaXd7u8RhBQPjmhsdcX3sDmCGmSr3WK9EkTRKStE2lb6ilOn-969h4dYWekwUUCSX"
}
],
"format": "tar.gz",
+2
View File
@@ -1,5 +1,6 @@
{
"name": "@react-native/debugger-shell",
"productName": "React Native DevTools",
"version": "0.82.0-main",
"description": "Experimental debugger shell for React Native for use with @react-native/debugger-frontend",
"keywords": [
@@ -34,6 +35,7 @@
},
"devDependencies": {
"electron": "37.2.6",
"electron-store": "^8.2.0",
"semver": "^7.1.3"
},
"files": [
@@ -9,10 +9,12 @@
*/
// $FlowFixMe[unclear-type] We have no Flow types for the Electron API.
const {BrowserWindow, app, shell, ipcMain} = require('electron') as any;
const {BrowserWindow, Menu, app, shell, ipcMain} = require('electron') as any;
const Store = require('electron-store');
const path = require('path');
const util = require('util');
const appSettings = new Store();
const windowMetadata = new WeakMap<
typeof BrowserWindow,
$ReadOnly<{
@@ -53,10 +55,11 @@ function handleLaunchArgs(argv: string[]) {
}, 1000);
}
} else {
// Create the browser window.
frontendWindow = new BrowserWindow({
width: 1200,
height: 600,
...(getSavedWindowPosition(windowKey) ?? {
width: 1200,
height: 600,
}),
webPreferences: {
partition: 'persist:react-native-devtools',
preload: require.resolve('./preload.js'),
@@ -66,6 +69,8 @@ function handleLaunchArgs(argv: string[]) {
});
// Auto-hide the Windows/Linux menu bar
frontendWindow.setMenuBarVisibility(false);
// Observe and update saved window position
setupWindowResizeListeners(frontendWindow, windowKey);
}
// Open links in the default browser instead of in new Electron windows.
@@ -91,8 +96,68 @@ function handleLaunchArgs(argv: string[]) {
frontendWindow.focus();
}
function configureAppMenu() {
const template = [
...(process.platform === 'darwin' ? [{role: 'appMenu'}] : []),
{role: 'fileMenu'},
{role: 'editMenu'},
{role: 'viewMenu'},
{role: 'windowMenu'},
{
role: 'help',
submenu: [
{
label: 'React Native Website',
click: () => shell.openExternal('https://reactnative.dev'),
},
{
label: 'Release Notes',
click: () =>
shell.openExternal(
'https://github.com/facebook/react-native/releases',
),
},
],
},
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
}
function getSavedWindowPosition(
windowKey: string,
): ?{width: number, height: number, x?: number, y?: number} {
return appSettings.get('windowArrangements', {})[windowKey];
}
function saveWindowPosition(
windowKey: string,
position: {x: number, y: number, width: number, height: number},
) {
const windowArrangements = appSettings.get('windowArrangements', {});
windowArrangements[windowKey] = position;
appSettings.set('windowArrangements', windowArrangements);
}
function setupWindowResizeListeners(
browserWindow: typeof BrowserWindow,
windowKey: string,
) {
const savePosition = () => {
if (!browserWindow.isDestroyed()) {
const [x, y] = browserWindow.getPosition();
const [width, height] = browserWindow.getSize();
saveWindowPosition(windowKey, {x, y, width, height});
}
};
browserWindow.on('moved', savePosition);
browserWindow.on('resized', savePosition);
browserWindow.on('closed', savePosition);
}
app.whenReady().then(() => {
handleLaunchArgs(process.argv.slice(app.isPackaged ? 1 : 2));
configureAppMenu();
app.on(
'second-instance',
@@ -16,9 +16,8 @@ const util = require('util');
// $FlowFixMe[unclear-type] We have no Flow types for the Electron API.
const {app} = require('electron') as any;
// Set the app name and version early - these are used in --version as well as
// in the User-Agent string.
app.setName(pkg.name);
// Set the application name and version
app.setName(pkg.productName ?? pkg.name);
app.setVersion(pkg.version + '-' + buildInfo.revision);
// Handle global command line arguments which don't require a window
@@ -31,7 +30,7 @@ const {
strict: false,
});
if (version) {
console.log(`${app.getName()} v${app.getVersion()}`);
console.log(`${pkg.name} v${app.getVersion()}`);
// Not app.quit() - we want to exit immediately without initialising the graphical subsystem.
app.exit(0);
}
+1 -1
View File
@@ -33,7 +33,7 @@
"nullthrows": "^1.1.1",
"open": "^7.0.3",
"serve-static": "^1.16.2",
"ws": "^6.2.3"
"ws": "^7.5.10"
},
"engines": {
"node": ">= 20.19.4"
@@ -98,11 +98,11 @@ class PrepareGlogTaskTest {
val glogThirdPartyJniPath = tempFolder.newFolder("glogpath/jni")
val output = tempFolder.newFolder("output")
val task =
createTestTask<PrepareGlogTask> {
it.glogPath.setFrom(glogpath)
it.glogThirdPartyJniPath.set(glogThirdPartyJniPath)
it.glogVersion.set("1.0.0")
it.outputDir.set(output)
createTestTask<PrepareGlogTask> { task ->
task.glogPath.setFrom(glogpath)
task.glogThirdPartyJniPath.set(glogThirdPartyJniPath)
task.glogVersion.set("1.0.0")
task.outputDir.set(output)
}
File(glogpath, "glog-1.0.0/src/glog.h.in").apply {
parentFile.mkdirs()
@@ -264,7 +264,7 @@ const Switch: component(
disabled,
onTintColor: trackColorForTrue,
style: StyleSheet.compose(
{height: 31, width: 51},
{alignSelf: 'flex-start' as const},
StyleSheet.compose(
style,
ios_backgroundColor == null
@@ -29,6 +29,16 @@ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
supportedCommands: ['hotspotUpdate', 'setPressed'],
});
/**
* `ViewNativeComponent` is an internal React Native host component, and is
* exported to provide lower-level access for libraries.
*
* @warning `<unstable_NativeView>` provides no semver guarantees and is not
* intended to be used in app code. Please use
* [`<View>`](https://reactnative.dev/docs/view) instead.
*/
// Additional note: Our long term plan is to reduce the overhead of the <Text>
// and <View> wrappers so that we no longer have any reason to export these APIs.
export default ViewNativeComponent;
export type ViewNativeComponentType = HostComponent<Props>;
+5 -1
View File
@@ -35,7 +35,11 @@ export interface SectionBase<ItemT, SectionT = DefaultSectionT> {
renderItem?: SectionListRenderItem<ItemT, SectionT> | undefined;
ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;
ItemSeparatorComponent?:
| React.ComponentType<any>
| React.ReactElement
| null
| undefined;
keyExtractor?: ((item: ItemT, index: number) => string) | undefined;
}
@@ -65,6 +65,16 @@ const virtualTextViewConfig = {
uiViewClassName: 'RCTVirtualText',
};
/**
* `NativeText` is an internal React Native host component, and is exported to
* provide lower-level access for libraries.
*
* @warning `<unstable_NativeText>` provides no semver guarantees and is not
* intended to be used in app code. Please use
* [`<Text>`](https://reactnative.dev/docs/text) instead.
*/
// Additional note: Our long term plan is to reduce the overhead of the <Text>
// and <View> wrappers so that we no longer have any reason to export these APIs.
export const NativeText: HostComponent<NativeTextProps> =
(createReactNativeComponentClass('RCTText', () =>
/* $FlowFixMe[incompatible-type] Natural Inference rollout. See
+17 -1
View File
@@ -68,6 +68,17 @@ let reactOSCompat = RNTarget(
path: "ReactCommon/oscompat"
)
let rctSwiftUI = RNTarget(
name: .rctSwiftUI,
path: "ReactApple/RCTSwiftUI"
)
let rctSwiftUIWrapper = RNTarget(
name: .rctSwiftUIWrapper,
path: "ReactApple/RCTSwiftUIWrapper",
dependencies: [.rctSwiftUI]
)
// React-rendererconsistency.podspec
let reactRendererConsistency = RNTarget(
name: .reactRendererConsistency,
@@ -439,7 +450,7 @@ let reactFabric = RNTarget(
let reactRCTFabric = RNTarget(
name: .reactRCTFabric,
path: "React/Fabric",
dependencies: [.reactNativeDependencies, .reactCore, .reactRCTImage, .yoga, .reactRCTText, .jsi, .reactFabricComponents, .reactGraphics, .reactImageManager, .reactDebug, .reactUtils, .reactPerformanceTimeline, .reactRendererDebug, .reactRendererConsistency, .reactRuntimeScheduler, .reactRCTAnimation, .reactJsInspector, .reactJsInspectorNetwork, .reactJsInspectorTracing, .reactFabric, .reactFabricImage]
dependencies: [.reactNativeDependencies, .reactCore, .reactRCTImage, .yoga, .reactRCTText, .jsi, .reactFabricComponents, .reactGraphics, .reactImageManager, .reactDebug, .reactUtils, .reactPerformanceTimeline, .reactRendererDebug, .reactRendererConsistency, .reactRuntimeScheduler, .reactRCTAnimation, .reactJsInspector, .reactJsInspectorNetwork, .reactJsInspectorTracing, .reactFabric, .reactFabricImage, .rctSwiftUIWrapper]
)
/// React-FabricComponents.podspec
@@ -579,6 +590,8 @@ let targets = [
reactCore,
reactCoreRCTWebsocket,
reactFabric,
rctSwiftUI,
rctSwiftUIWrapper,
reactRCTFabric,
reactFabricComponents,
reactFabricImage,
@@ -728,6 +741,9 @@ extension String {
static let logger = "React-logger"
static let mapbuffer = "React-Mapbuffer"
static let rctSwiftUI = "RCTSwiftUI"
static let rctSwiftUIWrapper = "RCTSwiftUIWrapper"
static let rctDeprecation = "RCT-Deprecation"
static let yoga = "Yoga"
static let reactUtils = "React-utils"
@@ -12,6 +12,7 @@
#import <objc/runtime.h>
#import <ranges>
#import <RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.h>
#import <React/RCTAssert.h>
#import <React/RCTBorderDrawing.h>
#import <React/RCTBoxShadow.h>
@@ -50,6 +51,7 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
UIView *_containerView;
BOOL _useCustomContainerView;
NSMutableSet<NSString *> *_accessibilityOrderNativeIDs;
RCTSwiftUIContainerViewWrapper *_swiftUIWrapper;
}
#ifdef RCT_DYNAMIC_FRAMEWORKS
@@ -576,6 +578,10 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
auto newTransform = _props->resolveTransform(layoutMetrics);
self.layer.transform = RCTCATransform3DFromTransformMatrix(newTransform);
}
if (_swiftUIWrapper != nullptr) {
[_swiftUIWrapper updateLayoutWithBounds:self.bounds];
}
}
- (BOOL)isJSResponder
@@ -793,43 +799,95 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
((!_props->boxShadow.empty() || (clipToPaddingBox && nonZeroBorderWidth)) || _props->outlineWidth != 0);
}
// The view that is used as the receiver for all styling (borders, background,
// etc.). Most of the time, this is just `self`. When a view has a filter like
// `blur` applied, we need to wrap it in a SwiftUI view to render the effect.
// In this case, `effectiveContentView` will be the content view inside the
// SwiftUI wrapper.
- (UIView *)effectiveContentView
{
if (!ReactNativeFeatureFlags::enableSwiftUIBasedFilters()) {
return self;
}
UIView *effectiveContentView = self;
if (self.styleNeedsSwiftUIContainer) {
if (_swiftUIWrapper == nullptr) {
_swiftUIWrapper = [RCTSwiftUIContainerViewWrapper new];
UIView *swiftUIContentView = [[UIView alloc] init];
for (UIView *subview = nullptr in self.subviews) {
[swiftUIContentView addSubview:subview];
}
swiftUIContentView.clipsToBounds = self.clipsToBounds;
self.clipsToBounds = NO;
swiftUIContentView.layer.mask = self.layer.mask;
self.layer.mask = nil;
[_swiftUIWrapper updateContentView:swiftUIContentView];
[_swiftUIWrapper updateLayoutWithBounds:self.bounds];
[self addSubview:_swiftUIWrapper.hostingView];
[self transferVisualPropertiesFromView:self toView:swiftUIContentView];
}
effectiveContentView = _swiftUIWrapper.contentView;
} else {
if (_swiftUIWrapper != nullptr) {
UIView *swiftUIContentView = _swiftUIWrapper.contentView;
for (UIView *subview = nullptr in swiftUIContentView.subviews) {
[self addSubview:subview];
}
self.clipsToBounds = swiftUIContentView.clipsToBounds;
self.layer.mask = swiftUIContentView.layer.mask;
[self transferVisualPropertiesFromView:swiftUIContentView toView:self];
[_swiftUIWrapper.hostingView removeFromSuperview];
_swiftUIWrapper = nil;
}
}
return effectiveContentView;
}
// This UIView is the UIView that holds all subviews. It is sometimes not self
// because we want to render "overflow ink" that extends beyond the bounds of
// the view and is not affected by clipping.
- (UIView *)currentContainerView
{
UIView *effectiveContentView = self.effectiveContentView;
if (_useCustomContainerView) {
if (!_containerView) {
_containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
for (UIView *subview in self.subviews) {
for (UIView *subview = nullptr in effectiveContentView.subviews) {
[_containerView addSubview:subview];
}
_containerView.clipsToBounds = self.clipsToBounds;
self.clipsToBounds = NO;
_containerView.layer.mask = self.layer.mask;
self.layer.mask = nil;
[self addSubview:_containerView];
_containerView.clipsToBounds = effectiveContentView.clipsToBounds;
effectiveContentView.clipsToBounds = NO;
_containerView.layer.mask = effectiveContentView.layer.mask;
effectiveContentView.layer.mask = nil;
[effectiveContentView addSubview:_containerView];
}
return _containerView;
effectiveContentView = _containerView;
} else {
if (_containerView) {
for (UIView *subview in _containerView.subviews) {
[self addSubview:subview];
[effectiveContentView addSubview:subview];
}
self.clipsToBounds = _containerView.clipsToBounds;
self.layer.mask = _containerView.layer.mask;
effectiveContentView.clipsToBounds = _containerView.clipsToBounds;
effectiveContentView.layer.mask = _containerView.layer.mask;
[_containerView removeFromSuperview];
_containerView = nil;
}
return self;
}
return effectiveContentView;
}
- (void)invalidateLayer
{
CALayer *layer = self.layer;
CALayer *layer = self.effectiveContentView.layer;
if (CGSizeEqualToSize(layer.bounds.size, CGSizeZero)) {
return;
@@ -910,7 +968,7 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
if (!_backgroundColorLayer) {
_backgroundColorLayer = [CALayer layer];
_backgroundColorLayer.zPosition = BACKGROUND_COLOR_ZPOSITION;
[self.layer addSublayer:_backgroundColorLayer];
[layer addSublayer:_backgroundColorLayer];
}
[self shapeLayerToMatchView:_backgroundColorLayer borderMetrics:borderMetrics];
_backgroundColorLayer.backgroundColor = backgroundColor.CGColor;
@@ -986,31 +1044,43 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
// filter
[_filterLayer removeFromSuperlayer];
_filterLayer = nil;
if (_swiftUIWrapper != nullptr) {
[_swiftUIWrapper updateBlurRadius:@(0)];
}
self.layer.opacity = (float)_props->opacity;
if (!_props->filter.empty()) {
float multiplicativeBrightness = 1;
bool hasBrightnessFilter = false;
for (const auto &primitive : _props->filter) {
if (std::holds_alternative<Float>(primitive.parameters)) {
if (primitive.type == FilterType::Brightness) {
multiplicativeBrightness *= std::get<Float>(primitive.parameters);
hasBrightnessFilter = true;
} else if (primitive.type == FilterType::Opacity) {
self.layer.opacity *= std::get<Float>(primitive.parameters);
} else if (primitive.type == FilterType::Blur) {
if (_swiftUIWrapper != nullptr) {
Float blurRadius = std::get<Float>(primitive.parameters);
[_swiftUIWrapper updateBlurRadius:@(blurRadius)];
}
}
}
}
_filterLayer = [CALayer layer];
[self shapeLayerToMatchView:_filterLayer borderMetrics:borderMetrics];
_filterLayer.compositingFilter = @"multiplyBlendMode";
_filterLayer.backgroundColor = [UIColor colorWithRed:multiplicativeBrightness
green:multiplicativeBrightness
blue:multiplicativeBrightness
alpha:self.layer.opacity]
.CGColor;
// So that this layer is always above any potential sublayers this view may
// add
_filterLayer.zPosition = CGFLOAT_MAX;
[self.layer addSublayer:_filterLayer];
if (hasBrightnessFilter) {
_filterLayer = [CALayer layer];
[self shapeLayerToMatchView:_filterLayer borderMetrics:borderMetrics];
_filterLayer.compositingFilter = @"multiplyBlendMode";
_filterLayer.backgroundColor = [UIColor colorWithRed:multiplicativeBrightness
green:multiplicativeBrightness
blue:multiplicativeBrightness
alpha:self.layer.opacity]
.CGColor;
// So that this layer is always above any potential sublayers this view may
// add
_filterLayer.zPosition = CGFLOAT_MAX;
[layer addSublayer:_filterLayer];
}
}
// background image
@@ -1025,7 +1095,7 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
[self shapeLayerToMatchView:backgroundImageLayer borderMetrics:borderMetrics];
backgroundImageLayer.masksToBounds = YES;
backgroundImageLayer.zPosition = BACKGROUND_COLOR_ZPOSITION;
[self.layer addSublayer:backgroundImageLayer];
[layer addSublayer:backgroundImageLayer];
[_backgroundImageLayers addObject:backgroundImageLayer];
} else if (std::holds_alternative<RadialGradient>(backgroundImage)) {
const auto &radialGradient = std::get<RadialGradient>(backgroundImage);
@@ -1034,7 +1104,7 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
[self shapeLayerToMatchView:backgroundImageLayer borderMetrics:borderMetrics];
backgroundImageLayer.masksToBounds = YES;
backgroundImageLayer.zPosition = BACKGROUND_COLOR_ZPOSITION;
[self.layer addSublayer:backgroundImageLayer];
[layer addSublayer:backgroundImageLayer];
[_backgroundImageLayers addObject:backgroundImageLayer];
}
}
@@ -1056,7 +1126,7 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths),
self.layer.bounds.size);
shadowLayer.zPosition = _borderLayer.zPosition;
[self.layer addSublayer:shadowLayer];
[layer addSublayer:shadowLayer];
[_boxShadowLayers addObject:shadowLayer];
}
}
@@ -1410,6 +1480,66 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
return RCTNSStringFromString([[self class] componentDescriptorProvider].name);
}
- (BOOL)styleNeedsSwiftUIContainer
{
if (!_props->filter.empty()) {
for (const auto &primitive : _props->filter) {
if (primitive.type == FilterType::Blur) {
return YES;
}
}
}
return NO;
}
- (void)transferVisualPropertiesFromView:(UIView *)sourceView toView:(UIView *)destinationView
{
// shadow
destinationView.layer.shadowColor = sourceView.layer.shadowColor;
sourceView.layer.shadowColor = nil;
destinationView.layer.shadowOffset = sourceView.layer.shadowOffset;
sourceView.layer.shadowOffset = CGSizeZero;
destinationView.layer.shadowOpacity = sourceView.layer.shadowOpacity;
sourceView.layer.shadowOpacity = 0;
destinationView.layer.shadowRadius = sourceView.layer.shadowRadius;
sourceView.layer.shadowRadius = 0;
// background
destinationView.layer.backgroundColor = sourceView.layer.backgroundColor;
sourceView.layer.backgroundColor = nil;
if (_backgroundColorLayer != nullptr) {
[destinationView.layer addSublayer:_backgroundColorLayer];
}
// border
destinationView.layer.borderColor = sourceView.layer.borderColor;
sourceView.layer.borderColor = nil;
destinationView.layer.borderWidth = sourceView.layer.borderWidth;
sourceView.layer.borderWidth = 0;
// corner
destinationView.layer.cornerRadius = sourceView.layer.cornerRadius;
sourceView.layer.cornerRadius = 0;
destinationView.layer.cornerCurve = sourceView.layer.cornerCurve;
// custom layers
if (_borderLayer != nullptr) {
[destinationView.layer addSublayer:_borderLayer];
}
if (_outlineLayer != nullptr) {
[destinationView.layer addSublayer:_outlineLayer];
}
if (_filterLayer != nullptr) {
[destinationView.layer addSublayer:_filterLayer];
}
for (CALayer *layer = nullptr in _backgroundImageLayers) {
[destinationView.layer addSublayer:layer];
}
for (CALayer *layer = nullptr in _boxShadowLayers) {
[destinationView.layer addSublayer:layer];
}
}
@end
#ifdef __cplusplus
@@ -63,6 +63,7 @@ Pod::Spec.new do |s|
s.dependency "Yoga"
s.dependency "React-RCTText"
s.dependency "React-jsi"
s.dependency "RCTSwiftUIWrapper"
add_dependency(s, "React-FabricImage")
add_dependency(s, "React-Fabric", :additional_framework_paths => [
@@ -0,0 +1,16 @@
/*
* 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 <UIKit/UIKit.h>
#import <React/RCTDefines.h>
NS_ASSUME_NONNULL_BEGIN
RCT_EXTERN UIFont *__nullable RCTGetLegacyDefaultFont(CGFloat fontSize, UIFontWeight fontWeight);
NS_ASSUME_NONNULL_END
+3 -1
View File
@@ -17,8 +17,10 @@ typedef CGFloat RCTFontWeight;
* provide a different base font, use this override. The font weight supplied to your
* handler will be one of "ultralight", "thin", "light", "regular", "medium",
* "semibold", "extrabold", "bold", "heavy", or "black".
*
* @deprecated Use RCTSetDefaultFontResolver
*/
RCT_EXTERN void RCTSetDefaultFontHandler(RCTFontHandler handler);
RCT_EXTERN void RCTSetDefaultFontHandler(RCTFontHandler handler) __attribute__((deprecated));
RCT_EXTERN BOOL RCTHasFontHandlerSet(void);
RCT_EXTERN RCTFontWeight RCTGetFontWeight(UIFont *font);
+13 -2
View File
@@ -6,6 +6,8 @@
*/
#import "RCTFont.h"
#import "RCTFont+Private.h"
#import "RCTAssert.h"
#import "RCTLog.h"
@@ -122,6 +124,15 @@ static NSString *FontWeightDescriptionFromUIFontWeight(UIFontWeight fontWeight)
return @"regular";
}
UIFont *RCTGetLegacyDefaultFont(CGFloat size, UIFontWeight fontWeight)
{
if (defaultFontHandler != nil) {
return defaultFontHandler(size, FontWeightDescriptionFromUIFontWeight(fontWeight));
} else {
return nil;
}
}
static UIFont *cachedSystemFont(CGFloat size, RCTFontWeight weight)
{
static NSCache<NSValue *, UIFont *> *fontCache = [NSCache new];
@@ -135,8 +146,8 @@ static UIFont *cachedSystemFont(CGFloat size, RCTFontWeight weight)
NSValue *cacheKey = [[NSValue alloc] initWithBytes:&key objCType:@encode(CacheKey)];
UIFont *font = [fontCache objectForKey:cacheKey];
if (!font) {
if (defaultFontHandler) {
if (font == nil) {
if (defaultFontHandler != nil) {
NSString *fontWeightDescription = FontWeightDescriptionFromUIFontWeight(weight);
font = defaultFontHandler(size, fontWeightDescription);
} else {
@@ -5246,6 +5246,7 @@ public class com/facebook/react/viewmanagers/VirtualViewExperimentalManagerDeleg
public abstract interface class com/facebook/react/viewmanagers/VirtualViewExperimentalManagerInterface : com/facebook/react/uimanager/ViewManagerWithGeneratedInterface {
public abstract fun setInitialHidden (Landroid/view/View;Z)V
public abstract fun setRemoveClippedSubviews (Landroid/view/View;Z)V
public abstract fun setRenderState (Landroid/view/View;I)V
}
@@ -6725,9 +6726,10 @@ public final class com/facebook/react/views/virtual/viewexperimental/ReactVirtua
public fun onLayoutChange (Landroid/view/View;IIIIIIII)V
public fun onModeChange (Lcom/facebook/react/views/virtual/VirtualViewMode;Landroid/graphics/Rect;)V
public synthetic fun recycleView$xplat_js_react_native_github_packages_react_native_ReactAndroid_src_main_java_com_facebook_react_views_view_viewAndroid ()V
public fun updateClippingRect (Ljava/util/Set;)V
}
public final class com/facebook/react/views/virtual/viewexperimental/ReactVirtualViewExperimentalManager : com/facebook/react/uimanager/ViewGroupManager, com/facebook/react/viewmanagers/VirtualViewExperimentalManagerInterface {
public final class com/facebook/react/views/virtual/viewexperimental/ReactVirtualViewExperimentalManager : com/facebook/react/views/view/ReactClippingViewManager, com/facebook/react/viewmanagers/VirtualViewExperimentalManagerInterface {
public static final field Companion Lcom/facebook/react/views/virtual/viewexperimental/ReactVirtualViewExperimentalManager$Companion;
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
@@ -6739,6 +6741,7 @@ public final class com/facebook/react/views/virtual/viewexperimental/ReactVirtua
public fun setInitialHidden (Lcom/facebook/react/views/virtual/viewexperimental/ReactVirtualViewExperimental;Z)V
public synthetic fun setNativeId (Landroid/view/View;Ljava/lang/String;)V
public fun setNativeId (Lcom/facebook/react/views/virtual/viewexperimental/ReactVirtualViewExperimental;Ljava/lang/String;)V
public synthetic fun setRemoveClippedSubviews (Landroid/view/View;Z)V
public synthetic fun setRenderState (Landroid/view/View;I)V
public fun setRenderState (Lcom/facebook/react/views/virtual/viewexperimental/ReactVirtualViewExperimental;I)V
}
@@ -196,11 +196,9 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext) :
private val nodesManagerRef = AtomicReference<NativeAnimatedNodesManager?>()
private var batchingControlledByJS = false // TODO T71377544: delete
@Volatile private var currentFrameNumber: Long = 0
@Volatile private var currentFrameNumber: Long = 0 // TODO T71377544: delete
@Volatile private var currentBatchNumber: Long = 0
@Volatile private var currentBatchNumber: Long = 0 // frame number at last operations dispatch
private var initializedForFabric = false
private var initializedForNonFabric = false
@@ -282,22 +280,19 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext) :
var batchNumber = currentBatchNumber - 1
// TODO T71377544: delete this when the JS method is confirmed safe
if (!batchingControlledByJS) {
// The problem we're trying to solve here: we could be in the middle of queueing
// a batch of related animation operations when Fabric flushes a batch of MountItems.
// It's visually bad if we execute half of the animation ops and then wait another frame
// (or more) to execute the rest.
// See mFrameNumber. If the dispatchedFrameNumber drifts too far - that
// is, if no MountItems are scheduled for a while, which can happen if a tree
// is committed but there are no changes - bring these counts back in sync and
// execute any queued operations. This number is arbitrary, but we want it low
// enough that the user shouldn't be able to see this delay in most cases.
currentFrameNumber++
if ((currentFrameNumber - currentBatchNumber) > 2) {
currentBatchNumber = currentFrameNumber
batchNumber = currentBatchNumber
}
// The problem we're trying to solve here: we could be in the middle of queueing
// a batch of related animation operations when Fabric flushes a batch of MountItems.
// It's visually bad if we execute half of the animation ops and then wait another frame
// (or more) to execute the rest.
// See mFrameNumber. If the dispatchedFrameNumber drifts too far - that
// is, if no MountItems are scheduled for a while, which can happen if a tree
// is committed but there are no changes - bring these counts back in sync and
// execute any queued operations. This number is arbitrary, but we want it low
// enough that the user shouldn't be able to see this delay in most cases.
currentFrameNumber++
if ((currentFrameNumber - currentBatchNumber) > 2) {
currentBatchNumber = currentFrameNumber
batchNumber = currentBatchNumber
}
preOperations.executeBatch(batchNumber, nodesManager)
@@ -484,14 +479,14 @@ public class NativeAnimatedModule(reactContext: ReactApplicationContext) :
}
}
@Suppress("DEPRECATION")
override fun startOperationBatch() {
batchingControlledByJS = true
currentBatchNumber++
// no-op
}
@Suppress("DEPRECATION")
override fun finishOperationBatch() {
batchingControlledByJS = false
currentBatchNumber++
// no-op
}
override fun createAnimatedNode(tagDouble: Double, config: ReadableMap) {
@@ -774,12 +774,8 @@ public class NativeAnimatedNodesManager(
("Looks like animated nodes graph has ${reason}, there are $activeNodesCount but toposort visited only $updatedNodesCount")
)
if (eventListenerInitializedForFabric && cyclesDetected == 0) {
// TODO T71377544: investigate these SoftExceptions and see if we can remove entirely
// or fix the root cause
ReactSoftExceptionLogger.logSoftException(TAG, ReactNoCrashSoftException(ex))
} else if (eventListenerInitializedForFabric) {
// TODO T71377544: investigate these SoftExceptions and see if we can remove entirely
// or fix the root cause
ReactSoftExceptionLogger.logSoftException(TAG, ReactNoCrashSoftException(ex))
} else {
throw ex
@@ -25,7 +25,7 @@ public abstract class ReactContextBaseJavaModule : BaseJavaModule {
* this method whenever you actually need the Activity and make sure to check for `null`.
*/
@Deprecated(
"Deprecated in 0.80.0. Use getReactApplicationContext.getCurrentActivity() instead.",
"Deprecated in 0.80.0. Use getReactApplicationContext().getCurrentActivity() instead.",
ReplaceWith("reactApplicationContext.currentActivity"),
)
protected fun getCurrentActivity(): Activity? {
@@ -229,6 +229,7 @@ public abstract class DevSupportManagerBase(
}
context
},
{ openDebugger(DebuggerFrontendPanelName.PERFORMANCE.toString()) },
)
}
}
@@ -386,10 +387,14 @@ public abstract class DevSupportManagerBase(
TracingState.ENABLEDINBACKGROUNDMODE ->
DevOptionHandler {
UiThreadUtil.runOnUiThread {
if (reactInstanceDevHelper is PerfMonitorDevHelper)
reactInstanceDevHelper.inspectorTarget?.pauseAndAnalyzeBackgroundTrace()
if (reactInstanceDevHelper is PerfMonitorDevHelper) {
reactInstanceDevHelper.inspectorTarget?.let {
if (it.pauseAndAnalyzeBackgroundTrace()) {
openDebugger(DebuggerFrontendPanelName.PERFORMANCE.toString())
}
}
}
}
openDebugger(DebuggerFrontendPanelName.PERFORMANCE.toString())
}
TracingState.DISABLED ->
DevOptionHandler {
@@ -17,8 +17,11 @@ internal interface PerfMonitorInspectorTargetBinding {
/** Get the current CDP or background performance tracing state. */
public fun getTracingState(): TracingState
/** Attempt to pause the current background performance trace, and open in DevTools. */
public fun pauseAndAnalyzeBackgroundTrace()
/**
* Attempt to pause the current background performance trace, and open in DevTools. Returns true
* if there is an active session that can display the trace, false otherwise.
*/
public fun pauseAndAnalyzeBackgroundTrace(): Boolean
/** Attempt to start a new background performance trace. */
public fun resumeBackgroundTrace()
@@ -15,10 +15,12 @@ import javax.inject.Provider
internal class PerfMonitorOverlayManager(
private val devHelper: PerfMonitorDevHelper,
private val contextProvider: Provider<Context?>,
private val onRequestOpenDevTools: () -> Unit,
) : PerfMonitorUpdateListener {
private var enabled: Boolean = false
private var initialized: Boolean = false
private var view: PerfMonitorOverlayView? = null
private var tracingState: TracingState = TracingState.ENABLEDINCDPMODE
private fun init() {
if (initialized || !enabled) {
@@ -27,7 +29,7 @@ internal class PerfMonitorOverlayManager(
UiThreadUtil.runOnUiThread {
val context = contextProvider.get() ?: return@runOnUiThread
view = PerfMonitorOverlayView(context)
view = PerfMonitorOverlayView(context, ::handleRecordingButtonPress)
// Start background tracing
devHelper.inspectorTarget?.resumeBackgroundTrace()
@@ -59,6 +61,23 @@ internal class PerfMonitorOverlayManager(
}
override fun onRecordingStateChanged(state: TracingState) {
tracingState = state
view?.updateRecordingState(state)
}
private fun handleRecordingButtonPress() {
when (tracingState) {
TracingState.ENABLEDINBACKGROUNDMODE -> {
devHelper.inspectorTarget?.let {
if (!it.pauseAndAnalyzeBackgroundTrace()) {
onRequestOpenDevTools()
}
}
}
TracingState.DISABLED -> {
devHelper.inspectorTarget?.resumeBackgroundTrace()
}
TracingState.ENABLEDINCDPMODE -> Unit
}
}
}
@@ -27,6 +27,7 @@ import com.facebook.react.uimanager.PixelUtil
internal class PerfMonitorOverlayView(
private val context: Context,
private val onButtonPress: () -> Unit,
) {
private val dialog: Dialog
private lateinit var statusLabel: TextView
@@ -101,6 +102,7 @@ internal class PerfMonitorOverlayView(
textContainer.addView(tooltipLabel)
val containerLayout = createInnerLayout()
containerLayout.setOnClickListener { onButtonPress() }
containerLayout.addView(statusIndicator)
containerLayout.addView(textContainer)
@@ -108,12 +110,7 @@ internal class PerfMonitorOverlayView(
createAnchoredDialog(dpToPx(12f), dpToPx(12f)).apply { setContentView(containerLayout) }
dialog.window?.apply {
attributes =
attributes?.apply {
flags =
flags or
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
}
attributes?.apply { flags = flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE }
}
return dialog
@@ -99,7 +99,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -738,11 +737,17 @@ public class FabricUIManager
* vertical insets.
*/
private long getEncodedScreenSizeWithoutVerticalInsets(int surfaceId) {
SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
Objects.requireNonNull(surfaceMountingManager);
ThemedReactContext context = Objects.requireNonNull(surfaceMountingManager.getContext());
return DisplayMetricsHolder.getEncodedScreenSizeWithoutVerticalInsets(
context.getCurrentActivity());
ThemedReactContext context =
mMountingManager
.getSurfaceManagerEnforced(surfaceId, "getEncodedScreenSizeWithoutVerticalInsets")
.getContext();
if (context == null) {
FLog.w(TAG, "Couldn't get context from SurfaceMountingManager for surfaceId %d", surfaceId);
return 0;
} else {
return DisplayMetricsHolder.getEncodedScreenSizeWithoutVerticalInsets(
context.getCurrentActivity());
}
}
@Override
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<af10f4eea240ae4a228de9bbc4b78b7e>>
* @generated SignedSource<<f089964c958dfcac00f83c3371ccbefc>>
*/
/**
@@ -252,6 +252,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableResourceTimingAPI(): Boolean = accessor.enableResourceTimingAPI()
/**
* When enabled, it will use SwiftUI for filter effects like blur on iOS.
*/
@JvmStatic
public fun enableSwiftUIBasedFilters(): Boolean = accessor.enableSwiftUIBasedFilters()
/**
* Enables View Culling: as soon as a view goes off screen, it can be reused anywhere in the UI and pieced together with other items to create new UI elements.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<0b5ee4e7d8800ea89c97b2501d121b6e>>
* @generated SignedSource<<912dec895495052328e7e52b94a6738a>>
*/
/**
@@ -57,6 +57,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enablePreparedTextLayoutCache: Boolean? = null
private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null
private var enableResourceTimingAPICache: Boolean? = null
private var enableSwiftUIBasedFiltersCache: Boolean? = null
private var enableViewCullingCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var enableViewRecyclingForImageCache: Boolean? = null
@@ -426,6 +427,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableSwiftUIBasedFilters(): Boolean {
var cached = enableSwiftUIBasedFiltersCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableSwiftUIBasedFilters()
enableSwiftUIBasedFiltersCache = cached
}
return cached
}
override fun enableViewCulling(): Boolean {
var cached = enableViewCullingCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<5fbbabfffca4f13066ad1ab7f9462c13>>
* @generated SignedSource<<ba1e53d93b9fdaf298a034543bc44a57>>
*/
/**
@@ -102,6 +102,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableResourceTimingAPI(): Boolean
@DoNotStrip @JvmStatic public external fun enableSwiftUIBasedFilters(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewCulling(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewRecycling(): Boolean
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<bcad5baef5d072b71afba69bffabdb41>>
* @generated SignedSource<<7601cbcde75ff19ef0fe67f6faef2549>>
*/
/**
@@ -97,6 +97,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableResourceTimingAPI(): Boolean = false
override fun enableSwiftUIBasedFilters(): Boolean = false
override fun enableViewCulling(): Boolean = false
override fun enableViewRecycling(): Boolean = false
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<0733f7a2ea498a0230bcfaa5b15a0b89>>
* @generated SignedSource<<3a13f8e35423b634ed4ef46fbac3c1e9>>
*/
/**
@@ -61,6 +61,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enablePreparedTextLayoutCache: Boolean? = null
private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null
private var enableResourceTimingAPICache: Boolean? = null
private var enableSwiftUIBasedFiltersCache: Boolean? = null
private var enableViewCullingCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var enableViewRecyclingForImageCache: Boolean? = null
@@ -467,6 +468,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun enableSwiftUIBasedFilters(): Boolean {
var cached = enableSwiftUIBasedFiltersCache
if (cached == null) {
cached = currentProvider.enableSwiftUIBasedFilters()
accessedFeatureFlags.add("enableSwiftUIBasedFilters")
enableSwiftUIBasedFiltersCache = cached
}
return cached
}
override fun enableViewCulling(): Boolean {
var cached = enableViewCullingCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a51d970a5ea4e74b7871cc9521f9edce>>
* @generated SignedSource<<143b568248e68033efaefc3f178ff6db>>
*/
/**
@@ -97,6 +97,8 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableResourceTimingAPI(): Boolean
@DoNotStrip public fun enableSwiftUIBasedFilters(): Boolean
@DoNotStrip public fun enableViewCulling(): Boolean
@DoNotStrip public fun enableViewRecycling(): Boolean
@@ -55,7 +55,7 @@ public class AndroidInfoModule(reactContext: ReactApplicationContext) :
constants["ServerHost"] =
AndroidInfoHelpers.getServerHost(reactApplicationContext.applicationContext)
}
constants["isTesting"] = "true" == System.getProperty(IS_TESTING) || isRunningScreenshotTest()
constants["isTesting"] = "true" == System.getProperty(IS_TESTING)
val isDisableAnimations = System.getProperty(IS_DISABLE_ANIMATIONS)
if (isDisableAnimations != null) {
constants["isDisableAnimations"] = "true" == isDisableAnimations
@@ -71,15 +71,6 @@ public class AndroidInfoModule(reactContext: ReactApplicationContext) :
override fun invalidate() {}
private fun isRunningScreenshotTest(): Boolean {
return try {
Class.forName("com.facebook.testing.react.screenshots.ReactAppScreenshotTestActivity")
true
} catch (ignored: ClassNotFoundException) {
false
}
}
public companion object {
public const val NAME: String = NativePlatformConstantsAndroidSpec.NAME
private const val IS_TESTING = "IS_TESTING"
@@ -37,7 +37,7 @@ internal class ReactHostInspectorTarget(reactHostImpl: ReactHostImpl) :
external fun startBackgroundTrace(): Boolean
external fun stopAndStashBackgroundTrace()
external fun stopAndMaybeEmitBackgroundTrace(): Boolean
external fun stopAndDiscardBackgroundTrace()
@@ -51,11 +51,13 @@ internal class ReactHostInspectorTarget(reactHostImpl: ReactHostImpl) :
perfMonitorListeners.add(listener)
}
override fun pauseAndAnalyzeBackgroundTrace() {
stopAndStashBackgroundTrace()
override fun pauseAndAnalyzeBackgroundTrace(): Boolean {
val emitted = stopAndMaybeEmitBackgroundTrace()
perfMonitorListeners.forEach { listener ->
listener.onRecordingStateChanged(TracingState.DISABLED)
}
return emitted
}
override fun resumeBackgroundTrace() {
@@ -50,11 +50,13 @@ private fun rectsOverlap(rect1: Rect, rect2: Rect): Boolean {
internal class VirtualViewContainerState {
private val prerenderRatio: Double = ReactNativeFeatureFlags.virtualViewPrerenderRatio()
private val hysteresisRatio: Double = ReactNativeFeatureFlags.virtualViewHysteresisRatio()
private val virtualViews: MutableSet<VirtualView> = mutableSetOf()
private val emptyRect: Rect = Rect()
private val visibleRect: Rect = Rect()
private val prerenderRect: Rect = Rect()
private val hysteresisRect: Rect = Rect()
private val onWindowFocusChangeListener =
if (ReactNativeFeatureFlags.enableVirtualViewWindowFocusDetection()) {
ViewTreeObserver.OnWindowFocusChangeListener {
@@ -119,11 +121,12 @@ internal class VirtualViewContainerState {
(-prerenderRect.height() * prerenderRatio).toInt(),
)
val virtualViewsIt = if (virtualView != null) listOf(virtualView) else virtualViews
val virtualViewsIt =
if (virtualView != null) listOf(virtualView) else virtualViews.toMutableSet()
virtualViewsIt.forEach { vv ->
val rect = vv.containerRelativeRect
var mode = VirtualViewMode.Hidden
var mode: VirtualViewMode? = VirtualViewMode.Hidden
var thresholdRect = emptyRect
when {
rectsOverlap(rect, visibleRect) -> {
@@ -142,14 +145,29 @@ internal class VirtualViewContainerState {
mode = VirtualViewMode.Prerender
thresholdRect = prerenderRect
}
else -> {}
else -> {
if (hysteresisRatio > 0.0) {
hysteresisRect.set(prerenderRect)
hysteresisRect.inset(
(-visibleRect.width() * hysteresisRatio).toInt(),
(-visibleRect.height() * hysteresisRatio).toInt(),
)
if (rectsOverlap(rect, hysteresisRect)) {
mode = null
}
}
}
}
debugLog(
"updateModes",
{ "virtualView=${vv.virtualViewID} mode=$mode rect=$rect thresholdRect=$thresholdRect" },
)
vv.onModeChange(mode, thresholdRect)
if (mode != null) {
vv.onModeChange(mode, thresholdRect)
debugLog(
"updateModes",
{
"virtualView=${vv.virtualViewID} mode=$mode rect=$rect thresholdRect=$thresholdRect"
},
)
}
}
}
}
@@ -16,9 +16,11 @@ import com.facebook.common.logging.FLog
import com.facebook.react.R
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.uimanager.ReactClippingViewGroup
import com.facebook.react.uimanager.ReactRoot
import com.facebook.react.views.scroll.VirtualView
import com.facebook.react.views.scroll.VirtualViewContainer
import com.facebook.react.views.scroll.debugLog
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.virtual.VirtualViewMode
import com.facebook.react.views.virtual.VirtualViewModeChangeEmitter
@@ -34,6 +36,7 @@ public class ReactVirtualViewExperimental(context: Context) :
private var scrollView: VirtualViewContainer? = null
private val lastContainerRelativeRect: Rect = Rect()
private val lastClippingRect: Rect = Rect()
override val containerRelativeRect: Rect = Rect()
private var offsetX: Int = 0
private var offsetY: Int = 0
@@ -120,6 +123,7 @@ public class ReactVirtualViewExperimental(context: Context) :
modeChangeEmitter = null
hadLayout = false
lastContainerRelativeRect.setEmpty()
lastClippingRect.setEmpty()
containerRelativeRect.setEmpty()
}
@@ -132,7 +136,12 @@ public class ReactVirtualViewExperimental(context: Context) :
modeChangeEmitter ?: return
scrollView ?: return
if (newMode == VirtualViewMode.Visible) {
updateClippingRect(null)
}
if (newMode == mode) {
debugLog("onModeChange") { "no change $newMode" }
return
}
@@ -141,6 +150,10 @@ public class ReactVirtualViewExperimental(context: Context) :
debugLog("onModeChange") { "$oldMode->$newMode" }
if (oldMode == VirtualViewMode.Visible) {
updateClippingRect(null)
}
when (newMode) {
VirtualViewMode.Visible -> {
if (renderState == VirtualViewRenderState.Unknown) {
@@ -187,6 +200,37 @@ public class ReactVirtualViewExperimental(context: Context) :
}
}
// Note: We co-opt subview clipping on ReactVirtualView by returning the
// clipping rect of the ScrollView. This means we clip the children of ReactVirtualView
// when they are out of the viewport, but not ReactVirtualView itself.
override fun updateClippingRect(excludedViews: Set<Int>?) {
if (!_removeClippedSubviews) {
return
}
// If no ScrollView, or ScrollView has disabled removeClippedSubviews, use default behavior
if (
scrollView == null ||
!((scrollView as ReactClippingViewGroup)?.removeClippedSubviews ?: false)
) {
super.updateClippingRect(excludedViews)
return
}
val clippingRect = checkNotNull(clippingRect)
(scrollView as ReactClippingViewGroup).getClippingRect(clippingRect)
clippingRect.intersect(containerRelativeRect)
clippingRect.offset(-containerRelativeRect.left, -containerRelativeRect.top)
if (lastClippingRect == clippingRect) {
return
}
updateClippingToRect(clippingRect, excludedViews)
lastClippingRect.set(clippingRect)
}
private fun updateParentOffset() {
val virtualViewScrollView = scrollView ?: return
offsetX = 0
@@ -212,8 +256,11 @@ public class ReactVirtualViewExperimental(context: Context) :
debugLog("reportRectChangeToContainer") { "no rect change $containerRelativeRect" }
return
}
scrollView?.virtualViewContainerState?.onChange(this)
lastContainerRelativeRect.set(containerRelativeRect)
if (scrollView != null) {
scrollView?.virtualViewContainerState?.onChange(this)
lastContainerRelativeRect.set(containerRelativeRect)
}
}
private fun getScrollView(): VirtualViewContainer? = traverseParentStack(true)
@@ -13,12 +13,12 @@ import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.viewmanagers.VirtualViewExperimentalManagerDelegate
import com.facebook.react.viewmanagers.VirtualViewExperimentalManagerInterface
import com.facebook.react.views.view.ReactClippingViewManager
import com.facebook.react.views.virtual.VirtualViewMode
import com.facebook.react.views.virtual.VirtualViewModeChangeEmitter
import com.facebook.react.views.virtual.VirtualViewModeChangeEvent
@@ -26,7 +26,7 @@ import com.facebook.react.views.virtual.VirtualViewRenderState
@ReactModule(name = ReactVirtualViewExperimentalManager.REACT_CLASS)
public class ReactVirtualViewExperimentalManager :
ViewGroupManager<ReactVirtualViewExperimental>(),
ReactClippingViewManager<ReactVirtualViewExperimental>(),
VirtualViewExperimentalManagerInterface<ReactVirtualViewExperimental> {
private val _delegate = VirtualViewExperimentalManagerDelegate(this)
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b3357ac501bc00f026a3a7ed90c83ba3>>
* @generated SignedSource<<92c9aa29df580c6d12faa14e60b00e4f>>
*/
/**
@@ -261,6 +261,12 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}
bool enableSwiftUIBasedFilters() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableSwiftUIBasedFilters");
return method(javaProvider_);
}
bool enableViewCulling() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableViewCulling");
@@ -660,6 +666,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableResourceTimingAPI(
return ReactNativeFeatureFlags::enableResourceTimingAPI();
}
bool JReactNativeFeatureFlagsCxxInterop::enableSwiftUIBasedFilters(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableSwiftUIBasedFilters();
}
bool JReactNativeFeatureFlagsCxxInterop::enableViewCulling(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableViewCulling();
@@ -977,6 +988,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableResourceTimingAPI",
JReactNativeFeatureFlagsCxxInterop::enableResourceTimingAPI),
makeNativeMethod(
"enableSwiftUIBasedFilters",
JReactNativeFeatureFlagsCxxInterop::enableSwiftUIBasedFilters),
makeNativeMethod(
"enableViewCulling",
JReactNativeFeatureFlagsCxxInterop::enableViewCulling),
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<2c969005f4c7bb24f98bf4e3ed3dc0e9>>
* @generated SignedSource<<124d1378990fdd09a4d97f9103f81a6a>>
*/
/**
@@ -141,6 +141,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableResourceTimingAPI(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableSwiftUIBasedFilters(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableViewCulling(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -157,9 +157,16 @@ tracing::TraceRecordingState JReactHostInspectorTarget::stopTracing() {
}
}
void JReactHostInspectorTarget::stopAndStashBackgroundTrace() {
jboolean JReactHostInspectorTarget::stopAndMaybeEmitBackgroundTrace() {
auto capturedTrace = inspectorTarget_->stopTracing();
if (inspectorTarget_->hasActiveSessionWithFuseboxClient()) {
inspectorTarget_->emitTraceRecordingForFirstFuseboxClient(
std::move(capturedTrace));
return jboolean(true);
}
stashTraceRecordingState(std::move(capturedTrace));
return jboolean(false);
}
void JReactHostInspectorTarget::stopAndDiscardBackgroundTrace() {
@@ -188,8 +195,8 @@ void JReactHostInspectorTarget::registerNatives() {
"startBackgroundTrace",
JReactHostInspectorTarget::startBackgroundTrace),
makeNativeMethod(
"stopAndStashBackgroundTrace",
JReactHostInspectorTarget::stopAndStashBackgroundTrace),
"stopAndMaybeEmitBackgroundTrace",
JReactHostInspectorTarget::stopAndMaybeEmitBackgroundTrace),
makeNativeMethod(
"stopAndDiscardBackgroundTrace",
JReactHostInspectorTarget::stopAndDiscardBackgroundTrace),
@@ -82,17 +82,6 @@ class JReactHostInspectorTarget
static void registerNatives();
void sendDebuggerResumeCommand();
/**
* Starts a background trace recording for this HostTarget.
*
* \return false if already tracing, true otherwise.
*/
bool startBackgroundTrace();
/**
* Stops previously started trace recording and stashes the captured trace,
* which will be emitted the next time CDP session is created.
*/
void stopAndStashBackgroundTrace();
/**
* Get the state of the background trace: running, stopped, or disabled
* Background tracing will be disabled if there is no metro connection or if
@@ -101,6 +90,20 @@ class JReactHostInspectorTarget
* \return the background trace state
*/
jint tracingState();
/**
* Starts a background trace recording for this HostTarget.
*
* \return false if already tracing, true otherwise.
*/
bool startBackgroundTrace();
/**
* Stops previously started trace recording and:
* - If there is an active CDP session with Fusebox client enabled, emits the
* trace and returns true.
* - Otherwise, stashes the captured trace, that will be emitted when the CDP
* session is initialized. Returns false.
*/
jboolean stopAndMaybeEmitBackgroundTrace();
/**
* Stops previously started trace recording and discards the captured trace.
*/
@@ -0,0 +1,39 @@
# 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.
require "json"
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which we're presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
Pod::Spec.new do |s|
s.name = "RCTSwiftUI"
s.version = version
s.summary = "Swift utilities for React Native."
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.source_files = "*.{h,m,swift}"
s.public_header_files = "*.h"
s.module_name = "RCTSwiftUI"
s.header_dir = "RCTSwiftUI"
# Swift-specific configuration
s.pod_target_xcconfig = {
"SWIFT_VERSION" => "5.0",
"DEFINES_MODULE" => "YES",
}
end
@@ -0,0 +1,76 @@
/*
* 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 SwiftUI
import UIKit
@MainActor @objc public class RCTSwiftUIContainerView: NSObject {
private var containerViewModel = ContainerViewModel()
private var hostingController: UIHostingController<SwiftUIContainerView>?
@objc public override init() {
super.init()
hostingController = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel))
guard let view = hostingController?.view else {
return
}
view.backgroundColor = .clear
}
@objc public func updateContentView(_ view: UIView) {
containerViewModel.contentView = view
}
@objc public func hostingView() -> UIView? {
return hostingController?.view
}
@objc public func contentView() -> UIView? {
return containerViewModel.contentView
}
@objc public func updateBlurRadius(_ radius: NSNumber) {
let blurRadius = CGFloat(radius.floatValue)
containerViewModel.blurRadius = blurRadius
}
@objc public func updateLayout(withBounds bounds: CGRect) {
hostingController?.view.frame = bounds
containerViewModel.contentView?.frame = bounds
}
@objc public func resetStyles() {
containerViewModel.blurRadius = 0
}
}
class ContainerViewModel: ObservableObject {
@Published var blurRadius: CGFloat = 0
@Published var contentView: UIView?
}
struct SwiftUIContainerView: View {
@ObservedObject var viewModel: ContainerViewModel
var body: some View {
if let contentView = viewModel.contentView {
UIViewWrapper(view: contentView)
.blur(radius: viewModel.blurRadius)
}
}
}
struct UIViewWrapper: UIViewRepresentable {
let view: UIView
func makeUIView(context: Context) -> UIView {
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
}
}
@@ -0,0 +1,24 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface RCTSwiftUIContainerViewWrapper : NSObject
- (UIView *_Nullable)contentView;
- (void)updateBlurRadius:(NSNumber *)radius;
- (void)updateContentView:(UIView *)view;
- (UIView *_Nullable)hostingView;
- (void)resetStyles;
- (void)updateLayoutWithBounds:(CGRect)bounds;
@end
NS_ASSUME_NONNULL_END
@@ -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.
*/
#import "RCTSwiftUIContainerViewWrapper.h"
@import RCTSwiftUI;
@interface RCTSwiftUIContainerViewWrapper ()
@property (nonatomic, strong) RCTSwiftUIContainerView *swiftContainerView;
@end
@implementation RCTSwiftUIContainerViewWrapper
- (instancetype)init
{
if (self = [super init]) {
_swiftContainerView = [RCTSwiftUIContainerView new];
}
return self;
}
- (UIView *_Nullable)contentView
{
return [self.swiftContainerView contentView];
}
- (UIView *_Nullable)hostingView
{
return [self.swiftContainerView hostingView];
}
- (void)resetStyles
{
[self.swiftContainerView resetStyles];
}
- (void)updateContentView:(UIView *)view
{
return [self.swiftContainerView updateContentView:view];
}
- (void)updateBlurRadius:(NSNumber *)radius
{
[self.swiftContainerView updateBlurRadius:radius];
}
- (void)updateLayoutWithBounds:(CGRect)bounds
{
[self.swiftContainerView updateLayoutWithBounds:bounds];
}
@end
@@ -0,0 +1,38 @@
# 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.
require "json"
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which we're presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
Pod::Spec.new do |s|
s.name = "RCTSwiftUIWrapper"
s.version = version
s.summary = "Swift utilities for React Native."
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.source_files = "*.{h,m}"
s.public_header_files = "*.h"
s.module_name = "RCTSwiftUIWrapper"
s.header_dir = "RCTSwiftUIWrapper"
s.dependency "RCTSwiftUI"
s.pod_target_xcconfig = {
"SWIFT_VERSION" => "5.0",
}
end
@@ -41,18 +41,14 @@ class HostAgent::Impl final {
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
VoidExecutor executor)
: frontendChannel_(frontendChannel),
targetController_(targetController),
hostMetadata_(std::move(hostMetadata)),
sessionState_(sessionState),
networkIOAgent_(NetworkIOAgent(frontendChannel, std::move(executor))),
tracingAgent_(TracingAgent(
frontendChannel,
sessionState,
targetController,
std::move(traceRecordingToEmit))) {}
tracingAgent_(
TracingAgent(frontendChannel, sessionState, targetController)) {}
~Impl() {
if (isPausedInDebuggerOverlayVisible_) {
@@ -201,6 +197,14 @@ class HostAgent::Impl final {
"ReactNativeApplication.metadataUpdated",
createHostMetadataPayload(hostMetadata_)));
auto stashedTraceRecording =
targetController_.getDelegate()
.unstable_getTraceRecordingThatWillBeEmittedOnInitialization();
if (stashedTraceRecording.has_value()) {
tracingAgent_.emitExternalTraceRecording(
std::move(stashedTraceRecording.value()));
}
return {
.isFinishedHandlingRequest = true,
.shouldSendOKResponse = true,
@@ -336,12 +340,24 @@ class HostAgent::Impl final {
}
}
bool hasFuseboxClientConnected() const {
return fuseboxClientType_ == FuseboxClientType::Fusebox;
}
void emitExternalTraceRecording(
tracing::TraceRecordingState traceRecording) const {
assert(
hasFuseboxClientConnected() &&
"Attempted to emit a trace recording to a non-Fusebox client");
tracingAgent_.emitExternalTraceRecording(std::move(traceRecording));
}
private:
enum class FuseboxClientType { Unknown, Fusebox, NonFusebox };
/**
* Send a simple Log.entryAdded notification with the given
* \param text. You must ensure that the frontend has enabled Log
* \param text You must ensure that the frontend has enabled Log
* notifications (using Log.enable) prior to calling this function. In Chrome
* DevTools, the message will appear in the Console tab along with regular
* console messages. The difference between Log.entryAdded and
@@ -432,11 +448,15 @@ class HostAgent::Impl final {
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit) {}
VoidExecutor executor) {}
void handleRequest(const cdp::PreparsedRequest& req) {}
void setCurrentInstanceAgent(std::shared_ptr<InstanceAgent> agent) {}
bool hasFuseboxClientConnected() const {
return false;
}
void emitExternalTraceRecording(tracing::TraceRecordingState traceRecording) {
}
};
#endif // REACT_NATIVE_DEBUGGER_ENABLED
@@ -446,16 +466,14 @@ HostAgent::HostAgent(
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
VoidExecutor executor)
: impl_(std::make_unique<Impl>(
*this,
frontendChannel,
targetController,
std::move(hostMetadata),
sessionState,
std::move(executor),
std::move(traceRecordingToEmit))) {}
std::move(executor))) {}
HostAgent::~HostAgent() = default;
@@ -468,6 +486,15 @@ void HostAgent::setCurrentInstanceAgent(
impl_->setCurrentInstanceAgent(std::move(instanceAgent));
}
bool HostAgent::hasFuseboxClientConnected() const {
return impl_->hasFuseboxClientConnected();
}
void HostAgent::emitExternalTraceRecording(
tracing::TraceRecordingState traceRecording) const {
impl_->emitExternalTraceRecording(std::move(traceRecording));
}
#pragma mark - Tracing
HostTracingAgent::HostTracingAgent(tracing::TraceRecordingState& state)
@@ -36,16 +36,13 @@ class HostAgent final {
* \param hostMetadata Metadata about the host that created this agent.
* \param sessionState The state of the session that created this agent.
* \param executor A void executor to be used by async-aware handlers.
* \param traceRecordingToEmit If set, this is the trace that Host has
* requested to display in the Frontend.
*/
HostAgent(
const FrontendChannel& frontendChannel,
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit);
VoidExecutor executor);
HostAgent(const HostAgent&) = delete;
HostAgent(HostAgent&&) = delete;
@@ -69,6 +66,20 @@ class HostAgent final {
*/
void setCurrentInstanceAgent(std::shared_ptr<InstanceAgent> agent);
/**
* Returns whether this HostAgent is part of the session that has an active
* Fusebox client connecte, i.e. with Chrome DevTools Frontend fork for React
* Native.
*/
bool hasFuseboxClientConnected() const;
/**
* Emits the trace recording that was captured externally, not via the
* CDP-initiated request.
*/
void emitExternalTraceRecording(
tracing::TraceRecordingState traceRecording) const;
private:
// We use the private implementation idiom to ensure this class has the same
// layout regardless of whether REACT_NATIVE_DEBUGGER_ENABLED is defined. The
@@ -34,8 +34,7 @@ class HostTargetSession {
std::unique_ptr<IRemoteConnection> remote,
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
VoidExecutor executor)
: remote_(std::make_shared<RAIIRemoteConnection>(std::move(remote))),
frontendChannel_(
[remoteWeak = std::weak_ptr(remote_)](std::string_view message) {
@@ -48,8 +47,7 @@ class HostTargetSession {
targetController,
std::move(hostMetadata),
state_,
std::move(executor),
std::move(traceRecordingToEmit)) {}
std::move(executor)) {}
/**
* Called by CallbackLocalConnection to send a message to this Session's
@@ -103,6 +101,19 @@ class HostTargetSession {
}
}
/**
* Returns whether the ReactNativeApplication CDP domain is enabled.
*
* Chrome DevTools Frontend enables this domain as a client.
*/
bool hasFuseboxClient() const {
return hostAgent_.hasFuseboxClientConnected();
}
void emitTraceRecording(tracing::TraceRecordingState traceRecording) const {
hostAgent_.emitExternalTraceRecording(std::move(traceRecording));
}
private:
// Owned by this instance, but shared (weakly) with the frontend channel
std::shared_ptr<RAIIRemoteConnection> remote_;
@@ -205,8 +216,7 @@ std::unique_ptr<ILocalConnection> HostTarget::connect(
std::move(connectionToFrontend),
controller_,
delegate_.getMetadata(),
makeVoidExecutor(executorFromThis()),
delegate_.unstable_getTraceRecordingThatWillBeEmittedOnInitialization());
makeVoidExecutor(executorFromThis()));
session->setCurrentInstance(currentInstance_.get());
sessions_.insert(std::weak_ptr(session));
return std::make_unique<CallbackLocalConnection>(
@@ -347,4 +357,32 @@ folly::dynamic createHostMetadataPayload(const HostTargetMetadata& metadata) {
return result;
}
bool HostTarget::hasActiveSessionWithFuseboxClient() const {
bool hasActiveFuseboxSession = false;
sessions_.forEach([&](HostTargetSession& session) {
hasActiveFuseboxSession |= session.hasFuseboxClient();
});
return hasActiveFuseboxSession;
}
void HostTarget::emitTraceRecordingForFirstFuseboxClient(
tracing::TraceRecordingState traceRecording) const {
bool emitted = false;
sessions_.forEach([&](HostTargetSession& session) {
if (emitted) {
/**
* TraceRecordingState object is not copiable for performance reasons,
* because it could contain large Runtime sampling profile object.
*
* This approach would not work with multi-client debugger setup.
*/
return;
}
if (session.hasFuseboxClient()) {
session.emitTraceRecording(std::move(traceRecording));
emitted = true;
}
});
}
} // namespace facebook::react::jsinspector_modern
@@ -297,6 +297,21 @@ class JSINSPECTOR_EXPORT HostTarget
*/
tracing::TracingState tracingState() const;
/**
* Returns whether there is an active session with the Fusebox client, i.e.
* with Chrome DevTools Frontend fork for React Native.
*/
bool hasActiveSessionWithFuseboxClient() const;
/**
* Emits the trace recording for the first active session with the Fusebox
* client.
*
* @see \c hasActiveFrontendSession
*/
void emitTraceRecordingForFirstFuseboxClient(
tracing::TraceRecordingState traceRecording) const;
private:
/**
* Constructs a new HostTarget.
@@ -38,17 +38,10 @@ const uint16_t PROFILE_TRACE_EVENT_CHUNK_SIZE = 1;
TracingAgent::TracingAgent(
FrontendChannel frontendChannel,
SessionState& sessionState,
HostTargetController& hostTargetController,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
HostTargetController& hostTargetController)
: frontendChannel_(std::move(frontendChannel)),
sessionState_(sessionState),
hostTargetController_(hostTargetController) {
if (traceRecordingToEmit.has_value()) {
frontendChannel_(
cdp::jsonNotification("ReactNativeApplication.traceRequested"));
emitTraceRecording(std::move(traceRecordingToEmit.value()));
}
}
hostTargetController_(hostTargetController) {}
TracingAgent::~TracingAgent() {
// Agents are owned by the session. If the agent is destroyed, it means that
@@ -100,15 +93,22 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
return false;
}
void TracingAgent::emitExternalTraceRecording(
tracing::TraceRecordingState traceRecording) const {
frontendChannel_(
cdp::jsonNotification("ReactNativeApplication.traceRequested"));
emitTraceRecording(std::move(traceRecording));
}
void TracingAgent::emitTraceRecording(
tracing::TraceRecordingState state) const {
tracing::TraceRecordingState traceRecording) const {
auto dataCollectedCallback = [this](folly::dynamic&& eventsChunk) {
frontendChannel_(cdp::jsonNotification(
"Tracing.dataCollected",
folly::dynamic::object("value", std::move(eventsChunk))));
};
tracing::TraceRecordingStateSerializer::emitAsDataCollectedChunks(
std::move(state),
std::move(traceRecording),
dataCollectedCallback,
TRACE_EVENT_CHUNK_SIZE,
PROFILE_TRACE_EVENT_CHUNK_SIZE);
@@ -28,14 +28,11 @@ class TracingAgent {
* \param hostTargetController An interface to the HostTarget that this agent
* is attached to. The caller is responsible for ensuring that the
* HostTargetDelegate and underlying HostTarget both outlive the agent.
* \param traceRecordingToEmit If set, this is the trace that Host has
* requested to display in the Frontend.
*/
TracingAgent(
FrontendChannel frontendChannel,
SessionState& sessionState,
HostTargetController& hostTargetController,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit);
HostTargetController& hostTargetController);
~TracingAgent();
@@ -46,6 +43,12 @@ class TracingAgent {
*/
bool handleRequest(const cdp::PreparsedRequest& req);
/**
* Emits the Trace Recording that was stashed externally by the HostTarget.
*/
void emitExternalTraceRecording(
tracing::TraceRecordingState traceRecording) const;
private:
/**
* A channel used to send responses and events to the frontend.
@@ -60,7 +63,7 @@ class TracingAgent {
* Emits the captured Trace Recording state in a series of
* Tracing.dataCollected events, followed by a Tracing.tracingComplete event.
*/
void emitTraceRecording(tracing::TraceRecordingState state) const;
void emitTraceRecording(tracing::TraceRecordingState traceRecording) const;
};
} // namespace facebook::react::jsinspector_modern
@@ -49,7 +49,7 @@ std::string jsonResult(RequestId id, const folly::dynamic& result) {
}
std::string jsonNotification(
std::string_view method,
const std::string& method,
std::optional<folly::dynamic> params) {
auto dynamicNotification = folly::dynamic::object("method", method);
if (params) {
@@ -60,7 +60,7 @@ std::string jsonNotification(
std::string jsonRequest(
RequestId id,
std::string_view method,
const std::string& method,
std::optional<folly::dynamic> params) {
auto dynamicRequest = folly::dynamic::object("id", id)("method", method);
if (params) {
@@ -118,7 +118,7 @@ std::string jsonResult(
* \param params Optional payload object.
*/
std::string jsonNotification(
std::string_view method,
const std::string& method,
std::optional<folly::dynamic> params = std::nullopt);
/**
@@ -132,7 +132,7 @@ std::string jsonNotification(
*/
std::string jsonRequest(
RequestId id,
std::string_view method,
const std::string& method,
std::optional<folly::dynamic> params = std::nullopt);
} // namespace facebook::react::jsinspector_modern::cdp
@@ -56,7 +56,7 @@ bool NetworkHandler::disable() {
}
enabled_.store(false, std::memory_order_release);
requestBodyBuffer_.clear();
responseBodyBuffer_.clear();
return true;
}
@@ -113,7 +113,10 @@ void NetworkHandler::onResponseReceived(
}
auto resourceType = cdp::network::resourceTypeFromMimeType(response.mimeType);
resourceTypeMap_.emplace(requestId, resourceType);
{
std::lock_guard<std::mutex> lock(resourceTypeMapMutex_);
resourceTypeMap_.emplace(requestId, resourceType);
}
auto params = cdp::network::ResponseReceivedParams{
.requestId = requestId,
@@ -166,23 +169,26 @@ void NetworkHandler::onLoadingFinished(
void NetworkHandler::onLoadingFailed(
const std::string& requestId,
bool cancelled) const {
bool cancelled) {
if (!isEnabledNoSync()) {
return;
}
auto params = cdp::network::LoadingFailedParams{
.requestId = requestId,
.timestamp = getCurrentUnixTimestampSeconds(),
.type = resourceTypeMap_.find(requestId) != resourceTypeMap_.end()
? resourceTypeMap_.at(requestId)
: "Other",
.errorText = cancelled ? "net::ERR_ABORTED" : "net::ERR_FAILED",
.canceled = cancelled,
};
{
std::lock_guard<std::mutex> lock(resourceTypeMapMutex_);
auto params = cdp::network::LoadingFailedParams{
.requestId = requestId,
.timestamp = getCurrentUnixTimestampSeconds(),
.type = resourceTypeMap_.find(requestId) != resourceTypeMap_.end()
? resourceTypeMap_.at(requestId)
: "Other",
.errorText = cancelled ? "net::ERR_ABORTED" : "net::ERR_FAILED",
.canceled = cancelled,
};
frontendChannel_(
cdp::jsonNotification("Network.loadingFailed", params.toDynamic()));
frontendChannel_(
cdp::jsonNotification("Network.loadingFailed", params.toDynamic()));
}
}
void NetworkHandler::storeResponseBody(
@@ -190,13 +196,13 @@ void NetworkHandler::storeResponseBody(
std::string_view body,
bool base64Encoded) {
std::lock_guard<std::mutex> lock(requestBodyMutex_);
requestBodyBuffer_.put(requestId, body, base64Encoded);
responseBodyBuffer_.put(requestId, body, base64Encoded);
}
std::optional<std::tuple<std::string, bool>> NetworkHandler::getResponseBody(
const std::string& requestId) {
std::lock_guard<std::mutex> lock(requestBodyMutex_);
auto responseBody = requestBodyBuffer_.get(requestId);
auto responseBody = responseBodyBuffer_.get(requestId);
if (responseBody == nullptr) {
return std::nullopt;
@@ -100,7 +100,7 @@ class NetworkHandler {
/**
* @cdp Network.loadingFailed
*/
void onLoadingFailed(const std::string& requestId, bool cancelled) const;
void onLoadingFailed(const std::string& requestId, bool cancelled);
/**
* Store the fetched response body for a text or image network response.
@@ -139,8 +139,9 @@ class NetworkHandler {
FrontendChannel frontendChannel_;
std::map<std::string, std::string> resourceTypeMap_{};
std::mutex resourceTypeMapMutex_{};
BoundedRequestBuffer requestBodyBuffer_{};
BoundedRequestBuffer responseBodyBuffer_{};
std::mutex requestBodyMutex_;
};
@@ -124,7 +124,7 @@ std::optional<std::vector<TraceEvent>> PerformanceTracer::stopTracing() {
}
void PerformanceTracer::reportMark(
const std::string_view& name,
const std::string& name,
HighResTimeStamp start,
folly::dynamic&& detail) {
if (!tracingAtomic_) {
@@ -137,7 +137,7 @@ void PerformanceTracer::reportMark(
}
enqueueEvent(PerformanceTracerEventMark{
.name = std::string(name),
.name = name,
.start = start,
.detail = std::move(detail),
.threadId = getCurrentThreadId(),
@@ -145,7 +145,7 @@ void PerformanceTracer::reportMark(
}
void PerformanceTracer::reportMeasure(
const std::string_view& name,
const std::string& name,
HighResTimeStamp start,
HighResDuration duration,
folly::dynamic&& detail) {
@@ -159,7 +159,7 @@ void PerformanceTracer::reportMeasure(
}
enqueueEvent(PerformanceTracerEventMeasure{
.name = std::string(name),
.name = name,
.start = start,
.duration = duration,
.detail = std::move(detail),
@@ -168,7 +168,7 @@ void PerformanceTracer::reportMeasure(
}
void PerformanceTracer::reportTimeStamp(
std::string name,
const std::string& name,
std::optional<ConsoleTimeStampEntry> start,
std::optional<ConsoleTimeStampEntry> end,
std::optional<std::string> trackName,
@@ -184,7 +184,7 @@ void PerformanceTracer::reportTimeStamp(
}
enqueueEvent(PerformanceTracerEventTimeStamp{
.name = std::move(name),
.name = name,
.start = std::move(start),
.end = std::move(end),
.trackName = std::move(trackName),
@@ -232,6 +232,50 @@ void PerformanceTracer::reportEventLoopMicrotasks(
});
}
void PerformanceTracer::reportResourceTiming(
const std::string& requestId,
const std::string& url,
HighResTimeStamp fetchStart,
HighResTimeStamp responseStart,
HighResTimeStamp responseEnd,
int statusCode,
const std::string& requestMethod,
const std::string& resourceType) {
if (!tracingAtomic_) {
return;
}
std::lock_guard<std::mutex> lock(mutex_);
if (!tracingAtomic_) {
return;
}
enqueueEvent(PerformanceTracerResourceWillSendRequest{
.requestId = requestId,
.start = fetchStart,
.threadId = getCurrentThreadId(),
});
enqueueEvent(PerformanceTracerResourceSendRequest{
.requestId = requestId,
.url = url,
.start = fetchStart,
.requestMethod = requestMethod,
.resourceType = resourceType,
.threadId = getCurrentThreadId(),
});
enqueueEvent(PerformanceTracerResourceReceiveResponse{
.requestId = requestId,
.start = responseStart,
.statusCode = statusCode,
.threadId = getCurrentThreadId(),
});
enqueueEvent(PerformanceTracerResourceFinish{
.requestId = requestId,
.start = responseEnd,
.threadId = getCurrentThreadId(),
});
}
/* static */ TraceEvent PerformanceTracer::constructRuntimeProfileTraceEvent(
RuntimeProfileId profileId,
ProcessId processId,
@@ -505,6 +549,73 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
.args = folly::dynamic::object("data", std::move(data)),
});
},
[&](PerformanceTracerResourceWillSendRequest&& event) {
folly::dynamic data =
folly::dynamic::object("requestId", std::move(event.requestId));
events.emplace_back(TraceEvent{
.name = "ResourceWillSendRequest",
.cat = "devtools.timeline",
.ph = 'I',
.ts = event.start,
.pid = processId_,
.s = 't',
.tid = event.threadId,
.args = folly::dynamic::object("data", std::move(data)),
});
},
[&](PerformanceTracerResourceSendRequest&& event) {
folly::dynamic data =
folly::dynamic::object("initiator", folly::dynamic::object())(
"renderBlocking", "non_blocking")(
"requestId", std::move(event.requestId))(
"requestMethod", std::move(event.requestMethod))(
"resourceType", std::move(event.resourceType))(
"url", std::move(event.url));
events.emplace_back(TraceEvent{
.name = "ResourceSendRequest",
.cat = "devtools.timeline",
.ph = 'I',
.ts = event.start,
.pid = processId_,
.s = 't',
.tid = event.threadId,
.args = folly::dynamic::object("data", std::move(data)),
});
},
[&](PerformanceTracerResourceReceiveResponse&& event) {
folly::dynamic data = folly::dynamic::object("protocol", "h2")(
"requestId", std::move(event.requestId))(
"statusCode", event.statusCode)(
"timing", folly::dynamic::object());
events.emplace_back(TraceEvent{
.name = "ResourceReceiveResponse",
.cat = "devtools.timeline",
.ph = 'I',
.ts = event.start,
.pid = processId_,
.s = 't',
.tid = event.threadId,
.args = folly::dynamic::object("data", std::move(data)),
});
},
[&](PerformanceTracerResourceFinish&& event) {
folly::dynamic data = folly::dynamic::object("didFail", false)(
"requestId", std::move(event.requestId));
events.emplace_back(TraceEvent{
.name = "ResourceFinish",
.cat = "devtools.timeline",
.ph = 'I',
.ts = event.start,
.pid = processId_,
.s = 't',
.tid = event.threadId,
.args = folly::dynamic::object("data", std::move(data)),
});
},
},
std::move(event));
}
@@ -65,7 +65,7 @@ class PerformanceTracer {
* See https://w3c.github.io/user-timing/#mark-method.
*/
void reportMark(
const std::string_view& name,
const std::string& name,
HighResTimeStamp start,
folly::dynamic&& detail = nullptr);
@@ -76,7 +76,7 @@ class PerformanceTracer {
* See https://w3c.github.io/user-timing/#measure-method.
*/
void reportMeasure(
const std::string_view& name,
const std::string& name,
HighResTimeStamp start,
HighResDuration duration,
folly::dynamic&& detail = nullptr);
@@ -89,7 +89,7 @@ class PerformanceTracer {
https://developer.chrome.com/docs/devtools/performance/extension#inject_your_data_with_consoletimestamp
*/
void reportTimeStamp(
std::string name,
const std::string& name,
std::optional<ConsoleTimeStampEntry> start = std::nullopt,
std::optional<ConsoleTimeStampEntry> end = std::nullopt,
std::optional<std::string> trackName = std::nullopt,
@@ -108,6 +108,21 @@ class PerformanceTracer {
*/
void reportEventLoopMicrotasks(HighResTimeStamp start, HighResTimeStamp end);
/**
* Record a "ResourceSendRequest"/"ResourceFinish" event pair - a labelled
* duration in the Performance timeline Network track. If not currently
* tracing, this is a no-op.
*/
void reportResourceTiming(
const std::string& requestId,
const std::string& url,
HighResTimeStamp fetchStart,
HighResTimeStamp responseStart,
HighResTimeStamp responseEnd,
int statusCode,
const std::string& requestMethod,
const std::string& resourceType);
/**
* Creates "Profile" Trace Event.
*
@@ -181,12 +196,48 @@ class PerformanceTracer {
HighResTimeStamp createdAt = HighResTimeStamp::now();
};
struct PerformanceTracerResourceWillSendRequest {
std::string requestId;
HighResTimeStamp start;
ThreadId threadId;
HighResTimeStamp createdAt = HighResTimeStamp::now();
};
struct PerformanceTracerResourceSendRequest {
std::string requestId;
std::string url;
HighResTimeStamp start;
std::string requestMethod;
std::string resourceType;
ThreadId threadId;
HighResTimeStamp createdAt = HighResTimeStamp::now();
};
struct PerformanceTracerResourceFinish {
std::string requestId;
HighResTimeStamp start;
ThreadId threadId;
HighResTimeStamp createdAt = HighResTimeStamp::now();
};
struct PerformanceTracerResourceReceiveResponse {
std::string requestId;
HighResTimeStamp start;
int statusCode;
ThreadId threadId;
HighResTimeStamp createdAt = HighResTimeStamp::now();
};
using PerformanceTracerEvent = std::variant<
PerformanceTracerEventTimeStamp,
PerformanceTracerEventEventLoopTask,
PerformanceTracerEventEventLoopMicrotask,
PerformanceTracerEventMark,
PerformanceTracerEventMeasure>;
PerformanceTracerEventMeasure,
PerformanceTracerResourceWillSendRequest,
PerformanceTracerResourceSendRequest,
PerformanceTracerResourceReceiveResponse,
PerformanceTracerResourceFinish>;
#pragma mark - Private fields and methods
@@ -49,8 +49,14 @@ struct RuntimeSamplingProfile {
/// id of the corresponding script in the VM.
uint32_t scriptId;
/// name of the function that represents call frame.
/// Storing a std::string_view should be considered safe here, beacause
/// the lifetime of the string contents are guaranteed as long as the raw
// Sampling Profiler object from Hermes is allocated.
std::string_view functionName;
/// source url of the corresponding script in the VM.
/// Storing a std::string_view should be considered safe here, beacause
/// the lifetime of the string contents are guaranteed as long as the raw
// Sampling Profiler object from Hermes is allocated.
std::optional<std::string_view> scriptURL = std::nullopt;
/// 0-based line number of the corresponding call frame.
std::optional<uint32_t> lineNumber = std::nullopt;
@@ -55,6 +55,12 @@ struct TraceEvent {
/** The ID for the process that output this event. */
ProcessId pid;
/**
* The scope of the event, either global (g), process (p), or thread (t).
* Only applicable to instant events ("ph": "i").
*/
std::optional<char> s;
/** The ID for the thread that output this event. */
ThreadId tid;
@@ -26,6 +26,9 @@ namespace facebook::react::jsinspector_modern::tracing {
result["ph"] = std::string(1, event.ph);
result["ts"] = highResTimeStampToTracingClockTimeStamp(event.ts);
result["pid"] = event.pid;
if (event.s.has_value()) {
result["s"] = std::string(1, event.s.value());
}
result["tid"] = event.tid;
result["args"] = std::move(event.args);
if (event.dur.has_value()) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<2cbb1a339481d2ba6d3047c2f16d6d10>>
* @generated SignedSource<<42bea10b4b62a91dce8fde7674f76ceb>>
*/
/**
@@ -174,6 +174,10 @@ bool ReactNativeFeatureFlags::enableResourceTimingAPI() {
return getAccessor().enableResourceTimingAPI();
}
bool ReactNativeFeatureFlags::enableSwiftUIBasedFilters() {
return getAccessor().enableSwiftUIBasedFilters();
}
bool ReactNativeFeatureFlags::enableViewCulling() {
return getAccessor().enableViewCulling();
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<f35eabad586b13eb735569c22e9ee2ce>>
* @generated SignedSource<<40421ac664927693136a8e3197e3c07c>>
*/
/**
@@ -224,6 +224,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableResourceTimingAPI();
/**
* When enabled, it will use SwiftUI for filter effects like blur on iOS.
*/
RN_EXPORT static bool enableSwiftUIBasedFilters();
/**
* Enables View Culling: as soon as a view goes off screen, it can be reused anywhere in the UI and pieced together with other items to create new UI elements.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<e3f5d6617de0780d530908a7246676d4>>
* @generated SignedSource<<e433f2f36d7a2852aaea2b37f671a7e1>>
*/
/**
@@ -695,6 +695,24 @@ bool ReactNativeFeatureFlagsAccessor::enableResourceTimingAPI() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() {
auto flagValue = enableSwiftUIBasedFilters_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(37, "enableSwiftUIBasedFilters");
flagValue = currentProvider_->enableSwiftUIBasedFilters();
enableSwiftUIBasedFilters_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableViewCulling() {
auto flagValue = enableViewCulling_.load();
@@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(37, "enableViewCulling");
markFlagAsAccessed(38, "enableViewCulling");
flagValue = currentProvider_->enableViewCulling();
enableViewCulling_ = flagValue;
@@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(38, "enableViewRecycling");
markFlagAsAccessed(39, "enableViewRecycling");
flagValue = currentProvider_->enableViewRecycling();
enableViewRecycling_ = flagValue;
@@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(39, "enableViewRecyclingForImage");
markFlagAsAccessed(40, "enableViewRecyclingForImage");
flagValue = currentProvider_->enableViewRecyclingForImage();
enableViewRecyclingForImage_ = flagValue;
@@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(40, "enableViewRecyclingForScrollView");
markFlagAsAccessed(41, "enableViewRecyclingForScrollView");
flagValue = currentProvider_->enableViewRecyclingForScrollView();
enableViewRecyclingForScrollView_ = flagValue;
@@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(41, "enableViewRecyclingForText");
markFlagAsAccessed(42, "enableViewRecyclingForText");
flagValue = currentProvider_->enableViewRecyclingForText();
enableViewRecyclingForText_ = flagValue;
@@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(42, "enableViewRecyclingForView");
markFlagAsAccessed(43, "enableViewRecyclingForView");
flagValue = currentProvider_->enableViewRecyclingForView();
enableViewRecyclingForView_ = flagValue;
@@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(43, "enableVirtualViewDebugFeatures");
markFlagAsAccessed(44, "enableVirtualViewDebugFeatures");
flagValue = currentProvider_->enableVirtualViewDebugFeatures();
enableVirtualViewDebugFeatures_ = flagValue;
@@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewRenderState() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(44, "enableVirtualViewRenderState");
markFlagAsAccessed(45, "enableVirtualViewRenderState");
flagValue = currentProvider_->enableVirtualViewRenderState();
enableVirtualViewRenderState_ = flagValue;
@@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewWindowFocusDetection() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(45, "enableVirtualViewWindowFocusDetection");
markFlagAsAccessed(46, "enableVirtualViewWindowFocusDetection");
flagValue = currentProvider_->enableVirtualViewWindowFocusDetection();
enableVirtualViewWindowFocusDetection_ = flagValue;
@@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableWebPerformanceAPIsByDefault() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(46, "enableWebPerformanceAPIsByDefault");
markFlagAsAccessed(47, "enableWebPerformanceAPIsByDefault");
flagValue = currentProvider_->enableWebPerformanceAPIsByDefault();
enableWebPerformanceAPIsByDefault_ = flagValue;
@@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(47, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
markFlagAsAccessed(48, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact();
fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue;
@@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(48, "fuseboxEnabledRelease");
markFlagAsAccessed(49, "fuseboxEnabledRelease");
flagValue = currentProvider_->fuseboxEnabledRelease();
fuseboxEnabledRelease_ = flagValue;
@@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(49, "fuseboxNetworkInspectionEnabled");
markFlagAsAccessed(50, "fuseboxNetworkInspectionEnabled");
flagValue = currentProvider_->fuseboxNetworkInspectionEnabled();
fuseboxNetworkInspectionEnabled_ = flagValue;
@@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(50, "hideOffscreenVirtualViewsOnIOS");
markFlagAsAccessed(51, "hideOffscreenVirtualViewsOnIOS");
flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS();
hideOffscreenVirtualViewsOnIOS_ = flagValue;
@@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(51, "overrideBySynchronousMountPropsAtMountingAndroid");
markFlagAsAccessed(52, "overrideBySynchronousMountPropsAtMountingAndroid");
flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid();
overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue;
@@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(52, "perfMonitorV2Enabled");
markFlagAsAccessed(53, "perfMonitorV2Enabled");
flagValue = currentProvider_->perfMonitorV2Enabled();
perfMonitorV2Enabled_ = flagValue;
@@ -992,7 +1010,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(53, "preparedTextCacheSize");
markFlagAsAccessed(54, "preparedTextCacheSize");
flagValue = currentProvider_->preparedTextCacheSize();
preparedTextCacheSize_ = flagValue;
@@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(54, "preventShadowTreeCommitExhaustion");
markFlagAsAccessed(55, "preventShadowTreeCommitExhaustion");
flagValue = currentProvider_->preventShadowTreeCommitExhaustion();
preventShadowTreeCommitExhaustion_ = flagValue;
@@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(55, "shouldPressibilityUseW3CPointerEventsForHover");
markFlagAsAccessed(56, "shouldPressibilityUseW3CPointerEventsForHover");
flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover();
shouldPressibilityUseW3CPointerEventsForHover_ = flagValue;
@@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause()
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(56, "skipActivityIdentityAssertionOnHostPause");
markFlagAsAccessed(57, "skipActivityIdentityAssertionOnHostPause");
flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause();
skipActivityIdentityAssertionOnHostPause_ = flagValue;
@@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::sweepActiveTouchOnChildNativeGesturesAndro
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(57, "sweepActiveTouchOnChildNativeGesturesAndroid");
markFlagAsAccessed(58, "sweepActiveTouchOnChildNativeGesturesAndroid");
flagValue = currentProvider_->sweepActiveTouchOnChildNativeGesturesAndroid();
sweepActiveTouchOnChildNativeGesturesAndroid_ = flagValue;
@@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(58, "traceTurboModulePromiseRejectionsOnAndroid");
markFlagAsAccessed(59, "traceTurboModulePromiseRejectionsOnAndroid");
flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid();
traceTurboModulePromiseRejectionsOnAndroid_ = flagValue;
@@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit(
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(59, "updateRuntimeShadowNodeReferencesOnCommit");
markFlagAsAccessed(60, "updateRuntimeShadowNodeReferencesOnCommit");
flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit();
updateRuntimeShadowNodeReferencesOnCommit_ = flagValue;
@@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(60, "useAlwaysAvailableJSErrorHandling");
markFlagAsAccessed(61, "useAlwaysAvailableJSErrorHandling");
flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling();
useAlwaysAvailableJSErrorHandling_ = flagValue;
@@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(61, "useFabricInterop");
markFlagAsAccessed(62, "useFabricInterop");
flagValue = currentProvider_->useFabricInterop();
useFabricInterop_ = flagValue;
@@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(62, "useNativeEqualsInNativeReadableArrayAndroid");
markFlagAsAccessed(63, "useNativeEqualsInNativeReadableArrayAndroid");
flagValue = currentProvider_->useNativeEqualsInNativeReadableArrayAndroid();
useNativeEqualsInNativeReadableArrayAndroid_ = flagValue;
@@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(63, "useNativeTransformHelperAndroid");
markFlagAsAccessed(64, "useNativeTransformHelperAndroid");
flagValue = currentProvider_->useNativeTransformHelperAndroid();
useNativeTransformHelperAndroid_ = flagValue;
@@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(64, "useNativeViewConfigsInBridgelessMode");
markFlagAsAccessed(65, "useNativeViewConfigsInBridgelessMode");
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
useNativeViewConfigsInBridgelessMode_ = flagValue;
@@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(65, "useOptimizedEventBatchingOnAndroid");
markFlagAsAccessed(66, "useOptimizedEventBatchingOnAndroid");
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
useOptimizedEventBatchingOnAndroid_ = flagValue;
@@ -1226,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(66, "useRawPropsJsiValue");
markFlagAsAccessed(67, "useRawPropsJsiValue");
flagValue = currentProvider_->useRawPropsJsiValue();
useRawPropsJsiValue_ = flagValue;
@@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(67, "useShadowNodeStateOnClone");
markFlagAsAccessed(68, "useShadowNodeStateOnClone");
flagValue = currentProvider_->useShadowNodeStateOnClone();
useShadowNodeStateOnClone_ = flagValue;
@@ -1262,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(68, "useTurboModuleInterop");
markFlagAsAccessed(69, "useTurboModuleInterop");
flagValue = currentProvider_->useTurboModuleInterop();
useTurboModuleInterop_ = flagValue;
@@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(69, "useTurboModules");
markFlagAsAccessed(70, "useTurboModules");
flagValue = currentProvider_->useTurboModules();
useTurboModules_ = flagValue;
@@ -1298,7 +1316,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewHysteresisRatio() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(70, "virtualViewHysteresisRatio");
markFlagAsAccessed(71, "virtualViewHysteresisRatio");
flagValue = currentProvider_->virtualViewHysteresisRatio();
virtualViewHysteresisRatio_ = flagValue;
@@ -1316,7 +1334,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(71, "virtualViewPrerenderRatio");
markFlagAsAccessed(72, "virtualViewPrerenderRatio");
flagValue = currentProvider_->virtualViewPrerenderRatio();
virtualViewPrerenderRatio_ = flagValue;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a2ef803074301ea53c309422af099355>>
* @generated SignedSource<<6f05211b44f2be076b37ef9178e5ef43>>
*/
/**
@@ -69,6 +69,7 @@ class ReactNativeFeatureFlagsAccessor {
bool enablePreparedTextLayout();
bool enablePropsUpdateReconciliationAndroid();
bool enableResourceTimingAPI();
bool enableSwiftUIBasedFilters();
bool enableViewCulling();
bool enableViewRecycling();
bool enableViewRecyclingForImage();
@@ -115,7 +116,7 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;
std::array<std::atomic<const char*>, 72> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 73> accessedFeatureFlags_;
std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> cdpInteractionMetricsEnabled_;
@@ -154,6 +155,7 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> enablePreparedTextLayout_;
std::atomic<std::optional<bool>> enablePropsUpdateReconciliationAndroid_;
std::atomic<std::optional<bool>> enableResourceTimingAPI_;
std::atomic<std::optional<bool>> enableSwiftUIBasedFilters_;
std::atomic<std::optional<bool>> enableViewCulling_;
std::atomic<std::optional<bool>> enableViewRecycling_;
std::atomic<std::optional<bool>> enableViewRecyclingForImage_;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<680ccef60b08f17fcbfd718087d30955>>
* @generated SignedSource<<b6da08857919846dda053b3635fb9702>>
*/
/**
@@ -175,6 +175,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableSwiftUIBasedFilters() override {
return false;
}
bool enableViewCulling() override {
return false;
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<7f3aa6b2ab640df702ea9e8f248d1098>>
* @generated SignedSource<<737e882a924b2730d0c67cc8dc27c8a7>>
*/
/**
@@ -378,6 +378,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
return ReactNativeFeatureFlagsDefaults::enableResourceTimingAPI();
}
bool enableSwiftUIBasedFilters() override {
auto value = values_["enableSwiftUIBasedFilters"];
if (!value.isNull()) {
return value.getBool();
}
return ReactNativeFeatureFlagsDefaults::enableSwiftUIBasedFilters();
}
bool enableViewCulling() override {
auto value = values_["enableViewCulling"];
if (!value.isNull()) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<d3b21492391b7b81324b22de1b28771f>>
* @generated SignedSource<<4045a760f000400d47117728119f0d21>>
*/
/**
@@ -62,6 +62,7 @@ class ReactNativeFeatureFlagsProvider {
virtual bool enablePreparedTextLayout() = 0;
virtual bool enablePropsUpdateReconciliationAndroid() = 0;
virtual bool enableResourceTimingAPI() = 0;
virtual bool enableSwiftUIBasedFilters() = 0;
virtual bool enableViewCulling() = 0;
virtual bool enableViewRecycling() = 0;
virtual bool enableViewRecyclingForImage() = 0;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c5fd32fcb5f9241f8039ee983e2fc872>>
* @generated SignedSource<<5042321d7d0da40cc0436ffaeedda168>>
*/
/**
@@ -229,6 +229,11 @@ bool NativeReactNativeFeatureFlags::enableResourceTimingAPI(
return ReactNativeFeatureFlags::enableResourceTimingAPI();
}
bool NativeReactNativeFeatureFlags::enableSwiftUIBasedFilters(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableSwiftUIBasedFilters();
}
bool NativeReactNativeFeatureFlags::enableViewCulling(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableViewCulling();
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b5d49010286872a588ff74942fd22723>>
* @generated SignedSource<<b1583692e9e07ae68b946496cb94e3e9>>
*/
/**
@@ -110,6 +110,8 @@ class NativeReactNativeFeatureFlags
bool enableResourceTimingAPI(jsi::Runtime& runtime);
bool enableSwiftUIBasedFilters(jsi::Runtime& runtime);
bool enableViewCulling(jsi::Runtime& runtime);
bool enableViewRecycling(jsi::Runtime& runtime);
@@ -8,7 +8,9 @@
#include "NetworkReporter.h"
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
#include "jsinspector-modern/network/NetworkHandler.h"
#include <jsinspector-modern/network/CdpNetwork.h>
#include <jsinspector-modern/network/HttpUtils.h>
#include <jsinspector-modern/network/NetworkHandler.h>
#endif
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/performance/timeline/PerformanceEntryReporter.h>
@@ -43,6 +45,7 @@ void NetworkReporter::reportRequestStart(
requestId,
ResourceTimingData{
.url = requestInfo.url,
.requestMethod = requestInfo.httpMethod,
.fetchStart = now,
.requestStart = now,
});
@@ -108,6 +111,13 @@ void NetworkReporter::reportResponseStart(
it->second.connectEnd = now;
it->second.responseStart = now;
it->second.responseStatus = responseInfo.statusCode;
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
// Debug build: Compute additional fields to send in CDP trace events
it->second.resourceType =
jsinspector_modern::cdp::network::resourceTypeFromMimeType(
jsinspector_modern::mimeTypeFromHeaders(
responseInfo.headers.value_or(Headers{})));
#endif
}
}
}
@@ -155,7 +165,10 @@ void NetworkReporter::reportResponseEnd(
eventData.connectEnd.value_or(now),
eventData.responseStart.value_or(now),
now,
eventData.responseStatus);
eventData.responseStatus,
requestId,
eventData.requestMethod,
eventData.resourceType);
perfTimingsBuffer_.erase(requestId);
}
}
@@ -28,6 +28,8 @@ namespace facebook::react {
*/
struct ResourceTimingData {
std::string url;
std::string requestMethod;
std::optional<std::string> resourceType;
HighResTimeStamp fetchStart;
HighResTimeStamp requestStart;
std::optional<HighResTimeStamp> connectStart;
@@ -307,7 +307,10 @@ void PerformanceEntryReporter::reportResourceTiming(
std::optional<HighResTimeStamp> connectEnd,
HighResTimeStamp responseStart,
HighResTimeStamp responseEnd,
const std::optional<int>& responseStatus) {
const std::optional<int>& responseStatus,
const std::optional<std::string>& devtoolsRequestId,
const std::optional<std::string>& requestMethod,
const std::optional<std::string>& resourceType) {
const auto entry = PerformanceResourceTiming{
{.name = url, .startTime = fetchStart},
fetchStart,
@@ -319,6 +322,8 @@ void PerformanceEntryReporter::reportResourceTiming(
responseStatus,
};
traceResourceTiming(entry, devtoolsRequestId, requestMethod, resourceType);
// Add to buffers & notify observers
{
std::unique_lock lock(buffersMutex_);
@@ -370,4 +375,31 @@ void PerformanceEntryReporter::traceMeasure(
}
}
void PerformanceEntryReporter::traceResourceTiming(
const PerformanceResourceTiming& entry,
const std::optional<std::string>& devtoolsRequestId,
const std::optional<std::string>& requestMethod,
const std::optional<std::string>& resourceType) const {
if (!entry.responseStart.has_value() || !entry.responseEnd.has_value() ||
!entry.responseStatus.has_value() || !devtoolsRequestId.has_value() ||
!requestMethod.has_value() || !resourceType.has_value()) {
return;
}
auto& performanceTracer =
jsinspector_modern::tracing::PerformanceTracer::getInstance();
if (performanceTracer.isTracing()) {
performanceTracer.reportResourceTiming(
*devtoolsRequestId,
entry.name,
entry.fetchStart,
*entry.responseStart,
*entry.responseEnd,
*entry.responseStatus,
*requestMethod,
*resourceType);
}
}
} // namespace facebook::react
@@ -118,7 +118,10 @@ class PerformanceEntryReporter {
std::optional<HighResTimeStamp> connectEnd,
HighResTimeStamp responseStart,
HighResTimeStamp responseEnd,
const std::optional<int>& responseStatus);
const std::optional<int>& responseStatus,
const std::optional<std::string>& devtoolsRequestId,
const std::optional<std::string>& requestMethod,
const std::optional<std::string>& resourceType);
private:
std::unique_ptr<PerformanceObserverRegistry> observerRegistry_;
@@ -182,6 +185,11 @@ class PerformanceEntryReporter {
void traceMeasure(
const PerformanceMeasure& entry,
UserTimingDetailProvider&& detailProvider) const;
void traceResourceTiming(
const PerformanceResourceTiming& entry,
const std::optional<std::string>& devtoolsRequestId,
const std::optional<std::string>& requestMethod,
const std::optional<std::string>& resourceType) const;
};
} // namespace facebook::react
@@ -13,6 +13,7 @@
namespace facebook::react {
// NOLINTNEXTLINE(facebook-hte-CArray,modernize-avoid-c-arrays)
constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";
@@ -147,7 +147,7 @@ class CSSSyntaxParser {
*
* https://www.w3.org/TR/css-syntax-3/#consume-component-value
*
* @param <ReturnT> caller-specified return type of visitors. This type will
* @tparam ReturnT caller-specified return type of visitors. This type will
* be set to its default constructed state if consuming a component value with
* no matching visitors, or syntax error
* @param visitors A unique list of CSSComponentValueVisitor to be called on a
@@ -5,15 +5,23 @@
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTDefines.h>
#import <UIKit/UIKit.h>
#import <react/renderer/textlayoutmanager/RCTFontProperties.h>
NS_ASSUME_NONNULL_BEGIN
using RCTDefaultFontResolver = UIFont *__nullable (^)(const RCTFontProperties &);
/**
* React Native will use the System font for rendering by default. If you want to
* provide a different base font, use this override.
*/
RCT_EXTERN void RCTSetDefaultFontResolver(RCTDefaultFontResolver handler);
/**
* Returns UIFont instance corresponded to given font properties.
*/
UIFont *RCTFontWithFontProperties(RCTFontProperties fontProperties);
RCT_EXTERN UIFont *RCTFontWithFontProperties(RCTFontProperties fontProperties);
NS_ASSUME_NONNULL_END
@@ -6,7 +6,9 @@
*/
#import "RCTFontUtils.h"
#import <CoreText/CoreText.h>
#import <React/RCTFont+Private.h>
#import <React/RCTFont.h>
#import <algorithm>
@@ -246,32 +248,61 @@ static NSArray *RCTFontFeatures(RCTFontVariant fontVariant)
return fontFeatures;
}
static UIFont *RCTDefaultFontWithFontProperties(RCTFontProperties fontProperties)
static RCTDefaultFontResolver defaultFontResolver;
void RCTSetDefaultFontResolver(RCTDefaultFontResolver handler)
{
defaultFontResolver = handler;
}
static UIFont *RCTDefaultFontWithFontProperties(const RCTFontProperties &fontProperties)
{
static NSCache *fontCache;
static std::mutex fontCacheMutex;
CGFloat effectiveFontSize = fontProperties.sizeMultiplier * fontProperties.size;
NSString *cacheKey = [NSString
stringWithFormat:@"%.1f/%.2f/%ld", effectiveFontSize, fontProperties.weight, (long)fontProperties.style];
NSString *cacheKey = [NSString stringWithFormat:@"%@/%.1f/%.2f/%ld",
fontProperties.family,
effectiveFontSize,
fontProperties.weight,
(long)fontProperties.style];
UIFont *font;
{
std::lock_guard<std::mutex> lock(fontCacheMutex);
if (fontCache == nullptr) {
if (fontCache == nil) {
fontCache = [NSCache new];
}
font = [fontCache objectForKey:cacheKey];
}
if (font == nullptr) {
font = [UIFont systemFontOfSize:effectiveFontSize weight:fontProperties.weight];
if (font == nil) {
if (defaultFontResolver != nil) {
font = defaultFontResolver(fontProperties);
}
if (fontProperties.style == RCTFontStyleItalic) {
if (font == nil) {
font = RCTGetLegacyDefaultFont(effectiveFontSize, fontProperties.weight);
}
if (font == nil) {
font = [UIFont systemFontOfSize:effectiveFontSize weight:fontProperties.weight];
}
BOOL isItalicFont = fontProperties.style == RCTFontStyleItalic;
BOOL isCondensedFont = [fontProperties.family isEqualToString:@"SystemCondensed"];
if (isItalicFont || isCondensedFont) {
UIFontDescriptor *fontDescriptor = [font fontDescriptor];
UIFontDescriptorSymbolicTraits symbolicTraits = fontDescriptor.symbolicTraits;
symbolicTraits |= UIFontDescriptorTraitItalic;
if (isItalicFont) {
symbolicTraits |= UIFontDescriptorTraitItalic;
}
if (isCondensedFont) {
symbolicTraits |= UIFontDescriptorTraitCondensed;
}
fontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:symbolicTraits];
font = [UIFont fontWithDescriptor:fontDescriptor size:effectiveFontSize];
@@ -333,7 +364,7 @@ UIFont *RCTFontWithFontProperties(RCTFontProperties fontProperties)
fontWeight = (fontWeight != 0.0) ?: RCTGetFontWeight(font);
} else {
// Failback to system font.
font = [UIFont systemFontOfSize:effectiveFontSize weight:fontProperties.weight];
font = RCTDefaultFontWithFontProperties(fontProperties);
}
}
@@ -354,7 +385,7 @@ UIFont *RCTFontWithFontProperties(RCTFontProperties fontProperties)
}
}
if (font == nullptr) {
if (font == nil) {
// If we still don't have a match at least return the first font in the
// fontFamily This is to support built-in font Zapfino and other custom
// single font families like Impact
@@ -26,7 +26,7 @@ RCTHermesInstance::RCTHermesInstance(CrashManagerProvider crashManagerProvider,
std::unique_ptr<JSRuntime> RCTHermesInstance::createJSRuntime(
std::shared_ptr<MessageQueueThread> msgQueueThread) noexcept
{
return _hermesInstance->createJSRuntime(
return facebook::react::HermesInstance::createJSRuntime(
_crashManagerProvider ? _crashManagerProvider() : nullptr, std::move(msgQueueThread), _allocInOldGenBeforeTTI);
}
+13 -13
View File
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<0a0286ba0bc29af2abd2e8fd836077fb>>
* @generated SignedSource<<4ccde3daef50fa7522f10bc7146c0cc6>>
*
* This file was generated by scripts/js-api/build-types/index.js.
*/
@@ -3498,7 +3498,7 @@ declare type OptionalVirtualizedListProps = {
initialNumToRender?: number
initialScrollIndex?: number
inverted?: boolean
ItemSeparatorComponent?: React.ComponentType<any>
ItemSeparatorComponent?: React.ComponentType<any> | React.JSX.Element
keyExtractor?: (item: Item, index: number) => string
ListEmptyComponent?: React.ComponentType<any> | React.JSX.Element
ListFooterComponent?: React.ComponentType<any> | React.JSX.Element
@@ -4578,7 +4578,7 @@ declare type SectionBase<
SectionT = DefaultVirtualizedSectionT,
> = {
data: ReadonlyArray<SectionItemT>
ItemSeparatorComponent?: React.ComponentType<any>
ItemSeparatorComponent?: React.ComponentType<any> | React.JSX.Element
key?: string
renderItem?: (info: {
index: number
@@ -6013,8 +6013,8 @@ export {
EventSubscription, // b8d084aa
ExtendedExceptionData, // 5a6ccf5a
FilterFunction, // bf24c0e3
FlatList, // 4f1b407e
FlatListProps, // b225fb7a
FlatList, // cbb48cbe
FlatListProps, // 451be810
FocusEvent, // 529b43eb
FontVariant, // 7c7558bb
GestureResponderEvent, // b466f6d6
@@ -6151,12 +6151,12 @@ export {
ScrollViewPropsAndroid, // 84e2134b
ScrollViewPropsIOS, // d83c9733
ScrollViewScrollToOptions, // 3313411e
SectionBase, // 0ccaedac
SectionList, // a1a4786b
SectionListData, // 1c80bb2e
SectionListProps, // 7fb5371e
SectionListRenderItem, // cffebb53
SectionListRenderItemInfo, // 946c2128
SectionBase, // b376bddc
SectionList, // ff1193b2
SectionListData, // 119baf83
SectionListProps, // c9ac8e07
SectionListRenderItem, // 1fad0435
SectionListRenderItemInfo, // 745e1992
Separators, // 6a45f7e3
Settings, // 4282b0da
Share, // e4591b32
@@ -6219,9 +6219,9 @@ export {
ViewStyle, // c2db0e6e
VirtualViewMode, // 85a69ef6
VirtualizedList, // 4d513939
VirtualizedListProps, // be716140
VirtualizedListProps, // a99d36db
VirtualizedSectionList, // 446ba0df
VirtualizedSectionListProps, // a6899dfb
VirtualizedSectionListProps, // 6cd4b378
WrapperComponentProvider, // 9cf3844c
codegenNativeCommands, // e16d62f7
codegenNativeComponent, // ed4c8103
+6
View File
@@ -66,6 +66,12 @@ module.exports = {
get Modal() {
return require('./Libraries/Modal/Modal').default;
},
get unstable_NativeText() {
return require('./Libraries/Text/TextNativeComponent').NativeText;
},
get unstable_NativeView() {
return require('./Libraries/Components/View/ViewNativeComponent').default;
},
get Pressable() {
return require('./Libraries/Components/Pressable/Pressable').default;
},
+3
View File
@@ -127,6 +127,8 @@ export {default as Switch} from './Libraries/Components/Switch/Switch';
export type {TextProps} from './Libraries/Text/Text';
export {default as Text} from './Libraries/Text/Text';
export type {NativeTextProps as unstable_NativeTextProps} from './Libraries/Text/TextNativeComponent';
export {NativeText as unstable_NativeText} from './Libraries/Text/TextNativeComponent';
export {default as unstable_TextAncestorContext} from './Libraries/Text/TextAncestorContext';
export type {
@@ -180,6 +182,7 @@ export type {
ViewPropsIOS,
} from './Libraries/Components/View/ViewPropTypes';
export {default as View} from './Libraries/Components/View/View';
export {default as unstable_NativeView} from './Libraries/Components/View/ViewNativeComponent';
export type {
ListRenderItemInfo,
+2 -1
View File
@@ -175,6 +175,7 @@
"commander": "^12.0.0",
"flow-enums-runtime": "^0.0.6",
"glob": "^7.1.1",
"hermes-compiler": "0.0.0",
"invariant": "^2.2.4",
"jest-environment-node": "^29.7.0",
"memoize-one": "^5.0.0",
@@ -190,7 +191,7 @@
"semver": "^7.1.3",
"stacktrace-parser": "^0.1.10",
"whatwg-fetch": "^3.0.0",
"ws": "^6.2.3",
"ws": "^7.5.10",
"yargs": "^17.6.2"
},
"codegenConfig": {
@@ -59,6 +59,11 @@ function getInputFiles(appPath /*: string */, appPkgJson /*: $FlowFixMe */) {
!projectPath.includes('/Pods/') && // exclude Pods/Pods.xcodeproj
!projectPath.includes('/node_modules/'), // exclude all the xcodeproj in node_modules of libraries
)[0];
if (!xcodeproj) {
throw new Error(
`Cannot find .xcodeproj file inside ${appPath}. This is required to determine codegen spec paths relative to native project.`,
);
}
const jsFiles = '-name "Native*.js" -or -name "*NativeComponent.js"';
const tsFiles = '-name "Native*.ts" -or -name "*NativeComponent.ts"';
const findCommand = `find ${path.join(appPath, jsSrcsDir)} -type f -not -path "*/__mocks__/*" -and \\( ${jsFiles} -or ${tsFiles} \\)`;
@@ -440,6 +440,17 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'none',
},
enableSwiftUIBasedFilters: {
defaultValue: false,
metadata: {
dateAdded: '2025-07-30',
description:
'When enabled, it will use SwiftUI for filter effects like blur on iOS.',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
enableViewCulling: {
defaultValue: false,
metadata: {
@@ -151,6 +151,8 @@ def use_react_native! (
pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
pod 'React-RCTFBReactNativeSpec', :path => "#{prefix}/React"
pod 'React-jsi', :path => "#{prefix}/ReactCommon/jsi"
pod 'RCTSwiftUI', :path => "#{prefix}/ReactApple/RCTSwiftUI"
pod 'RCTSwiftUIWrapper', :path => "#{prefix}/ReactApple/RCTSwiftUIWrapper"
if hermes_enabled
setup_hermes!(:react_native_path => prefix)
@@ -79,6 +79,12 @@ type VirtualViewExperimentalNativeProps = $ReadOnly<{
*/
renderState: Int32,
/**
* This was needed to get VirtualViewManagerDelegate to set this property.
* TODO: Investigate why spread ViewProps doesn't call setter
*/
removeClippedSubviews?: boolean,
/**
* See `NativeModeChangeEvent`.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b1ab664114aa99d0f674d049c81bdc67>>
* @generated SignedSource<<054add14ea0c9a96d3c3e32af8995437>>
* @flow strict
* @noformat
*/
@@ -87,6 +87,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
enablePreparedTextLayout: Getter<boolean>,
enablePropsUpdateReconciliationAndroid: Getter<boolean>,
enableResourceTimingAPI: Getter<boolean>,
enableSwiftUIBasedFilters: Getter<boolean>,
enableViewCulling: Getter<boolean>,
enableViewRecycling: Getter<boolean>,
enableViewRecyclingForImage: Getter<boolean>,
@@ -351,6 +352,10 @@ export const enablePropsUpdateReconciliationAndroid: Getter<boolean> = createNat
* Enables the reporting of network resource timings through `PerformanceObserver`.
*/
export const enableResourceTimingAPI: Getter<boolean> = createNativeFlagGetter('enableResourceTimingAPI', false);
/**
* When enabled, it will use SwiftUI for filter effects like blur on iOS.
*/
export const enableSwiftUIBasedFilters: Getter<boolean> = createNativeFlagGetter('enableSwiftUIBasedFilters', false);
/**
* Enables View Culling: as soon as a view goes off screen, it can be reused anywhere in the UI and pieced together with other items to create new UI elements.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<14e017052313836604a3150fa08a1ebe>>
* @generated SignedSource<<ae5e2e1799601c6f630a465ec8e64ef6>>
* @flow strict
* @noformat
*/
@@ -62,6 +62,7 @@ export interface Spec extends TurboModule {
+enablePreparedTextLayout?: () => boolean;
+enablePropsUpdateReconciliationAndroid?: () => boolean;
+enableResourceTimingAPI?: () => boolean;
+enableSwiftUIBasedFilters?: () => boolean;
+enableViewCulling?: () => boolean;
+enableViewRecycling?: () => boolean;
+enableViewRecyclingForImage?: () => boolean;
@@ -58,4 +58,5 @@ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
export default (codegenNativeComponent<SwitchNativeProps>('Switch', {
paperComponentName: 'RCTSwitch',
excludedPlatforms: ['android'],
interfaceOnly: true,
}): ComponentType);
+33
View File
@@ -94,6 +94,9 @@ PODS:
- glog
- RCTDeprecation (1000.0.0)
- RCTRequired (1000.0.0)
- RCTSwiftUI (1000.0.0)
- RCTSwiftUIWrapper (1000.0.0):
- RCTSwiftUI
- RCTTypeSafety (1000.0.0):
- FBLazyVector (= 1000.0.0)
- RCTRequired (= 1000.0.0)
@@ -576,6 +579,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -618,6 +622,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -643,6 +648,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -668,6 +674,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -693,6 +700,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -718,6 +726,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -743,6 +752,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -772,6 +782,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -797,6 +808,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -822,6 +834,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -847,6 +860,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -874,6 +888,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -899,6 +914,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -924,6 +940,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -949,6 +966,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -974,6 +992,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -999,6 +1018,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -1024,6 +1044,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -1050,6 +1071,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -1075,6 +1097,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -1103,6 +1126,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -1128,6 +1152,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -1153,6 +1178,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -1180,6 +1206,7 @@ PODS:
- RCT-Folly
- RCT-Folly/Fabric
- RCTRequired
- RCTSwiftUIWrapper
- RCTTypeSafety
- React-Core
- React-cxxreact
@@ -2436,6 +2463,8 @@ DEPENDENCIES:
- RCT-Folly (from `../react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTDeprecation (from `../react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
- RCTRequired (from `../react-native/Libraries/Required`)
- RCTSwiftUI (from `../react-native/ReactApple/RCTSwiftUI`)
- RCTSwiftUIWrapper (from `../react-native/ReactApple/RCTSwiftUIWrapper`)
- RCTTypeSafety (from `../react-native/Libraries/TypeSafety`)
- React (from `../react-native/`)
- React-callinvoker (from `../react-native/ReactCommon/callinvoker`)
@@ -2536,6 +2565,10 @@ EXTERNAL SOURCES:
:path: "../react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
RCTRequired:
:path: "../react-native/Libraries/Required"
RCTSwiftUI:
:path: "../react-native/ReactApple/RCTSwiftUI"
RCTSwiftUIWrapper:
:path: "../react-native/ReactApple/RCTSwiftUIWrapper"
RCTTypeSafety:
:path: "../react-native/Libraries/TypeSafety"
React:
@@ -10,15 +10,15 @@
0EA618032BE537D3001875EF /* RNTesterBundle.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 0EA618022BE537D3001875EF /* RNTesterBundle.bundle */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */; };
3584606AB7F8ADF7A07A3E14 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF9F45393190A3F008764D08 /* libPods-RNTesterIntegrationTests.a */; };
383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */; };
3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; };
3F4D148C63BBF774A25488A6 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */; };
46C0FD761B0B9B1E8662B759 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B312B0EEE90BA411618B015 /* libPods-RNTesterUnitTests.a */; };
5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; };
8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; };
832F45BB2A8A6E1F0097B4E6 /* SwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */; };
A36E4394472D388C2F6BBABA /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 48A747D61749335D863001E9 /* libPods-RNTester.a */; };
A975CA6C2C05EADF0043F72A /* RCTNetworkTaskTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */; };
BF2C34488C1E5FF62D331DD4 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E89C730A8F64BC35672D4D81 /* libPods-RNTesterUnitTests.a */; };
C175B6D9ED9336FB66637943 /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */; };
CD10C7A5290BD4EB0033E1ED /* RCTEventEmitterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */; };
E62F11832A5C6580000BF1C8 /* FlexibleSizeExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.mm */; };
E62F11842A5C6584000BF1C8 /* UpdatePropertiesExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */; };
@@ -84,27 +84,28 @@
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNTester/AppDelegate.h; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = "<group>"; };
20B55D3C33B683598D2A4424 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = "<group>"; };
272E6B3B1BEA849E001FCF37 /* UpdatePropertiesExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UpdatePropertiesExampleView.h; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.h; sourceTree = "<group>"; };
272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UpdatePropertiesExampleView.mm; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm; sourceTree = "<group>"; };
2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = "<group>"; };
27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FlexibleSizeExampleView.mm; path = RNTester/NativeExampleViews/FlexibleSizeExampleView.mm; sourceTree = "<group>"; };
27F441EA1BEBE5030039B79C /* FlexibleSizeExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FlexibleSizeExampleView.h; path = RNTester/NativeExampleViews/FlexibleSizeExampleView.h; sourceTree = "<group>"; };
2B312B0EEE90BA411618B015 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNTester/Images.xcassets; sourceTree = "<group>"; };
359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = "<group>"; };
383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = "<group>"; };
3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "legacy_image@2x.png"; path = "RNTester/legacy_image@2x.png"; sourceTree = "<group>"; };
48A747D61749335D863001E9 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3FF60722627F93D8F62FA1E3 /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = "<group>"; };
4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; };
51BC9297B6C3163C14532020 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = "<group>"; };
5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = "<group>"; };
66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = "<group>"; };
7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = "<group>"; };
8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = "<group>"; };
832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftTest.swift; path = RNTester/SwiftTest.swift; sourceTree = "<group>"; };
8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = "<group>"; };
9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = "<group>"; };
93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkTaskTests.m; sourceTree = "<group>"; };
AC474BFB29BBD4A1002BDAED /* RNTester.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = RNTester.xctestplan; path = RNTester/RNTester.xctestplan; sourceTree = "<group>"; };
B0E70A8A05E03E868F8703FE /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = "<group>"; };
CA59C9994B1822826D8983F0 /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = "<group>"; };
CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventEmitterTests.m; sourceTree = "<group>"; };
DF9F45393190A3F008764D08 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
D134EB89DD98253FCF879A47 /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = "<group>"; };
E771AEEA22B44E3100EA1189 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = "<group>"; };
E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterIntegrationTests.m; sourceTree = "<group>"; };
E7DB209F22B2BA84005AC45F /* RNTesterUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -166,7 +167,6 @@
E7DB215E22B2F3EC005AC45F /* RCTLoggingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLoggingTests.m; sourceTree = "<group>"; };
E7DB215F22B2F3EC005AC45F /* RCTUIManagerScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerScenarioTests.m; sourceTree = "<group>"; };
E7DB218B22B41FCD005AC45F /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = XCTest.framework; sourceTree = DEVELOPER_DIR; };
E89C730A8F64BC35672D4D81 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
F0D621C22BBB9E38005960AC /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -175,7 +175,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A36E4394472D388C2F6BBABA /* libPods-RNTester.a in Frameworks */,
C175B6D9ED9336FB66637943 /* libPods-RNTester.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -184,7 +184,7 @@
buildActionMask = 2147483647;
files = (
E7DB213122B2C649005AC45F /* JavaScriptCore.framework in Frameworks */,
BF2C34488C1E5FF62D331DD4 /* libPods-RNTesterUnitTests.a in Frameworks */,
46C0FD761B0B9B1E8662B759 /* libPods-RNTesterUnitTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -194,7 +194,7 @@
files = (
E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */,
E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */,
3584606AB7F8ADF7A07A3E14 /* libPods-RNTesterIntegrationTests.a in Frameworks */,
3F4D148C63BBF774A25488A6 /* libPods-RNTesterIntegrationTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -265,9 +265,9 @@
E7DB211822B2BD53005AC45F /* libReact-RCTText.a */,
E7DB211A22B2BD53005AC45F /* libReact-RCTVibration.a */,
E7DB212222B2BD53005AC45F /* libyoga.a */,
48A747D61749335D863001E9 /* libPods-RNTester.a */,
DF9F45393190A3F008764D08 /* libPods-RNTesterIntegrationTests.a */,
E89C730A8F64BC35672D4D81 /* libPods-RNTesterUnitTests.a */,
4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */,
93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */,
2B312B0EEE90BA411618B015 /* libPods-RNTesterUnitTests.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -308,12 +308,12 @@
E23BD6487B06BD71F1A86914 /* Pods */ = {
isa = PBXGroup;
children = (
2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */,
9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */,
66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */,
7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */,
359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */,
8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */,
CA59C9994B1822826D8983F0 /* Pods-RNTester.debug.xcconfig */,
51BC9297B6C3163C14532020 /* Pods-RNTester.release.xcconfig */,
20B55D3C33B683598D2A4424 /* Pods-RNTesterIntegrationTests.debug.xcconfig */,
B0E70A8A05E03E868F8703FE /* Pods-RNTesterIntegrationTests.release.xcconfig */,
D134EB89DD98253FCF879A47 /* Pods-RNTesterUnitTests.debug.xcconfig */,
3FF60722627F93D8F62FA1E3 /* Pods-RNTesterUnitTests.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@@ -378,14 +378,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNTester" */;
buildPhases = (
ABDE2A52ACD1B95E14790B5E /* [CP] Check Pods Manifest.lock */,
F28F13DD10D40D98C0BB7BE8 /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */,
79E8BE2B119D4C5CCD2F04B3 /* [RN] Copy Hermes Framework */,
02B6FEF7E86B613B42F31284 /* [CP] Embed Pods Frameworks */,
5625E703156DD564DE9175B0 /* [CP] Copy Pods Resources */,
17FE348EDF12252D972FFC2F /* [CP] Embed Pods Frameworks */,
DFEE284B22AD5E88BBF1026A /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -400,12 +400,12 @@
isa = PBXNativeTarget;
buildConfigurationList = E7DB20A622B2BA84005AC45F /* Build configuration list for PBXNativeTarget "RNTesterUnitTests" */;
buildPhases = (
4F76596957F7356516B534CE /* [CP] Check Pods Manifest.lock */,
B8A88048D4E22316B9E74600 /* [CP] Check Pods Manifest.lock */,
E7DB209B22B2BA84005AC45F /* Sources */,
E7DB209C22B2BA84005AC45F /* Frameworks */,
E7DB209D22B2BA84005AC45F /* Resources */,
A904658C20543C2EDC217D15 /* [CP] Embed Pods Frameworks */,
01934C30687B8C926E4F59CD /* [CP] Copy Pods Resources */,
FD96BE05C0CECDF7D53C7CC9 /* [CP] Embed Pods Frameworks */,
5ECFFC3767E171859C7610A6 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -421,12 +421,12 @@
isa = PBXNativeTarget;
buildConfigurationList = E7DB215A22B2F332005AC45F /* Build configuration list for PBXNativeTarget "RNTesterIntegrationTests" */;
buildPhases = (
B7EB74515CDE78D98087DD53 /* [CP] Check Pods Manifest.lock */,
2978D2EE0533828E5DB62B8F /* [CP] Check Pods Manifest.lock */,
E7DB214F22B2F332005AC45F /* Sources */,
E7DB215022B2F332005AC45F /* Frameworks */,
E7DB215122B2F332005AC45F /* Resources */,
4F27ACC9DB890B37D6C267F1 /* [CP] Embed Pods Frameworks */,
E446637427ECD101CAACE52B /* [CP] Copy Pods Resources */,
A27E74B2EEF82EC119BCB5A2 /* [CP] Embed Pods Frameworks */,
48BF6B9FD13CB20F2C71C2A2 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -510,24 +510,7 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
01934C30687B8C926E4F59CD /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
02B6FEF7E86B613B42F31284 /* [CP] Embed Pods Frameworks */ = {
17FE348EDF12252D972FFC2F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -544,24 +527,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
4F27ACC9DB890B37D6C267F1 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
4F76596957F7356516B534CE /* [CP] Check Pods Manifest.lock */ = {
2978D2EE0533828E5DB62B8F /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -576,28 +542,45 @@
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt",
"$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
5625E703156DD564DE9175B0 /* [CP] Copy Pods Resources */ = {
48BF6B9FD13CB20F2C71C2A2 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
5ECFFC3767E171859C7610A6 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */ = {
@@ -634,24 +617,63 @@
shellPath = /bin/sh;
shellScript = ". ../react-native/sdks/hermes-engine/utils/copy-hermes-xcode.sh\n";
};
A904658C20543C2EDC217D15 /* [CP] Embed Pods Frameworks */ = {
A27E74B2EEF82EC119BCB5A2 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
ABDE2A52ACD1B95E14790B5E /* [CP] Check Pods Manifest.lock */ = {
B8A88048D4E22316B9E74600 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
DFEE284B22AD5E88BBF1026A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources.sh\"\n";
showEnvVarsInLog = 0;
};
F28F13DD10D40D98C0BB7BE8 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -673,43 +695,21 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
B7EB74515CDE78D98087DD53 /* [CP] Check Pods Manifest.lock */ = {
FD96BE05C0CECDF7D53C7CC9 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt",
"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
E446637427ECD101CAACE52B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -794,7 +794,7 @@
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */;
baseConfigurationReference = CA59C9994B1822826D8983F0 /* Pods-RNTester.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -832,7 +832,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */;
baseConfigurationReference = 51BC9297B6C3163C14532020 /* Pods-RNTester.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -1063,7 +1063,7 @@
};
E7DB20A722B2BA84005AC45F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */;
baseConfigurationReference = D134EB89DD98253FCF879A47 /* Pods-RNTesterUnitTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ANALYZER_NONNULL = YES;
@@ -1101,7 +1101,7 @@
};
E7DB20A822B2BA84005AC45F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */;
baseConfigurationReference = 3FF60722627F93D8F62FA1E3 /* Pods-RNTesterUnitTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ANALYZER_NONNULL = YES;
@@ -1139,7 +1139,7 @@
};
E7DB215B22B2F332005AC45F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */;
baseConfigurationReference = 20B55D3C33B683598D2A4424 /* Pods-RNTesterIntegrationTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
@@ -1178,7 +1178,7 @@
};
E7DB215C22B2F332005AC45F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */;
baseConfigurationReference = B0E70A8A05E03E868F8703FE /* Pods-RNTesterIntegrationTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
@@ -15,7 +15,7 @@ import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
import React from 'react';
import {useState} from 'react';
import {Image, StyleSheet, Text, View} from 'react-native';
import {Animated, Button, Image, StyleSheet, Text, View} from 'react-native';
const alphaHotdog = require('../../assets/alpha-hotdog.png');
const hotdog = require('../../assets/hotdog.jpg');
@@ -67,6 +67,14 @@ function StaticViewAndImageWithState(props: Props): React.Node {
}
const styles = StyleSheet.create({
blurWithShadow: {
filter: [{blur: 10}],
boxShadow: '0 0 10px 10px black',
overflow: 'hidden',
backgroundColor: 'pink',
height: 100,
width: 100,
},
commonView: {
width: 150,
height: 150,
@@ -189,7 +197,6 @@ exports.examples = [
title: 'Blur',
description: 'blur(10)',
name: 'blur',
platform: 'android',
render(): React.Node {
return (
<StaticViewAndImageComparison
@@ -199,6 +206,27 @@ exports.examples = [
);
},
},
{
title: 'Blur with boxShadow + overflow hidden + outline',
description: 'This tests container view with blur and outline on iOS',
name: 'blur-with-overflow',
render(): React.Node {
return (
<View
style={styles.blurWithShadow}
testID="filter-test-blur-overflow-hidden"
/>
);
},
},
{
title: 'Animated Blur',
description: 'Animated blur',
name: 'animated-blur',
render(): React.Node {
return <AnimatedBlurExample />;
},
},
{
title: 'Drop Shadow',
description: 'drop-shadow(30px 10px 4px #4444dd)',
@@ -253,3 +281,35 @@ exports.examples = [
},
},
] as Array<RNTesterModuleExample>;
const AnimatedBlurExample = () => {
const animatedValue = React.useRef(new Animated.Value(0)).current;
const [isBlurred, setIsBlurred] = React.useState(false);
const onPress = () => {
Animated.timing(animatedValue, {
toValue: isBlurred ? 0 : 20,
duration: 1000,
useNativeDriver: false,
}).start(() => setIsBlurred(!isBlurred));
};
return (
<View style={{flexDirection: 'column', alignItems: 'center'}}>
<Button
onPress={onPress}
title={isBlurred ? 'Remove Blur' : 'Animate Blur'}
/>
<Animated.View
style={[
{
filter: [{blur: animatedValue}],
backgroundColor: 'pink',
height: 100,
width: 100,
},
]}
/>
</View>
);
};
@@ -577,42 +577,23 @@ const examples = [
description:
('Shows system font families including system-ui/ui-sans-serif, ui-serif, ui-monospace, and ui-rounded': string),
render: function (): React.Node {
const baseTextStyle = {fontSize: 20};
return (
<View testID={'ios-font-families'}>
<Text
style={{
fontFamily: 'system-ui',
fontSize: 32,
marginBottom: 20,
}}>
`fontFamily: system-ui` (same as `ui-sans-serif`)
<View testID={'ios-font-families'} style={{gap: 10}}>
<Text style={{...baseTextStyle, fontFamily: 'system-ui'}}>
system-ui (same as ui-sans-serif)
</Text>
<Text
style={{
fontFamily: 'ui-sans-serif',
fontSize: 32,
marginBottom: 20,
}}>
`fontFamily: ui-sans-serif` (same as `system-ui`)
<Text style={{...baseTextStyle, fontFamily: 'ui-sans-serif'}}>
ui-sans-serif (same as system-ui)
</Text>
<Text
style={{fontFamily: 'ui-serif', fontSize: 32, marginBottom: 20}}>
`fontFamily: ui-serif`
<Text style={{...baseTextStyle, fontFamily: 'ui-serif'}}>
ui-serif
</Text>
<Text
style={{
fontFamily: 'ui-monospace',
fontSize: 32,
marginBottom: 20,
}}>
`fontFamily: ui-monospace`
<Text style={{...baseTextStyle, fontFamily: 'ui-monospace'}}>
ui-monospace
</Text>
<Text
style={{
fontFamily: 'ui-rounded',
fontSize: 32,
}}>
`fontFamily: ui-rounded`
<Text style={{...baseTextStyle, fontFamily: 'ui-rounded'}}>
ui-rounded
</Text>
</View>
);
@@ -767,6 +748,7 @@ const examples = [
}}>
Verdana bold
</Text>
<Text style={{fontFamily: 'SystemCondensed'}}>SystemCondensed</Text>
<Text style={{fontFamily: 'Unknown Font Family'}}>
Unknown Font Family
</Text>
+5 -1
View File
@@ -152,7 +152,11 @@ export interface VirtualizedListWithoutRenderItemProps<ItemT>
/**
* Rendered in between each item, but not at the top or bottom
*/
ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;
ItemSeparatorComponent?:
| React.ComponentType<any>
| React.ReactElement
| null
| undefined;
/**
* Rendered when the list is empty. Can be a React Component Class, a render function, or
@@ -24,9 +24,10 @@ import {StyleSheet, View} from 'react-native';
export type Props<ItemT> = {
CellRendererComponent?: ?React.ComponentType<CellRendererProps<ItemT>>,
ItemSeparatorComponent: ?React.ComponentType<
any | {highlighted: boolean, leadingItem: ?ItemT},
>,
ItemSeparatorComponent?: ?(
| React.ComponentType<any | {highlighted: boolean, leadingItem: ?ItemT}>
| React.MixedElement
),
ListItemComponent?: ?(React.ComponentType<any> | React.MixedElement),
cellKey: string,
horizontal: ?boolean,
@@ -199,6 +200,8 @@ export default class CellRenderer<ItemT> extends React.PureComponent<
ItemSeparatorComponent
: // $FlowFixMe[incompatible-type]
ItemSeparatorComponent && (
// $FlowFixMe[incompatible-type]
// $FlowFixMe[not-a-component]
<ItemSeparatorComponent {...this.state.separatorProps} />
);
const cellStyle = inversionStyle
@@ -129,7 +129,7 @@ type OptionalVirtualizedListProps = {
* which will update the `highlighted` prop, but you can also add custom props with
* `separators.updateProps`.
*/
ItemSeparatorComponent?: ?React.ComponentType<any>,
ItemSeparatorComponent?: ?(React.ComponentType<any> | React.MixedElement),
/**
* Takes an item from `data` and renders it into the list. Example usage:
*

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