Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import LocalizationProvider from '@material-ui/lab/LocalizationProvider';
import DateRangePickerDay from '@material-ui/lab/DateRangePickerDay';
import { adapterToUse, AdapterClassToUse } from '../internal/pickers/test-utils';

describe('<DateRangePickeryarDay />', () => {
describe('<DateRangePickerDay />', () => {
const mount = createMount();
let classes: Record<string, string>;

Expand All @@ -20,7 +20,6 @@ describe('<DateRangePickeryarDay />', () => {
day={adapterToUse.date()}
outsideCurrentMonth={false}
selected
focused
onDaySelect={() => {}}
isHighlighting
isPreviewing
Expand All @@ -37,7 +36,6 @@ describe('<DateRangePickeryarDay />', () => {
day={adapterToUse.date()}
outsideCurrentMonth={false}
selected
focused
onDaySelect={() => {}}
isHighlighting
isPreviewing
Expand Down
33 changes: 5 additions & 28 deletions packages/material-ui-lab/src/DayPicker/PickersCalendar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import * as React from 'react';
import clsx from 'clsx';
import Typography from '@material-ui/core/Typography';
import { StyleRules, WithStyles, withStyles, useTheme, Theme } from '@material-ui/core/styles';
import { StyleRules, WithStyles, withStyles, Theme } from '@material-ui/core/styles';
import PickersDay, { PickersDayProps } from '../PickersDay/PickersDay';
import { useUtils, useNow } from '../internal/pickers/hooks/useUtils';
import { PickerOnChangeFn } from '../internal/pickers/hooks/useViews';
import { DAY_SIZE, DAY_MARGIN } from '../internal/pickers/constants/dimensions';
import { PickerSelectionState } from '../internal/pickers/hooks/usePickerState';
import { useGlobalKeyDown, keycode } from '../internal/pickers/hooks/useKeyDown';
import SlideTransition, { SlideDirection, SlideTransitionProps } from './PickersSlideTransition';

export interface ExportedCalendarProps<TDate>
Expand Down Expand Up @@ -46,7 +45,7 @@ export interface ExportedCalendarProps<TDate>
}

export interface PickersCalendarProps<TDate> extends ExportedCalendarProps<TDate> {
date: TDate | null | Array<TDate | null>;
date: TDate | [TDate | null, TDate | null] | null;
isDateDisabled: (day: TDate) => boolean;
slideDirection: SlideDirection;
currentMonth: TDate;
Expand Down Expand Up @@ -132,8 +131,6 @@ function PickersCalendar<TDate>(props: PickersCalendarProps<TDate> & WithStyles<

const now = useNow<TDate>();
const utils = useUtils<TDate>();
const theme = useTheme();

const handleDaySelect = React.useCallback(
(day: TDate, isFinish: PickerSelectionState = 'finish') => {
// TODO possibly buggy line figure out and add tests
Expand All @@ -144,22 +141,6 @@ function PickersCalendar<TDate>(props: PickersCalendarProps<TDate> & WithStyles<
[date, now, onChange, utils],
);

const initialDate = Array.isArray(date) ? date[0] : date;

const nowFocusedDay = focusedDay || initialDate || now;
useGlobalKeyDown(Boolean(allowKeyboardControl), {
[keycode.ArrowUp]: () => changeFocusedDay(utils.addDays(nowFocusedDay, -7)),
[keycode.ArrowDown]: () => changeFocusedDay(utils.addDays(nowFocusedDay, 7)),
[keycode.ArrowLeft]: () =>
changeFocusedDay(utils.addDays(nowFocusedDay, theme.direction === 'ltr' ? -1 : 1)),
[keycode.ArrowRight]: () =>
changeFocusedDay(utils.addDays(nowFocusedDay, theme.direction === 'ltr' ? 1 : -1)),
[keycode.Home]: () => changeFocusedDay(utils.startOfWeek(nowFocusedDay)),
[keycode.End]: () => changeFocusedDay(utils.endOfWeek(nowFocusedDay)),
[keycode.PageUp]: () => changeFocusedDay(utils.getNextMonth(nowFocusedDay)),
[keycode.PageDown]: () => changeFocusedDay(utils.getPreviousMonth(nowFocusedDay)),
});

const currentMonthNumber = utils.getMonth(currentMonth);
const selectedDates = (Array.isArray(date) ? date : [date])
.filter(Boolean)
Expand Down Expand Up @@ -202,21 +183,17 @@ function PickersCalendar<TDate>(props: PickersCalendarProps<TDate> & WithStyles<
disabled: isDateDisabled(day),
allowKeyboardControl,
allowSameDateSelection,
focused:
autoFocus:
allowKeyboardControl &&
Boolean(focusedDay) &&
utils.isSameDay(day, nowFocusedDay),
focusedDay !== null &&
utils.isSameDay(day, focusedDay),
today: utils.isSameDay(day, now),
outsideCurrentMonth: utils.getMonth(day) !== currentMonthNumber,
selected: selectedDates.some(
(selectedDate) => selectedDate && utils.isSameDay(selectedDate, day),
),
disableHighlightToday,
showDaysOutsideCurrentMonth,
focusable:
allowKeyboardControl &&
Boolean(nowFocusedDay) &&
utils.toJsDate(nowFocusedDay).getDate() === utils.toJsDate(day).getDate(),
onDayFocus: changeFocusedDay,
onDaySelect: handleDaySelect,
};
Expand Down
6 changes: 5 additions & 1 deletion packages/material-ui-lab/src/DayPicker/useCalendarState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export const createCalendarStateReducer = <TDate extends unknown>(
};

case 'changeFocusedDay': {
if (state.focusedDay !== null && utils.isSameDay(action.focusedDay, state.focusedDay)) {
return state;
}

const needMonthSwitch =
Boolean(action.focusedDay) &&
!disableSwitchToMonthOnDayFocus &&
Expand Down Expand Up @@ -99,7 +103,7 @@ export function useCalendarState<TDate>({

const [calendarState, dispatch] = React.useReducer(reducerFn, {
isMonthSwitchingAnimating: false,
focusedDay: date,
focusedDay: date || now,
currentMonth: utils.startOfMonth(date ?? defaultCalendarMonth ?? now),
slideDirection: 'left',
});
Expand Down
45 changes: 32 additions & 13 deletions packages/material-ui-lab/src/PickersDay/PickersDay.test.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import * as React from 'react';
import { getClasses, createMount, describeConformance } from 'test/utils';
import LocalizationProvider from '@material-ui/lab/LocalizationProvider';
import { expect } from 'chai';
import { spy } from 'sinon';
import { getClasses, describeConformance, fireEvent, screen } from 'test/utils';
import PickersDay from '@material-ui/lab/PickersDay';
import { adapterToUse, AdapterClassToUse } from '../internal/pickers/test-utils';
import {
adapterToUse,
createPickerMount,
createPickerRender,
} from '../internal/pickers/test-utils';

describe('<PickersDay />', () => {
const mount = createMount();
const mount = createPickerMount();
const render = createPickerRender();
let classes: Record<string, string>;

const localizedMount = (node: React.ReactNode) => {
return mount(
<LocalizationProvider dateAdapter={AdapterClassToUse}>{node}</LocalizationProvider>,
);
};

before(() => {
classes = getClasses(
<PickersDay
day={adapterToUse.date()}
outsideCurrentMonth={false}
selected
focused
onDaySelect={() => {}}
/>,
);
Expand All @@ -31,16 +30,36 @@ describe('<PickersDay />', () => {
day={adapterToUse.date()}
outsideCurrentMonth={false}
selected
focused
onDaySelect={() => {}}
/>,
() => ({
classes,
inheritComponent: 'button',
mount: localizedMount,
mount,
refInstanceof: window.HTMLButtonElement,
// cannot test reactTestRenderer because of required context
skip: ['componentProp', 'reactTestRenderer'],
}),
);

it('selects the date on click, Enter and Space', () => {
const handleDaySelect = spy();
const day = adapterToUse.date();
render(<PickersDay day={day} outsideCurrentMonth={false} onDaySelect={handleDaySelect} />);
const targetDay = screen.getByRole('button', {
name: `${adapterToUse.format(day, 'fullDate')}`,
});

// A native button implies Enter and Space keydown behavior
// These keydown events only trigger click behavior if they're trusted (programmatically dispatched events aren't trusted).
// If this breaks, make sure to add tests for
// - fireEvent.keyDown(targetDay, { key: 'Enter' })
// - fireEvent.keyUp(targetDay, { key: 'Space' })
expect(targetDay.tagName).to.equal('BUTTON');

fireEvent.click(targetDay);

expect(handleDaySelect.callCount).to.equal(1);
expect(handleDaySelect.args[0][0]).toEqualDateTime(day);
});
});
Loading