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');
+ });
+ });
});
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);