Skip to content
Closed
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": "Fix TextInput clearTextOnSubmit-style behavior regression in Fabric architecture",
"type": "prerelease",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ const examples: Array<RNTesterModuleExample> = [
},
// [Windows
{
title: 'Clear text on submit',
title: 'Clear text on submitting',
render: function (): React.Node {
return (
<View>
Expand Down Expand Up @@ -799,6 +799,38 @@ const examples: Array<RNTesterModuleExample> = [
);
},
},
{
title: 'Manual clear text on submit (setValue in onSubmitEditing)',
render: function () {
function ManualClearExample() {
const [value, setValue] = React.useState('');
const submitValue = () => {
// Simulate the regression scenario: manual setValue('') during onSubmitEditing
if (value !== '') {
setValue('');
}
};
return (
<View>
<Text>
Manual clear using setValue('') in onSubmitEditing callback:
</Text>
<ExampleTextInput
style={styles.singleLine}
value={value}
onChangeText={setValue}
onSubmitEditing={submitValue}
submitKeyEvents={[{code: 'Enter'}]}
testID="textinput-manual-clear-on-submit"
placeholder="Type text and press Enter to clear"
/>
<Text>Current value: "{value}"</Text>
</View>
);
}
return <ManualClearExample />;
},
},
{
title: 'Stop propagation sample',
render: function (): React.Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ exports[`TextInput Tests Text have cursorColor 1`] = `
"Visual Tree": {
"Comment": "textinput-cursorColor",
"Offset": "0, 0, 0",
"Size": "916, 32",
"Size": "916, 33",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -1153,7 +1153,7 @@ exports[`TextInput Tests TextInputs can be defined as a set using accessibilityP
"Visual Tree": {
"Comment": "textinput-set",
"Offset": "0, 0, 0",
"Size": "916, 94",
"Size": "916, 93",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -1222,12 +1222,12 @@ exports[`TextInput Tests TextInputs can be defined as a set using accessibilityP
},
{
"Offset": "0, 31, 0",
"Size": "916, 32",
"Size": "916, 33",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "916, 32",
"Size": "916, 33",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -1286,12 +1286,12 @@ exports[`TextInput Tests TextInputs can be defined as a set using accessibilityP
},
{
"Offset": "0, 62, 0",
"Size": "916, 33",
"Size": "916, 32",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "916, 33",
"Size": "916, 32",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -2757,7 +2757,7 @@ exports[`TextInput Tests TextInputs can have caretHidden 1`] = `
"Visual Tree": {
"Comment": "textinput-carethidden",
"Offset": "0, 0, 0",
"Size": "916, 32",
"Size": "916, 33",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -4333,7 +4333,7 @@ exports[`TextInput Tests TextInputs can have shadows 1`] = `
"Visual Tree": {
"Comment": "textinput-shadow",
"Offset": "0, 0, 0",
"Size": "916, 33",
"Size": "916, 32",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -6041,17 +6041,17 @@ exports[`TextInput Tests TextInputs which have a searchbox role should also supp
"Visual Tree": {
"Comment": "textinput-searchbox",
"Offset": "0, 0, 0",
"Size": "916, 31",
"Size": "916, 32",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "916, 33",
"Size": "916, 32",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "916, 33",
"Size": "916, 32",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81312,6 +81312,51 @@ exports[`snapshotAllPages TextInput 43`] = `
`;

exports[`snapshotAllPages TextInput 44`] = `
<View_withRef>
<Text>
Manual clear using setValue('') in onSubmitEditing callback:
</Text>
<TextInput
onChangeText={[Function]}
onSubmitEditing={[Function]}
placeholder="Type text and press Enter to clear"
style={
[
{
"backgroundColor": "#ffffffff",
"borderColor": "#3c3c432d",
"color": "#000000ff",
},
{
"borderWidth": 1,
"flexGrow": 1,
"flexShrink": 1,
"fontSize": 13,
"padding": 4,
},
{
"fontSize": 16,
},
]
}
submitKeyEvents={
[
{
"code": "Enter",
},
]
}
testID="textinput-manual-clear-on-submit"
value=""
/>
<Text>
Current value: "
"
</Text>
</View_withRef>
`;

exports[`snapshotAllPages TextInput 45`] = `
[
<View_withRef
focusable={true}
Expand Down Expand Up @@ -81377,7 +81422,7 @@ exports[`snapshotAllPages TextInput 44`] = `
]
`;

exports[`snapshotAllPages TextInput 45`] = `
exports[`snapshotAllPages TextInput 46`] = `
[
<Text>
Spell Check Enabled:
Expand Down Expand Up @@ -81426,7 +81471,7 @@ exports[`snapshotAllPages TextInput 45`] = `
]
`;

exports[`snapshotAllPages TextInput 46`] = `
exports[`snapshotAllPages TextInput 47`] = `
<View_withRef>
<Text>
CaretHidden
Expand Down Expand Up @@ -81458,7 +81503,7 @@ exports[`snapshotAllPages TextInput 46`] = `
</View_withRef>
`;

exports[`snapshotAllPages TextInput 47`] = `
exports[`snapshotAllPages TextInput 48`] = `
<View_withRef>
<Text>
Cursorcolor
Expand Down Expand Up @@ -81490,7 +81535,7 @@ exports[`snapshotAllPages TextInput 47`] = `
</View_withRef>
`;

exports[`snapshotAllPages TextInput 48`] = `
exports[`snapshotAllPages TextInput 49`] = `
<View_withRef>
<Text>
Shadow
Expand Down Expand Up @@ -81528,7 +81573,7 @@ exports[`snapshotAllPages TextInput 48`] = `
</View_withRef>
`;

exports[`snapshotAllPages TextInput 49`] = `
exports[`snapshotAllPages TextInput 50`] = `
<View_withRef
accessible={true}
testID="textinput-set"
Expand Down Expand Up @@ -81611,7 +81656,7 @@ exports[`snapshotAllPages TextInput 49`] = `
</View_withRef>
`;

exports[`snapshotAllPages TextInput 50`] = `
exports[`snapshotAllPages TextInput 51`] = `
<View_withRef
accessible={true}
testID="textinput-searchbox"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,19 @@ void WindowsTextInputComponentView::HandleCommand(
std::optional<winrt::hstring> text;

winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), eventCount, text, begin, end);
if (eventCount >= m_nativeEventCount) {

// Standard synchronization check - only accept current or future events
bool isCurrentEvent = eventCount >= m_nativeEventCount;

// Special case: Allow setValue('') if it's responding to the exact onSubmitEditing event
// This is safe because clearing text doesn't depend on intermediate state
bool isSubmitClearResponse = false;
if (!isCurrentEvent && text.has_value() && winrt::to_string(text.value()).empty()) {
// Only allow if this is responding to the exact submit event we fired
isSubmitClearResponse = (m_lastSubmitEventCount != -1 && eventCount == m_lastSubmitEventCount);
}

if (isCurrentEvent || isSubmitClearResponse) {
m_comingFromJS = true;
{
if (text.has_value()) {
Expand All @@ -564,6 +576,11 @@ void WindowsTextInputComponentView::HandleCommand(
m_textServices->TxSendMessage(EM_SETSEL, static_cast<WPARAM>(begin), static_cast<LPARAM>(end), &res));
}

// Clear the submit event count after using it to prevent reuse
if (isSubmitClearResponse) {
m_lastSubmitEventCount = -1;
}

m_comingFromJS = false;
}
}
Expand Down Expand Up @@ -959,6 +976,7 @@ void WindowsTextInputComponentView::OnCharacterReceived(
facebook::react::WindowsTextInputEventEmitter::OnSubmitEditing onSubmitEditingArgs;
onSubmitEditingArgs.text = GetTextFromRichEdit();
onSubmitEditingArgs.eventCount = ++m_nativeEventCount;
m_lastSubmitEventCount = m_nativeEventCount; // Track this submit event
emitter->onSubmitEditing(onSubmitEditingArgs);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct WindowsTextInputComponentView
float m_fontSizeMultiplier{1.0};
int64_t m_mostRecentEventCount{0};
int m_nativeEventCount{0};
int m_lastSubmitEventCount{-1}; // Track the event count of the last onSubmitEditing
bool m_comingFromJS{false};
bool m_comingFromState{false};
int m_cDrawBlock{0};
Expand Down
Loading