From 6cab6c2a13b89cbee1a2c1957ea561f82cb6700a Mon Sep 17 00:00:00 2001 From: shubhamguptadream11 Date: Fri, 23 Aug 2024 11:13:33 -0700 Subject: [PATCH] feat(iOS): line break mode cpp changes and new functions (#46130) Summary: Solves this issue: https://github.com/facebook/react-native/issues/44107 ## Changelog: [IOS] [ADDED] - Line break mode for TextInput components. **This includes cpp changes and new functions.** This PR is a breakdown of [this](https://github.com/facebook/react-native/pull/45968) PR. Pull Request resolved: https://github.com/facebook/react-native/pull/46130 Test Plan: - Tested builds in new and old architecture mode. Reviewed By: andrewdacenko Differential Revision: D61656894 Pulled By: cipolleschi fbshipit-source-id: 9a25387cb27cded072e76575e6d2fca01963c621 --- .../Libraries/Text/RCTTextAttributes.h | 1 + .../Libraries/Text/RCTTextAttributes.mm | 8 ++++++++ .../renderer/attributedstring/TextAttributes.h | 2 ++ .../renderer/attributedstring/primitives.h | 9 +++++++++ .../RCTAttributedTextUtils.mm | 5 +++++ .../RCTTextPrimitivesConversions.h | 18 ++++++++++++++++++ 6 files changed, 43 insertions(+) diff --git a/packages/react-native/Libraries/Text/RCTTextAttributes.h b/packages/react-native/Libraries/Text/RCTTextAttributes.h index 22fb646d434..c6923928d2d 100644 --- a/packages/react-native/Libraries/Text/RCTTextAttributes.h +++ b/packages/react-native/Libraries/Text/RCTTextAttributes.h @@ -44,6 +44,7 @@ extern NSString *const RCTTextAttributesTagAttributeName; @property (nonatomic, assign) NSTextAlignment alignment; @property (nonatomic, assign) NSWritingDirection baseWritingDirection; @property (nonatomic, assign) NSLineBreakStrategy lineBreakStrategy; +@property (nonatomic, assign) NSLineBreakMode lineBreakMode; // Decoration @property (nonatomic, strong, nullable) UIColor *textDecorationColor; @property (nonatomic, assign) NSUnderlineStyle textDecorationStyle; diff --git a/packages/react-native/Libraries/Text/RCTTextAttributes.mm b/packages/react-native/Libraries/Text/RCTTextAttributes.mm index c8323388ce6..57283d1820a 100644 --- a/packages/react-native/Libraries/Text/RCTTextAttributes.mm +++ b/packages/react-native/Libraries/Text/RCTTextAttributes.mm @@ -28,6 +28,7 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib _alignment = NSTextAlignmentNatural; _baseWritingDirection = NSWritingDirectionNatural; _lineBreakStrategy = NSLineBreakStrategyNone; + _lineBreakMode = NSLineBreakByWordWrapping; _textShadowRadius = NAN; _opacity = NAN; _textTransform = RCTTextTransformUndefined; @@ -70,6 +71,7 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib ? textAttributes->_baseWritingDirection : _baseWritingDirection; // * _lineBreakStrategy = textAttributes->_lineBreakStrategy ?: _lineBreakStrategy; + _lineBreakMode = textAttributes->_lineBreakMode ?: _lineBreakMode; // Decoration _textDecorationColor = textAttributes->_textDecorationColor ?: _textDecorationColor; @@ -128,6 +130,11 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib } } + if (_lineBreakMode != NSLineBreakByWordWrapping) { + paragraphStyle.lineBreakMode = _lineBreakMode; + isParagraphStyleUsed = YES; + } + if (!isnan(_lineHeight)) { CGFloat lineHeight = _lineHeight * self.effectiveFontSizeMultiplier; paragraphStyle.minimumLineHeight = lineHeight; @@ -336,6 +343,7 @@ static NSString *capitalizeText(NSString *text) // Paragraph Styles RCTTextAttributesCompareFloats(_lineHeight) && RCTTextAttributesCompareFloats(_alignment) && RCTTextAttributesCompareOthers(_baseWritingDirection) && RCTTextAttributesCompareOthers(_lineBreakStrategy) && + RCTTextAttributesCompareOthers(_lineBreakMode) && // Decoration RCTTextAttributesCompareObjects(_textDecorationColor) && RCTTextAttributesCompareOthers(_textDecorationStyle) && RCTTextAttributesCompareOthers(_textDecorationLine) && diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h index c8ff0cbd40a..37db36656f8 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h @@ -60,6 +60,7 @@ class TextAttributes : public DebugStringConvertible { std::optional alignment{}; std::optional baseWritingDirection{}; std::optional lineBreakStrategy{}; + std::optional lineBreakMode{}; // Decoration SharedColor textDecorationColor{}; @@ -128,6 +129,7 @@ struct hash { textAttributes.textAlignVertical, textAttributes.baseWritingDirection, textAttributes.lineBreakStrategy, + textAttributes.lineBreakMode, textAttributes.textDecorationColor, textAttributes.textDecorationLineType, textAttributes.textDecorationStyle, diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h index 49afdff3525..9bc23079e43 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h @@ -103,6 +103,15 @@ enum class LineBreakStrategy { // system uses for standard UI labels. }; +enum class LineBreakMode { + Word, // Wrap at word boundaries, default + Char, // Wrap at character boundaries + Clip, // Simply clip + Head, // Truncate at head of line: "...wxyz" + Middle, // Truncate middle of line: "ab...yz" + Tail // Truncate at tail of line: "abcd..." +}; + enum class TextDecorationLineType { None, Underline, diff --git a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm index 5bdeac31b49..2b2cf02fa11 100644 --- a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +++ b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm @@ -233,6 +233,11 @@ NSDictionary *RCTNSTextAttributesFromTextAttributes(c isParagraphStyleUsed = YES; } + if (textAttributes.lineBreakMode.has_value()) { + paragraphStyle.lineBreakMode = RCTNSLineBreakModeFromLineBreakMode(textAttributes.lineBreakMode.value()); + isParagraphStyleUsed = YES; + } + if (!isnan(textAttributes.lineHeight)) { CGFloat lineHeight = textAttributes.lineHeight * RCTEffectiveFontSizeMultiplierFromTextAttributes(textAttributes); paragraphStyle.minimumLineHeight = lineHeight; diff --git a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextPrimitivesConversions.h b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextPrimitivesConversions.h index c3f3ac20bd8..6a9624bff9f 100644 --- a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextPrimitivesConversions.h +++ b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextPrimitivesConversions.h @@ -63,6 +63,24 @@ inline static NSLineBreakStrategy RCTNSLineBreakStrategyFromLineBreakStrategy( } } +inline static NSLineBreakMode RCTNSLineBreakModeFromLineBreakMode(facebook::react::LineBreakMode lineBreakMode) +{ + switch (lineBreakMode) { + case facebook::react::LineBreakMode::Word: + return NSLineBreakByWordWrapping; + case facebook::react::LineBreakMode::Char: + return NSLineBreakByCharWrapping; + case facebook::react::LineBreakMode::Clip: + return NSLineBreakByClipping; + case facebook::react::LineBreakMode::Head: + return NSLineBreakByTruncatingHead; + case facebook::react::LineBreakMode::Middle: + return NSLineBreakByTruncatingMiddle; + case facebook::react::LineBreakMode::Tail: + return NSLineBreakByTruncatingTail; + } +} + inline static RCTFontStyle RCTFontStyleFromFontStyle(facebook::react::FontStyle fontStyle) { switch (fontStyle) {