forked from mui/mui-x
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shared.ts
109 lines (98 loc) · 3.63 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
import * as React from 'react';
import { useThemeProps } from '@mui/material/styles';
import { ParseableDate } from '../internals/models/parseableDate';
import { useDefaultDates, useUtils } from '../internals/hooks/useUtils';
import { CalendarPickerView, MuiPickersAdapter } from '../internals/models';
import { ExportedCalendarPickerProps } from '../CalendarPicker/CalendarPicker';
import { DateValidationError } from '../internals/hooks/validation/useDateValidation';
import { ValidationProps } from '../internals/hooks/validation/useValidation';
import { ExportedDateInputProps } from '../internals/components/PureDateInput';
import { BasePickerProps } from '../internals/models/props/basePickerProps';
import { BaseToolbarProps } from '../internals/models/props/baseToolbarProps';
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 an HTML element or a component.
* @default {}
*/
components?: ExportedCalendarPickerProps<TDate>['components'] &
ExportedDateInputProps<ParseableDate<TDate>, TDate | null>['components'];
/**
* Callback fired on view change.
* @param {CalendarPickerView} view The new view.
*/
onViewChange?: (view: CalendarPickerView) => void;
/**
* First view to show.
*/
openTo?: CalendarPickerView;
/**
* Component that will replace default toolbar renderer.
* @default DatePickerToolbar
*/
ToolbarComponent?: React.JSXElementConstructor<BaseToolbarProps<TDate | null>>;
/**
* Mobile picker title, displaying in the toolbar.
* @default 'Select date'
*/
toolbarTitle?: React.ReactNode;
/**
* Array of views to show.
*/
views?: readonly CalendarPickerView[];
}
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 = <TDate>(
views: readonly CalendarPickerView[],
utils: MuiPickersAdapter<TDate>,
): { 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<TDate, Props extends BaseDatePickerProps<TDate>>(
props: Props,
name: string,
): DefaultizedProps<Props> & Required<Pick<BaseDatePickerProps<unknown>, 'openTo' | 'views'>> {
const utils = useUtils<TDate>();
const defaultDates = useDefaultDates();
// 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.
const themeProps = useThemeProps({
props,
name,
});
const views = themeProps.views ?? ['year', 'day'];
return {
openTo: 'day',
minDate: defaultDates.minDate,
maxDate: defaultDates.maxDate,
...getFormatAndMaskByViews(views, utils),
...themeProps,
views,
};
}