diff --git a/change/react-native-windows-fix-textinput-placeholder.json b/change/react-native-windows-fix-textinput-placeholder.json new file mode 100644 index 00000000000..b759d12c2d5 --- /dev/null +++ b/change/react-native-windows-fix-textinput-placeholder.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Fix placeholder layout constraints fed physical px instead of DIPs; fix no-op NaN fontSize guard in CreatePlaceholderLayout", + "packageName": "react-native-windows", + "email": "collindanielschneide@gmail.com", + "dependentChangeType": "patch" +} diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp index 2fd8fcde9a1..d9e4393685d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp @@ -1690,7 +1690,7 @@ winrt::com_ptr<::IDWriteTextLayout> WindowsTextInputComponentView::CreatePlaceho const auto &props = windowsTextInputProps(); facebook::react::TextAttributes textAttributes = props.textAttributes; if (std::isnan(props.textAttributes.fontSize)) { - facebook::react::TextAttributes::defaultTextAttributes().fontSize; + textAttributes.fontSize = facebook::react::TextAttributes::defaultTextAttributes().fontSize; } textAttributes.fontSizeMultiplier = m_fontSizeMultiplier; fragment1.string = props.placeholder; @@ -1698,8 +1698,13 @@ winrt::com_ptr<::IDWriteTextLayout> WindowsTextInputComponentView::CreatePlaceho attributedString.appendFragment(std::move(fragment1)); facebook::react::LayoutConstraints constraints; - constraints.maximumSize.width = static_cast(m_imgWidth); - constraints.maximumSize.height = static_cast(m_imgHeight); + // m_imgWidth/m_imgHeight are physical pixels (frame * pointScaleFactor), but + // LayoutConstraints are expressed in DIPs. Feeding physical px laid the + // placeholder out in a box pointScaleFactor x too large, so the placeholder was + // measured/positioned at a different height than the typed text. Convert to DIPs. + const float scale = m_layoutMetrics.pointScaleFactor != 0.0f ? m_layoutMetrics.pointScaleFactor : 1.0f; + constraints.maximumSize.width = static_cast(m_imgWidth) / scale; + constraints.maximumSize.height = static_cast(m_imgHeight) / scale; facebook::react::WindowsTextLayoutManager::GetTextLayout( facebook::react::AttributedStringBox(attributedString), {} /*TODO*/, constraints, textLayout);