From d4fff24fcd217ca7209450aae13e3b4646f29e6e Mon Sep 17 00:00:00 2001 From: iray-tno Date: Fri, 9 Oct 2026 13:39:30 +0000 Subject: [PATCH 1/2] Add android_lineBreakStyle and android_lineBreakWordStyle to Text Android 13 (API 33) added LineBreakConfig, which selects the strictness of the line-breaking rules (CSS `line-break`: loose, normal, strict) and phrase-based breaking for Japanese (CSS `word-break: auto-phrase`). React Native measures and draws Text with a StaticLayout it builds itself, so neither setting can be reached from outside: a native module could only change the drawn TextView, which would then disagree with the height Yoga measured. Add two Android-only paragraph props, plumbed the same way as android_hyphenationFrequency: - android_lineBreakStyle: 'none' | 'loose' | 'normal' | 'strict' - android_lineBreakWordStyle: 'none' | 'phrase' They go into ParagraphAttributes and the paragraph MapBuffer, are applied to the StaticLayout.Builder in TextLayoutManager (measurement and the prepared layout), and to ReactTextView through @ReactProp setters (drawing). Both are ignored below API 33. When both are 'none' (the default) no LineBreakConfig is set, so existing text lays out exactly as before. TextInput is left out: it does not list the props in its view config. Co-Authored-By: Claude Opus 5.5 --- .../Libraries/Text/TextNativeComponent.js | 2 + .../react-native/Libraries/Text/TextProps.js | 20 ++++ .../ReactAndroid/api/ReactAndroid.api | 4 + .../react/views/text/ReactTextView.java | 37 +++++++ .../react/views/text/ReactTextViewManager.kt | 14 +++ .../react/views/text/TextAttributeProps.kt | 30 ++++++ .../react/views/text/TextLayoutManager.kt | 48 +++++++++ ...erAbsoluteLayoutWithFractionalPixelTest.kt | 5 + .../TextLayoutManagerMinimumFontScaleTest.kt | 5 + .../TextLayoutManagerStartOverhangTest.kt | 5 + .../attributedstring/ParagraphAttributes.cpp | 12 +++ .../attributedstring/ParagraphAttributes.h | 12 +++ .../renderer/attributedstring/conversions.h | 98 +++++++++++++++++++ .../renderer/attributedstring/primitives.h | 20 ++++ .../tests/ParagraphAttributesTest.cpp | 32 ++++++ .../components/text/BaseParagraphProps.cpp | 12 +++ .../text/HostPlatformParagraphProps.cpp | 12 +++ packages/react-native/ReactNativeApi.d.ts | 10 +- .../types_DEPRECATED/Libraries/Text/Text.d.ts | 12 +++ .../js/examples/Text/TextExample.android.js | 48 +++++++++ 20 files changed, 434 insertions(+), 4 deletions(-) diff --git a/packages/react-native/Libraries/Text/TextNativeComponent.js b/packages/react-native/Libraries/Text/TextNativeComponent.js index 50815d71d91..5d77cf14fe7 100644 --- a/packages/react-native/Libraries/Text/TextNativeComponent.js +++ b/packages/react-native/Libraries/Text/TextNativeComponent.js @@ -47,6 +47,8 @@ const textViewConfig = { onTextLayout: true, dataDetectorType: true, android_hyphenationFrequency: true, + android_lineBreakStyle: true, + android_lineBreakWordStyle: true, lineBreakStrategyIOS: true, }, directEventTypes: { diff --git a/packages/react-native/Libraries/Text/TextProps.js b/packages/react-native/Libraries/Text/TextProps.js index c8f28ddc4b4..f5fb1f38f18 100644 --- a/packages/react-native/Libraries/Text/TextProps.js +++ b/packages/react-native/Libraries/Text/TextProps.js @@ -149,6 +149,26 @@ type TextBaseProps = Readonly<{ */ android_hyphenationFrequency?: ?('normal' | 'none' | 'full'), + /** + * Sets the strictness of the line-breaking rules, such as which characters + * may start or end a line in Chinese and Japanese text (kinsoku). Matches CSS + * `line-break`. Ignored below Android 13 (API level 33). + * + * @default `'none'` + * @platform android + */ + android_lineBreakStyle?: ?('none' | 'loose' | 'normal' | 'strict'), + + /** + * Sets word-based line breaking. `'phrase'` breaks Japanese text at phrase + * boundaries instead of between any two characters. Matches CSS + * `word-break: auto-phrase`. Ignored below Android 13 (API level 33). + * + * @default `'none'` + * @platform android + */ + android_lineBreakWordStyle?: ?('none' | 'phrase'), + children?: ?React.Node, /** diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 6c76d3a2197..85346a6d337 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6042,6 +6042,8 @@ public class com/facebook/react/views/text/ReactTextView : androidx/appcompat/wi public fun setHyphenationFrequency (I)V public fun setIncludeFontPadding (Z)V public fun setLetterSpacing (F)V + public fun setLineBreakStyle (I)V + public fun setLineBreakWordStyle (I)V public fun setLinkifyMask (I)V public fun setMinimumFontScale (F)V public fun setMinimumFontSize (F)V @@ -6077,6 +6079,8 @@ public class com/facebook/react/views/text/ReactTextViewManager : com/facebook/r public final fun setAccessible (Lcom/facebook/react/views/text/ReactTextView;Z)V public final fun setAdjustFontSizeToFit (Lcom/facebook/react/views/text/ReactTextView;Z)V public final fun setAndroidHyphenationFrequency (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;)V + public final fun setAndroidLineBreakStyle (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;)V + public final fun setAndroidLineBreakWordStyle (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;)V public final fun setBorderColor (Lcom/facebook/react/views/text/ReactTextView;ILjava/lang/Integer;)V public final fun setBorderRadius (Lcom/facebook/react/views/text/ReactTextView;IF)V public final fun setBorderRadius (Lcom/facebook/react/views/text/ReactTextView;ILcom/facebook/react/bridge/Dynamic;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index 677eb472660..aa0eef59b40 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -7,9 +7,11 @@ package com.facebook.react.views.text; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; +import android.graphics.text.LineBreakConfig; import android.os.Build; import android.text.Layout; import android.text.Spannable; @@ -26,6 +28,7 @@ import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.appcompat.widget.AppCompatTextView; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.ViewCompat; @@ -194,6 +197,10 @@ private void initView() { } setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + setLineBreakStyle(LineBreakConfig.LINE_BREAK_STYLE_NONE); + setLineBreakWordStyle(LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE); + } updateView(); // call after changing ellipsizeLocation in particular } @@ -246,6 +253,8 @@ protected void onDraw(Canvas canvas) { getIncludeFontPadding(), getBreakStrategy(), getHyphenationFrequency(), + getLineBreakStyleCompat(), + getLineBreakWordStyleCompat(), // always passing ALIGN_NORMAL here should be fine, since this method doesn't depend on // how exactly lines are aligned, just their width Layout.Alignment.ALIGN_NORMAL, @@ -575,6 +584,34 @@ public void setHyphenationFrequency(int hyphenationFrequency) { mShouldAdjustSpannableFontSize = true; } + @Override + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + public void setLineBreakStyle(int lineBreakStyle) { + super.setLineBreakStyle(lineBreakStyle); + mShouldAdjustSpannableFontSize = true; + } + + @Override + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + public void setLineBreakWordStyle(int lineBreakWordStyle) { + super.setLineBreakWordStyle(lineBreakWordStyle); + mShouldAdjustSpannableFontSize = true; + } + + @SuppressLint("InlinedApi") + private int getLineBreakStyleCompat() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + ? getLineBreakStyle() + : LineBreakConfig.LINE_BREAK_STYLE_NONE; + } + + @SuppressLint("InlinedApi") + private int getLineBreakWordStyleCompat() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + ? getLineBreakWordStyle() + : LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE; + } + @Override public void setLetterSpacing(float letterSpacing) { if (Float.isNaN(letterSpacing)) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt index 92d781317a8..3f36228decf 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt @@ -339,6 +339,20 @@ public constructor( } } + @ReactProp(name = "android_lineBreakStyle") + public fun setAndroidLineBreakStyle(view: ReactTextView, lineBreakStyle: String?) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + view.lineBreakStyle = TextAttributeProps.getLineBreakStyle(lineBreakStyle) + } + } + + @ReactProp(name = "android_lineBreakWordStyle") + public fun setAndroidLineBreakWordStyle(view: ReactTextView, lineBreakWordStyle: String?) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + view.lineBreakWordStyle = TextAttributeProps.getLineBreakWordStyle(lineBreakWordStyle) + } + } + @ReactPropGroup( names = [ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt index 4ebaa5630c0..fdae4da63f6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt @@ -7,6 +7,8 @@ package com.facebook.react.views.text +import android.annotation.SuppressLint +import android.graphics.text.LineBreakConfig import android.os.Build import android.text.Layout import android.text.TextUtils.TruncateAt @@ -608,6 +610,34 @@ public class TextAttributeProps private constructor() { else -> Layout.HYPHENATION_FREQUENCY_FULL } + // The LineBreakConfig constants are inlined at compile time, so reading them is safe below API + // 33. Callers apply the result only on API 33+. + @SuppressLint("InlinedApi") + internal fun getLineBreakStyle(lineBreakStyle: String?): Int = + when (lineBreakStyle) { + null, + "none" -> LineBreakConfig.LINE_BREAK_STYLE_NONE + "loose" -> LineBreakConfig.LINE_BREAK_STYLE_LOOSE + "normal" -> LineBreakConfig.LINE_BREAK_STYLE_NORMAL + "strict" -> LineBreakConfig.LINE_BREAK_STYLE_STRICT + else -> { + FLog.w(ReactConstants.TAG, "Invalid android_lineBreakStyle: $lineBreakStyle") + LineBreakConfig.LINE_BREAK_STYLE_NONE + } + } + + @SuppressLint("InlinedApi") + internal fun getLineBreakWordStyle(lineBreakWordStyle: String?): Int = + when (lineBreakWordStyle) { + null, + "none" -> LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE + "phrase" -> LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE + else -> { + FLog.w(ReactConstants.TAG, "Invalid android_lineBreakWordStyle: $lineBreakWordStyle") + LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE + } + } + public fun getEllipsizeMode(ellipsizeMode: String?): TruncateAt? = when (ellipsizeMode) { "head" -> TruncateAt.START diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt index d9c28ca5fa2..2712612bf8e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt @@ -11,6 +11,7 @@ import android.content.res.AssetManager import android.graphics.Color import android.graphics.RectF import android.graphics.Typeface +import android.graphics.text.LineBreakConfig import android.os.Build import android.text.BoringLayout import android.text.Layout @@ -99,6 +100,8 @@ internal object TextLayoutManager { const val PA_KEY_TEXT_ALIGN_VERTICAL: Int = 8 const val PA_KEY_TEXT_WIDTH_MODE: Int = 9 const val PA_KEY_MINIMUM_FONT_SCALE: Int = 10 + const val PA_KEY_LINE_BREAK_STYLE: Int = 11 + const val PA_KEY_LINE_BREAK_WORD_STYLE: Int = 12 private val TAG: String = TextLayoutManager::class.java.simpleName @@ -847,6 +850,8 @@ internal object TextLayoutManager { includeFontPadding: Boolean, textBreakStrategy: Int, hyphenationFrequency: Int, + lineBreakStyle: Int, + lineBreakWordStyle: Int, alignment: Layout.Alignment, justificationMode: Int, ellipsizeMode: TextUtils.TruncateAt?, @@ -893,6 +898,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -911,6 +918,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -961,6 +970,8 @@ internal object TextLayoutManager { includeFontPadding: Boolean, textBreakStrategy: Int, hyphenationFrequency: Int, + lineBreakStyle: Int, + lineBreakWordStyle: Int, alignment: Layout.Alignment, justificationMode: Int, ellipsizeMode: TextUtils.TruncateAt?, @@ -988,6 +999,21 @@ internal object TextLayoutManager { builder.setUseLineSpacingFromFallbacks(true) } + // Leave the platform default in place unless a style was requested, so text without these props + // lays out exactly as before. + if ( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && + (lineBreakStyle != LineBreakConfig.LINE_BREAK_STYLE_NONE || + lineBreakWordStyle != LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE) + ) { + builder.setLineBreakConfig( + LineBreakConfig.Builder() + .setLineBreakStyle(lineBreakStyle) + .setLineBreakWordStyle(lineBreakWordStyle) + .build() + ) + } + // Android shifts negative (left-side) start overhang itself. RTL start overhang is on the // right, so createLayout reserves that space in a second pass while preserving the EXACT Yoga // measurement returned to the caller. @@ -1147,6 +1173,18 @@ internal object TextLayoutManager { TextAttributeProps.getHyphenationFrequency( paragraphAttributes.getString(PA_KEY_HYPHENATION_FREQUENCY), ) + val lineBreakStyle = + TextAttributeProps.getLineBreakStyle( + if (paragraphAttributes.contains(PA_KEY_LINE_BREAK_STYLE)) + paragraphAttributes.getString(PA_KEY_LINE_BREAK_STYLE) + else null, + ) + val lineBreakWordStyle = + TextAttributeProps.getLineBreakWordStyle( + if (paragraphAttributes.contains(PA_KEY_LINE_BREAK_WORD_STYLE)) + paragraphAttributes.getString(PA_KEY_LINE_BREAK_WORD_STYLE) + else null, + ) val adjustFontSizeToFit = if (paragraphAttributes.contains(PA_KEY_ADJUST_FONT_SIZE_TO_FIT)) paragraphAttributes.getBoolean(PA_KEY_ADJUST_FONT_SIZE_TO_FIT) @@ -1189,6 +1227,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, paint, @@ -1204,6 +1244,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -1227,6 +1269,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -1349,6 +1393,8 @@ internal object TextLayoutManager { includeFontPadding: Boolean, textBreakStrategy: Int, hyphenationFrequency: Int, + lineBreakStyle: Int, + lineBreakWordStyle: Int, alignment: Layout.Alignment, justificationMode: Int, paint: TextPaint, @@ -1413,6 +1459,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, null, diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt index 33e00f0af10..5d270272574 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt @@ -8,6 +8,7 @@ package com.facebook.react.views.text import android.annotation.SuppressLint +import android.graphics.text.LineBreakConfig import android.text.BoringLayout import android.text.Layout import android.text.SpannableString @@ -104,6 +105,8 @@ class TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest { java.lang.Boolean.TYPE, java.lang.Integer.TYPE, java.lang.Integer.TYPE, + java.lang.Integer.TYPE, + java.lang.Integer.TYPE, Layout.Alignment::class.java, java.lang.Integer.TYPE, TextUtils.TruncateAt::class.java, @@ -121,6 +124,8 @@ class TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest { /* includeFontPadding = */ false, /* textBreakStrategy = */ Layout.BREAK_STRATEGY_HIGH_QUALITY, /* hyphenationFrequency = */ Layout.HYPHENATION_FREQUENCY_NONE, + /* lineBreakStyle = */ LineBreakConfig.LINE_BREAK_STYLE_NONE, + /* lineBreakWordStyle = */ LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE, Layout.Alignment.ALIGN_NORMAL, /* justificationMode = */ 0, /* ellipsizeMode = */ null, diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerMinimumFontScaleTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerMinimumFontScaleTest.kt index 1fba91156cb..fe201880259 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerMinimumFontScaleTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerMinimumFontScaleTest.kt @@ -7,6 +7,7 @@ package com.facebook.react.views.text +import android.graphics.text.LineBreakConfig import android.text.Layout import android.text.SpannableString import android.text.Spanned @@ -123,6 +124,8 @@ class TextLayoutManagerMinimumFontScaleTest { true, Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NONE, + /* lineBreakStyle = */ LineBreakConfig.LINE_BREAK_STYLE_NONE, + /* lineBreakWordStyle = */ LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE, Layout.Alignment.ALIGN_NORMAL, 0, newPaint(), @@ -149,6 +152,8 @@ class TextLayoutManagerMinimumFontScaleTest { true, Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NONE, + /* lineBreakStyle = */ LineBreakConfig.LINE_BREAK_STYLE_NONE, + /* lineBreakWordStyle = */ LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE, Layout.Alignment.ALIGN_NORMAL, 0, newPaint(), diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerStartOverhangTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerStartOverhangTest.kt index 2f23db9c304..db1cf120fc0 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerStartOverhangTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerStartOverhangTest.kt @@ -9,6 +9,7 @@ package com.facebook.react.views.text import android.annotation.SuppressLint import android.graphics.RectF +import android.graphics.text.LineBreakConfig import android.text.BoringLayout import android.text.Layout import android.text.SpannableString @@ -145,6 +146,8 @@ class TextLayoutManagerStartOverhangTest { java.lang.Boolean.TYPE, java.lang.Integer.TYPE, java.lang.Integer.TYPE, + java.lang.Integer.TYPE, + java.lang.Integer.TYPE, Layout.Alignment::class.java, java.lang.Integer.TYPE, TextUtils.TruncateAt::class.java, @@ -162,6 +165,8 @@ class TextLayoutManagerStartOverhangTest { /* includeFontPadding = */ false, /* textBreakStrategy = */ Layout.BREAK_STRATEGY_HIGH_QUALITY, /* hyphenationFrequency = */ Layout.HYPHENATION_FREQUENCY_NONE, + /* lineBreakStyle = */ LineBreakConfig.LINE_BREAK_STYLE_NONE, + /* lineBreakWordStyle = */ LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE, Layout.Alignment.ALIGN_NORMAL, /* justificationMode = */ 0, /* ellipsizeMode = */ ellipsizeMode, diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp b/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp index af4c92f8561..820f9a88413 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp @@ -23,6 +23,8 @@ bool ParagraphAttributes::operator==(const ParagraphAttributes& rhs) const { adjustsFontSizeToFit, includeFontPadding, android_hyphenationFrequency, + android_lineBreakStyle, + android_lineBreakWordStyle, textAlignVertical) == std::tie( rhs.maximumNumberOfLines, @@ -32,6 +34,8 @@ bool ParagraphAttributes::operator==(const ParagraphAttributes& rhs) const { rhs.adjustsFontSizeToFit, rhs.includeFontPadding, rhs.android_hyphenationFrequency, + rhs.android_lineBreakStyle, + rhs.android_lineBreakWordStyle, rhs.textAlignVertical) && floatEquality(minimumFontSize, rhs.minimumFontSize) && floatEquality(minimumFontScale, rhs.minimumFontScale); @@ -75,6 +79,14 @@ SharedDebugStringConvertibleList ParagraphAttributes::getDebugProps() const { "android_hyphenationFrequency", android_hyphenationFrequency, paragraphAttributes.android_hyphenationFrequency), + debugStringConvertibleItem( + "android_lineBreakStyle", + android_lineBreakStyle, + paragraphAttributes.android_lineBreakStyle), + debugStringConvertibleItem( + "android_lineBreakWordStyle", + android_lineBreakWordStyle, + paragraphAttributes.android_lineBreakWordStyle), debugStringConvertibleItem( "textAlignVertical", textAlignVertical, diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h index a944b9e14ff..b0593210aec 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h @@ -68,6 +68,16 @@ class ParagraphAttributes : public DebugStringConvertible { */ HyphenationFrequency android_hyphenationFrequency{}; + /* + * (Android only) Strictness of the line-breaking rules. + */ + LineBreakStyle android_lineBreakStyle{}; + + /* + * (Android only) Word-based line breaking. + */ + LineBreakWordStyle android_lineBreakWordStyle{}; + /* * In case of font size adjustment enabled, defines the minimum font size. * Deprecated in favor of minimumFontScale. @@ -112,6 +122,8 @@ struct hash { attributes.minimumFontSize, attributes.includeFontPadding, attributes.android_hyphenationFrequency, + attributes.android_lineBreakStyle, + attributes.android_lineBreakWordStyle, attributes.minimumFontScale, attributes.textAlignVertical); } diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h index 263d53e9b86..5a0e20918b7 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h @@ -1034,6 +1034,88 @@ inline void fromRawValue(const PropsParserContext &context, const RawValue &valu result = HyphenationFrequency::None; } +inline std::string toString(const LineBreakStyle &lineBreakStyle) +{ + switch (lineBreakStyle) { + case LineBreakStyle::None: + return "none"; + case LineBreakStyle::Loose: + return "loose"; + case LineBreakStyle::Normal: + return "normal"; + case LineBreakStyle::Strict: + return "strict"; + } + + LOG(ERROR) << "Unsupported LineBreakStyle value"; + react_native_expect(false); + return "none"; +} + +inline void fromRawValue(const PropsParserContext &context, const RawValue &value, LineBreakStyle &result) +{ + react_native_expect(value.hasType()); + if (value.hasType()) { + auto string = (std::string)value; + if (string == "none") { + result = LineBreakStyle::None; + } else if (string == "loose") { + result = LineBreakStyle::Loose; + } else if (string == "normal") { + result = LineBreakStyle::Normal; + } else if (string == "strict") { + result = LineBreakStyle::Strict; + } else { + // sane default + LOG(ERROR) << "Unsupported LineBreakStyle value: " << string; + react_native_expect(false); + result = LineBreakStyle::None; + } + return; + } + + LOG(ERROR) << "Unsupported LineBreakStyle type"; + react_native_expect(false); + result = LineBreakStyle::None; +} + +inline std::string toString(const LineBreakWordStyle &lineBreakWordStyle) +{ + switch (lineBreakWordStyle) { + case LineBreakWordStyle::None: + return "none"; + case LineBreakWordStyle::Phrase: + return "phrase"; + } + + LOG(ERROR) << "Unsupported LineBreakWordStyle value"; + react_native_expect(false); + return "none"; +} + +inline void fromRawValue(const PropsParserContext &context, const RawValue &value, LineBreakWordStyle &result) +{ + react_native_expect(value.hasType()); + if (value.hasType()) { + auto string = (std::string)value; + if (string == "none") { + result = LineBreakWordStyle::None; + } else if (string == "phrase") { + result = LineBreakWordStyle::Phrase; + } else { + // sane default + LOG(ERROR) << "Unsupported LineBreakWordStyle value: " << string; + react_native_expect(false); + result = LineBreakWordStyle::None; + } + return; + } + + LOG(ERROR) << "Unsupported LineBreakWordStyle type"; + react_native_expect(false); + result = LineBreakWordStyle::None; +} + inline ParagraphAttributes convertRawProp( const PropsParserContext &context, const RawProps &rawProps, @@ -1096,6 +1178,18 @@ inline ParagraphAttributes convertRawProp( "android_hyphenationFrequency", sourceParagraphAttributes.android_hyphenationFrequency, defaultParagraphAttributes.android_hyphenationFrequency); + paragraphAttributes.android_lineBreakStyle = convertRawProp( + context, + rawProps, + "android_lineBreakStyle", + sourceParagraphAttributes.android_lineBreakStyle, + defaultParagraphAttributes.android_lineBreakStyle); + paragraphAttributes.android_lineBreakWordStyle = convertRawProp( + context, + rawProps, + "android_lineBreakWordStyle", + sourceParagraphAttributes.android_lineBreakWordStyle, + defaultParagraphAttributes.android_lineBreakWordStyle); paragraphAttributes.textAlignVertical = convertRawProp( context, rawProps, @@ -1190,6 +1284,8 @@ constexpr static MapBuffer::Key PA_KEY_MINIMUM_FONT_SIZE = 6; constexpr static MapBuffer::Key PA_KEY_TEXT_ALIGN_VERTICAL = 8; constexpr static MapBuffer::Key PA_KEY_TEXT_WIDTH_MODE = 9; constexpr static MapBuffer::Key PA_KEY_MINIMUM_FONT_SCALE = 10; +constexpr static MapBuffer::Key PA_KEY_LINE_BREAK_STYLE = 11; +constexpr static MapBuffer::Key PA_KEY_LINE_BREAK_WORD_STYLE = 12; inline MapBuffer toMapBuffer(const ParagraphAttributes ¶graphAttributes) { @@ -1201,6 +1297,8 @@ inline MapBuffer toMapBuffer(const ParagraphAttributes ¶graphAttributes) builder.putBool(PA_KEY_ADJUST_FONT_SIZE_TO_FIT, paragraphAttributes.adjustsFontSizeToFit); builder.putBool(PA_KEY_INCLUDE_FONT_PADDING, paragraphAttributes.includeFontPadding); builder.putString(PA_KEY_HYPHENATION_FREQUENCY, toString(paragraphAttributes.android_hyphenationFrequency)); + builder.putString(PA_KEY_LINE_BREAK_STYLE, toString(paragraphAttributes.android_lineBreakStyle)); + builder.putString(PA_KEY_LINE_BREAK_WORD_STYLE, toString(paragraphAttributes.android_lineBreakWordStyle)); if (paragraphAttributes.textAlignVertical.has_value()) { builder.putString(PA_KEY_TEXT_ALIGN_VERTICAL, toString(*paragraphAttributes.textAlignVertical)); } diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h index b96661bd4dd..fb612bf005c 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h @@ -163,4 +163,24 @@ enum class HyphenationFrequency { Full // Standard amount of hyphenation. }; +/* + * (Android only) Strictness of the line-breaking rules, as CSS `line-break`. + * Values match `android.graphics.text.LineBreakConfig.LINE_BREAK_STYLE_*`. + */ +enum class LineBreakStyle { + None, // The platform's default rules. + Loose, // The least restrictive rules. + Normal, // The most common rules. + Strict // The most restrictive rules. +}; + +/* + * (Android only) Word-based line breaking, as CSS `word-break: auto-phrase`. + * Values match `android.graphics.text.LineBreakConfig.LINE_BREAK_WORD_STYLE_*`. + */ +enum class LineBreakWordStyle { + None, // No word-based line breaking. + Phrase // Break Japanese text at phrase boundaries. +}; + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/ParagraphAttributesTest.cpp b/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/ParagraphAttributesTest.cpp index 3478df3f838..db4a1c17e19 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/ParagraphAttributesTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/ParagraphAttributesTest.cpp @@ -93,4 +93,36 @@ TEST(ParagraphAttributesTest, testAutoTextWidthModeSerializesAsAuto) { EXPECT_EQ(toString(TextWidthMode::Auto), "auto"); } +TEST(ParagraphAttributesTest, testOperatorEqualsIncludesLineBreakStyles) { + ParagraphAttributes defaults{}; + ParagraphAttributes strict{}; + strict.android_lineBreakStyle = LineBreakStyle::Strict; + ParagraphAttributes phrase{}; + phrase.android_lineBreakWordStyle = LineBreakWordStyle::Phrase; + + EXPECT_FALSE(defaults == strict); + EXPECT_FALSE(defaults == phrase); + EXPECT_NE( + std::hash{}(defaults), + std::hash{}(strict)); +} + +TEST(ParagraphAttributesTest, testLineBreakStylesDefaultToNone) { + ParagraphAttributes defaults{}; + + EXPECT_EQ(defaults.android_lineBreakStyle, LineBreakStyle::None); + EXPECT_EQ(defaults.android_lineBreakWordStyle, LineBreakWordStyle::None); +} + +// The Android TextLayoutManager parses these strings, so they must match the +// values accepted from JavaScript. +TEST(ParagraphAttributesTest, testLineBreakStylesSerializeToPropValues) { + EXPECT_EQ(toString(LineBreakStyle::None), "none"); + EXPECT_EQ(toString(LineBreakStyle::Loose), "loose"); + EXPECT_EQ(toString(LineBreakStyle::Normal), "normal"); + EXPECT_EQ(toString(LineBreakStyle::Strict), "strict"); + EXPECT_EQ(toString(LineBreakWordStyle::None), "none"); + EXPECT_EQ(toString(LineBreakWordStyle::Phrase), "phrase"); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp index dbe0ba096cb..de7bc6e5cb7 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp @@ -116,6 +116,18 @@ void BaseParagraphProps::setProp( paragraphAttributes, android_hyphenationFrequency, "android_hyphenationFrequency"); + REBUILD_FIELD_SWITCH_CASE( + paDefaults, + value, + paragraphAttributes, + android_lineBreakStyle, + "android_lineBreakStyle"); + REBUILD_FIELD_SWITCH_CASE( + paDefaults, + value, + paragraphAttributes, + android_lineBreakWordStyle, + "android_lineBreakWordStyle"); REBUILD_FIELD_SWITCH_CASE( paDefaults, value, diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/platform/android/react/renderer/components/text/HostPlatformParagraphProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/platform/android/react/renderer/components/text/HostPlatformParagraphProps.cpp index 9cba413645c..e91e700c637 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/platform/android/react/renderer/components/text/HostPlatformParagraphProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/platform/android/react/renderer/components/text/HostPlatformParagraphProps.cpp @@ -140,6 +140,18 @@ folly::dynamic HostPlatformParagraphProps::getDiffProps( toString(paragraphAttributes.android_hyphenationFrequency); } + if (paragraphAttributes.android_lineBreakStyle != + oldProps->paragraphAttributes.android_lineBreakStyle) { + result["android_lineBreakStyle"] = + toString(paragraphAttributes.android_lineBreakStyle); + } + + if (paragraphAttributes.android_lineBreakWordStyle != + oldProps->paragraphAttributes.android_lineBreakWordStyle) { + result["android_lineBreakWordStyle"] = + toString(paragraphAttributes.android_lineBreakWordStyle); + } + if (paragraphAttributes.textAlignVertical != oldProps->paragraphAttributes.textAlignVertical) { result["textAlignVertical"] = diff --git a/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts index cb67856cb4b..903c741654e 100644 --- a/packages/react-native/ReactNativeApi.d.ts +++ b/packages/react-native/ReactNativeApi.d.ts @@ -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<<2ceaa8e472a53fc667994edb63ccd995>> + * @generated SignedSource<<9a2d069de549e0b4b9879dbd63ab8295>> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -4857,6 +4857,8 @@ declare type Text = typeof Text declare type TextBaseProps = { readonly allowFontScaling?: boolean readonly android_hyphenationFrequency?: "full" | "none" | "normal" + readonly android_lineBreakStyle?: "loose" | "none" | "normal" | "strict" + readonly android_lineBreakWordStyle?: "none" | "phrase" readonly children?: React.ReactNode readonly ellipsizeMode?: "clip" | "head" | "middle" | "tail" readonly id?: string @@ -5779,7 +5781,7 @@ export { AlertOptions, // 8a116d2a AlertType, // 5ab91217 AndroidKeyboardEvent, // e03becc8 - Animated, // ed4648e6 + Animated, // 1b75aea1 AppConfig, // 35c0ca70 AppRegistry, // edec2a30 AppState, // 12012be5 @@ -6013,7 +6015,7 @@ export { TVViewPropsIOS, // 1c612e4e TargetedEvent, // 16e98910 TaskProvider, // 266dedf2 - Text, // 39a4d091 + Text, // 66e53c98 TextContentType, // 239b3ecc TextInput, // 9981d7ab TextInputAndroidProps, // 9ebbc103 @@ -6030,7 +6032,7 @@ export { TextInputSubmitEditingEvent, // e811fdbd TextInstance, // 7c7e2069 TextLayoutEvent, // 1a21e24a - TextProps, // e4fdaaad + TextProps, // 12437236 TextStyle, // 898adfd1 ToastAndroid, // 88a8969a TouchableHighlight, // c5f5b1c2 diff --git a/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts b/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts index 25d8d8abe1e..e776c897902 100644 --- a/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts +++ b/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts @@ -88,6 +88,18 @@ export interface TextPropsAndroid { * Hyphenation strategy */ android_hyphenationFrequency?: 'normal' | 'none' | 'full' | undefined; + + /** + * Strictness of the line-breaking rules (CSS `line-break`). + * Ignored below Android 13 (API level 33). + */ + android_lineBreakStyle?: 'none' | 'loose' | 'normal' | 'strict' | undefined; + + /** + * Word-based line breaking (CSS `word-break: auto-phrase`). + * Ignored below Android 13 (API level 33). + */ + android_lineBreakWordStyle?: 'none' | 'phrase' | undefined; } // https://reactnative.dev/docs/text#props diff --git a/packages/rn-tester/js/examples/Text/TextExample.android.js b/packages/rn-tester/js/examples/Text/TextExample.android.js index 39b1c94aa24..c3da1f7f953 100644 --- a/packages/rn-tester/js/examples/Text/TextExample.android.js +++ b/packages/rn-tester/js/examples/Text/TextExample.android.js @@ -595,6 +595,42 @@ function HyphenationExample(props: {}): React.Node { ); } +const LINE_BREAK_SAMPLE = + 'キャッシュをチェックしてショートカットからコンピューターのメモリーをクリーンアップします。'; + +function LineBreakStyleExample(props: {}): React.Node { + // Each paragraph has a background so that a mismatch between the measured + // height and the drawn lines is visible. Requires Android 13 (API 33). + return ( + <> + {(['none', 'loose', 'normal', 'strict'] as const).map(lineBreakStyle => ( + + + android_lineBreakStyle="{lineBreakStyle}" + + + {LINE_BREAK_SAMPLE} + + + ))} + {(['none', 'phrase'] as const).map(lineBreakWordStyle => ( + + + android_lineBreakWordStyle="{lineBreakWordStyle}" + + + {LINE_BREAK_SAMPLE} + + + ))} + + ); +} + function FontWeightExample(props: {}): React.Node { return ( @@ -1447,6 +1483,13 @@ const examples = [ return ; }, }, + { + title: 'Line break style', + name: 'lineBreakStyle', + render(): React.Node { + return ; + }, + }, { title: 'Padding', name: 'padding', @@ -1931,6 +1974,11 @@ const styles = StyleSheet.create({ wrappedText: { maxWidth: 300, }, + lineBreakSample: { + backgroundColor: '#eee', + fontSize: 16, + width: 150, + }, }); module.exports = { From cdfab439b7c81f321853fe4a00b9b604e369322e Mon Sep 17 00:00:00 2001 From: iray-tno Date: Mon, 12 Oct 2026 04:15:17 +0000 Subject: [PATCH 2/2] Update C++ API snapshots and document phrase locale dependence Regenerate the Frameworks C++ API snapshots (Common, Android, Apple) for the new LineBreakStyle and LineBreakWordStyle enums, their conversions, the ParagraphAttributes fields and the paragraph MapBuffer keys. Generated with `yarn cxx-api-build` using Doxygen 1.16.1, the version the validation workflow pins. Document that android_lineBreakWordStyle="phrase" depends on the locale: Android Text is laid out in the device locale, and where that locale has no phrase-based breaking the setting has no effect. Co-Authored-By: Claude Opus 5.5 --- .../react-native/Libraries/Text/TextProps.js | 3 +++ .../types_DEPRECATED/Libraries/Text/Text.d.ts | 3 ++- .../ReactAndroidFrameworksCxx.api | 20 +++++++++++++++++++ .../api-snapshots/ReactAppleFrameworksCxx.api | 18 +++++++++++++++++ .../ReactCommonFrameworksCxx.api | 18 +++++++++++++++++ 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Text/TextProps.js b/packages/react-native/Libraries/Text/TextProps.js index f5fb1f38f18..9e4cd29b111 100644 --- a/packages/react-native/Libraries/Text/TextProps.js +++ b/packages/react-native/Libraries/Text/TextProps.js @@ -164,6 +164,9 @@ type TextBaseProps = Readonly<{ * boundaries instead of between any two characters. Matches CSS * `word-break: auto-phrase`. Ignored below Android 13 (API level 33). * + * Support depends on the locale, and text is laid out in the device locale: + * where that locale has no phrase-based breaking, `'phrase'` has no effect. + * * @default `'none'` * @platform android */ diff --git a/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts b/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts index e776c897902..ab5221da77d 100644 --- a/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts +++ b/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts @@ -97,7 +97,8 @@ export interface TextPropsAndroid { /** * Word-based line breaking (CSS `word-break: auto-phrase`). - * Ignored below Android 13 (API level 33). + * Ignored below Android 13 (API level 33). Has no effect where the device + * locale has no phrase-based breaking. */ android_lineBreakWordStyle?: 'none' | 'phrase' | undefined; } diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api index 88cc6107ec1..d0915383047 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api @@ -411,6 +411,8 @@ static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_ADJUST_ static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_ELLIPSIZE_MODE; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_HYPHENATION_FREQUENCY; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_INCLUDE_FONT_PADDING; +static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_LINE_BREAK_STYLE; +static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_LINE_BREAK_WORD_STYLE; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_MAX_NUMBER_OF_LINES; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_MINIMUM_FONT_SCALE; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_MINIMUM_FONT_SIZE; @@ -803,6 +805,8 @@ std::string facebook::react::toString(const facebook::react::ImportantForAccessi std::string facebook::react::toString(const facebook::react::LayoutDirection& layoutDirection); std::string facebook::react::toString(const facebook::react::LineBreakMode& lineBreakMode); std::string facebook::react::toString(const facebook::react::LineBreakStrategy& lineBreakStrategy); +std::string facebook::react::toString(const facebook::react::LineBreakStyle& lineBreakStyle); +std::string facebook::react::toString(const facebook::react::LineBreakWordStyle& lineBreakWordStyle); std::string facebook::react::toString(const facebook::react::Role& role); std::string facebook::react::toString(const facebook::react::ScrollViewSnapToAlignment& value); std::string facebook::react::toString(const facebook::react::SharedColor& value); @@ -899,6 +903,8 @@ void facebook::react::fromRawValue(const facebook::react::PropsParserContext& co void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::HyphenationFrequency& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::ImportantForAccessibility& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakStrategy& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakStyle& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakWordStyle& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::OutlineStyle& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::PointerEventsMode& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::Role& result); @@ -3149,6 +3155,8 @@ class facebook::react::ParagraphAttributes : public facebook::react::DebugString public facebook::react::Float minimumFontScale; public facebook::react::Float minimumFontSize; public facebook::react::HyphenationFrequency android_hyphenationFrequency; + public facebook::react::LineBreakStyle android_lineBreakStyle; + public facebook::react::LineBreakWordStyle android_lineBreakWordStyle; public facebook::react::TextBreakStrategy textBreakStrategy; public facebook::react::TextWidthMode textWidthMode; public int maximumNumberOfLines; @@ -5146,6 +5154,18 @@ enum facebook::react::LineBreakStrategy : uint8_t { Standard, } +enum facebook::react::LineBreakStyle { + Loose, + None, + Normal, + Strict, +} + +enum facebook::react::LineBreakWordStyle { + None, + Phrase, +} + enum facebook::react::ModalHostViewAnimationType { Fade, None, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api index fa368ff91c6..edce1e36571 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -3588,6 +3588,8 @@ std::string facebook::react::toString(const facebook::react::ImportantForAccessi std::string facebook::react::toString(const facebook::react::LayoutDirection& layoutDirection); std::string facebook::react::toString(const facebook::react::LineBreakMode& lineBreakMode); std::string facebook::react::toString(const facebook::react::LineBreakStrategy& lineBreakStrategy); +std::string facebook::react::toString(const facebook::react::LineBreakStyle& lineBreakStyle); +std::string facebook::react::toString(const facebook::react::LineBreakWordStyle& lineBreakWordStyle); std::string facebook::react::toString(const facebook::react::Role& role); std::string facebook::react::toString(const facebook::react::ScrollViewSnapToAlignment& value); std::string facebook::react::toString(const facebook::react::SharedColor& value); @@ -3684,6 +3686,8 @@ void facebook::react::fromRawValue(const facebook::react::PropsParserContext& co void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::KeyboardAppearance& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::KeyboardType& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakStrategy& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakStyle& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakWordStyle& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::OutlineStyle& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::PointerEventsMode& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::ReturnKeyType& result); @@ -5362,6 +5366,8 @@ class facebook::react::ParagraphAttributes : public facebook::react::DebugString public facebook::react::Float minimumFontScale; public facebook::react::Float minimumFontSize; public facebook::react::HyphenationFrequency android_hyphenationFrequency; + public facebook::react::LineBreakStyle android_lineBreakStyle; + public facebook::react::LineBreakWordStyle android_lineBreakWordStyle; public facebook::react::TextBreakStrategy textBreakStrategy; public facebook::react::TextWidthMode textWidthMode; public int maximumNumberOfLines; @@ -7313,6 +7319,18 @@ enum facebook::react::LineBreakStrategy : uint8_t { Standard, } +enum facebook::react::LineBreakStyle { + Loose, + None, + Normal, + Strict, +} + +enum facebook::react::LineBreakWordStyle { + None, + Phrase, +} + enum facebook::react::ModalHostViewAnimationType { Fade, None, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api index b8fbabd4a81..1d6a4e8bad6 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api @@ -378,6 +378,8 @@ std::string facebook::react::toString(const facebook::react::ImportantForAccessi std::string facebook::react::toString(const facebook::react::LayoutDirection& layoutDirection); std::string facebook::react::toString(const facebook::react::LineBreakMode& lineBreakMode); std::string facebook::react::toString(const facebook::react::LineBreakStrategy& lineBreakStrategy); +std::string facebook::react::toString(const facebook::react::LineBreakStyle& lineBreakStyle); +std::string facebook::react::toString(const facebook::react::LineBreakWordStyle& lineBreakWordStyle); std::string facebook::react::toString(const facebook::react::Role& role); std::string facebook::react::toString(const facebook::react::ScrollViewSnapToAlignment& value); std::string facebook::react::toString(const facebook::react::SharedColor& value); @@ -465,6 +467,8 @@ void facebook::react::fromRawValue(const facebook::react::PropsParserContext& co void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::HyphenationFrequency& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::ImportantForAccessibility& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakStrategy& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakStyle& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::LineBreakWordStyle& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::OutlineStyle& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::PointerEventsMode& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::Role& result); @@ -1812,6 +1816,8 @@ class facebook::react::ParagraphAttributes : public facebook::react::DebugString public bool operator==(const facebook::react::ParagraphAttributes& rhs) const; public facebook::react::EllipsizeMode ellipsizeMode; public facebook::react::HyphenationFrequency android_hyphenationFrequency; + public facebook::react::LineBreakStyle android_lineBreakStyle; + public facebook::react::LineBreakWordStyle android_lineBreakWordStyle; public facebook::react::TextBreakStrategy textBreakStrategy; public facebook::react::TextWidthMode textWidthMode; public int maximumNumberOfLines; @@ -3536,6 +3542,18 @@ enum facebook::react::LineBreakStrategy : uint8_t { Standard, } +enum facebook::react::LineBreakStyle { + Loose, + None, + Normal, + Strict, +} + +enum facebook::react::LineBreakWordStyle { + None, + Phrase, +} + enum facebook::react::NullValueStrategy { Ignore, Override,