Skip to content

Commit

Permalink
[typescript] Make all components generic for date type (mui#2045)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmtrKovalenko authored Aug 4, 2020
1 parent bb7ea79 commit 6d9b428
Show file tree
Hide file tree
Showing 40 changed files with 731 additions and 579 deletions.
2 changes: 1 addition & 1 deletion docs/pages/demo/datepicker/CustomDay.example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function CustomDay(demoProps: any) {
const renderWeekPickerDay = (
date: Date,
_selectedDates: Date[],
DayComponentProps: PickersDayProps
DayComponentProps: PickersDayProps<Date>
) => {
const dateClone = makeJSDateObject(date);
const selectedDateClone = makeJSDateObject(selectedDate ?? new Date());
Expand Down
2 changes: 0 additions & 2 deletions docs/pages/demo/datepicker/ServerRequest.example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,11 @@ export default function ServerRequest() {
value={value}
loading={highlightedDays === null}
onChange={(newValue) => setValue(newValue)}
// @ts-expect-error fix typings of components
onMonthChange={handleMonthChange}
// loading
renderInput={(props) => <TextField {...props} />}
renderLoading={() => <CalendarSkeleton />}
renderDay={(day, value, DayComponentProps) => {
// @ts-expect-error fix typings of components
const date = makeJSDateObject(day ?? new Date()); // skip this step, it is required to support date libs
const isSelected =
DayComponentProps.inCurrentMonth && highlightedDays.includes(date.getDate());
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/regression/RegressionDay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React from 'react';
import { IUtils } from '@date-io/core/IUtils';
import { PickersDay, PickersDayProps } from '@material-ui/pickers';

export const createRegressionDay = (utils: IUtils<any>) => (
export const createRegressionDay = <TDate extends any>(utils: IUtils<TDate>) => (
day: any,
selectedDate: any,
dayProps: PickersDayProps
dayProps: PickersDayProps<TDate>
) => {
return <PickersDay {...dayProps} data-day={utils.formatByString(day, 'dd/MM/yyyy')} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,39 @@ import { useUtils } from '../_shared/hooks/useUtils';
import { DatePickerToolbar } from './DatePickerToolbar';
import { WithViewsProps } from '../Picker/SharedPickerProps';
import { ResponsiveWrapper } from '../wrappers/ResponsiveWrapper';
import { useParsedDate } from '../_shared/hooks/date-helpers-hooks';
import { useParsedDate, OverrideParsableDateProps } from '../_shared/hooks/date-helpers-hooks';
import { ExportedCalendarViewProps } from '../views/Calendar/CalendarView';
import { MobileWrapper, DesktopWrapper, StaticWrapper } from '../wrappers/Wrapper';
import { MobileWrapper, DesktopWrapper, StaticWrapper, SomeWrapper } from '../wrappers/Wrapper';
import { makeValidationHook, ValidationProps } from '../_shared/hooks/useValidation';
import { ParsableDate, defaultMinDate, defaultMaxDate } from '../constants/prop-types';
import { makePickerWithStateAndWrapper, AllPickerProps } from '../Picker/makePickerWithState';
import { getFormatAndMaskByViews, validateDate, DateValidationError } from '../_helpers/date-utils';
import {
makePickerWithStateAndWrapper,
AllPickerProps,
SharedPickerProps,
} from '../Picker/makePickerWithState';
import { getFormatAndMaskByViews, DateValidationError, validateDate } from '../_helpers/date-utils';

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

export interface BaseDatePickerProps
export interface BaseDatePickerProps<TDate>
extends WithViewsProps<'year' | 'date' | 'month'>,
ValidationProps<DateValidationError, ParsableDate>,
ExportedCalendarViewProps {}
OverrideParsableDateProps<TDate, ExportedCalendarViewProps<TDate>, 'minDate' | 'maxDate'> {}

const datePickerConfig = {
useValidation: makeValidationHook<DateValidationError, ParsableDate, BaseDatePickerProps>(
validateDate
),
useValidation: makeValidationHook<
DateValidationError,
ParsableDate,
BaseDatePickerProps<unknown>
>(validateDate),
DefaultToolbarComponent: DatePickerToolbar,
useInterceptProps: ({
openTo = 'date',
views = ['year', 'date'],
minDate: __minDate = defaultMinDate,
maxDate: __maxDate = defaultMaxDate,
...other
}: AllPickerProps<BaseDatePickerProps>) => {
}: AllPickerProps<BaseDatePickerProps<unknown>>) => {
const utils = useUtils();
const minDate = useParsedDate(__minDate);
const maxDate = useParsedDate(__maxDate);
Expand All @@ -44,21 +50,31 @@ const datePickerConfig = {
},
};

export const DatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps>(ResponsiveWrapper, {
name: 'MuiDatePicker',
...datePickerConfig,
});
type DatePickerComponent<TWrapper extends SomeWrapper> = <TDate>(
props: BaseDatePickerProps<TDate> & SharedPickerProps<TDate, TWrapper>
) => JSX.Element;

export const DatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps<unknown>>(
ResponsiveWrapper,
{
name: 'MuiDatePicker',
...datePickerConfig,
}
) as DatePickerComponent<typeof ResponsiveWrapper>;

export type DatePickerProps = React.ComponentProps<typeof DatePicker>;

export const MobileDatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps>(MobileWrapper, {
name: 'MuiMobileDatePicker',
...datePickerConfig,
});
export const MobileDatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps<unknown>>(
MobileWrapper,
{
name: 'MuiMobileDatePicker',
...datePickerConfig,
}
) as DatePickerComponent<typeof MobileWrapper>;

export type MobileDatePickerProps = React.ComponentProps<typeof MobileDatePicker>;

export const DesktopDatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps>(
export const DesktopDatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps<unknown>>(
DesktopWrapper,
{
name: 'MuiDesktopDatePicker',
Expand All @@ -68,9 +84,12 @@ export const DesktopDatePicker = makePickerWithStateAndWrapper<BaseDatePickerPro

export type DesktopDatePickerProps = React.ComponentProps<typeof DesktopDatePicker>;

export const StaticDatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps>(StaticWrapper, {
name: 'MuiStaticDatePicker',
...datePickerConfig,
});
export const StaticDatePicker = makePickerWithStateAndWrapper<BaseDatePickerProps<unknown>>(
StaticWrapper,
{
name: 'MuiStaticDatePicker',
...datePickerConfig,
}
) as DatePickerComponent<typeof StaticWrapper>;

export type StaticDatePickerProps = React.ComponentProps<typeof StaticDatePicker>;
20 changes: 11 additions & 9 deletions lib/src/DateRangePicker/DateRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import {
DateRangeValidationError,
} from '../_helpers/date-utils';

export interface BaseDateRangePickerProps
extends ExportedDateRangePickerViewProps,
ValidationProps<DateRangeValidationError, RangeInput>,
export interface BaseDateRangePickerProps<TDate>
extends ExportedDateRangePickerViewProps<TDate>,
ValidationProps<DateRangeValidationError, RangeInput<TDate>>,
ExportedDateRangePickerInputProps {
/**
* Text for start input label and toolbar placeholder
Expand All @@ -44,7 +44,7 @@ export interface BaseDateRangePickerProps
}

type RangePickerComponent<TWrapper extends SomeWrapper> = <TDate>(
props: BaseDateRangePickerProps &
props: BaseDateRangePickerProps<TDate> &
ExtendWrapper<TWrapper> &
AllSharedDateRangePickerProps<TDate> &
React.RefAttributes<HTMLDivElement>
Expand All @@ -53,7 +53,7 @@ type RangePickerComponent<TWrapper extends SomeWrapper> = <TDate>(
export const useDateRangeValidation = makeValidationHook<
DateRangeValidationError,
RangeInput,
BaseDateRangePickerProps
BaseDateRangePickerProps<any>
>(validateDateRange, {
defaultValidationError: [null, null],
isSameError: (a, b) => a[1] === b[1] && a[0] === b[0],
Expand Down Expand Up @@ -82,10 +82,12 @@ export function makeRangePicker<TWrapper extends SomeWrapper>(
startText = 'Start',
endText = 'End',
inputFormat: passedInputFormat,
minDate: __minDate = defaultMinDate,
maxDate: __maxDate = defaultMaxDate,
minDate: __minDate = defaultMinDate as TDate,
maxDate: __maxDate = defaultMaxDate as TDate,
...other
}: BaseDateRangePickerProps & AllSharedDateRangePickerProps<TDate> & ExtendWrapper<TWrapper>) {
}: BaseDateRangePickerProps<TDate> &
AllSharedDateRangePickerProps<TDate> &
ExtendWrapper<TWrapper>) {
const utils = useUtils();
const minDate = useParsedDate(__minDate);
const maxDate = useParsedDate(__maxDate);
Expand Down Expand Up @@ -126,7 +128,7 @@ export function makeRangePicker<TWrapper extends SomeWrapper>(

return (
<WrapperComponent wrapperProps={wrapperProps} DateInputProps={DateInputProps} {...restProps}>
<DateRangePickerView
<DateRangePickerView<any>
open={wrapperProps.open}
DateInputProps={DateInputProps}
calendars={calendars}
Expand Down
10 changes: 5 additions & 5 deletions lib/src/DateRangePicker/DateRangePickerDay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DAY_MARGIN } from '../constants/dimensions';
import { useUtils } from '../_shared/hooks/useUtils';
import { Day, DayProps, areDayPropsEqual } from '../views/Calendar/Day';

export interface DateRangeDayProps extends DayProps {
export interface DateRangeDayProps<TDate> extends DayProps<TDate> {
isHighlighting: boolean;
isEndOfHighlighting: boolean;
isStartOfHighlighting: boolean;
Expand Down Expand Up @@ -96,7 +96,7 @@ const useStyles = makeStyles(
{ name: 'MuiPickersDateRangeDay' }
);

export const PureDateRangeDay = (props: DateRangeDayProps) => {
export function PureDateRangeDay<TDate>(props: DateRangeDayProps<TDate>) {
const {
className,
day,
Expand Down Expand Up @@ -136,7 +136,7 @@ export const PureDateRangeDay = (props: DateRangeDayProps) => {
[classes.rangeIntervalDayPreviewStart]: isStartOfPreviewing || isStartOfMonth,
})}
>
<Day
<Day<any>
{...other}
disableMargin
allowSameDateSelection
Expand All @@ -158,7 +158,7 @@ export const PureDateRangeDay = (props: DateRangeDayProps) => {
</div>
</div>
);
};
}

PureDateRangeDay.displayName = 'DateRangeDay';

Expand All @@ -172,4 +172,4 @@ export const DateRangeDay = React.memo(PureDateRangeDay, (prevProps, nextProps)
prevProps.isStartOfPreviewing === nextProps.isStartOfPreviewing &&
areDayPropsEqual(prevProps, nextProps)
);
});
}) as typeof PureDateRangeDay;
Loading

0 comments on commit 6d9b428

Please sign in to comment.