-
Notifications
You must be signed in to change notification settings - Fork 833
/
KeyboardDateInput.tsx
124 lines (117 loc) · 3.67 KB
/
KeyboardDateInput.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
import * as React from 'react';
import InputAdornment, { InputAdornmentProps } from '@material-ui/core/InputAdornment';
import TextField, { BaseTextFieldProps, TextFieldProps } from '@material-ui/core/TextField';
import { Rifm } from 'rifm';
import { IconButton } from '@material-ui/core';
import { ExtendMui } from '../typings/extendMui';
import { KeyboardIcon } from './icons/KeyboardIcon';
import { IconButtonProps } from '@material-ui/core/IconButton';
import { makeMaskFromFormat, maskedDateFormatter } from '../_helpers/text-field-helper';
export interface KeyboardDateInputProps
extends ExtendMui<BaseTextFieldProps, 'variant' | 'onError' | 'onChange' | 'value'> {
format: string;
onChange: (value: string | null) => void;
onClick?: () => void;
validationError?: React.ReactNode;
inputValue: string;
inputProps?: TextFieldProps['inputProps'];
InputProps?: TextFieldProps['InputProps'];
/** Override input component */
TextFieldComponent?: React.ComponentType<TextFieldProps>;
/** Icon displaying for open picker button */
keyboardIcon?: React.ReactNode;
/** Pass material-ui text field variant down, bypass internal variant prop */
inputVariant?: TextFieldProps['variant'];
/**
* Custom mask. Can be used to override generate from format. (e.g. __/__/____ __:__)
*/
mask?: string;
/**
* Char string that will be replaced with number (for "_" mask will be "__/__/____")
* @default '_'
*/
maskChar?: string;
/**
* Refuse values regexp
* @default /[^\d]+/gi
*/
refuse?: RegExp;
/**
* Props to pass to keyboard input adornment
* @type {Partial<InputAdornmentProps>}
*/
InputAdornmentProps?: Partial<InputAdornmentProps>;
/**
* Props to pass to keyboard adornment button
* @type {Partial<IconButtonProps>}
*/
KeyboardButtonProps?: Partial<IconButtonProps>;
/** Custom formatter to be passed into Rifm component */
rifmFormatter?: (str: string) => string;
}
const KeyboardDateInput: React.FunctionComponent<KeyboardDateInputProps> = ({
inputValue,
inputVariant,
validationError,
KeyboardButtonProps,
InputAdornmentProps,
onClick,
onChange,
InputProps,
mask,
maskChar = '_',
refuse = /[^\d]+/gi,
format,
keyboardIcon,
disabled,
rifmFormatter,
TextFieldComponent = TextField,
...other
}) => {
const inputMask = mask || makeMaskFromFormat(format, maskChar);
// prettier-ignore
const formatter = React.useCallback(
maskedDateFormatter(inputMask, maskChar, refuse),
[mask, maskChar]
);
const position =
InputAdornmentProps && InputAdornmentProps.position ? InputAdornmentProps.position : 'end';
const handleChange = (text: string) => {
const finalString = text === '' || text === inputMask ? null : text;
onChange(finalString);
};
return (
<Rifm
value={inputValue}
onChange={handleChange}
refuse={refuse}
format={rifmFormatter || formatter}
>
{({ onChange, value }) => (
<TextFieldComponent
disabled={disabled}
error={Boolean(validationError)}
helperText={validationError}
{...other}
value={value}
onChange={onChange}
variant={inputVariant as any}
InputProps={{
...InputProps,
[`${position}Adornment`]: (
<InputAdornment position={position} {...InputAdornmentProps}>
<IconButton disabled={disabled} {...KeyboardButtonProps} onClick={onClick}>
{keyboardIcon}
</IconButton>
</InputAdornment>
),
}}
/>
)}
</Rifm>
);
};
KeyboardDateInput.defaultProps = {
keyboardIcon: <KeyboardIcon />,
};
export default KeyboardDateInput;