From fd698aacd4e51dc57e0dfc9aefbc3e57f744a093 Mon Sep 17 00:00:00 2001 From: Linh Date: Wed, 5 Aug 2026 15:55:25 +0700 Subject: [PATCH 1/2] fix: android 15+ text cut off --- patches/react-native/details.md | 7 +++ ...-android15-text-clipping-boundswidth.patch | 47 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch diff --git a/patches/react-native/details.md b/patches/react-native/details.md index f59d0a5ec3d0..e6fbd1fb9e93 100644 --- a/patches/react-native/details.md +++ b/patches/react-native/details.md @@ -333,3 +333,10 @@ - Upstream PR/issue: 🛑 - E/App issue: https://github.com/Expensify/App/issues/57556 - PR introducing patch: https://github.com/Expensify/App/pull/94332 + +### [react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch](react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch) + +- Reason: On Android 15+, `StaticLayout`/`TextView` can use glyph visual bounds (which are wider than advance-based width) when rendering, causing trailing characters or whole words to be clipped off (e.g. "You appear to be offline" rendering as "You appear to be"). RN 0.85.3 already ships an implementation of a fix for this behind the `fixTextClippingAndroid15useBoundsForWidth` feature flag, but the flag defaults to `false` because the implementation has a bug: it computes each line's visual-bounds width as `getLineRight(i) - getLineLeft(i)`, which is wrong for lines with a nonzero left offset (e.g. leading margin spans) and caused regressions in unrelated text when tested. This patch enables the flag (both the Kotlin and C++ defaults) and fixes the width calculation to use `getLineMax(i)` instead, plus clamps the result so it can never shrink below the plain advance-based width (a safety net matching the direction of the still-unmerged upstream fix at https://github.com/react/react-native/pull/57117). +- Upstream PR/issue: https://github.com/react/react-native/pull/57117 +- E/App issue: https://github.com/Expensify/App/issues/76531 +- PR introducing patch: 🛑 (local testing only, not yet submitted) diff --git a/patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch b/patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch new file mode 100644 index 000000000000..afc194391f10 --- /dev/null +++ b/patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch @@ -0,0 +1,47 @@ +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +index f201093..e3efaf3 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +@@ -137,7 +137,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi + + override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean = false + +- override fun fixTextClippingAndroid15useBoundsForWidth(): Boolean = false ++ override fun fixTextClippingAndroid15useBoundsForWidth(): Boolean = true + + override fun fuseboxAssertSingleHostState(): Boolean = true + +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt +index dca0ecb..8b8d901 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt +@@ -873,10 +873,15 @@ internal object TextLayoutManager { + // Calculate visual bounds width from unconstrained layout + var desiredVisualWidth = 0f + for (i in 0 until unconstrainedLayout.lineCount) { +- val lineWidth = unconstrainedLayout.getLineRight(i) - unconstrainedLayout.getLineLeft(i) ++ val lineWidth = unconstrainedLayout.getLineMax(i) + desiredVisualWidth = max(desiredVisualWidth, lineWidth) + } + ++ // Never shrink below the plain advance-based width; the visual-bounds probe above should ++ // only ever grow the layout width to avoid clipping, never shrink it. ++ val advanceWidth = ceil(Layout.getDesiredWidth(text, paint)) ++ desiredVisualWidth = max(desiredVisualWidth, advanceWidth) ++ + val layoutWidth = + when (widthYogaMeasureMode) { + YogaMeasureMode.AT_MOST -> min(ceil(desiredVisualWidth).toInt(), floor(width).toInt()) +diff --git a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +index 8146298..7a0b920 100644 +--- a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h ++++ b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +@@ -256,7 +256,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { + } + + bool fixTextClippingAndroid15useBoundsForWidth() override { +- return false; ++ return true; + } + + bool fuseboxAssertSingleHostState() override { From 0a1defd5f7189c7b69a0f348077ef3970c99d841 Mon Sep 17 00:00:00 2001 From: Linh Date: Wed, 5 Aug 2026 17:32:19 +0700 Subject: [PATCH 2/2] fix: rebuild android 15 text-clipping patch on upstream's actual design The first version enabled RN's existing (buggy, disabled-by-default) fixTextClippingAndroid15useBoundsForWidth flag and patched its width calculation. PR review (chatgpt-codex-connector) caught that this also made the *final* rendered StaticLayout bounds-aware, not just the measurement probe - the exact path upstream reverted for regressing multiline/wrapping text, confirmed by cutoff seen in MenuItem's 2-line description text during testing. Rather than patch the old implementation further, this removes it entirely (it was already deleted upstream in react-native#56282, and the OSS-Experimental flag override that silently enabled it) and ports react-native#57117's replacement design unconditionally: a probe-only getDesiredWidth() helper using getLineMax with an advance-width floor, and an EXACTLY-mode short-circuit that respects Yoga's own width instead of substituting a computed one. Verified byte-for-byte against the actual upstream file at that PR's head commit, and round-trip validated against a freshly reconstructed pristine RN 0.85.3 baseline. --- patches/react-native/details.md | 6 +- ...-android15-text-clipping-boundswidth.patch | 268 +++++++++++++++--- 2 files changed, 231 insertions(+), 43 deletions(-) diff --git a/patches/react-native/details.md b/patches/react-native/details.md index e6fbd1fb9e93..d90c814411bc 100644 --- a/patches/react-native/details.md +++ b/patches/react-native/details.md @@ -336,7 +336,7 @@ ### [react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch](react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch) -- Reason: On Android 15+, `StaticLayout`/`TextView` can use glyph visual bounds (which are wider than advance-based width) when rendering, causing trailing characters or whole words to be clipped off (e.g. "You appear to be offline" rendering as "You appear to be"). RN 0.85.3 already ships an implementation of a fix for this behind the `fixTextClippingAndroid15useBoundsForWidth` feature flag, but the flag defaults to `false` because the implementation has a bug: it computes each line's visual-bounds width as `getLineRight(i) - getLineLeft(i)`, which is wrong for lines with a nonzero left offset (e.g. leading margin spans) and caused regressions in unrelated text when tested. This patch enables the flag (both the Kotlin and C++ defaults) and fixes the width calculation to use `getLineMax(i)` instead, plus clamps the result so it can never shrink below the plain advance-based width (a safety net matching the direction of the still-unmerged upstream fix at https://github.com/react/react-native/pull/57117). -- Upstream PR/issue: https://github.com/react/react-native/pull/57117 +- Reason: On Android 15+, `StaticLayout`/`TextView` can use glyph visual bounds (which are wider than advance-based width) when rendering, causing trailing characters or whole words to be clipped off (e.g. "You appear to be offline" rendering as "You appear to be"). RN 0.85.3's `fixTextClippingAndroid15useBoundsForWidth` feature flag was meant to fix this, and — unlike its `Defaults` value of `false` — the OSS Android "Experimental" flag profile (`ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android`/`ReactNativeFeatureFlagsOverridesOSSExperimental.h`) overrode it to `true`, so it was actually active. Its implementation had bugs: it computed each line's visual-bounds width as `getLineRight(i) - getLineLeft(i)` (wrong for lines with a nonzero left offset), applied `setUseBoundsForWidth(true)` to the *final* rendered `StaticLayout` and not just the measurement probe (the exact path upstream identified as causing multiline/wrapping regressions; flagged in PR review by chatgpt-codex-connector, https://github.com/Expensify/App/pull/97860#discussion_r3719363793), and never special-cased `YogaMeasureMode.EXACTLY`, so text with an already-determined exact width got resized to its desired width instead. Upstream abandoned that whole flag-gated implementation (facebook/react-native#56282, "Delete fixTextClippingAndroid15useBoundsForWidth()") rather than patch it in place, then proposed a from-scratch replacement (react/react-native#57117) with a `getDesiredWidth()` probe helper (using reflection for `StaticLayout.Builder.setUseBoundsForWidth` since the method is API 35+), `getLineMax(i)` for per-line width, a floor at the advance-based width, and an explicit `EXACTLY -> ceil(width).toInt()` short-circuit that skips the probe. This patch follows the same path: it removes the flag-gated implementation and the OSS-Experimental override entirely (mirroring an earlier internal attempt at this, Expensify/App#95922, which is unmerged/closed), then re-implements the fix unconditionally (SDK-gated only, no flag) matching PR 57117 as closely as possible — including porting `AndroidVersion.VERSION_CODE_VANILLA_ICE_CREAM` and the reflection-based `setUseBoundsForWidthMethod` — so this patch stays easy to diff against and eventually drop once 57117 (or an equivalent) lands upstream and we upgrade past it. +- Upstream PR/issue: https://github.com/facebook/react-native/pull/54721 (original flagged implementation, since abandoned), https://github.com/react/react-native/pull/56282 (deleted it), https://github.com/react/react-native/pull/57117 (unmerged replacement this patch ports) - E/App issue: https://github.com/Expensify/App/issues/76531 -- PR introducing patch: 🛑 (local testing only, not yet submitted) +- PR introducing patch: https://github.com/Expensify/App/pull/97860 diff --git a/patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch b/patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch index afc194391f10..773eeb5bd69e 100644 --- a/patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch +++ b/patches/react-native/react-native+0.85.3+040+fix-android15-text-clipping-boundswidth.patch @@ -1,47 +1,235 @@ -diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt -index f201093..e3efaf3 100644 ---- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt -+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt -@@ -137,7 +137,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi - - override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean = false - -- override fun fixTextClippingAndroid15useBoundsForWidth(): Boolean = false -+ override fun fixTextClippingAndroid15useBoundsForWidth(): Boolean = true - - override fun fuseboxAssertSingleHostState(): Boolean = true - +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt +index d740c6f..2fffcd0 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt +@@ -29,8 +29,6 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android : + + override fun enableSwiftUIBasedFilters(): Boolean = true + +- override fun fixTextClippingAndroid15useBoundsForWidth(): Boolean = true +- + override fun preventShadowTreeCommitExhaustion(): Boolean = true + + override fun useSharedAnimatedBackend(): Boolean = true +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/util/AndroidVersion.kt b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/util/AndroidVersion.kt +index 325ab60..05c9221 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/util/AndroidVersion.kt ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/util/AndroidVersion.kt +@@ -13,6 +13,13 @@ import android.os.Build + /** Helper class for checking Android version-related information. */ + internal object AndroidVersion { + ++ /** ++ * This is the version code for Android 15 (SDK Level 35). Internally at Meta this code is also ++ * compiled against SDK 34, so we need to retain this constant instead of using ++ * [Build.VERSION_CODES.VANILLA_ICE_CREAM] directly. ++ */ ++ internal const val VERSION_CODE_VANILLA_ICE_CREAM: Int = 35 ++ + /** + * This is the version code for Android 16 (SDK Level 36). Delete it once we bump up the default + * compile SDK version to 36. diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt -index dca0ecb..8b8d901 100644 +index dca0ecb..786b75a 100644 --- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt +++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt -@@ -873,10 +873,15 @@ internal object TextLayoutManager { - // Calculate visual bounds width from unconstrained layout - var desiredVisualWidth = 0f - for (i in 0 until unconstrainedLayout.lineCount) { -- val lineWidth = unconstrainedLayout.getLineRight(i) - unconstrainedLayout.getLineLeft(i) -+ val lineWidth = unconstrainedLayout.getLineMax(i) - desiredVisualWidth = max(desiredVisualWidth, lineWidth) +@@ -40,6 +40,7 @@ import com.facebook.react.uimanager.PixelUtil + import com.facebook.react.uimanager.PixelUtil.dpToPx + import com.facebook.react.uimanager.PixelUtil.pxToDp + import com.facebook.react.uimanager.ReactAccessibilityDelegate ++import com.facebook.react.util.AndroidVersion.VERSION_CODE_VANILLA_ICE_CREAM + import com.facebook.react.views.text.internal.span.CustomLetterSpacingSpan + import com.facebook.react.views.text.internal.span.CustomLineHeightSpan + import com.facebook.react.views.text.internal.span.CustomStyleSpan +@@ -170,6 +171,18 @@ internal object TextLayoutManager { + + private val tagToSpannableCache = ConcurrentHashMap() + ++ // Lazily cached Method for StaticLayout.Builder.setUseBoundsForWidth (API 35+). ++ // Reflection is needed because some internal targets compile against an SDK older than 35. ++ private val setUseBoundsForWidthMethod: java.lang.reflect.Method? by lazy { ++ try { ++ StaticLayout.Builder::class ++ .java ++ .getMethod("setUseBoundsForWidth", Boolean::class.javaPrimitiveType) ++ } catch (_: ReflectiveOperationException) { ++ null ++ } ++ } ++ + fun setCachedSpannableForTag(reactTag: Int, sp: Spannable): Unit { + tagToSpannableCache[reactTag] = sp + } +@@ -827,36 +840,69 @@ internal object TextLayoutManager { + ) } - -+ // Never shrink below the plain advance-based width; the visual-bounds probe above should -+ // only ever grow the layout width to avoid clipping, never shrink it. -+ val advanceWidth = ceil(Layout.getDesiredWidth(text, paint)) -+ desiredVisualWidth = max(desiredVisualWidth, advanceWidth) + +- // Pre-Android 15: Use existing advance-based logic ++ val layoutWidth = ++ when (widthYogaMeasureMode) { ++ YogaMeasureMode.EXACTLY -> ceil(width).toInt() ++ YogaMeasureMode.AT_MOST -> ++ min( ++ getDesiredWidth( ++ text, ++ includeFontPadding, ++ textBreakStrategy, ++ hyphenationFrequency, ++ alignment, ++ justificationMode, ++ paint, ++ ), ++ floor(width).toInt(), ++ ) ++ else -> ++ getDesiredWidth( ++ text, ++ includeFontPadding, ++ textBreakStrategy, ++ hyphenationFrequency, ++ alignment, ++ justificationMode, ++ paint, ++ ) ++ } ++ return buildLayout( ++ text, ++ layoutWidth, ++ includeFontPadding, ++ textBreakStrategy, ++ hyphenationFrequency, ++ alignment, ++ justificationMode, ++ ellipsizeMode, ++ maxNumberOfLines, ++ paint, ++ ) ++ } ++ ++ // Android 15+ can clip text whose visual glyph bounds are wider than its advance-based desired ++ // width. Probe the visual bounds width (when the setUseBoundsForWidth API is available) and use ++ // it only to grow the desired width — never to shrink below the plain advance-based width. ++ private fun getDesiredWidth( ++ text: Spannable, ++ includeFontPadding: Boolean, ++ textBreakStrategy: Int, ++ hyphenationFrequency: Int, ++ alignment: Layout.Alignment, ++ justificationMode: Int, ++ paint: TextPaint, ++ ): Int { ++ val advanceWidth = ceil(Layout.getDesiredWidth(text, paint)).toInt() + - val layoutWidth = - when (widthYogaMeasureMode) { - YogaMeasureMode.AT_MOST -> min(ceil(desiredVisualWidth).toInt(), floor(width).toInt()) -diff --git a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h -index 8146298..7a0b920 100644 ---- a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h -+++ b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h -@@ -256,7 +256,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { + if ( +- Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM || +- !ReactNativeFeatureFlags.fixTextClippingAndroid15useBoundsForWidth() ++ Build.VERSION.SDK_INT < VERSION_CODE_VANILLA_ICE_CREAM || ++ setUseBoundsForWidthMethod == null + ) { +- val desiredWidth = ceil(Layout.getDesiredWidth(text, paint)).toInt() +- +- val layoutWidth = +- when (widthYogaMeasureMode) { +- YogaMeasureMode.EXACTLY -> floor(width).toInt() +- YogaMeasureMode.AT_MOST -> min(desiredWidth, floor(width).toInt()) +- else -> desiredWidth +- } +- return buildLayout( +- text, +- layoutWidth, +- includeFontPadding, +- textBreakStrategy, +- hyphenationFrequency, +- alignment, +- justificationMode, +- ellipsizeMode, +- maxNumberOfLines, +- paint, +- ) ++ return advanceWidth + } + +- // Android 15+: Need to account for visual bounds +- // Step 1: Create unconstrained layout to get visual bounds width +- val unconstrainedLayout = ++ val visualBoundsLayout = + buildLayout( + text, + Int.MAX_VALUE / 2, +@@ -868,34 +914,15 @@ internal object TextLayoutManager { + null, + ReactConstants.UNSET, + paint, ++ useBoundsForWidth = true, + ) + +- // Calculate visual bounds width from unconstrained layout +- var desiredVisualWidth = 0f +- for (i in 0 until unconstrainedLayout.lineCount) { +- val lineWidth = unconstrainedLayout.getLineRight(i) - unconstrainedLayout.getLineLeft(i) +- desiredVisualWidth = max(desiredVisualWidth, lineWidth) ++ var visualBoundsWidth = 0f ++ for (i in 0 until visualBoundsLayout.lineCount) { ++ visualBoundsWidth = max(visualBoundsWidth, visualBoundsLayout.getLineMax(i)) + } + +- val layoutWidth = +- when (widthYogaMeasureMode) { +- YogaMeasureMode.AT_MOST -> min(ceil(desiredVisualWidth).toInt(), floor(width).toInt()) +- else -> ceil(desiredVisualWidth).toInt() +- } +- +- // Step 2: Create final layout with correct width +- return buildLayout( +- text, +- layoutWidth, +- includeFontPadding, +- textBreakStrategy, +- hyphenationFrequency, +- alignment, +- justificationMode, +- ellipsizeMode, +- maxNumberOfLines, +- paint, +- ) ++ return max(advanceWidth, ceil(visualBoundsWidth).toInt()) + } + + private fun buildLayout( +@@ -909,6 +936,7 @@ internal object TextLayoutManager { + ellipsizeMode: TextUtils.TruncateAt?, + maxNumberOfLines: Int, + paint: TextPaint, ++ useBoundsForWidth: Boolean = false, + ): Layout { + val builder = + StaticLayout.Builder.obtain(text, 0, text.length, paint, layoutWidth) +@@ -930,11 +958,8 @@ internal object TextLayoutManager { + builder.setUseLineSpacingFromFallbacks(true) + } + +- if ( +- Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && +- ReactNativeFeatureFlags.fixTextClippingAndroid15useBoundsForWidth() +- ) { +- builder.setUseBoundsForWidth(true) ++ if (useBoundsForWidth) { ++ setUseBoundsForWidthMethod?.invoke(builder, true) + } + + return builder.build() +diff --git a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +index b97ed6d..d5045cc 100644 +--- a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h ++++ b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +@@ -39,10 +39,6 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur + return true; } - - bool fixTextClippingAndroid15useBoundsForWidth() override { -- return false; -+ return true; + +- bool fixTextClippingAndroid15useBoundsForWidth() override { +- return true; +- } +- + bool preventShadowTreeCommitExhaustion() override { + return true; } - - bool fuseboxAssertSingleHostState() override {