From b94d6ccc0f1febe21d1e9da0de9f5c6dc10497d5 Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 19 Nov 2024 14:15:46 +0100 Subject: [PATCH 1/2] [pickers] Always use props.value when it changes --- .../internals/hooks/usePicker/usePickerValue.ts | 14 +++----------- .../hooks/usePicker/usePickerValue.types.ts | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts index f24d9e11a718a..d5552101b82b8 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts @@ -235,7 +235,7 @@ export const usePickerValue = < draft: initialValue, lastPublishedValue: initialValue, lastCommittedValue: initialValue, - lastControlledValue: inValueWithTimezoneToRender, + lastControlledValue: inValueWithoutRenderTimezone, hasBeenModifiedSinceMount: false, }; }); @@ -302,15 +302,7 @@ export const usePickerValue = < } }); - if ( - inValueWithTimezoneToRender !== undefined && - (dateState.lastControlledValue === undefined || - !valueManager.areValuesEqual( - utils, - dateState.lastControlledValue, - inValueWithTimezoneToRender, - )) - ) { + if (dateState.lastControlledValue !== inValueWithoutRenderTimezone) { const isUpdateComingFromPicker = valueManager.areValuesEqual( utils, dateState.draft, @@ -319,7 +311,7 @@ export const usePickerValue = < setDateState((prev) => ({ ...prev, - lastControlledValue: inValueWithTimezoneToRender, + lastControlledValue: inValueWithoutRenderTimezone, ...(isUpdateComingFromPicker ? {} : { diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts index 7e00de886ccfe..1feb2cad434db 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts @@ -142,7 +142,7 @@ export interface UsePickerValueState { */ lastCommittedValue: TValue; /** - * Last value passed with `props.value`. + * Last value passed to `props.value`. * Used to update the `draft` value whenever the `value` prop changes. */ lastControlledValue: TValue | undefined; From 8fac8d93e9f57065e5d9e097187e7bc8cd415a86 Mon Sep 17 00:00:00 2001 From: flavien Date: Wed, 20 Nov 2024 08:59:21 +0100 Subject: [PATCH 2/2] Add test --- .../tests/field.DesktopDatePicker.test.tsx | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx b/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx index b3a986e7e1edc..04ddd9c3b82b2 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/tests/field.DesktopDatePicker.test.tsx @@ -1,5 +1,6 @@ import { fireEvent } from '@mui/internal-test-utils'; import { DesktopDatePicker, DesktopDatePickerProps } from '@mui/x-date-pickers/DesktopDatePicker'; +import { fireUserEvent } from 'test/utils/fireUserEvent'; import { createPickerRenderer, buildFieldInteractions, @@ -98,6 +99,47 @@ describe(' - Field', () => { testFormat({ views: ['year', 'month', 'day'] }, 'MM/DD/YYYY'); testFormat({ views: ['year', 'day'] }, 'MM/DD/YYYY'); }); + + it('should allow to set the value to its previous valid value using props.value', () => { + // Test with accessible DOM structure + let view = renderWithProps( + { + enableAccessibleFieldDOMStructure: true as const, + value: adapterToUse.date('2022-10-31'), + }, + { componentFamily: 'picker' }, + ); + + view.selectSection('month'); + expectFieldValueV7(view.getSectionsContainer(), '10/31/2022'); + + view.pressKey(0, 'ArrowUp'); + expectFieldValueV7(view.getSectionsContainer(), '11/31/2022'); + + view.setProps({ value: adapterToUse.date('2022-10-31') }); + expectFieldValueV7(view.getSectionsContainer(), '10/31/2022'); + + view.unmount(); + + // Test with non-accessible DOM structure + view = renderWithProps( + { + enableAccessibleFieldDOMStructure: false as const, + value: adapterToUse.date('2022-10-31'), + }, + { componentFamily: 'picker' }, + ); + + const input = getTextbox(); + view.selectSection('month'); + expectFieldValueV6(input, '10/31/2022'); + + fireUserEvent.keyPress(input, { key: 'ArrowUp' }); + expectFieldValueV6(input, '11/31/2022'); + + view.setProps({ value: adapterToUse.date('2022-10-31') }); + expectFieldValueV6(input, '10/31/2022'); + }); }); describe('slots: field', () => {