From f9386374dc86279dcc8f9fb46bc543e2b2bdf8a4 Mon Sep 17 00:00:00 2001 From: iray-tno Date: Fri, 9 Oct 2026 13:39:30 +0000 Subject: [PATCH 1/3] 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 50815d71d91f..5d77cf14fe75 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 c8f28ddc4b49..f5fb1f38f181 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 6c76d3a2197f..85346a6d3370 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 d388d1d5f365..b124faeef128 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; @@ -197,6 +200,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 } @@ -249,6 +256,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, @@ -597,6 +606,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 8512fccba2f6..e7165e8f2a5c 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 @@ -343,6 +343,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 ca2d10ece398..441e99c9a371 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 @@ -612,6 +614,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 f3bac78200aa..7f82c30eb311 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 @@ -849,6 +852,8 @@ internal object TextLayoutManager { includeFontPadding: Boolean, textBreakStrategy: Int, hyphenationFrequency: Int, + lineBreakStyle: Int, + lineBreakWordStyle: Int, alignment: Layout.Alignment, justificationMode: Int, ellipsizeMode: TextUtils.TruncateAt?, @@ -895,6 +900,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -913,6 +920,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -963,6 +972,8 @@ internal object TextLayoutManager { includeFontPadding: Boolean, textBreakStrategy: Int, hyphenationFrequency: Int, + lineBreakStyle: Int, + lineBreakWordStyle: Int, alignment: Layout.Alignment, justificationMode: Int, ellipsizeMode: TextUtils.TruncateAt?, @@ -990,6 +1001,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. @@ -1169,6 +1195,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) @@ -1211,6 +1249,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, paint, @@ -1226,6 +1266,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -1249,6 +1291,8 @@ internal object TextLayoutManager { includeFontPadding, textBreakStrategy, hyphenationFrequency, + lineBreakStyle, + lineBreakWordStyle, alignment, justificationMode, ellipsizeMode, @@ -1372,6 +1416,8 @@ internal object TextLayoutManager { includeFontPadding: Boolean, textBreakStrategy: Int, hyphenationFrequency: Int, + lineBreakStyle: Int, + lineBreakWordStyle: Int, alignment: Layout.Alignment, justificationMode: Int, paint: TextPaint, @@ -1436,6 +1482,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 33e00f0af10c..5d2702725743 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 1fba91156cb6..fe2018802595 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 2f23db9c3047..db1cf120fc0b 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 af4c92f85611..820f9a88413c 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 a944b9e14ff8..b0593210aec7 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 263d53e9b864..5a0e20918b71 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 b96661bd4dd4..fb612bf005cc 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 3478df3f838b..db4a1c17e198 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 dbe0ba096cbe..de7bc6e5cb7f 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 9cba413645c2..e91e700c6377 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 74c407136ff1..45beba7ead0e 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<> + * @generated SignedSource<> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -4864,6 +4864,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 @@ -5786,7 +5788,7 @@ export { AlertOptions, // 8a116d2a AlertType, // 5ab91217 AndroidKeyboardEvent, // e03becc8 - Animated, // f6f7758c + Animated, // 1552ef82 AppConfig, // 35c0ca70 AppRegistry, // edec2a30 AppState, // 12012be5 @@ -6020,7 +6022,7 @@ export { TVViewPropsIOS, // 1c612e4e TargetedEvent, // 16e98910 TaskProvider, // 266dedf2 - Text, // 6f8269c1 + Text, // ebb273ac TextContentType, // 239b3ecc TextInput, // cf6467dc TextInputAndroidProps, // 9ebbc103 @@ -6037,7 +6039,7 @@ export { TextInputSubmitEditingEvent, // e811fdbd TextInstance, // 7c7e2069 TextLayoutEvent, // 1a21e24a - TextProps, // ab00c755 + TextProps, // e0367583 TextStyle, // 898adfd1 ToastAndroid, // 88a8969a TouchableHighlight, // a015710f 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 25d8d8abe1ef..e776c8979027 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 896cede7ce64..38c73a41e827 100644 --- a/packages/rn-tester/js/examples/Text/TextExample.android.js +++ b/packages/rn-tester/js/examples/Text/TextExample.android.js @@ -607,6 +607,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 ( @@ -1459,6 +1495,13 @@ const examples = [ return ; }, }, + { + title: 'Line break style', + name: 'lineBreakStyle', + render(): React.Node { + return ; + }, + }, { title: 'Padding', name: 'padding', @@ -1943,6 +1986,11 @@ const styles = StyleSheet.create({ wrappedText: { maxWidth: 300, }, + lineBreakSample: { + backgroundColor: '#eee', + fontSize: 16, + width: 150, + }, }); module.exports = { From 8e85522c7aed2f08dba51d9fae30c1251e1ec90f Mon Sep 17 00:00:00 2001 From: iray-tno Date: Mon, 12 Oct 2026 04:15:17 +0000 Subject: [PATCH 2/3] 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 f5fb1f38f181..9e4cd29b1116 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 e776c8979027..ab5221da77d2 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 011a67c223d2..c6a5e5022f24 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; @@ -802,6 +804,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); @@ -898,6 +902,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); @@ -3146,6 +3152,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; @@ -5139,6 +5147,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 4293fa4df491..0b2c616a2541 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -3577,6 +3577,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); @@ -3673,6 +3675,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); @@ -5354,6 +5358,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; @@ -7296,6 +7302,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 b3011c1fec07..0601d592841d 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api @@ -377,6 +377,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); @@ -464,6 +466,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); @@ -1815,6 +1819,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; @@ -3535,6 +3541,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, From c4f4b9e1a8dfdcabab1fc9a2518c49e5cf3ec557 Mon Sep 17 00:00:00 2001 From: iray-tno Date: Thu, 15 Oct 2026 06:20:36 +0000 Subject: [PATCH 3/3] Rename to CSS lineBreak and wordBreak Per review, align the props with CSS `line-break` and `word-break` instead of Android's LineBreakConfig terms, and document them as Android-only for now: - android_lineBreakStyle ('none' | 'loose' | 'normal' | 'strict') -> lineBreak ('auto' | 'loose' | 'normal' | 'strict') - android_lineBreakWordStyle ('none' | 'phrase') -> wordBreak ('normal' | 'auto-phrase') The C++ enums, ParagraphAttributes fields and MapBuffer keys follow the CSS names. 'auto' and 'normal' still set no LineBreakConfig, so default layout is unchanged. Regenerate the TypeScript and C++ API snapshots. Co-Authored-By: Claude Opus 5.5 --- .../Libraries/Text/TextNativeComponent.js | 4 +- .../react-native/Libraries/Text/TextProps.js | 22 +++-- .../ReactAndroid/api/ReactAndroid.api | 4 +- .../react/views/text/ReactTextViewManager.kt | 12 +-- .../react/views/text/TextAttributeProps.kt | 20 ++-- .../react/views/text/TextLayoutManager.kt | 12 +-- .../attributedstring/ParagraphAttributes.cpp | 16 ++-- .../attributedstring/ParagraphAttributes.h | 14 +-- .../renderer/attributedstring/conversions.h | 96 +++++++++---------- .../renderer/attributedstring/primitives.h | 18 ++-- .../tests/ParagraphAttributesTest.cpp | 28 +++--- .../components/text/BaseParagraphProps.cpp | 12 +-- .../text/HostPlatformParagraphProps.cpp | 14 ++- packages/react-native/ReactNativeApi.d.ts | 12 +-- .../types_DEPRECATED/Libraries/Text/Text.d.ts | 12 +-- .../js/examples/Text/TextExample.android.js | 28 +++--- .../ReactAndroidFrameworksCxx.api | 40 ++++---- .../api-snapshots/ReactAppleFrameworksCxx.api | 36 +++---- .../ReactCommonFrameworksCxx.api | 36 +++---- 19 files changed, 209 insertions(+), 227 deletions(-) diff --git a/packages/react-native/Libraries/Text/TextNativeComponent.js b/packages/react-native/Libraries/Text/TextNativeComponent.js index 5d77cf14fe75..98ae591a5204 100644 --- a/packages/react-native/Libraries/Text/TextNativeComponent.js +++ b/packages/react-native/Libraries/Text/TextNativeComponent.js @@ -47,8 +47,8 @@ const textViewConfig = { onTextLayout: true, dataDetectorType: true, android_hyphenationFrequency: true, - android_lineBreakStyle: true, - android_lineBreakWordStyle: true, + lineBreak: true, + wordBreak: true, lineBreakStrategyIOS: true, }, directEventTypes: { diff --git a/packages/react-native/Libraries/Text/TextProps.js b/packages/react-native/Libraries/Text/TextProps.js index 9e4cd29b1116..6fb8b163595a 100644 --- a/packages/react-native/Libraries/Text/TextProps.js +++ b/packages/react-native/Libraries/Text/TextProps.js @@ -151,26 +151,28 @@ type TextBaseProps = Readonly<{ /** * 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). + * may start or end a line in Chinese and Japanese text (kinsoku), as CSS + * `line-break`. Currently Android only, and ignored below Android 13 (API + * level 33). * - * @default `'none'` + * @default `'auto'` * @platform android */ - android_lineBreakStyle?: ?('none' | 'loose' | 'normal' | 'strict'), + lineBreak?: ?('auto' | '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). + * Sets word-based line breaking, as CSS `word-break`. `'auto-phrase'` breaks + * Japanese text at phrase boundaries instead of between any two characters. + * Currently Android only, and 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. + * where that locale has no phrase-based breaking, `'auto-phrase'` has no + * effect. * - * @default `'none'` + * @default `'normal'` * @platform android */ - android_lineBreakWordStyle?: ?('none' | 'phrase'), + wordBreak?: ?('normal' | 'auto-phrase'), children?: ?React.Node, diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 85346a6d3370..ba540f18c54d 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6079,8 +6079,6 @@ 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 @@ -6092,6 +6090,7 @@ public class com/facebook/react/views/text/ReactTextViewManager : com/facebook/r public final fun setFontSize (Lcom/facebook/react/views/text/ReactTextView;F)V public final fun setIncludeFontPadding (Lcom/facebook/react/views/text/ReactTextView;Z)V public final fun setLetterSpacing (Lcom/facebook/react/views/text/ReactTextView;F)V + public final fun setLineBreak (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;)V public final fun setNumberOfLines (Lcom/facebook/react/views/text/ReactTextView;I)V public final fun setOverflow (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;)V public synthetic fun setPadding (Landroid/view/View;IIII)V @@ -6100,6 +6099,7 @@ public class com/facebook/react/views/text/ReactTextViewManager : com/facebook/r public final fun setSelectable (Lcom/facebook/react/views/text/ReactTextView;Z)V public final fun setSelectionColor (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/Integer;)V public final fun setTextAlignVertical (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;)V + public final fun setWordBreak (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;)V public synthetic fun updateExtraData (Landroid/view/View;Ljava/lang/Object;)V public fun updateExtraData (Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/Object;)V public synthetic fun updateState (Landroid/view/View;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; 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 e7165e8f2a5c..ef7c3a33b04e 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 @@ -343,17 +343,17 @@ public constructor( } } - @ReactProp(name = "android_lineBreakStyle") - public fun setAndroidLineBreakStyle(view: ReactTextView, lineBreakStyle: String?) { + @ReactProp(name = "lineBreak") + public fun setLineBreak(view: ReactTextView, lineBreak: String?) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - view.lineBreakStyle = TextAttributeProps.getLineBreakStyle(lineBreakStyle) + view.lineBreakStyle = TextAttributeProps.getLineBreakStyle(lineBreak) } } - @ReactProp(name = "android_lineBreakWordStyle") - public fun setAndroidLineBreakWordStyle(view: ReactTextView, lineBreakWordStyle: String?) { + @ReactProp(name = "wordBreak") + public fun setWordBreak(view: ReactTextView, wordBreak: String?) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - view.lineBreakWordStyle = TextAttributeProps.getLineBreakWordStyle(lineBreakWordStyle) + view.lineBreakWordStyle = TextAttributeProps.getLineBreakWordStyle(wordBreak) } } 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 441e99c9a371..24aaea509f52 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 @@ -616,28 +616,30 @@ public class TextAttributeProps private constructor() { // The LineBreakConfig constants are inlined at compile time, so reading them is safe below API // 33. Callers apply the result only on API 33+. + // Maps CSS `line-break` values to LineBreakConfig.LINE_BREAK_STYLE_*. @SuppressLint("InlinedApi") - internal fun getLineBreakStyle(lineBreakStyle: String?): Int = - when (lineBreakStyle) { + internal fun getLineBreakStyle(lineBreak: String?): Int = + when (lineBreak) { null, - "none" -> LineBreakConfig.LINE_BREAK_STYLE_NONE + "auto" -> 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") + FLog.w(ReactConstants.TAG, "Invalid lineBreak: $lineBreak") LineBreakConfig.LINE_BREAK_STYLE_NONE } } + // Maps CSS `word-break` values to LineBreakConfig.LINE_BREAK_WORD_STYLE_*. @SuppressLint("InlinedApi") - internal fun getLineBreakWordStyle(lineBreakWordStyle: String?): Int = - when (lineBreakWordStyle) { + internal fun getLineBreakWordStyle(wordBreak: String?): Int = + when (wordBreak) { null, - "none" -> LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE - "phrase" -> LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE + "normal" -> LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE + "auto-phrase" -> LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE else -> { - FLog.w(ReactConstants.TAG, "Invalid android_lineBreakWordStyle: $lineBreakWordStyle") + FLog.w(ReactConstants.TAG, "Invalid wordBreak: $wordBreak") LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE } } 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 7f82c30eb311..54288339c7d8 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 @@ -100,8 +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 + const val PA_KEY_LINE_BREAK: Int = 11 + const val PA_KEY_WORD_BREAK: Int = 12 private val TAG: String = TextLayoutManager::class.java.simpleName @@ -1197,14 +1197,14 @@ internal object TextLayoutManager { ) val lineBreakStyle = TextAttributeProps.getLineBreakStyle( - if (paragraphAttributes.contains(PA_KEY_LINE_BREAK_STYLE)) - paragraphAttributes.getString(PA_KEY_LINE_BREAK_STYLE) + if (paragraphAttributes.contains(PA_KEY_LINE_BREAK)) + paragraphAttributes.getString(PA_KEY_LINE_BREAK) else null, ) val lineBreakWordStyle = TextAttributeProps.getLineBreakWordStyle( - if (paragraphAttributes.contains(PA_KEY_LINE_BREAK_WORD_STYLE)) - paragraphAttributes.getString(PA_KEY_LINE_BREAK_WORD_STYLE) + if (paragraphAttributes.contains(PA_KEY_WORD_BREAK)) + paragraphAttributes.getString(PA_KEY_WORD_BREAK) else null, ) val adjustFontSizeToFit = diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp b/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp index 820f9a88413c..c6bbbf364ce4 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp @@ -23,8 +23,8 @@ bool ParagraphAttributes::operator==(const ParagraphAttributes& rhs) const { adjustsFontSizeToFit, includeFontPadding, android_hyphenationFrequency, - android_lineBreakStyle, - android_lineBreakWordStyle, + lineBreak, + wordBreak, textAlignVertical) == std::tie( rhs.maximumNumberOfLines, @@ -34,8 +34,8 @@ bool ParagraphAttributes::operator==(const ParagraphAttributes& rhs) const { rhs.adjustsFontSizeToFit, rhs.includeFontPadding, rhs.android_hyphenationFrequency, - rhs.android_lineBreakStyle, - rhs.android_lineBreakWordStyle, + rhs.lineBreak, + rhs.wordBreak, rhs.textAlignVertical) && floatEquality(minimumFontSize, rhs.minimumFontSize) && floatEquality(minimumFontScale, rhs.minimumFontScale); @@ -80,13 +80,9 @@ SharedDebugStringConvertibleList ParagraphAttributes::getDebugProps() const { android_hyphenationFrequency, paragraphAttributes.android_hyphenationFrequency), debugStringConvertibleItem( - "android_lineBreakStyle", - android_lineBreakStyle, - paragraphAttributes.android_lineBreakStyle), + "lineBreak", lineBreak, paragraphAttributes.lineBreak), debugStringConvertibleItem( - "android_lineBreakWordStyle", - android_lineBreakWordStyle, - paragraphAttributes.android_lineBreakWordStyle), + "wordBreak", wordBreak, paragraphAttributes.wordBreak), 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 b0593210aec7..7a8d8dba13a1 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h @@ -69,14 +69,16 @@ class ParagraphAttributes : public DebugStringConvertible { HyphenationFrequency android_hyphenationFrequency{}; /* - * (Android only) Strictness of the line-breaking rules. + * Strictness of the line-breaking rules (CSS `line-break`). + * Currently applied on Android only. */ - LineBreakStyle android_lineBreakStyle{}; + LineBreak lineBreak{}; /* - * (Android only) Word-based line breaking. + * Word-based line breaking (CSS `word-break`). + * Currently applied on Android only. */ - LineBreakWordStyle android_lineBreakWordStyle{}; + WordBreak wordBreak{}; /* * In case of font size adjustment enabled, defines the minimum font size. @@ -122,8 +124,8 @@ struct hash { attributes.minimumFontSize, attributes.includeFontPadding, attributes.android_hyphenationFrequency, - attributes.android_lineBreakStyle, - attributes.android_lineBreakWordStyle, + attributes.lineBreak, + attributes.wordBreak, 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 5a0e20918b71..61353692b086 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h @@ -1034,86 +1034,86 @@ inline void fromRawValue(const PropsParserContext &context, const RawValue &valu result = HyphenationFrequency::None; } -inline std::string toString(const LineBreakStyle &lineBreakStyle) +inline std::string toString(const LineBreak &lineBreak) { - switch (lineBreakStyle) { - case LineBreakStyle::None: - return "none"; - case LineBreakStyle::Loose: + switch (lineBreak) { + case LineBreak::Auto: + return "auto"; + case LineBreak::Loose: return "loose"; - case LineBreakStyle::Normal: + case LineBreak::Normal: return "normal"; - case LineBreakStyle::Strict: + case LineBreak::Strict: return "strict"; } - LOG(ERROR) << "Unsupported LineBreakStyle value"; + LOG(ERROR) << "Unsupported LineBreak value"; react_native_expect(false); - return "none"; + return "auto"; } -inline void fromRawValue(const PropsParserContext &context, const RawValue &value, LineBreakStyle &result) +inline void fromRawValue(const PropsParserContext &context, const RawValue &value, LineBreak &result) { react_native_expect(value.hasType()); if (value.hasType()) { auto string = (std::string)value; - if (string == "none") { - result = LineBreakStyle::None; + if (string == "auto") { + result = LineBreak::Auto; } else if (string == "loose") { - result = LineBreakStyle::Loose; + result = LineBreak::Loose; } else if (string == "normal") { - result = LineBreakStyle::Normal; + result = LineBreak::Normal; } else if (string == "strict") { - result = LineBreakStyle::Strict; + result = LineBreak::Strict; } else { // sane default - LOG(ERROR) << "Unsupported LineBreakStyle value: " << string; + LOG(ERROR) << "Unsupported LineBreak value: " << string; react_native_expect(false); - result = LineBreakStyle::None; + result = LineBreak::Auto; } return; } - LOG(ERROR) << "Unsupported LineBreakStyle type"; + LOG(ERROR) << "Unsupported LineBreak type"; react_native_expect(false); - result = LineBreakStyle::None; + result = LineBreak::Auto; } -inline std::string toString(const LineBreakWordStyle &lineBreakWordStyle) +inline std::string toString(const WordBreak &wordBreak) { - switch (lineBreakWordStyle) { - case LineBreakWordStyle::None: - return "none"; - case LineBreakWordStyle::Phrase: - return "phrase"; + switch (wordBreak) { + case WordBreak::Normal: + return "normal"; + case WordBreak::AutoPhrase: + return "auto-phrase"; } - LOG(ERROR) << "Unsupported LineBreakWordStyle value"; + LOG(ERROR) << "Unsupported WordBreak value"; react_native_expect(false); - return "none"; + return "normal"; } -inline void fromRawValue(const PropsParserContext &context, const RawValue &value, LineBreakWordStyle &result) +inline void fromRawValue(const PropsParserContext &context, const RawValue &value, WordBreak &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; + if (string == "normal") { + result = WordBreak::Normal; + } else if (string == "auto-phrase") { + result = WordBreak::AutoPhrase; } else { // sane default - LOG(ERROR) << "Unsupported LineBreakWordStyle value: " << string; + LOG(ERROR) << "Unsupported WordBreak value: " << string; react_native_expect(false); - result = LineBreakWordStyle::None; + result = WordBreak::Normal; } return; } - LOG(ERROR) << "Unsupported LineBreakWordStyle type"; + LOG(ERROR) << "Unsupported WordBreak type"; react_native_expect(false); - result = LineBreakWordStyle::None; + result = WordBreak::Normal; } inline ParagraphAttributes convertRawProp( @@ -1178,18 +1178,10 @@ 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.lineBreak = convertRawProp( + context, rawProps, "lineBreak", sourceParagraphAttributes.lineBreak, defaultParagraphAttributes.lineBreak); + paragraphAttributes.wordBreak = convertRawProp( + context, rawProps, "wordBreak", sourceParagraphAttributes.wordBreak, defaultParagraphAttributes.wordBreak); paragraphAttributes.textAlignVertical = convertRawProp( context, rawProps, @@ -1284,8 +1276,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; +constexpr static MapBuffer::Key PA_KEY_LINE_BREAK = 11; +constexpr static MapBuffer::Key PA_KEY_WORD_BREAK = 12; inline MapBuffer toMapBuffer(const ParagraphAttributes ¶graphAttributes) { @@ -1297,8 +1289,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)); + builder.putString(PA_KEY_LINE_BREAK, toString(paragraphAttributes.lineBreak)); + builder.putString(PA_KEY_WORD_BREAK, toString(paragraphAttributes.wordBreak)); 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 fb612bf005cc..265860f687ff 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h @@ -164,23 +164,23 @@ enum class HyphenationFrequency { }; /* - * (Android only) Strictness of the line-breaking rules, as CSS `line-break`. - * Values match `android.graphics.text.LineBreakConfig.LINE_BREAK_STYLE_*`. + * Strictness of the line-breaking rules, as CSS `line-break`. + * Currently applied on Android only. */ -enum class LineBreakStyle { - None, // The platform's default rules. +enum class LineBreak { + Auto, // 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_*`. + * Word-based line breaking, as CSS `word-break`. + * Currently applied on Android only. */ -enum class LineBreakWordStyle { - None, // No word-based line breaking. - Phrase // Break Japanese text at phrase boundaries. +enum class WordBreak { + Normal, // No word-based line breaking. + AutoPhrase // 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 db4a1c17e198..d9b69e53c8e7 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/ParagraphAttributesTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/ParagraphAttributesTest.cpp @@ -93,12 +93,12 @@ TEST(ParagraphAttributesTest, testAutoTextWidthModeSerializesAsAuto) { EXPECT_EQ(toString(TextWidthMode::Auto), "auto"); } -TEST(ParagraphAttributesTest, testOperatorEqualsIncludesLineBreakStyles) { +TEST(ParagraphAttributesTest, testOperatorEqualsIncludesLineBreakAndWordBreak) { ParagraphAttributes defaults{}; ParagraphAttributes strict{}; - strict.android_lineBreakStyle = LineBreakStyle::Strict; + strict.lineBreak = LineBreak::Strict; ParagraphAttributes phrase{}; - phrase.android_lineBreakWordStyle = LineBreakWordStyle::Phrase; + phrase.wordBreak = WordBreak::AutoPhrase; EXPECT_FALSE(defaults == strict); EXPECT_FALSE(defaults == phrase); @@ -107,22 +107,24 @@ TEST(ParagraphAttributesTest, testOperatorEqualsIncludesLineBreakStyles) { std::hash{}(strict)); } -TEST(ParagraphAttributesTest, testLineBreakStylesDefaultToNone) { +TEST( + ParagraphAttributesTest, + testLineBreakAndWordBreakDefaultToCssInitialValues) { ParagraphAttributes defaults{}; - EXPECT_EQ(defaults.android_lineBreakStyle, LineBreakStyle::None); - EXPECT_EQ(defaults.android_lineBreakWordStyle, LineBreakWordStyle::None); + EXPECT_EQ(defaults.lineBreak, LineBreak::Auto); + EXPECT_EQ(defaults.wordBreak, WordBreak::Normal); } // 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"); +TEST(ParagraphAttributesTest, testLineBreakAndWordBreakSerializeToPropValues) { + EXPECT_EQ(toString(LineBreak::Auto), "auto"); + EXPECT_EQ(toString(LineBreak::Loose), "loose"); + EXPECT_EQ(toString(LineBreak::Normal), "normal"); + EXPECT_EQ(toString(LineBreak::Strict), "strict"); + EXPECT_EQ(toString(WordBreak::Normal), "normal"); + EXPECT_EQ(toString(WordBreak::AutoPhrase), "auto-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 de7bc6e5cb7f..6175bf755ea5 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp @@ -117,17 +117,9 @@ void BaseParagraphProps::setProp( android_hyphenationFrequency, "android_hyphenationFrequency"); REBUILD_FIELD_SWITCH_CASE( - paDefaults, - value, - paragraphAttributes, - android_lineBreakStyle, - "android_lineBreakStyle"); + paDefaults, value, paragraphAttributes, lineBreak, "lineBreak"); REBUILD_FIELD_SWITCH_CASE( - paDefaults, - value, - paragraphAttributes, - android_lineBreakWordStyle, - "android_lineBreakWordStyle"); + paDefaults, value, paragraphAttributes, wordBreak, "wordBreak"); 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 e91e700c6377..13fc83e55c2f 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,16 +140,14 @@ 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.lineBreak != + oldProps->paragraphAttributes.lineBreak) { + result["lineBreak"] = toString(paragraphAttributes.lineBreak); } - if (paragraphAttributes.android_lineBreakWordStyle != - oldProps->paragraphAttributes.android_lineBreakWordStyle) { - result["android_lineBreakWordStyle"] = - toString(paragraphAttributes.android_lineBreakWordStyle); + if (paragraphAttributes.wordBreak != + oldProps->paragraphAttributes.wordBreak) { + result["wordBreak"] = toString(paragraphAttributes.wordBreak); } if (paragraphAttributes.textAlignVertical != diff --git a/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts index 45beba7ead0e..814663cf7006 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<> + * @generated SignedSource<<4a9c44fd63e273e2c994c3bf310743df>> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -4864,11 +4864,10 @@ 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 + readonly lineBreak?: "auto" | "loose" | "normal" | "strict" readonly maxFontSizeMultiplier?: number readonly nativeID?: string readonly numberOfLines?: number @@ -4892,6 +4891,7 @@ declare type TextBaseProps = { readonly selectable?: boolean readonly style?: TextStyleProp readonly testID?: string + readonly wordBreak?: "auto-phrase" | "normal" } declare type TextContentType = | "addressCity" @@ -5788,7 +5788,7 @@ export { AlertOptions, // 8a116d2a AlertType, // 5ab91217 AndroidKeyboardEvent, // e03becc8 - Animated, // 1552ef82 + Animated, // 33fe7464 AppConfig, // 35c0ca70 AppRegistry, // edec2a30 AppState, // 12012be5 @@ -6022,7 +6022,7 @@ export { TVViewPropsIOS, // 1c612e4e TargetedEvent, // 16e98910 TaskProvider, // 266dedf2 - Text, // ebb273ac + Text, // 935ec305 TextContentType, // 239b3ecc TextInput, // cf6467dc TextInputAndroidProps, // 9ebbc103 @@ -6039,7 +6039,7 @@ export { TextInputSubmitEditingEvent, // e811fdbd TextInstance, // 7c7e2069 TextLayoutEvent, // 1a21e24a - TextProps, // e0367583 + TextProps, // b3707dfc TextStyle, // 898adfd1 ToastAndroid, // 88a8969a TouchableHighlight, // a015710f 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 ab5221da77d2..e793c03bc6d5 100644 --- a/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts +++ b/packages/react-native/types_DEPRECATED/Libraries/Text/Text.d.ts @@ -91,16 +91,16 @@ export interface TextPropsAndroid { /** * Strictness of the line-breaking rules (CSS `line-break`). - * Ignored below Android 13 (API level 33). + * Currently Android only, and ignored below Android 13 (API level 33). */ - android_lineBreakStyle?: 'none' | 'loose' | 'normal' | 'strict' | undefined; + lineBreak?: 'auto' | 'loose' | 'normal' | 'strict' | undefined; /** - * Word-based line breaking (CSS `word-break: auto-phrase`). - * Ignored below Android 13 (API level 33). Has no effect where the device - * locale has no phrase-based breaking. + * Word-based line breaking (CSS `word-break`). Currently Android only, and + * ignored below Android 13 (API level 33). `'auto-phrase'` has no effect + * where the device locale has no phrase-based breaking. */ - android_lineBreakWordStyle?: 'none' | 'phrase' | undefined; + wordBreak?: 'normal' | 'auto-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 38c73a41e827..aae2faacf9a0 100644 --- a/packages/rn-tester/js/examples/Text/TextExample.android.js +++ b/packages/rn-tester/js/examples/Text/TextExample.android.js @@ -610,31 +610,27 @@ function HyphenationExample(props: {}): React.Node { const LINE_BREAK_SAMPLE = 'キャッシュをチェックしてショートカットからコンピューターのメモリーをクリーンアップします。'; -function LineBreakStyleExample(props: {}): React.Node { +function LineBreakExample(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 => ( - + {(['auto', 'loose', 'normal', 'strict'] as const).map(lineBreak => ( + - android_lineBreakStyle="{lineBreakStyle}" + lineBreak="{lineBreak}" - + {LINE_BREAK_SAMPLE} ))} - {(['none', 'phrase'] as const).map(lineBreakWordStyle => ( - + {(['normal', 'auto-phrase'] as const).map(wordBreak => ( + - android_lineBreakWordStyle="{lineBreakWordStyle}" + wordBreak="{wordBreak}" - + {LINE_BREAK_SAMPLE} @@ -1496,10 +1492,10 @@ const examples = [ }, }, { - title: 'Line break style', - name: 'lineBreakStyle', + title: 'Line break (lineBreak, wordBreak)', + name: 'lineBreak', render(): React.Node { - return ; + return ; }, }, { diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api index c6a5e5022f24..1759713d080e 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api @@ -411,14 +411,14 @@ 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_LINE_BREAK; 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; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_TEXT_ALIGN_VERTICAL; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_TEXT_BREAK_STRATEGY; static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_TEXT_WIDTH_MODE; +static constexpr facebook::react::MapBuffer::Key facebook::react::PA_KEY_WORD_BREAK; static constexpr facebook::react::MapBuffer::Key facebook::react::TA_KEY_ACCESSIBILITY_ROLE; static constexpr facebook::react::MapBuffer::Key facebook::react::TA_KEY_ALIGNMENT; static constexpr facebook::react::MapBuffer::Key facebook::react::TA_KEY_ALIGNMENT_VERTICAL; @@ -802,10 +802,9 @@ std::string facebook::react::toString(const facebook::react::ImageResizeMode& va std::string facebook::react::toString(const facebook::react::ImageSource& value); std::string facebook::react::toString(const facebook::react::ImportantForAccessibility& importantForAccessibility); std::string facebook::react::toString(const facebook::react::LayoutDirection& layoutDirection); +std::string facebook::react::toString(const facebook::react::LineBreak& lineBreak); 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); @@ -816,6 +815,7 @@ std::string facebook::react::toString(const facebook::react::TextDecorationLineT std::string facebook::react::toString(const facebook::react::TextDecorationStyle& textDecorationStyle); std::string facebook::react::toString(const facebook::react::TextTransform& textTransform); std::string facebook::react::toString(const facebook::react::TextWidthMode& textWidthMode); +std::string facebook::react::toString(const facebook::react::WordBreak& wordBreak); std::string facebook::react::toString(const facebook::react::WritingDirection& writingDirection); std::string facebook::react::toString(double doubleValue, char suffix); std::string facebook::react::toString(facebook::react::AccessibilityLiveRegion accessibilityLiveRegion); @@ -901,9 +901,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::FontWeight& result); 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::LineBreak& 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); @@ -919,6 +918,7 @@ 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::TextTransform& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::Transform& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::TransformOrigin& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::WordBreak& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::WritingDirection& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::yoga::Align& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::yoga::Direction& result); @@ -3152,10 +3152,10 @@ 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::LineBreak lineBreak; public facebook::react::TextBreakStrategy textBreakStrategy; public facebook::react::TextWidthMode textWidthMode; + public facebook::react::WordBreak wordBreak; public int maximumNumberOfLines; public std::optional textAlignVertical; } @@ -5131,6 +5131,13 @@ enum facebook::react::LayoutDirection { Undefined, } +enum facebook::react::LineBreak { + Auto, + Loose, + Normal, + Strict, +} + enum facebook::react::LineBreakMode : uint8_t { Char, Clip, @@ -5147,18 +5154,6 @@ 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, @@ -5481,6 +5476,11 @@ enum facebook::react::UnitType { Undefined, } +enum facebook::react::WordBreak { + AutoPhrase, + Normal, +} + enum facebook::react::WritingDirection : uint8_t { LeftToRight, Natural, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api index 0b2c616a2541..f29e0605ee6c 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -3575,10 +3575,9 @@ std::string facebook::react::toString(const facebook::react::ImageResizeMode& va std::string facebook::react::toString(const facebook::react::ImageSource& value); std::string facebook::react::toString(const facebook::react::ImportantForAccessibility& importantForAccessibility); std::string facebook::react::toString(const facebook::react::LayoutDirection& layoutDirection); +std::string facebook::react::toString(const facebook::react::LineBreak& lineBreak); 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); @@ -3589,6 +3588,7 @@ std::string facebook::react::toString(const facebook::react::TextDecorationLineT std::string facebook::react::toString(const facebook::react::TextDecorationStyle& textDecorationStyle); std::string facebook::react::toString(const facebook::react::TextTransform& textTransform); std::string facebook::react::toString(const facebook::react::TextWidthMode& textWidthMode); +std::string facebook::react::toString(const facebook::react::WordBreak& wordBreak); std::string facebook::react::toString(const facebook::react::WritingDirection& writingDirection); std::string facebook::react::toString(double doubleValue, char suffix); std::string facebook::react::toString(facebook::react::AccessibilityLiveRegion accessibilityLiveRegion); @@ -3674,9 +3674,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::ImportantForAccessibility& result); 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::LineBreak& 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); @@ -3694,6 +3693,7 @@ 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::TextTransform& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::Transform& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::TransformOrigin& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::WordBreak& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::WritingDirection& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::yoga::Align& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::yoga::Direction& result); @@ -5358,10 +5358,10 @@ 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::LineBreak lineBreak; public facebook::react::TextBreakStrategy textBreakStrategy; public facebook::react::TextWidthMode textWidthMode; + public facebook::react::WordBreak wordBreak; public int maximumNumberOfLines; public std::optional textAlignVertical; } @@ -7286,6 +7286,13 @@ enum facebook::react::LayoutDirection { Undefined, } +enum facebook::react::LineBreak { + Auto, + Loose, + Normal, + Strict, +} + enum facebook::react::LineBreakMode : uint8_t { Char, Clip, @@ -7302,18 +7309,6 @@ 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, @@ -7660,6 +7655,11 @@ enum facebook::react::UnitType { Undefined, } +enum facebook::react::WordBreak { + AutoPhrase, + Normal, +} + enum facebook::react::WritingDirection : uint8_t { LeftToRight, Natural, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api index 0601d592841d..4814ff677f29 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api @@ -375,10 +375,9 @@ std::string facebook::react::toString(const facebook::react::ImageResizeMode& va std::string facebook::react::toString(const facebook::react::ImageSource& value); std::string facebook::react::toString(const facebook::react::ImportantForAccessibility& importantForAccessibility); std::string facebook::react::toString(const facebook::react::LayoutDirection& layoutDirection); +std::string facebook::react::toString(const facebook::react::LineBreak& lineBreak); 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); @@ -389,6 +388,7 @@ std::string facebook::react::toString(const facebook::react::TextDecorationLineT std::string facebook::react::toString(const facebook::react::TextDecorationStyle& textDecorationStyle); std::string facebook::react::toString(const facebook::react::TextTransform& textTransform); std::string facebook::react::toString(const facebook::react::TextWidthMode& textWidthMode); +std::string facebook::react::toString(const facebook::react::WordBreak& wordBreak); std::string facebook::react::toString(const facebook::react::WritingDirection& writingDirection); std::string facebook::react::toString(double doubleValue, char suffix); std::string facebook::react::toString(facebook::react::AccessibilityLiveRegion accessibilityLiveRegion); @@ -465,9 +465,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::FontWeight& result); 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::LineBreak& 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); @@ -483,6 +482,7 @@ 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::TextTransform& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::Transform& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::TransformOrigin& result); +void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::WordBreak& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::react::WritingDirection& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::yoga::Align& result); void facebook::react::fromRawValue(const facebook::react::PropsParserContext& context, const facebook::react::RawValue& value, facebook::yoga::Direction& result); @@ -1819,10 +1819,10 @@ 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::LineBreak lineBreak; public facebook::react::TextBreakStrategy textBreakStrategy; public facebook::react::TextWidthMode textWidthMode; + public facebook::react::WordBreak wordBreak; public int maximumNumberOfLines; public std::optional textAlignVertical; } @@ -3525,6 +3525,13 @@ enum facebook::react::LayoutDirection { Undefined, } +enum facebook::react::LineBreak { + Auto, + Loose, + Normal, + Strict, +} + enum facebook::react::LineBreakMode : uint8_t { Char, Clip, @@ -3541,18 +3548,6 @@ 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, @@ -3854,6 +3849,11 @@ enum facebook::react::UnitType { Undefined, } +enum facebook::react::WordBreak { + AutoPhrase, + Normal, +} + enum facebook::react::WritingDirection : uint8_t { LeftToRight, Natural,