From 801f79b249de01b46ef985f8dc658dd98fbf6366 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Fri, 10 Feb 2023 15:40:15 +0100 Subject: [PATCH] [fields] Support Backspace key on Android (#7842) --- .../tests/editing.DateField.test.tsx | 40 +++++++++++-------- .../src/internals/hooks/useField/useField.ts | 11 +++++ .../internals/hooks/useField/useFieldState.ts | 1 + 3 files changed, 36 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 1809bbdd6c71..d5619f51d4a7 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 @@ -921,17 +921,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'); }); @@ -950,17 +954,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'); }); 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 ab2bfdf830ad..1827d949ccbe 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -373,6 +373,17 @@ 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 before the second `onChange` call and then would cause false positives. + React.useEffect(() => { + if (state.tempValueStrAndroid != null && selectedSectionIndexes != null) { + resetCharacterQuery(); + 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, })); };