Skip to content

Commit

Permalink
Implement baseline alignment function on the new architecture (#45102)
Browse files Browse the repository at this point in the history
Summary:
On the new architecture, the setup that would allow Yoga to read the baseline of a node was missing. This PR adds it:
- adds new ShadowNode trait - `BaselineYogaNode` that marks a node as having a custom baseline function
- adds `yogaNodeBaselineCallbackConnector` that's responsible for allowing Yoga to call baseline function on the node
- changes signatures of `lastBaseline` and `firstBaseline` to accept `LayoutContext` as the first argument, which is necessary to build an attributed string
- adds implementation of `lastBaseline` that's invoked by `yogaNodeBaselineCallbackConnector`
- adds methods for calculating the last baseline in platform-specific `TextLayoutManagers`, using the same approach on both Android and iOS (this differs from the old architecture where calculations were different)

## Changelog:

[GENERAL] [FIXED] - Fixed `alignItems: 'baseline'` not working correctly on the new architecture

Pull Request resolved: #45102

Test Plan:
Tested on the relevant part of RNTester:

### Android

|Old arch|New arch before|New arch after|
|-|-|-|
|<img width="426" alt="baseline-android-old-arch" src="https://github.com/facebook/react-native/assets/21055725/08550dfc-cf30-4938-8872-9bef916dc53c">|<img width="426" alt="baseline-android-new-arch-before" src="https://github.com/facebook/react-native/assets/21055725/9e3667f7-5c42-4e23-8972-fd2e994694a4">|<img width="409" alt="Screenshot 2024-07-02 at 16 40 38" src="https://github.com/facebook/react-native/assets/21055725/13379b11-b69e-4082-81cc-dec5e6d092f2">|

### iOS

|Old arch|New arch before|New arch after|
|-|-|-|
|<img width="519" alt="baseline-ios-old-arch" src="https://github.com/facebook/react-native/assets/21055725/da3956a1-5588-4933-87ce-4b5a9c256957">|<img width="519" alt="baseline-ios-new-arch-before" src="https://github.com/facebook/react-native/assets/21055725/09aef2c1-2eec-4710-b237-0f4a0c3d52d0">|<img width="519" alt="Screenshot 2024-07-02 at 16 40 29" src="https://github.com/facebook/react-native/assets/21055725/0a8a7251-1f6f-40db-81d7-4f37142932db">|

Reviewed By: NickGerleman

Differential Revision: D59323974

Pulled By: cortinico

fbshipit-source-id: e50882d399a0791a39ce8b416ed96d8fd3c48f23
  • Loading branch information
j-piasecki authored and facebook-github-bot committed Jul 10, 2024
1 parent 8371629 commit 2932c0f
Show file tree
Hide file tree
Showing 40 changed files with 525 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<<e7aaf58d91c8e25685f2a3ec5ca171a9>>
* @generated SignedSource<<8443301e7625595b6ca21901da0ccb88>>
*/

/**
Expand Down Expand Up @@ -58,6 +58,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun destroyFabricSurfacesInReactInstanceManager(): Boolean = accessor.destroyFabricSurfacesInReactInstanceManager()

/**
* Kill-switch to turn off support for aling-items:baseline on Fabric iOS.
*/
@JvmStatic
public fun enableAlignItemsBaselineOnFabricIOS(): Boolean = accessor.enableAlignItemsBaselineOnFabricIOS()

/**
* Clean yoga node when <TextInput /> does not change.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<bd5baae4bc2e8a619f99dea15766e803>>
* @generated SignedSource<<27c99bbe01b2b8999c6fa44be28f62d3>>
*/

/**
Expand All @@ -25,6 +25,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var destroyFabricSurfacesInReactInstanceManagerCache: Boolean? = null
private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null
private var enableCleanTextInputYogaNodeCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableMicrotasksCache: Boolean? = null
Expand Down Expand Up @@ -93,6 +94,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}

override fun enableAlignItemsBaselineOnFabricIOS(): Boolean {
var cached = enableAlignItemsBaselineOnFabricIOSCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableAlignItemsBaselineOnFabricIOS()
enableAlignItemsBaselineOnFabricIOSCache = cached
}
return cached
}

override fun enableCleanTextInputYogaNode(): Boolean {
var cached = enableCleanTextInputYogaNodeCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<317e652e32f680ed7cfa4989a8133dad>>
* @generated SignedSource<<2602dcd923a97419bfc2086d59ef9e90>>
*/

/**
Expand Down Expand Up @@ -38,6 +38,8 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun destroyFabricSurfacesInReactInstanceManager(): Boolean

@DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean

@DoNotStrip @JvmStatic public external fun enableCleanTextInputYogaNode(): Boolean

@DoNotStrip @JvmStatic public external fun enableGranularShadowTreeStateReconciliation(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<9821cf51f5220e5a6e121044d024e1e6>>
* @generated SignedSource<<a05b272a8a6ad7eced30f680e73bd9be>>
*/

/**
Expand Down Expand Up @@ -33,6 +33,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun destroyFabricSurfacesInReactInstanceManager(): Boolean = false

override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true

override fun enableCleanTextInputYogaNode(): Boolean = false

override fun enableGranularShadowTreeStateReconciliation(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<1f61054f14a12ed03d8ee5f32221ec1f>>
* @generated SignedSource<<ffcb3d17adea4a1b95421862210665df>>
*/

/**
Expand All @@ -29,6 +29,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var destroyFabricSurfacesInReactInstanceManagerCache: Boolean? = null
private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null
private var enableCleanTextInputYogaNodeCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableMicrotasksCache: Boolean? = null
Expand Down Expand Up @@ -102,6 +103,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}

override fun enableAlignItemsBaselineOnFabricIOS(): Boolean {
var cached = enableAlignItemsBaselineOnFabricIOSCache
if (cached == null) {
cached = currentProvider.enableAlignItemsBaselineOnFabricIOS()
accessedFeatureFlags.add("enableAlignItemsBaselineOnFabricIOS")
enableAlignItemsBaselineOnFabricIOSCache = cached
}
return cached
}

override fun enableCleanTextInputYogaNode(): Boolean {
var cached = enableCleanTextInputYogaNodeCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<a3ee4e4eae374959d5211897be02b983>>
* @generated SignedSource<<1b1165f9b93f140f5e01561ec6e16be2>>
*/

/**
Expand Down Expand Up @@ -33,6 +33,8 @@ public interface ReactNativeFeatureFlagsProvider {

@DoNotStrip public fun destroyFabricSurfacesInReactInstanceManager(): Boolean

@DoNotStrip public fun enableAlignItemsBaselineOnFabricIOS(): Boolean

@DoNotStrip public fun enableCleanTextInputYogaNode(): Boolean

@DoNotStrip public fun enableGranularShadowTreeStateReconciliation(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<03c48c7281afa746734af581d6a17aa3>>
* @generated SignedSource<<3cb2d3e59dadfa27214c024780a664df>>
*/

/**
Expand Down Expand Up @@ -69,6 +69,12 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}

bool enableAlignItemsBaselineOnFabricIOS() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableAlignItemsBaselineOnFabricIOS");
return method(javaProvider_);
}

bool enableCleanTextInputYogaNode() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableCleanTextInputYogaNode");
Expand Down Expand Up @@ -230,6 +236,11 @@ bool JReactNativeFeatureFlagsCxxInterop::destroyFabricSurfacesInReactInstanceMan
return ReactNativeFeatureFlags::destroyFabricSurfacesInReactInstanceManager();
}

bool JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS();
}

bool JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableCleanTextInputYogaNode();
Expand Down Expand Up @@ -372,6 +383,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"destroyFabricSurfacesInReactInstanceManager",
JReactNativeFeatureFlagsCxxInterop::destroyFabricSurfacesInReactInstanceManager),
makeNativeMethod(
"enableAlignItemsBaselineOnFabricIOS",
JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS),
makeNativeMethod(
"enableCleanTextInputYogaNode",
JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<37f8ec65fb26fc58260a5846ab933098>>
* @generated SignedSource<<9e3b9014578cec97635c2bd8d3c7add3>>
*/

/**
Expand Down Expand Up @@ -45,6 +45,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool destroyFabricSurfacesInReactInstanceManager(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableAlignItemsBaselineOnFabricIOS(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableCleanTextInputYogaNode(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<8943825039460c1a95d0fdb6113f42e6>>
* @generated SignedSource<<08c9a03b2c6960cc548c41a126073300>>
*/

/**
Expand Down Expand Up @@ -41,6 +41,10 @@ bool ReactNativeFeatureFlags::destroyFabricSurfacesInReactInstanceManager() {
return getAccessor().destroyFabricSurfacesInReactInstanceManager();
}

bool ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS() {
return getAccessor().enableAlignItemsBaselineOnFabricIOS();
}

bool ReactNativeFeatureFlags::enableCleanTextInputYogaNode() {
return getAccessor().enableCleanTextInputYogaNode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<241d9d028d103ce587a886521af41fa8>>
* @generated SignedSource<<8f367ce041b58945348d0f0648adeca3>>
*/

/**
Expand Down Expand Up @@ -62,6 +62,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool destroyFabricSurfacesInReactInstanceManager();

/**
* Kill-switch to turn off support for aling-items:baseline on Fabric iOS.
*/
RN_EXPORT static bool enableAlignItemsBaselineOnFabricIOS();

/**
* Clean yoga node when <TextInput /> does not change.
*/
Expand Down
Loading

0 comments on commit 2932c0f

Please sign in to comment.