diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx
index e41859e4304f..f4c4ba2bf64d 100644
--- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx
+++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx
@@ -258,6 +258,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar<
rangePosition,
allowRangeFlip,
shouldMergeDateAndTime: true,
+ referenceDate,
});
const isNextSectionAvailable = availableRangePositions.includes(nextSelection);
diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx
index 078ffbc61c0b..bce93e8e49bd 100644
--- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx
+++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx
@@ -39,6 +39,25 @@ describe('', () => {
expect(expectFieldValueV7(startSectionsContainer, '01/11/2018 04:05 PM'));
expect(expectFieldValueV7(endSectionsContainer, '01/11/2018 05:10 PM'));
});
+
+ it('should use time from `referenceDate` when selecting the day', () => {
+ render(
+ ,
+ );
+
+ openPicker({ type: 'date-time-range', variant: 'desktop', initialFocus: 'start' });
+
+ fireEvent.click(screen.getByRole('gridcell', { name: '11' }));
+
+ expect(screen.getByRole('option', { name: '2 hours', selected: true })).not.to.equal(null);
+ expect(screen.getByRole('option', { name: '15 minutes', selected: true })).not.to.equal(null);
+ expect(screen.getByRole('option', { name: 'PM', selected: true })).not.to.equal(null);
+ const startSectionsContainer = getFieldSectionsContainer(0);
+ expect(expectFieldValueV7(startSectionsContainer, '04/11/2022 02:15 PM'));
+ });
});
describe('disabled dates', () => {
diff --git a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts
index 1b49f7b99c60..61f6bae9b5b8 100644
--- a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts
+++ b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.test.ts
@@ -17,6 +17,15 @@ describe('date-range-manager', () => {
expectedRange: [start2018, null],
expectedNextSelection: 'end' as const,
},
+ {
+ range: [null, null],
+ rangePosition: 'start' as const,
+ newDate: start2018,
+ expectedRange: [start2018At4PM, null],
+ expectedNextSelection: 'end' as const,
+ shouldMergeDateAndTime: true,
+ referenceDate: start2018At4PM,
+ },
{
range: [start2018, null],
rangePosition: 'start' as const,
@@ -98,7 +107,16 @@ describe('date-range-manager', () => {
expectedNextSelection: 'start' as const,
},
].forEach(
- ({ range, rangePosition, newDate, expectedRange, allowRangeFlip, expectedNextSelection }) => {
+ ({
+ range,
+ rangePosition,
+ newDate,
+ expectedRange,
+ allowRangeFlip,
+ expectedNextSelection,
+ shouldMergeDateAndTime,
+ referenceDate,
+ }) => {
it(`calculateRangeChange should return ${expectedRange} when selecting ${rangePosition} of ${range} with user input ${newDate}`, () => {
expect(
calculateRangeChange({
@@ -107,6 +125,8 @@ describe('date-range-manager', () => {
newDate,
rangePosition,
allowRangeFlip,
+ shouldMergeDateAndTime,
+ referenceDate,
}),
).to.deep.equal({
nextSelection: expectedNextSelection,
diff --git a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts
index 94d5d02e0eb0..649273ad88f5 100644
--- a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts
+++ b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts
@@ -14,6 +14,7 @@ interface CalculateRangeChangeOptions {
*/
allowRangeFlip?: boolean;
shouldMergeDateAndTime?: boolean;
+ referenceDate?: TDate | null;
}
interface CalculateRangeChangeResponse {
@@ -28,6 +29,7 @@ export function calculateRangeChange({
rangePosition,
allowRangeFlip = false,
shouldMergeDateAndTime = false,
+ referenceDate,
}: CalculateRangeChangeOptions): CalculateRangeChangeResponse {
const [start, end] = range;
@@ -41,21 +43,26 @@ export function calculateRangeChange({
}
}
+ const newSelectedDate =
+ referenceDate && selectedDate && shouldMergeDateAndTime
+ ? mergeDateAndTime(utils, selectedDate, referenceDate)
+ : selectedDate;
+
if (rangePosition === 'start') {
const truthyResult: CalculateRangeChangeResponse = allowRangeFlip
- ? { nextSelection: 'start', newRange: [end!, selectedDate] }
- : { nextSelection: 'end', newRange: [selectedDate, null] };
- return Boolean(end) && utils.isAfter(selectedDate!, end!)
+ ? { nextSelection: 'start', newRange: [end!, newSelectedDate] }
+ : { nextSelection: 'end', newRange: [newSelectedDate, null] };
+ return Boolean(end) && utils.isAfter(newSelectedDate!, end!)
? truthyResult
- : { nextSelection: 'end', newRange: [selectedDate, end] };
+ : { nextSelection: 'end', newRange: [newSelectedDate, end] };
}
const truthyResult: CalculateRangeChangeResponse = allowRangeFlip
- ? { nextSelection: 'end', newRange: [selectedDate, start!] }
- : { nextSelection: 'end', newRange: [selectedDate, null] };
- return Boolean(start) && utils.isBeforeDay(selectedDate!, start!)
+ ? { nextSelection: 'end', newRange: [newSelectedDate, start!] }
+ : { nextSelection: 'end', newRange: [newSelectedDate, null] };
+ return Boolean(start) && utils.isBeforeDay(newSelectedDate!, start!)
? truthyResult
- : { nextSelection: 'start', newRange: [start, selectedDate] };
+ : { nextSelection: 'start', newRange: [start, newSelectedDate] };
}
export function calculateRangePreview(