Skip to content

Commit

Permalink
[pickers] Keep the existing time when looking for closest enabled date (
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasTy authored Mar 11, 2024
1 parent b8566a0 commit 719fa0a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { createPickerRenderer, adapterToUse } from 'test/utils/pickers';
const isJSDOM = /jsdom/.test(window.navigator.userAgent);

describe('<DateCalendar />', () => {
const { render, clock } = createPickerRenderer({ clock: 'fake' });
const { render, clock } = createPickerRenderer({
clock: 'fake',
clockConfig: new Date('2019-01-02'),
});

it('switches between views uncontrolled', () => {
const handleViewChange = spy();
Expand Down Expand Up @@ -127,6 +130,26 @@ describe('<DateCalendar />', () => {
expect(screen.getAllByRole('rowheader').length).to.equal(5);
});

// test: https://github.com/mui/mui-x/issues/12373
it('should not reset day to `startOfDay` if value already exists when finding the closest enabled date', () => {
const onChange = spy();
const defaultDate = adapterToUse.date('2019-01-02T11:12:13');
render(<DateCalendar onChange={onChange} disablePast defaultValue={defaultDate} />);

userEvent.mousePress(
screen.getByRole('button', { name: 'calendar view is open, switch to year view' }),
);
userEvent.mousePress(screen.getByRole('radio', { name: '2020' }));
userEvent.mousePress(screen.getByRole('gridcell', { name: '1' }));
userEvent.mousePress(
screen.getByRole('button', { name: 'calendar view is open, switch to year view' }),
);
// select the current year with a date in the past to trigger "findClosestEnabledDate"
userEvent.mousePress(screen.getByRole('radio', { name: '2019' }));

expect(onChange.lastCall.firstArg).toEqualDateTime(defaultDate);
});

describe('Slot: calendarHeader', () => {
it('should allow to override the format', () => {
render(
Expand Down
20 changes: 20 additions & 0 deletions packages/x-date-pickers/src/internals/utils/date-utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect } from 'chai';
import { adapterToUse } from 'test/utils/pickers';
import { useFakeTimers } from 'sinon';
import { findClosestEnabledDate } from './date-utils';

describe('findClosestEnabledDate', () => {
Expand Down Expand Up @@ -99,6 +100,25 @@ describe('findClosestEnabledDate', () => {
expect(adapterToUse.isSameDay(result, today)).to.equal(true);
});

it('should return now with given time part if disablePast and now is valid', () => {
const clock = useFakeTimers({ now: new Date('2000-01-02') });

const tryDate = adapterToUse.date('2000-01-01T11:12:13');
const result = findClosestEnabledDate({
date: tryDate,
minDate: adapterToUse.date('1900-01-01'),
maxDate: adapterToUse.date('2100-01-01'),
utils: adapterToUse,
isDateDisabled: () => false,
disableFuture: false,
disablePast: true,
timezone: 'default',
})!;

expect(result).toEqualDateTime(adapterToUse.addDays(tryDate, 1));
clock.reset();
});

it('should fallback to today if disablePast+disableFuture and now is invalid', () => {
const today = adapterToUse.date();
const result = findClosestEnabledDate({
Expand Down
29 changes: 14 additions & 15 deletions packages/x-date-pickers/src/internals/utils/date-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ import {
import { DateOrTimeViewWithMeridiem } from '../models';
import { areViewsEqual } from './views';

export const mergeDateAndTime = <TDate extends PickerValidDate>(
utils: MuiPickersAdapter<TDate>,
dateParam: TDate,
timeParam: TDate,
) => {
let mergedDate = dateParam;
mergedDate = utils.setHours(mergedDate, utils.getHours(timeParam));
mergedDate = utils.setMinutes(mergedDate, utils.getMinutes(timeParam));
mergedDate = utils.setSeconds(mergedDate, utils.getSeconds(timeParam));

return mergedDate;
};

interface FindClosestDateParams<TDate extends PickerValidDate> {
date: TDate;
disableFuture?: boolean;
Expand All @@ -29,8 +42,7 @@ export const findClosestEnabledDate = <TDate extends PickerValidDate>({
utils,
timezone,
}: FindClosestDateParams<TDate>) => {
const today = utils.startOfDay(utils.date(undefined, timezone));

const today = mergeDateAndTime(utils, utils.date(undefined, timezone), date);
if (disablePast && utils.isBefore(minDate!, today)) {
minDate = today;
}
Expand Down Expand Up @@ -124,19 +136,6 @@ export const getMonthsInYear = <TDate extends PickerValidDate>(
return months;
};

export const mergeDateAndTime = <TDate extends PickerValidDate>(
utils: MuiPickersAdapter<TDate>,
dateParam: TDate,
timeParam: TDate,
) => {
let mergedDate = dateParam;
mergedDate = utils.setHours(mergedDate, utils.getHours(timeParam));
mergedDate = utils.setMinutes(mergedDate, utils.getMinutes(timeParam));
mergedDate = utils.setSeconds(mergedDate, utils.getSeconds(timeParam));

return mergedDate;
};

export const getTodayDate = <TDate extends PickerValidDate>(
utils: MuiPickersAdapter<TDate>,
timezone: PickersTimezone,
Expand Down

0 comments on commit 719fa0a

Please sign in to comment.