From d2300b92d231b227d0eded27811e8fe9a66a1116 Mon Sep 17 00:00:00 2001 From: delangle Date: Mon, 9 Jan 2023 08:25:00 +0100 Subject: [PATCH 1/2] [fields] Fix Android editing --- .../src/internals/hooks/useField/useField.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) 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 315334e68e47..c811d4a511da 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -160,12 +160,13 @@ export const useField = < return; } - const valueStr = cleanString(event.target.value); + const valueStr = event.target.value; + const cleanValueStr = cleanString(valueStr); // If no section is selected, we just try to parse the new value // This line is mostly triggered by imperative code / application tests. if (selectedSectionIndexes == null) { - updateValueFromValueStr(valueStr); + updateValueFromValueStr(cleanValueStr); return; } @@ -174,13 +175,13 @@ export const useField = < let startOfDiffIndex = -1; let endOfDiffIndex = -1; for (let i = 0; i < prevValueStr.length; i += 1) { - if (startOfDiffIndex === -1 && prevValueStr[i] !== valueStr[i]) { + if (startOfDiffIndex === -1 && prevValueStr[i] !== cleanValueStr[i]) { startOfDiffIndex = i; } if ( endOfDiffIndex === -1 && - prevValueStr[prevValueStr.length - i - 1] !== valueStr[valueStr.length - i - 1] + prevValueStr[prevValueStr.length - i - 1] !== cleanValueStr[cleanValueStr.length - i - 1] ) { endOfDiffIndex = i; } @@ -199,11 +200,11 @@ export const useField = < // The active section being selected, the browser has replaced its value with the key pressed by the user. const activeSectionEndRelativeToNewValue = - valueStr.length - + cleanValueStr.length - prevValueStr.length + activeSection.end - cleanString(activeSection.endSeparator || '').length; - const keyPressed = valueStr.slice(activeSection.start, activeSectionEndRelativeToNewValue); + const keyPressed = cleanValueStr.slice(activeSection.start, activeSectionEndRelativeToNewValue); if (isAndroid() && keyPressed.length === 0) { setTempAndroidValueStr(valueStr); From 6397e990a3294cd089153622f63de9626c83a5cb Mon Sep 17 00:00:00 2001 From: delangle Date: Tue, 10 Jan 2023 08:31:22 +0100 Subject: [PATCH 2/2] Add test --- .../tests/editing.DateField.test.tsx | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) 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 f7346b3cdf26..ffff1948f02c 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 @@ -773,4 +773,78 @@ describe(' - Editing', () => { expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2022, 8, 16, 3, 3, 3)); }); }); + + describe('Android editing', () => { + let originalUserAgent: string = ''; + + beforeEach(() => { + originalUserAgent = global.navigator.userAgent; + Object.defineProperty(global.navigator, 'userAgent', { + configurable: true, + writable: true, + value: + 'Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Mobile Safari/537.36', + }); + }); + + afterEach(() => { + Object.defineProperty(global.navigator, 'userAgent', { + configurable: true, + value: originalUserAgent, + }); + }); + + it('should support digit editing', () => { + render(); + + const input = screen.getByRole('textbox'); + const initialValueStr = input.value; + const sectionStart = initialValueStr.indexOf('1'); + + clickOnInput(input, sectionStart, sectionStart + 1); + + // 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') } }); + + // 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') } }); + + expectInputValue(input, '05 / 21 / 2022'); + }); + + it('should support letter editing', () => { + render( + , + ); + + const input = screen.getByRole('textbox'); + const initialValueStr = input.value; + const sectionStart = initialValueStr.indexOf('M'); + + clickOnInput(input, sectionStart, sectionStart + 1); + + // 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') } }); + + // 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') } }); + + expectInputValue(input, 'June 2022'); + }); + }); });