TextInput: support editing completely empty TextInputs

Summary:
Before this change, C++ couldn't propagate changes that updated TextInputs that were completely empty. In C++ the AttributedString cannot contain Fragments with empty text, so a completely empty TextInput would have no Fragments; this breaks the C++ state value updating infra since it relies on copying over existing fragments.

Instead, now we propagate default TextAttributes and ShadowView through State, so that State updates can use them to construct new Fragments.

Changelog: [Internal]

Reviewed By: shergin, mdvacca

Differential Revision: D18835048

fbshipit-source-id: 58ac94c5454c8610c6287b096b62199045e5879b
This commit is contained in:
Joshua Gross
2019-12-05 13:20:30 -08:00
committed by Facebook Github Bot
parent 0556e86d09
commit b9491b7c51
2 changed files with 49 additions and 2 deletions
@@ -81,9 +81,12 @@ AttributedString AndroidTextInputShadowNode::getPlaceholderAttributedString(
auto textAttributes = TextAttributes::defaultTextAttributes();
textAttributes.apply(getProps()->textAttributes);
// If there's no text, it's possible that this Fragment isn't actually
// appended to the AttributedString (see implementation of appendFragment)
fragment.textAttributes = textAttributes;
fragment.parentShadowView = ShadowView(*this);
textAttributedString.appendFragment(fragment);
return textAttributedString;
}
@@ -112,10 +115,20 @@ void AndroidTextInputShadowNode::updateStateIfNeeded() {
return;
}
// Store default TextAttributes in state.
// In the case where the TextInput is completely empty (no value, no
// defaultValue, no placeholder, no children) there are therefore no fragments
// in the AttributedString, and when State is updated, it needs some way to
// reconstruct a Fragment with default TextAttributes.
auto defaultTextAttributes = TextAttributes::defaultTextAttributes();
defaultTextAttributes.apply(getProps()->textAttributes);
setStateData(AndroidTextInputState{state.mostRecentEventCount,
reactTreeAttributedString,
reactTreeAttributedString,
getProps()->paragraphAttributes,
defaultTextAttributes,
ShadowView(*this),
textLayoutManager_});
}