in vnext/Microsoft.ReactNative/Views/TextViewManager.cpp [211:318]
bool TextViewManager::UpdateProperty(
ShadowNodeBase *nodeToUpdate,
const std::string &propertyName,
const winrt::Microsoft::ReactNative::JSValue &propertyValue) {
auto textBlock = nodeToUpdate->GetView().as<xaml::Controls::TextBlock>();
if (textBlock == nullptr)
return true;
if (TryUpdateForeground(textBlock, propertyName, propertyValue)) {
const auto node = static_cast<TextShadowNode *>(nodeToUpdate);
if (IsValidOptionalColorValue(propertyValue)) {
node->m_foregroundColor = OptionalColorFrom(propertyValue);
node->RecalculateTextHighlighters();
}
} else if (TryUpdateFontProperties(textBlock, propertyName, propertyValue)) {
} else if (propertyName == "textTransform") {
auto textNode = static_cast<TextShadowNode *>(nodeToUpdate);
textNode->textTransform = TransformableText::GetTextTransform(propertyValue);
UpdateTextTransformForChildren(nodeToUpdate);
} else if (TryUpdatePadding(nodeToUpdate, textBlock, propertyName, propertyValue)) {
} else if (TryUpdateTextAlignment(textBlock, propertyName, propertyValue)) {
} else if (TryUpdateTextTrimming(textBlock, propertyName, propertyValue)) {
} else if (TryUpdateTextDecorationLine(textBlock, propertyName, propertyValue)) {
// Temporary workaround for bug in XAML which fails to flush old TextDecorationLine render
// Link to Bug: https://github.com/microsoft/microsoft-ui-xaml/issues/1093#issuecomment-514282402
winrt::hstring text(textBlock.Text().c_str());
textBlock.Text(L"");
textBlock.Text(text);
} else if (TryUpdateCharacterSpacing(textBlock, propertyName, propertyValue)) {
} else if (propertyName == "numberOfLines") {
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Double ||
propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Int64) {
auto numberLines = propertyValue.AsInt32();
if (numberLines == 1) {
textBlock.TextWrapping(xaml::TextWrapping::NoWrap); // setting no wrap for single line
// text for better trimming
// experience
} else {
textBlock.TextWrapping(xaml::TextWrapping::Wrap);
}
textBlock.MaxLines(numberLines);
} else if (propertyValue.IsNull()) {
textBlock.TextWrapping(xaml::TextWrapping::Wrap); // set wrapping back to default
textBlock.ClearValue(xaml::Controls::TextBlock::MaxLinesProperty());
}
} else if (propertyName == "lineHeight") {
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Double ||
propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Int64) {
textBlock.LineHeight(propertyValue.AsInt32());
textBlock.LineStackingStrategy(xaml::LineStackingStrategy::BlockLineHeight);
} else if (propertyValue.IsNull()) {
textBlock.ClearValue(xaml::Controls::TextBlock::LineHeightProperty());
textBlock.ClearValue(xaml::Controls::TextBlock::LineStackingStrategyProperty());
}
} else if (propertyName == "selectable") {
const auto node = static_cast<TextShadowNode *>(nodeToUpdate);
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
const auto selectable = propertyValue.AsBoolean();
textBlock.IsTextSelectionEnabled(selectable);
node->ToggleTouchEvents(textBlock, selectable);
if (selectable) {
EnsureUniqueTextFlyoutForXamlIsland(textBlock);
}
} else if (propertyValue.IsNull()) {
textBlock.ClearValue(xaml::Controls::TextBlock::IsTextSelectionEnabledProperty());
node->ToggleTouchEvents(textBlock, false);
ClearUniqueTextFlyoutForXamlIsland(textBlock);
}
} else if (propertyName == "allowFontScaling") {
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
textBlock.IsTextScaleFactorEnabled(propertyValue.AsBoolean());
} else {
textBlock.ClearValue(xaml::Controls::TextBlock::IsTextScaleFactorEnabledProperty());
}
} else if (propertyName == "selectionColor") {
if (IsValidColorValue(propertyValue)) {
textBlock.SelectionHighlightColor(SolidColorBrushFrom(propertyValue));
} else
textBlock.ClearValue(xaml::Controls::TextBlock::SelectionHighlightColorProperty());
} else if (propertyName == "backgroundColor") {
const auto node = static_cast<TextShadowNode *>(nodeToUpdate);
if (IsValidOptionalColorValue(propertyValue)) {
node->m_backgroundColor = OptionalColorFrom(propertyValue);
node->RecalculateTextHighlighters();
}
} else if (propertyName == "accessibilityRole") {
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::String) {
const std::string &role = propertyValue.AsString();
auto value = asHstring(propertyValue);
auto boxedValue = winrt::Windows::Foundation::PropertyValue::CreateString(value);
textBlock.SetValue(winrt::AutomationProperties::LocalizedControlTypeProperty(), boxedValue);
if (role == "header") {
xaml::Automation::AutomationProperties::SetHeadingLevel(
textBlock, winrt::Peers::AutomationHeadingLevel::Level2);
} else {
textBlock.ClearValue(winrt::AutomationProperties::HeadingLevelProperty());
}
} else if (propertyValue.IsNull()) {
textBlock.ClearValue(winrt::AutomationProperties::LocalizedControlTypeProperty());
textBlock.ClearValue(winrt::AutomationProperties::HeadingLevelProperty());
}
} else {
return Super::UpdateProperty(nodeToUpdate, propertyName, propertyValue);
}
return true;
}