diff --git a/change/react-native-windows-9b1e075e-6ff9-424b-99f6-d9bc58c34f86.json b/change/react-native-windows-9b1e075e-6ff9-424b-99f6-d9bc58c34f86.json
new file mode 100644
index 00000000000..d69abdcad64
--- /dev/null
+++ b/change/react-native-windows-9b1e075e-6ff9-424b-99f6-d9bc58c34f86.json
@@ -0,0 +1,7 @@
+{
+ "type": "prerelease",
+ "comment": "Add onPressIn / onPressOut events to TextInput",
+ "packageName": "react-native-windows",
+ "email": "igklemen@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js
index b34bf03c6b4..156e48d4fe5 100644
--- a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js
+++ b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js
@@ -131,6 +131,31 @@ class AutogrowingTextInputExample extends React.Component<{...}> {
}
}
+class PressInOutEvents extends React.Component<
+ $FlowFixMeProps,
+ $FlowFixMeState,
+> {
+ constructor(props) {
+ super(props);
+ this.state = {text: 'PressIn/PressOut message'};
+ }
+ render() {
+ return (
+
+ {this.state.text}
+
+ this.setState({text: 'Holding down the click/touch'})
+ }
+ onPressOut={() => this.setState({text: 'Released click/touch'})}
+ />
+
+ );
+ }
+}
+
const styles = StyleSheet.create({
multiline: {
height: 60,
@@ -424,4 +449,10 @@ exports.examples = ([
return ;
},
},
+ {
+ title: 'onPressIn, onPressOut events',
+ render: function(): React.Node {
+ return ;
+ },
+ },
]: Array);
diff --git a/vnext/Microsoft.ReactNative/Views/TextInputViewManager.cpp b/vnext/Microsoft.ReactNative/Views/TextInputViewManager.cpp
index badf5616544..392325a9351 100644
--- a/vnext/Microsoft.ReactNative/Views/TextInputViewManager.cpp
+++ b/vnext/Microsoft.ReactNative/Views/TextInputViewManager.cpp
@@ -355,6 +355,22 @@ void TextInputShadowNode::registerEvents() {
}
});
}
+
+ control.as().AddHandler(
+ xaml::UIElement::PointerPressedEvent(),
+ winrt::box_value(xaml::Input::PointerEventHandler([=](auto &&, xaml::Input::PointerRoutedEventArgs const &args) {
+ folly::dynamic eventData = folly::dynamic::object("target", tag);
+ GetViewManager()->GetReactContext().DispatchEvent(tag, "topTextInputPressIn", std::move(eventData));
+ })),
+ true);
+
+ control.as().AddHandler(
+ xaml::UIElement::PointerReleasedEvent(),
+ winrt::box_value(xaml::Input::PointerEventHandler([=](auto &&, xaml::Input::PointerRoutedEventArgs const &args) {
+ folly::dynamic eventData = folly::dynamic::object("target", tag);
+ GetViewManager()->GetReactContext().DispatchEvent(tag, "topTextInputPressOut", std::move(eventData));
+ })),
+ true);
}
xaml::Shapes::Shape TextInputShadowNode::FindCaret(xaml::DependencyObject element) {
@@ -688,6 +704,8 @@ void TextInputViewManager::GetExportedCustomDirectEventTypeConstants(
L"SelectionChange",
L"ContentSizeChange",
L"KeyPress",
+ L"PressIn",
+ L"PressOut",
L"OnScroll",
L"SubmitEditing"};