Skip to content

Commit 55d0bc4

Browse files
Align logic in BaseTextInputShadowNode to calculate placeholder string with AndroidTextInputShadowNode (facebook#48584)
Summary: Pull Request resolved: facebook#48584 [Changelog] [Internal] - Align logic in BaseTextInputShadowNode to calculate placeholder string with AndroidTextInputShadowNode As a preparation for facebook#48165 this aligns the implementation of those 2 methods Reviewed By: NickGerleman Differential Revision: D68004218 fbshipit-source-id: 722a33bb2665c59347ef1b0cd8ed7b35a05b2113
1 parent cf5ab03 commit 55d0bc4

File tree

2 files changed

+36
-36
lines changed

2 files changed

+36
-36
lines changed

packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputShadowNode.h

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,7 @@ class BaseTextInputShadowNode : public ConcreteViewShadowNode<
9797
auto attributedString = getAttributedString(layoutContext);
9898

9999
if (attributedString.isEmpty()) {
100-
auto placeholderString = !props.placeholder.empty()
101-
? props.placeholder
102-
: BaseTextShadowNode::getEmptyPlaceholder();
103-
auto textAttributes =
104-
props.getEffectiveTextAttributes(layoutContext.fontSizeMultiplier);
105-
attributedString.appendFragment(
106-
{std::move(placeholderString), textAttributes, {}});
100+
attributedString = getPlaceholderAttributedString(layoutContext);
107101
}
108102

109103
// Yoga expects a baseline relative to the Node's border-box edge instead of
@@ -217,21 +211,33 @@ class BaseTextInputShadowNode : public ConcreteViewShadowNode<
217211
: getAttributedString(layoutContext);
218212

219213
if (attributedString.isEmpty()) {
220-
const auto& props = BaseShadowNode::getConcreteProps();
221-
auto placeholder = props.placeholder;
222-
// Note: `zero-width space` is insufficient in some cases (e.g. when we
223-
// need to measure the "hight" of the font).
224-
// TODO T67606511: We will redefine the measurement of empty strings as
225-
// part of T67606511
226-
auto string = !placeholder.empty()
227-
? placeholder
228-
: BaseTextShadowNode::getEmptyPlaceholder();
229-
auto textAttributes =
230-
props.getEffectiveTextAttributes(layoutContext.fontSizeMultiplier);
231-
attributedString.appendFragment({string, textAttributes, {}});
214+
attributedString = getPlaceholderAttributedString(layoutContext);
232215
}
233216
return AttributedStringBox{attributedString};
234217
}
218+
219+
// For measurement purposes, we want to make sure that there's at least a
220+
// single character in the string so that the measured height is greater
221+
// than zero. Otherwise, empty TextInputs with no placeholder don't
222+
// display at all.
223+
// TODO T67606511: We will redefine the measurement of empty strings as part
224+
// of T67606511
225+
AttributedString getPlaceholderAttributedString(
226+
const LayoutContext& layoutContext) const {
227+
const auto& props = BaseShadowNode::getConcreteProps();
228+
229+
AttributedString attributedString;
230+
auto placeholderString = !props.placeholder.empty()
231+
? props.placeholder
232+
: BaseTextShadowNode::getEmptyPlaceholder();
233+
auto textAttributes =
234+
props.getEffectiveTextAttributes(layoutContext.fontSizeMultiplier);
235+
attributedString.appendFragment(
236+
{.string = std::move(placeholderString),
237+
.textAttributes = textAttributes,
238+
.parentShadowView = {}});
239+
return attributedString;
240+
}
235241
};
236242

237243
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -215,25 +215,19 @@ AttributedString AndroidTextInputShadowNode::getMostRecentAttributedString()
215215
// of T67606511
216216
AttributedString AndroidTextInputShadowNode::getPlaceholderAttributedString()
217217
const {
218-
// Return placeholder text, since text and children are empty.
219-
auto textAttributedString = AttributedString{};
220-
auto fragment = AttributedString::Fragment{};
221-
fragment.string = getConcreteProps().placeholder;
222-
223-
if (fragment.string.empty()) {
224-
fragment.string = BaseTextShadowNode::getEmptyPlaceholder();
225-
}
218+
const auto& props = BaseShadowNode::getConcreteProps();
226219

220+
AttributedString attributedString;
221+
auto placeholderString = !props.placeholder.empty()
222+
? props.placeholder
223+
: BaseTextShadowNode::getEmptyPlaceholder();
227224
auto textAttributes = TextAttributes::defaultTextAttributes();
228-
textAttributes.apply(getConcreteProps().textAttributes);
229-
230-
// If there's no text, it's possible that this Fragment isn't actually
231-
// appended to the AttributedString (see implementation of appendFragment)
232-
fragment.textAttributes = textAttributes;
233-
fragment.parentShadowView = ShadowView(*this);
234-
textAttributedString.appendFragment(std::move(fragment));
235-
236-
return textAttributedString;
225+
textAttributes.apply(props.textAttributes);
226+
attributedString.appendFragment(
227+
{.string = std::move(placeholderString),
228+
.textAttributes = textAttributes,
229+
.parentShadowView = ShadowView(*this)});
230+
return attributedString;
237231
}
238232

239233
} // namespace facebook::react

0 commit comments

Comments
 (0)