forked from marmelab/react-admin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDateInput.tsx
137 lines (122 loc) · 3.71 KB
/
DateInput.tsx
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import * as React from 'react';
import PropTypes from 'prop-types';
import TextField, { TextFieldProps } from '@material-ui/core/TextField';
import { useInput, FieldTitle, InputProps } from 'ra-core';
import sanitizeInputRestProps from './sanitizeInputRestProps';
import InputHelperText from './InputHelperText';
/**
* Convert Date object to String
*
* @param {Date} value value to convert
* @returns {String} A standardized date (yyyy-MM-dd), to be passed to an <input type="date" />
*/
const convertDateToString = (value: Date) => {
if (!(value instanceof Date) || isNaN(value.getDate())) return '';
const pad = '00';
const yyyy = value.getFullYear().toString();
const MM = (value.getMonth() + 1).toString();
const dd = value.getDate().toString();
return `${yyyy}-${(pad + MM).slice(-2)}-${(pad + dd).slice(-2)}`;
};
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
const defaultInputLabelProps = { shrink: true };
const getStringFromDate = (value: string | Date) => {
// null, undefined and empty string values should not go through dateFormatter
// otherwise, it returns undefined and will make the input an uncontrolled one.
if (value == null || value === '') {
return '';
}
if (value instanceof Date) {
return convertDateToString(value);
}
// valid dates should not be converted
if (dateRegex.test(value)) {
return value;
}
return convertDateToString(new Date(value));
};
const DateInput = ({
defaultValue,
format = getStringFromDate,
initialValue,
label,
name,
options,
source,
resource,
helperText,
margin = 'dense',
onBlur,
onChange,
onFocus,
parse,
validate,
variant = 'filled',
...rest
}: DateInputProps) => {
const sanitizedDefaultValue = defaultValue
? format(new Date(defaultValue))
: undefined;
const sanitizedInitialValue = initialValue
? format(new Date(initialValue))
: undefined;
const { id, input, isRequired, meta } = useInput({
defaultValue: sanitizedDefaultValue,
format,
formatOnBlur: true,
initialValue: sanitizedInitialValue,
name,
onBlur,
onChange,
onFocus,
parse,
resource,
source,
validate,
...rest,
});
const { error, submitError, touched } = meta;
return (
<TextField
id={id}
{...input}
// Workaround https://github.com/final-form/react-final-form/issues/529
// & https://github.com/final-form/react-final-form/issues/431
value={format(input.value) || ''}
variant={variant}
margin={margin}
type="date"
error={!!(touched && (error || submitError))}
helperText={
<InputHelperText
touched={touched}
error={error || submitError}
helperText={helperText}
/>
}
label={
<FieldTitle
label={label}
source={source}
resource={resource}
isRequired={isRequired}
/>
}
InputLabelProps={defaultInputLabelProps}
{...options}
{...sanitizeInputRestProps(rest)}
/>
);
};
DateInput.propTypes = {
label: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
options: PropTypes.object,
resource: PropTypes.string,
source: PropTypes.string,
};
DateInput.defaultProps = {
options: {},
};
export type DateInputProps = InputProps<TextFieldProps> &
Omit<TextFieldProps, 'helperText' | 'label'>;
export default DateInput;