From 44032c6e80c52e849f35c6f6fcdd54bf49de50fe Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 6 Feb 2023 17:50:57 +0100 Subject: [PATCH 1/4] [fields] Support Backspace key on Android --- .../src/internals/hooks/useField/useField.ts | 10 ++++++++++ .../src/internals/hooks/useField/useFieldState.ts | 1 + 2 files changed, 11 insertions(+) diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts index c811d4a511da..b50e4e112547 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -372,6 +372,16 @@ export const useField = < return () => window.clearTimeout(focusTimeoutRef.current); }, []); // eslint-disable-line react-hooks/exhaustive-deps + // If `state.tempValueStrAndroid` is still defined when running `useEffect`, + // Then `onChange` has only been called once, which means the user pressed `Backspace` to reset the section. + // This causes a small flickering on Android, + // But we can't use `useEnhancedEffect` which is always called the two `onChange` calls and would cause false positives. + React.useEffect(() => { + if (state.tempValueStrAndroid != null && selectedSectionIndexes != null) { + clearActiveSection(); + } + }, [state.tempValueStrAndroid]); // eslint-disable-line react-hooks/exhaustive-deps + const valueStr = React.useMemo( () => state.tempValueStrAndroid ?? fieldValueManager.getValueStrFromSections(state.sections), [state.sections, fieldValueManager, state.tempValueStrAndroid], diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts index 2dcab9e618cf..f454b09e91ec 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts @@ -242,6 +242,7 @@ export const useFieldState = < return setState((prevState) => ({ ...prevState, sections: newSections, + tempValueStrAndroid: null, ...newValue, })); }; From 84f38eb62c7b2852af6a97eb7bb257d0f9e1af6b Mon Sep 17 00:00:00 2001 From: delangle Date: Wed, 8 Feb 2023 13:04:39 +0100 Subject: [PATCH 2/4] Fix --- packages/x-date-pickers/src/internals/hooks/useField/useField.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts index 19fcdbb4163b..521061b812f2 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -379,6 +379,7 @@ export const useField = < // But we can't use `useEnhancedEffect` which is always called the two `onChange` calls and would cause false positives. React.useEffect(() => { if (state.tempValueStrAndroid != null && selectedSectionIndexes != null) { + resetCharacterQuery(); clearActiveSection(); } }, [state.tempValueStrAndroid]); // eslint-disable-line react-hooks/exhaustive-deps From 6abde04aa9cc7f286786bbb374b35e79b4f8afd2 Mon Sep 17 00:00:00 2001 From: delangle Date: Wed, 8 Feb 2023 13:05:13 +0100 Subject: [PATCH 3/4] Code review: Alex --- .../x-date-pickers/src/internals/hooks/useField/useField.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts index 521061b812f2..1827d949ccbe 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -376,7 +376,7 @@ export const useField = < // If `state.tempValueStrAndroid` is still defined when running `useEffect`, // Then `onChange` has only been called once, which means the user pressed `Backspace` to reset the section. // This causes a small flickering on Android, - // But we can't use `useEnhancedEffect` which is always called the two `onChange` calls and would cause false positives. + // But we can't use `useEnhancedEffect` which is always called before the second `onChange` call and then would cause false positives. React.useEffect(() => { if (state.tempValueStrAndroid != null && selectedSectionIndexes != null) { resetCharacterQuery(); From 7ae71a5865bf53b0b956f286217eb7b84074b71c Mon Sep 17 00:00:00 2001 From: delangle Date: Wed, 8 Feb 2023 13:28:41 +0100 Subject: [PATCH 4/4] Fix tests --- .../tests/editing.DateField.test.tsx | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx b/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx index 560bd321dc50..67c3dbdec1c9 100644 --- a/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx +++ b/packages/x-date-pickers/src/DateField/tests/editing.DateField.test.tsx @@ -888,17 +888,21 @@ describe(' - Editing', () => { clickOnInput(input, sectionStart, sectionStart + 1); - // Remove the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('16', '') } }); + act(() => { + // Remove the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('16', '') } }); - // // Set the key pressed in the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('16', '2') } }); + // // Set the key pressed in the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('16', '2') } }); + }); - // Remove the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('16', '') } }); + act(() => { + // Remove the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('16', '') } }); - // Set the key pressed in the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('16', '1') } }); + // Set the key pressed in the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('16', '1') } }); + }); expectInputValue(input, '05 / 21 / 2022'); }); @@ -917,17 +921,21 @@ describe(' - Editing', () => { clickOnInput(input, sectionStart, sectionStart + 1); - // Remove the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('May', '') } }); + act(() => { + // Remove the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('May', '') } }); - // // Set the key pressed in the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('May', 'J') } }); + // // Set the key pressed in the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('May', 'J') } }); + }); - // Remove the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('May', '') } }); + act(() => { + // Remove the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('May', '') } }); - // Set the key pressed in the selected section - fireEvent.change(input, { target: { value: initialValueStr.replace('May', 'u') } }); + // Set the key pressed in the selected section + fireEvent.change(input, { target: { value: initialValueStr.replace('May', 'u') } }); + }); expectInputValue(input, 'June 2022'); });