-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
/
shared.ts
115 lines (106 loc) · 3.72 KB
/
shared.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { useThemeProps } from '@mui/material/styles';
import { ParseableDate } from '../internal/pickers/constants/prop-types';
import { OverrideParseableDateProps } from '../internal/pickers/hooks/date-helpers-hooks';
import { MuiPickersAdapter, useDefaultDates, useUtils } from '../internal/pickers/hooks/useUtils';
import { CalendarPickerView } from '../CalendarPicker';
import { ExportedCalendarPickerProps } from '../CalendarPicker/CalendarPicker';
import { DateValidationError, ValidationProps } from '../internal/pickers/hooks/useValidation';
import { ExportedDateInputProps } from '../internal/pickers/PureDateInput';
import { BasePickerProps, ToolbarComponentProps } from '../internal/pickers/typings/BasePicker';
export type DatePickerView = 'year' | 'day' | 'month';
export interface BaseDatePickerProps<TDate>
extends ExportedCalendarPickerProps<TDate>,
BasePickerProps<ParseableDate<TDate>, TDate | null>,
ValidationProps<DateValidationError, ParseableDate<TDate>>,
ExportedDateInputProps<ParseableDate<TDate>, TDate | null> {
/**
* The components used for each slot.
* Either a string to use a HTML element or a component.
* @default {}
*/
components?: OverrideParseableDateProps<
TDate,
ExportedCalendarPickerProps<TDate>,
'minDate' | 'maxDate'
>['components'] &
ExportedDateInputProps<ParseableDate<TDate>, TDate | null>['components'];
/**
* Callback fired on view change.
*/
onViewChange?: (view: DatePickerView) => void;
/**
* First view to show.
*/
openTo?: DatePickerView;
/**
* Component that will replace default toolbar renderer.
* @default DatePickerToolbar
*/
ToolbarComponent?: React.JSXElementConstructor<ToolbarComponentProps<TDate | null>>;
/**
* Mobile picker title, displaying in the toolbar.
* @default 'Select date'
*/
toolbarTitle?: React.ReactNode;
/**
* Array of views to show.
*/
views?: readonly DatePickerView[];
}
export const isYearOnlyView = (
views: readonly CalendarPickerView[],
): views is ReadonlyArray<'year'> => views.length === 1 && views[0] === 'year';
export const isYearAndMonthViews = (
views: readonly CalendarPickerView[],
): views is ReadonlyArray<'month' | 'year'> =>
views.length === 2 && views.indexOf('month') !== -1 && views.indexOf('year') !== -1;
const getFormatAndMaskByViews = (
views: readonly CalendarPickerView[],
utils: MuiPickersAdapter,
): { disableMaskedInput?: boolean; inputFormat: string; mask?: string } => {
if (isYearOnlyView(views)) {
return {
mask: '____',
inputFormat: utils.formats.year,
};
}
if (isYearAndMonthViews(views)) {
return {
disableMaskedInput: true,
inputFormat: utils.formats.monthAndYear,
};
}
return {
mask: '__/__/____',
inputFormat: utils.formats.keyboardDate,
};
};
export type DefaultizedProps<Props> = Props & { inputFormat: string };
export function useDatePickerDefaultizedProps<Props extends BaseDatePickerProps<unknown>>(
{
openTo = 'day',
views = ['year', 'day'],
minDate: minDateProp,
maxDate: maxDateProp,
...other
}: Props,
name: string,
): DefaultizedProps<Props> & Required<Pick<BaseDatePickerProps<unknown>, 'openTo' | 'views'>> {
const utils = useUtils();
const defaultDates = useDefaultDates();
const minDate = minDateProp ?? defaultDates.minDate;
const maxDate = maxDateProp ?? defaultDates.maxDate;
// This is technically unsound if the type parameters appear in optional props.
// Optional props can be filled by `useThemeProps` with types that don't match the type parameters.
return useThemeProps({
props: {
views,
openTo,
minDate,
maxDate,
...getFormatAndMaskByViews(views, utils),
...(other as Props),
},
name,
});
}