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"};