diff --git a/packages/x-date-pickers/src/DateField/tests/onChangeInvalidDate.DateField.test.tsx b/packages/x-date-pickers/src/DateField/tests/onChangeInvalidDate.DateField.test.tsx new file mode 100644 index 0000000000000..a5e82b202e3df --- /dev/null +++ b/packages/x-date-pickers/src/DateField/tests/onChangeInvalidDate.DateField.test.tsx @@ -0,0 +1,68 @@ +import { spy } from 'sinon'; +import { DateField } from '@mui/x-date-pickers/DateField'; +import { describeAdapters } from 'test/utils/pickers'; + +describeAdapters( + 'DateField - onChange receives correct value for invalid input', + DateField, + ({ adapter, renderWithProps }) => { + it('should call onChange with Invalid Date (not null) when typing invalid month in valid field', async () => { + const handleChange = spy(); + + // start with VALID date + const view = renderWithProps({ + enableAccessibleFieldDOMStructure: true, + defaultValue: adapter.date('2022-04-17'), + onChange: handleChange, + }); + + await view.selectSectionAsync('month'); + view.pressKey(0, '0'); + + expect(handleChange.callCount).to.be.greaterThan(0); + + const lastCall = handleChange.lastCall; + const receivedValue = lastCall.args[0]; + + expect(receivedValue).not.to.equal(null); + expect(adapter.isValid(receivedValue)).to.equal(false); + + view.unmount(); + }); + + it('should call onChange with Invalid Date consistently when changing year after typing invalid month', async () => { + const handleChange = spy(); + + // start with VALID date + const view = renderWithProps({ + enableAccessibleFieldDOMStructure: true, + defaultValue: adapter.date('2022-04-17'), + onChange: handleChange, + }); + + await view.selectSectionAsync('month'); + view.pressKey(0, '0'); + + handleChange.resetHistory(); + + await view.selectSectionAsync('year'); + await view.user.keyboard('[ArrowUp]'); + + expect(handleChange.callCount).to.be.greaterThan(0); + let receivedValue = handleChange.lastCall.args[0]; + expect(receivedValue).not.to.equal(null); + expect(receivedValue).not.to.equal(undefined); + expect(adapter.isValid(receivedValue)).to.equal(false); + + // Press ArrowUp again should still give Invalid Date + await view.user.keyboard('[ArrowUp]'); + + receivedValue = handleChange.lastCall.args[0]; + expect(receivedValue).not.to.equal(null); + expect(receivedValue).not.to.equal(undefined); + expect(adapter.isValid(receivedValue)).to.equal(false); + + view.unmount(); + }); + }, +); 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 c50e2a745f380..fde70084e4bbd 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts @@ -372,13 +372,10 @@ export const useFieldState = < } /** - * If all the sections are filled but the date is invalid and the previous date is valid or null, + * If the date is invalid and all the sections are filled, * Then we publish an invalid date. */ - if ( - newActiveDateSections.every((sectionBis) => sectionBis.value !== '') && - (activeDate == null || adapter.isValid(activeDate)) - ) { + if (newActiveDateSections.every((sectionBis) => sectionBis.value !== '')) { setSectionUpdateToApplyOnNextInvalidDate(newSectionValue); return publishValue(fieldValueManager.updateDateInValue(value, section, newActiveDate)); }