Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"comment": "Add keyboardType prop support to Fabric TextInput for parity with Paper",
"type": "prerelease",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,11 @@ void WindowsTextInputComponentView::updateProps(
updateAutoCorrect(newTextInputProps.autoCorrect);
}

if (oldTextInputProps.keyboardType != newTextInputProps.keyboardType ||
oldTextInputProps.secureTextEntry != newTextInputProps.secureTextEntry) {
updateKeyboardType(newTextInputProps.keyboardType);
}

if (oldTextInputProps.selectionColor != newTextInputProps.selectionColor) {
m_needsRedraw = true;
}
Expand Down Expand Up @@ -1439,6 +1444,10 @@ void WindowsTextInputComponentView::onMounted() noexcept {
m_propBitsMask |= TXTBIT_CHARFORMATCHANGE;
m_propBits |= TXTBIT_CHARFORMATCHANGE;
}

// Initialize keyboardType
updateKeyboardType(windowsTextInputProps().keyboardType);

InternalFinalize();

// Handle autoFocus property - focus the component when mounted if autoFocus is true
Expand Down Expand Up @@ -1554,25 +1563,59 @@ void WindowsTextInputComponentView::UpdateParaFormat() noexcept {
m_pf.dwMask = PFM_ALL;

auto &textAlign = windowsTextInputProps().textAlign;
auto &baseWritingDirection = windowsTextInputProps().textAttributes.baseWritingDirection;

// Handle writingDirection (baseWritingDirection)
// For WritingDirection::Natural, use the computed layout direction from the layout tree
// since direction can be overridden at any point in the tree
bool isRTL = false;
if (baseWritingDirection.has_value()) {
if (*baseWritingDirection == facebook::react::WritingDirection::RightToLeft) {
isRTL = true;
m_pf.dwMask |= PFM_RTLPARA;
m_pf.wEffects |= PFE_RTLPARA;
} else if (*baseWritingDirection == facebook::react::WritingDirection::LeftToRight) {
isRTL = false;
// Ensure RTL flag is not set
m_pf.wEffects &= ~PFE_RTLPARA;
} else if (*baseWritingDirection == facebook::react::WritingDirection::Natural) {
// Natural uses the layout direction computed from the tree
isRTL = (layoutMetrics().layoutDirection == facebook::react::LayoutDirection::RightToLeft);
if (isRTL) {
m_pf.dwMask |= PFM_RTLPARA;
m_pf.wEffects |= PFE_RTLPARA;
} else {
m_pf.wEffects &= ~PFE_RTLPARA;
}
}
} else {
// No explicit writing direction set - use layout direction from tree
isRTL = (layoutMetrics().layoutDirection == facebook::react::LayoutDirection::RightToLeft);
if (isRTL) {
m_pf.dwMask |= PFM_RTLPARA;
m_pf.wEffects |= PFE_RTLPARA;
} else {
m_pf.wEffects &= ~PFE_RTLPARA;
}
}

// Handle textAlign
if (textAlign == facebook::react::TextAlignment::Center) {
m_pf.wAlignment = PFA_CENTER;
} else if (textAlign == facebook::react::TextAlignment::Right) {
m_pf.wAlignment = PFA_RIGHT;
} else if (textAlign == facebook::react::TextAlignment::Justified) {
m_pf.wAlignment = PFA_JUSTIFY;
} else if (textAlign == facebook::react::TextAlignment::Natural) {
// Natural alignment respects writing direction
m_pf.wAlignment = isRTL ? PFA_RIGHT : PFA_LEFT;
} else {
// Default to left alignment
m_pf.wAlignment = PFA_LEFT;
}

m_pf.cTabCount = 1;
m_pf.rgxTabs[0] = lDefaultTab;

/*
if (m_spcontroller->IsCurrentReadingOrderRTL())
{
m_pf.dwMask |= PFM_RTLPARA;
m_pf.wEffects |= PFE_RTLPARA;
}
*/
}

void WindowsTextInputComponentView::OnRenderingDeviceLost() noexcept {
Expand Down Expand Up @@ -1877,4 +1920,10 @@ void WindowsTextInputComponentView::ShowContextMenu(const winrt::Windows::Founda
DestroyMenu(menu);
}

void WindowsTextInputComponentView::updateKeyboardType(const std::string &keyboardType) noexcept {
// Store the keyboard type for future use
// Note: Fabric's windowless RichEdit doesn't have direct InputScope support like Paper's XAML controls.
// The keyboard type is stored but the actual keyboard behavior is handled by the system's IME.
m_keyboardType = keyboardType;
}
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct WindowsTextInputComponentView
void updateAutoCorrect(bool value) noexcept;
void updateSpellCheck(bool value) noexcept;
void ShowContextMenu(const winrt::Windows::Foundation::Point &position) noexcept;
void updateKeyboardType(const std::string &keyboardType) noexcept;

winrt::Windows::UI::Composition::CompositionSurfaceBrush m_brush{nullptr};
winrt::Microsoft::ReactNative::Composition::Experimental::ICaretVisual m_caretVisual{nullptr};
Expand Down Expand Up @@ -148,6 +149,7 @@ struct WindowsTextInputComponentView
HCURSOR m_hcursor{nullptr};
std::chrono::steady_clock::time_point m_lastClickTime{};
std::vector<facebook::react::CompWindowsTextInputSubmitKeyEventsStruct> m_submitKeyEvents;
std::string m_keyboardType{};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not be storing copies of props on the component. The value already exists in the prop object, lets not duplicate memory.

};

} // namespace winrt::Microsoft::ReactNative::Composition::implementation
Loading