diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp b/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp index 12907bfadd0037..cd32048480f540 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp @@ -108,6 +108,10 @@ void TextAttributes::apply(TextAttributes textAttributes) { ? textAttributes.accessibilityRole : accessibilityRole; role = textAttributes.role.has_value() ? textAttributes.role : role; + + textAlignVertical = textAttributes.textAlignVertical.has_value() + ? textAttributes.textAlignVertical + : textAlignVertical; } #pragma mark - Operators @@ -123,6 +127,7 @@ bool TextAttributes::operator==(const TextAttributes& rhs) const { allowFontScaling, dynamicTypeRamp, alignment, + textAlignVertical, baseWritingDirection, lineBreakStrategy, textDecorationColor, @@ -146,6 +151,7 @@ bool TextAttributes::operator==(const TextAttributes& rhs) const { rhs.allowFontScaling, rhs.dynamicTypeRamp, rhs.alignment, + rhs.textAlignVertical, rhs.baseWritingDirection, rhs.lineBreakStrategy, rhs.textDecorationColor, @@ -228,6 +234,8 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const { debugStringConvertibleItem("layoutDirection", layoutDirection), debugStringConvertibleItem("accessibilityRole", accessibilityRole), debugStringConvertibleItem("role", role), + + debugStringConvertibleItem("textAlignVertical", textAlignVertical), }; } #endif diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h index d259554839f5bd..c8ff0cbd40a4d8 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h @@ -84,6 +84,8 @@ class TextAttributes : public DebugStringConvertible { std::optional accessibilityRole{}; std::optional role{}; + std::optional textAlignVertical{}; + #pragma mark - Operations void apply(TextAttributes textAttributes); @@ -123,6 +125,7 @@ struct hash { textAttributes.textTransform, textAttributes.lineHeight, textAttributes.alignment, + textAttributes.textAlignVertical, textAttributes.baseWritingDirection, textAttributes.lineBreakStrategy, textAttributes.textDecorationColor, diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h index 653528f73c65c2..3e918b1c602bcd 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h @@ -456,6 +456,52 @@ inline std::string toString(const TextAlignment& textAlignment) { return "auto"; } +inline void fromRawValue( + const PropsParserContext& /*context*/, + const RawValue& value, + TextAlignmentVertical& result) { + react_native_expect(value.hasType()); + if (value.hasType()) { + auto string = (std::string)value; + if (string == "auto") { + result = TextAlignmentVertical::Auto; + } else if (string == "top") { + result = TextAlignmentVertical::Top; + } else if (string == "bottom") { + result = TextAlignmentVertical::Bottom; + } else if (string == "center") { + result = TextAlignmentVertical::Center; + } else { + LOG(ERROR) << "Unsupported TextAlignment value: " << string; + react_native_expect(false); + // sane default for prod + result = TextAlignmentVertical::Auto; + } + return; + } + + LOG(ERROR) << "Unsupported TextAlignmentVertical type"; + // sane default for prod + result = TextAlignmentVertical::Auto; +} + +inline std::string toString(const TextAlignmentVertical& textAlignment) { + switch (textAlignment) { + case TextAlignmentVertical::Auto: + return "auto"; + case TextAlignmentVertical::Top: + return "top"; + case TextAlignmentVertical::Bottom: + return "bottom"; + case TextAlignmentVertical::Center: + return "center"; + } + + LOG(ERROR) << "Unsupported TextAlignmentVertical value"; + // sane default for prod + return "auto"; +} + inline void fromRawValue( const PropsParserContext& context, const RawValue& value, @@ -893,6 +939,10 @@ inline folly::dynamic toDynamic(const TextAttributes& textAttributes) { _textAttributes( "accessibilityRole", toString(*textAttributes.accessibilityRole)); } + if (textAttributes.textAlignVertical.has_value()) { + _textAttributes( + "textAlignVertical", toString(*textAttributes.textAlignVertical)); + } return _textAttributes; } @@ -975,6 +1025,7 @@ constexpr static MapBuffer::Key TA_KEY_ACCESSIBILITY_ROLE = 24; constexpr static MapBuffer::Key TA_KEY_LINE_BREAK_STRATEGY = 25; constexpr static MapBuffer::Key TA_KEY_ROLE = 26; constexpr static MapBuffer::Key TA_KEY_TEXT_TRANSFORM = 27; +constexpr static MapBuffer::Key TA_KEY_ALIGNMENT_VERTICAL = 28; // constants for ParagraphAttributes serialization constexpr static MapBuffer::Key PA_KEY_MAX_NUMBER_OF_LINES = 0; @@ -1141,6 +1192,10 @@ inline MapBuffer toMapBuffer(const TextAttributes& textAttributes) { if (textAttributes.role.has_value()) { builder.putInt(TA_KEY_ROLE, static_cast(*textAttributes.role)); } + if (textAttributes.textAlignVertical.has_value()) { + builder.putString( + TA_KEY_ALIGNMENT_VERTICAL, toString(*textAttributes.textAlignVertical)); + } return builder.build(); } diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h index 817d487e3bb826..49afdff3525f51 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h @@ -80,6 +80,13 @@ enum class TextAlignment { Justified // Fully-justified. The last line in a paragraph is natural-aligned. }; +enum class TextAlignmentVertical { + Auto, + Top, + Bottom, + Center, +}; + enum class WritingDirection { Natural, // Determines direction using the Unicode Bidi Algorithm rules P2 and // P3. diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp index cb5a93b703f87f..8cf623e5b8084b 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp @@ -91,6 +91,12 @@ static TextAttributes convertRawProp( "textTransform", sourceTextAttributes.textTransform, defaultTextAttributes.textTransform); + textAttributes.textAlignVertical = convertRawProp( + context, + rawProps, + "textAlignVertical", + sourceTextAttributes.textAlignVertical, + defaultTextAttributes.textAlignVertical); // Paragraph textAttributes.lineHeight = convertRawProp( diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp index f75313b4229d38..6f318ca7095649 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp @@ -165,10 +165,6 @@ AndroidTextInputProps::AndroidTextInputProps( convertRawProp(context, rawProps, "fontWeight", sourceProps.fontWeight, {})), fontFamily(CoreFeatures::enablePropIteratorSetter? sourceProps.fontFamily : convertRawProp(context, rawProps, "fontFamily", sourceProps.fontFamily, {})), - textAlignVertical(CoreFeatures::enablePropIteratorSetter? sourceProps.textAlignVertical : convertRawProp(context, rawProps, - "textAlignVertical", - sourceProps.textAlignVertical, - {})), // See AndroidTextInputComponentDescriptor for usage // TODO T63008435: can these, and this feature, be removed entirely? hasPadding(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPadding : hasValue(rawProps, sourceProps.hasPadding, "padding")), @@ -250,7 +246,6 @@ void AndroidTextInputProps::setProp( RAW_SET_PROP_SWITCH_CASE_BASIC(includeFontPadding); RAW_SET_PROP_SWITCH_CASE_BASIC(fontWeight); RAW_SET_PROP_SWITCH_CASE_BASIC(fontFamily); - RAW_SET_PROP_SWITCH_CASE_BASIC(textAlignVertical); case CONSTEXPR_RAW_PROPS_KEY_HASH("value"): { fromRawValue(context, value, this->value, {}); @@ -348,7 +343,6 @@ folly::dynamic AndroidTextInputProps::getDynamic() const { props["includeFontPadding"] = includeFontPadding; props["fontWeight"] = fontWeight; props["fontFamily"] = fontFamily; - props["textAlignVertical"] = textAlignVertical; props["cursorColor"] = toAndroidRepr(cursorColor); props["mostRecentEventCount"] = mostRecentEventCount; props["text"] = text; diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h index 7049fea7f6c8a8..da41bb4ce251e8 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h @@ -111,7 +111,6 @@ class AndroidTextInputProps final : public BaseTextInputProps { bool includeFontPadding{false}; std::string fontWeight{}; std::string fontFamily{}; - std::string textAlignVertical{}; /** * Auxiliary information to detect if these props are set or not.