Skip to content

Commit

Permalink
Infrastructure preparation for DateRangePicker (mui#1573)
Browse files Browse the repository at this point in the history
* Make value for picker be a generic type

* Spread new props from passing to the dom element

* Split makePickerWith state hoc

* Better type inference for new makePickerWithWrapper

* Refactor and opimize shared prop types inference for pickers

* Rename eome type names and files

* Integrate validation back to usePickerState

* Remove DateRangePicker code

* Remove DateRangePickerUsage from index module

* Fix small linter and ts errors

* Fix build erros

* Run prettier manually
  • Loading branch information
dmtrKovalenko committed Mar 12, 2020
1 parent ba80c7e commit 35e6b2d
Show file tree
Hide file tree
Showing 28 changed files with 324 additions and 229 deletions.
1 change: 1 addition & 0 deletions docs/layout/components/navigationMap.ts
Expand Up @@ -21,6 +21,7 @@ export const navItems = [
title: 'Components Demo',
children: [
{ title: 'Date Picker', href: '/demo/datepicker' },
{ title: 'Date Range Picker', href: '/demo/daterangepicker' },
{ title: 'Time Picker', href: '/demo/timepicker' },
{ title: 'Date & Time Picker', href: '/demo/datetime-picker' },
],
Expand Down
10 changes: 10 additions & 0 deletions docs/pages/demo/daterangepicker/BasicDateRangePicker.example.jsx
@@ -0,0 +1,10 @@
import React, { useState } from 'react';
import { DatePicker as DateRangePicker } from '@material-ui/pickers';

function BasicDateRangePicker() {
const [selectedDate, handleDateChange] = useState([new Date(), null]);

return <DateRangePicker value={selectedDate} onChange={date => handleDateChange(date)} />;
}

export default BasicDateRangePicker;
20 changes: 20 additions & 0 deletions docs/pages/demo/daterangepicker/index.mdx
@@ -0,0 +1,20 @@
import Ad from '_shared/Ad';
import Example from '_shared/Example';
import PageMeta from '_shared/PageMeta';
import LinkedComponents from '_shared/LinkedComponents';

import * as BasicDateRangePicker from './BasicDateRangePicker.example';

<PageMeta component="Datepicker" />

## Date picker

[Date pickers](https://material.io/components/pickers/) let users select a date, or a range of dates. They should be suitable for the context in which they appear.

<Ad />

#### Basic usage

Will be rendered to modal dialog on mobile and textfield with popover on desktop.

<Example testId="datepicker-example" source={BasicDateRangePicker} />
2 changes: 1 addition & 1 deletion docs/tsconfig.json
Expand Up @@ -19,5 +19,5 @@
"target": "esnext",
"resolveJsonModule": true
},
"include": ["../docs/**/*.ts*", "../lib/typings.d.ts"]
"include": ["../docs/**/*.ts*", "./typings.d.ts", "../lib/typings.d.ts"]
}
22 changes: 11 additions & 11 deletions lib/.size-snapshot.json
@@ -1,26 +1,26 @@
{
"build/dist/material-ui-pickers.esm.js": {
"bundled": 143471,
"minified": 78671,
"gzipped": 21103,
"bundled": 145384,
"minified": 79576,
"gzipped": 21474,
"treeshaked": {
"rollup": {
"code": 64934,
"code": 65692,
"import_statements": 2099
},
"webpack": {
"code": 72410
"code": 73171
}
}
},
"build/dist/material-ui-pickers.umd.js": {
"bundled": 597704,
"minified": 222450,
"gzipped": 45688
"bundled": 599635,
"minified": 223221,
"gzipped": 45558
},
"build/dist/material-ui-pickers.umd.min.js": {
"bundled": 537438,
"minified": 203944,
"gzipped": 40910
"bundled": 539383,
"minified": 204705,
"gzipped": 40705
}
}
21 changes: 5 additions & 16 deletions lib/src/DatePicker/DatePicker.tsx
@@ -1,29 +1,18 @@
import { useUtils } from '../_shared/hooks/useUtils';
import { MaterialUiPickersDate } from '../typings/date';
import { DatePickerToolbar } from './DatePickerToolbar';
import { getFormatByViews } from '../_helpers/date-utils';
import { WithViewsProps } from '../Picker/SharedPickerProps';
import { datePickerDefaultProps } from '../constants/prop-types';
import { ResponsiveWrapper } from '../wrappers/ResponsiveWrapper';
import { ExportedCalendarViewProps } from '../views/Calendar/CalendarView';
import { makePickerWithStateAndWrapper } from '../Picker/makePickerWithState';
import { ModalWrapper, InlineWrapper, StaticWrapper } from '../wrappers/Wrapper';
import {
WithDateInputProps,
makePickerWithStateAndWrapper,
WithViewsProps,
} from '../Picker/makePickerWithState';

export type DatePickerView = 'year' | 'date' | 'month';

export interface BaseDatePickerProps extends ExportedCalendarViewProps {
/** Callback firing on year change @DateIOType */
onYearChange?: (date: MaterialUiPickersDate) => void;
/** Date format, that is displaying in toolbar */
toolbarFormat?: string;
}

export type DatePickerProps = BaseDatePickerProps &
WithDateInputProps &
WithViewsProps<'year' | 'date' | 'month'>;
export interface DatePickerProps
extends WithViewsProps<'year' | 'date' | 'month'>,
ExportedCalendarViewProps {}

const datePickerConfig = {
DefaultToolbarComponent: DatePickerToolbar,
Expand Down
22 changes: 8 additions & 14 deletions lib/src/DateTimePicker/DateTimePicker.tsx
@@ -1,22 +1,20 @@
import { useUtils } from '../_shared/hooks/useUtils';
import { BaseDatePickerProps } from '../DatePicker/DatePicker';
import { DateTimePickerToolbar } from './DateTimePickerToolbar';
import { ExportedClockViewProps } from '../views/Clock/ClockView';
import { ResponsiveWrapper } from '../wrappers/ResponsiveWrapper';
import { pick12hOr24hFormat } from '../_helpers/text-field-helper';
import { ExportedCalendarViewProps } from '../views/Calendar/CalendarView';
import { makePickerWithStateAndWrapper } from '../Picker/makePickerWithState';
import { InlineWrapper, ModalWrapper, StaticWrapper } from '../wrappers/Wrapper';
import { WithViewsProps, AllSharedPickerProps } from '../Picker/SharedPickerProps';
import { dateTimePickerDefaultProps, ParsableDate } from '../constants/prop-types';
import {
makePickerWithStateAndWrapper,
WithDateInputProps,
WithViewsProps,
} from '../Picker/makePickerWithState';

export type DateTimePickerView = 'year' | 'date' | 'month' | 'hours' | 'minutes' | 'seconds';

export type BaseDateTimePickerProps = ExportedClockViewProps & BaseDatePickerProps;

export interface DateTimePickerViewsProps extends BaseDateTimePickerProps {
export interface DateTimePickerProps
extends WithViewsProps<'year' | 'date' | 'month' | 'hours' | 'minutes'>,
ExportedClockViewProps,
ExportedCalendarViewProps {
/** To show tabs */
hideTabs?: boolean;
/** Date tab icon */
Expand All @@ -31,10 +29,6 @@ export interface DateTimePickerViewsProps extends BaseDateTimePickerProps {
toolbarFormat?: string;
}

export type DateTimePickerProps = WithDateInputProps &
DateTimePickerViewsProps &
WithViewsProps<'year' | 'date' | 'month' | 'hours' | 'minutes'>;

function useDefaultProps({
ampm,
mask,
Expand All @@ -44,7 +38,7 @@ function useDefaultProps({
orientation = 'portrait',
openTo = 'date',
views = ['year', 'date', 'hours', 'minutes'],
}: DateTimePickerProps) {
}: DateTimePickerProps & AllSharedPickerProps) {
const utils = useUtils();
const willUseAmPm = ampm ?? utils.is12HourCycleInCurrentLocale();

Expand Down
3 changes: 1 addition & 2 deletions lib/src/LocalizationProvider.tsx
Expand Up @@ -29,13 +29,12 @@ export const LocalizationProvider: React.FC<LocalizationProviderProps> = ({
};

LocalizationProvider.propTypes = {
// @ts-ignore
dateAdapter: PropTypes.func.isRequired,
locale: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
children: PropTypes.oneOfType([
PropTypes.element.isRequired,
PropTypes.arrayOf(PropTypes.element.isRequired),
]).isRequired,
};
} as any;

export default LocalizationProvider;
76 changes: 40 additions & 36 deletions lib/src/Picker/Picker.tsx
Expand Up @@ -4,60 +4,63 @@ import { WrapperVariant } from '../wrappers/Wrapper';
import { useViews } from '../_shared/hooks/useViews';
import { makeStyles } from '@material-ui/core/styles';
import { DateTimePickerView } from '../DateTimePicker';
import { WithViewsProps } from './makePickerWithState';
import { ParsableDate } from '../constants/prop-types';
import { BasePickerProps } from '../typings/BasePicker';
import { MaterialUiPickersDate } from '../typings/date';
import { DateInputProps } from '../_shared/PureDateInput';
import { CalendarView } from '../views/Calendar/CalendarView';
import { DatePickerView } from '../DatePicker/DatePicker';
import { useIsLandscape } from '../_shared/hooks/useIsLandscape';
import { WithViewsProps, AnyPickerView } from './SharedPickerProps';
import { DIALOG_WIDTH, VIEW_HEIGHT } from '../constants/dimensions';
import { WrapperVariantContext } from '../wrappers/WrapperVariantContext';
import { MobileKeyboardInputView } from '../views/MobileKeyboardInputView';
import { ClockView, ExportedClockViewProps } from '../views/Clock/ClockView';
import { BaseDatePickerProps, DatePickerView } from '../DatePicker/DatePicker';
import { CalendarView, ExportedCalendarViewProps } from '../views/Calendar/CalendarView';

export type PickerView = DateTimePickerView;
type CalendarAndClockProps = ExportedCalendarViewProps & ExportedClockViewProps;

export type ToolbarComponentProps<T extends PickerView = any> = BaseDatePickerProps &
ExportedClockViewProps & {
views: T[];
openView: T;
date: MaterialUiPickersDate;
setOpenView: (view: T) => void;
onChange: (date: MaterialUiPickersDate, isFinish?: boolean) => void;
toolbarTitle?: string;
// TODO move out, cause it is DateTimePickerOnly
hideTabs?: boolean;
dateRangeIcon?: React.ReactNode;
timeIcon?: React.ReactNode;
isLandscape: boolean;
ampmInClock?: boolean;
isMobileKeyboardViewOpen: boolean;
toggleMobileKeyboardView: () => void;
getMobileKeyboardInputViewButtonText?: () => string;
};
export type ToolbarComponentProps<
T extends AnyPickerView = AnyPickerView
> = CalendarAndClockProps & {
views: T[];
openView: T;
date: MaterialUiPickersDate;
setOpenView: (view: T) => void;
onChange: (date: MaterialUiPickersDate, isFinish?: boolean) => void;
toolbarTitle?: React.ReactNode;
toolbarFormat?: string;
// TODO move out, cause it is DateTimePickerOnly
hideTabs?: boolean;
dateRangeIcon?: React.ReactNode;
timeIcon?: React.ReactNode;
isLandscape: boolean;
ampmInClock?: boolean;
isMobileKeyboardViewOpen: boolean;
toggleMobileKeyboardView: () => void;
getMobileKeyboardInputViewButtonText?: () => string;
};

export interface PickerViewProps<TView extends PickerView>
export interface ExportedPickerProps<TView extends AnyPickerView>
extends Omit<BasePickerProps, 'value' | 'onChange'>,
WithViewsProps<TView>,
BaseDatePickerProps,
ExportedClockViewProps {
toolbarTitle?: string;
showToolbar?: boolean;
ToolbarComponent: React.ComponentType<ToolbarComponentProps<any>>;
CalendarAndClockProps,
WithViewsProps<TView> {
// TODO move out, cause it is DateTimePickerOnly
hideTabs?: boolean;
dateRangeIcon?: React.ReactNode;
timeIcon?: React.ReactNode;
}

interface PickerProps<T extends PickerView> extends PickerViewProps<T> {
export interface PickerProps<
TView extends AnyPickerView,
TInputValue = ParsableDate,
TDateValue = MaterialUiPickersDate
> extends ExportedPickerProps<TView> {
isMobileKeyboardViewOpen: boolean;
toggleMobileKeyboardView: () => void;
DateInputProps: DateInputProps;
date: MaterialUiPickersDate;
DateInputProps: DateInputProps<TInputValue, TDateValue>;
date: TDateValue | null;
onDateChange: (
date: MaterialUiPickersDate,
date: TDateValue,
currentVariant: WrapperVariant,
isFinish?: boolean | symbol
) => void;
Expand Down Expand Up @@ -97,13 +100,14 @@ export function Picker({
toolbarTitle,
showToolbar,
onDateChange,
ToolbarComponent,
ToolbarComponent = () => null,
orientation,
DateInputProps,
isMobileKeyboardViewOpen,
toggleMobileKeyboardView,
toolbarFormat,
...other
}: PickerProps<PickerView>) {
}: PickerProps<AnyPickerView>) {
const classes = useStyles();
const isLandscape = useIsLandscape(views, orientation);
const wrapperVariant = React.useContext(WrapperVariantContext);
Expand Down Expand Up @@ -141,7 +145,7 @@ export function Picker({
setOpenView={setOpenView}
openView={openView}
toolbarTitle={toolbarTitle}
ampmInClock={other.ampmInClock}
toolbarFormat={toolbarFormat}
isMobileKeyboardViewOpen={isMobileKeyboardViewOpen}
toggleMobileKeyboardView={toggleMobileKeyboardView}
/>
Expand Down
23 changes: 23 additions & 0 deletions lib/src/Picker/SharedPickerProps.tsx
@@ -0,0 +1,23 @@
import { DateTimePickerView } from '../DateTimePicker';
import { BasePickerProps } from '../typings/BasePicker';
import { ExportedDateInputProps } from '../_shared/PureDateInput';
import { DateValidationProps } from '../_helpers/text-field-helper';
import { WithDateAdapterProps } from '../_shared/withDateAdapterProp';

export type AnyPickerView = DateTimePickerView;

export type AllSharedPickerProps = WithDateAdapterProps &
BasePickerProps &
ExportedDateInputProps &
DateValidationProps;

export interface WithViewsProps<T extends AnyPickerView> {
/**
* Array of views to show
*/
views?: T[];
/** First view to show */
openTo?: T;
}

export type WithDateInputProps = DateValidationProps & BasePickerProps & ExportedDateInputProps;

0 comments on commit 35e6b2d

Please sign in to comment.