Skip to content

Commit

Permalink
[DateTimePicker] Better UI (mui#1771)
Browse files Browse the repository at this point in the history
* Support empty dates for the DatePicker

* Support empty dates for TimePicker

* Support empty dates for mobile toobars

* Support empty dates in YearSelection

* new DateTimePicker design

* Introduce `toolbarPlaceholder` prop for customization of empty date text

* Add tests

* Revert tabs color to the primary

* Remove flaky test

* Always display tabs for desktop wrapper
  • Loading branch information
dmtrKovalenko authored May 19, 2020
1 parent 0ce73c6 commit 482b290
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 73 deletions.
18 changes: 10 additions & 8 deletions lib/src/DateTimePicker/DateTimePickerTabs.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as React from 'react';
import clsx from 'clsx';
import Tab from '@material-ui/core/Tab';
import Tabs from '@material-ui/core/Tabs';
import Paper from '@material-ui/core/Paper';
import { TimeIcon } from '../_shared/icons/TimeIcon';
import { DateTimePickerView } from './DateTimePicker';
import { DateRangeIcon } from '../_shared/icons/DateRangeIcon';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import { WrapperVariantContext } from '../wrappers/WrapperVariantContext';

const viewToTabIndex = (openView: DateTimePickerView) => {
if (openView === 'date' || openView === 'year') {
Expand Down Expand Up @@ -38,6 +40,9 @@ export const useStyles = makeStyles(
: theme.palette.background.default;

return {
container: {
order: 1,
},
tabs: {
color: theme.palette.getContrastText(tabsBackground),
backgroundColor: tabsBackground,
Expand All @@ -50,20 +55,22 @@ export const useStyles = makeStyles(
export const DateTimePickerTabs: React.FC<DateTimePickerTabsProps> = ({
view,
onChange,
dateRangeIcon,
timeIcon,
timeIcon = <TimeIcon />,
dateRangeIcon = <DateRangeIcon />,
}) => {
const classes = useStyles();
const theme = useTheme();
const wrapperVariant = React.useContext(WrapperVariantContext);
const indicatorColor = theme.palette.type === 'light' ? 'secondary' : 'primary';

const handleChange = (e: React.ChangeEvent<{}>, value: DateTimePickerView) => {
if (value !== viewToTabIndex(view)) {
onChange(tabIndexToView(value));
}
};

return (
<Paper>
<Paper className={clsx({ [classes.container]: wrapperVariant === 'desktop' })}>
<Tabs
variant="fullWidth"
value={viewToTabIndex(view)}
Expand All @@ -78,9 +85,4 @@ export const DateTimePickerTabs: React.FC<DateTimePickerTabsProps> = ({
);
};

DateTimePickerTabs.defaultProps = {
dateRangeIcon: <DateRangeIcon />,
timeIcon: <TimeIcon />,
};

export default DateTimePickerTabs;
103 changes: 55 additions & 48 deletions lib/src/DateTimePicker/DateTimePickerToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DateTimePickerView } from './DateTimePicker';
import { makeStyles } from '@material-ui/core/styles';
import { MaterialUiPickersDate } from '../typings/date';
import { ToolbarComponentProps } from '../Picker/Picker';
import { WrapperVariantContext } from '../wrappers/WrapperVariantContext';

export const useStyles = makeStyles(
_ => ({
Expand Down Expand Up @@ -54,7 +55,11 @@ export const DateTimePickerToolbar: React.FC<ToolbarComponentProps> = ({
}) => {
const utils = useUtils();
const classes = useStyles();
const showTabs = !hideTabs && typeof window !== 'undefined' && window.innerHeight > 667;
const wrapperVariant = React.useContext(WrapperVariantContext);
const showTabs =
wrapperVariant === 'desktop'
? true
: !hideTabs && typeof window !== 'undefined' && window.innerHeight > 667;

const formatHours = (time: MaterialUiPickersDate) =>
ampm ? utils.format(time, 'hours12h') : utils.format(time, 'hours24h');
Expand All @@ -73,57 +78,59 @@ export const DateTimePickerToolbar: React.FC<ToolbarComponentProps> = ({

return (
<>
<PickerToolbar
toolbarTitle={toolbarTitle}
isLandscape={false}
penIconClassName={classes.penIcon}
className={classes.toolbar}
isMobileKeyboardViewOpen={isMobileKeyboardViewOpen}
toggleMobileKeyboardView={toggleMobileKeyboardView}
>
<div className={classes.dateContainer}>
<ToolbarButton
tabIndex={-1}
variant="subtitle1"
onClick={() => setOpenView('year')}
selected={openView === 'year'}
value={date ? utils.format(date, 'year') : '–'}
/>
{wrapperVariant !== 'desktop' && (
<PickerToolbar
toolbarTitle={toolbarTitle}
isLandscape={false}
penIconClassName={classes.penIcon}
className={classes.toolbar}
isMobileKeyboardViewOpen={isMobileKeyboardViewOpen}
toggleMobileKeyboardView={toggleMobileKeyboardView}
>
<div className={classes.dateContainer}>
<ToolbarButton
tabIndex={-1}
variant="subtitle1"
onClick={() => setOpenView('year')}
selected={openView === 'year'}
value={date ? utils.format(date, 'year') : '–'}
/>

<ToolbarButton
tabIndex={-1}
variant="h4"
data-mui-test="datetimepicker-toolbar-date"
onClick={() => setOpenView('date')}
selected={openView === 'date'}
value={dateText}
/>
</div>
<ToolbarButton
tabIndex={-1}
variant="h4"
data-mui-test="datetimepicker-toolbar-date"
onClick={() => setOpenView('date')}
selected={openView === 'date'}
value={dateText}
/>
</div>

<div className={classes.timeContainer}>
<ToolbarButton
tabIndex={-1}
variant="h3"
data-mui-test="hours"
onClick={() => setOpenView('hours')}
selected={openView === 'hours'}
value={date ? formatHours(date) : '--'}
typographyClassName={classes.timeTypography}
/>
<div className={classes.timeContainer}>
<ToolbarButton
tabIndex={-1}
variant="h3"
data-mui-test="hours"
onClick={() => setOpenView('hours')}
selected={openView === 'hours'}
value={date ? formatHours(date) : '--'}
typographyClassName={classes.timeTypography}
/>

<ToolbarText variant="h3" value=":" className={classes.separator} />
<ToolbarText variant="h3" value=":" className={classes.separator} />

<ToolbarButton
tabIndex={-1}
variant="h3"
data-mui-test="minutes"
onClick={() => setOpenView('minutes')}
selected={openView === 'minutes'}
value={date ? utils.format(date, 'minutes') : '--'}
typographyClassName={classes.timeTypography}
/>
</div>
</PickerToolbar>
<ToolbarButton
tabIndex={-1}
variant="h3"
data-mui-test="minutes"
onClick={() => setOpenView('minutes')}
selected={openView === 'minutes'}
value={date ? utils.format(date, 'minutes') : '--'}
typographyClassName={classes.timeTypography}
/>
</div>
</PickerToolbar>
)}

{showTabs && (
<DateTimePickerTabs
Expand Down
1 change: 0 additions & 1 deletion lib/src/__tests__/DatePicker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ test('Should not add to loading queue when synchronous', () => {
.find('button[data-mui-test="day"]')
.at(0)
.simulate('click');

expect(component.find('h4[data-mui-test="datepicker-toolbar-date"]').text()).not.toBe(
'Enter Date'
);
Expand Down
16 changes: 0 additions & 16 deletions lib/src/__tests__/unit/date-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,6 @@ describe('findClosestEnabledDate', () => {
expect(utilsToUse.isBefore(result, utilsToUse.addDays(today, 31))).toBe(true);
});

it('Should return past Saturday if disableFuture', () => {
const today = utilsToUse.startOfDay(utilsToUse.date());
const result = findClosestEnabledDate({
date: utilsToUse.date('2099-01-01'),
minDate: utilsToUse.date('1900-01-01'),
maxDate: utilsToUse.date('2100-01-01'),
utils: utilsToUse,
shouldDisableDate: only18th,
disableFuture: true,
disablePast: false,
});

expect(utilsToUse.isBeforeDay(result, today)).toBe(true);
expect(utilsToUse.isBefore(result, utilsToUse.addDays(today, -31))).toBe(false);
});

it('Should return now if disablePast+disableFuture and now is valid', () => {
const today = utilsToUse.startOfDay(utilsToUse.date());
const result = findClosestEnabledDate({
Expand Down
1 change: 1 addition & 0 deletions lib/src/views/Calendar/useCalendarState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const createCalendarStateReducer = (
};
}
case 'changeFocusedDay': {
// action.focusedDay = action.focusedDay || utils.date()
const needMonthSwitch =
Boolean(action.focusedDay) &&
!disableSwitchToMonthOnDayFocus &&
Expand Down

0 comments on commit 482b290

Please sign in to comment.