/
date-field.js
113 lines (102 loc) 路 3.48 KB
/
date-field.js
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
import React from 'react';
import PropTypes from 'prop-types';
import requiredIf from 'react-required-if';
import {
filterDataAttributes,
createSequentialId,
getFieldId,
} from '@commercetools-uikit/utils';
import Constraints from '@commercetools-uikit/constraints';
import Spacings from '@commercetools-uikit/spacings';
import FieldLabel from '@commercetools-uikit/field-label';
import DateInput from '@commercetools-uikit/date-input';
import FieldErrors from '@commercetools-uikit/field-errors';
const sequentialId = createSequentialId('date-field-');
const hasErrors = errors => errors && Object.values(errors).some(Boolean);
class DateField extends React.Component {
static displayName = 'DateField';
static propTypes = {
// DateField
id: PropTypes.string,
horizontalConstraint: PropTypes.oneOf(['m', 'l', 'xl', 'scale']),
errors: PropTypes.shape({
missing: PropTypes.bool,
}),
renderError: PropTypes.func,
isRequired: PropTypes.bool,
touched: PropTypes.bool,
// DateInput
name: PropTypes.string,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
onBlur: PropTypes.func,
onFocus: PropTypes.func,
isDisabled: PropTypes.bool,
isReadOnly: PropTypes.bool,
placeholder: PropTypes.string,
minValue: PropTypes.string,
maxValue: PropTypes.string,
// LabelField
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
hint: requiredIf(
PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
props => props.hintIcon
),
description: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
onInfoButtonClick: PropTypes.func,
hintIcon: PropTypes.node,
badge: PropTypes.node,
};
static defaultProps = {
horizontalConstraint: 'scale',
};
state = {
// We generate an id in case no id is provided by the parent to attach the
// label to the input component.
id: this.props.id,
};
static getDerivedStateFromProps = (props, state) => ({
id: getFieldId(props, state, sequentialId),
});
render() {
const hasError = this.props.touched && hasErrors(this.props.errors);
return (
<Constraints.Horizontal constraint={this.props.horizontalConstraint}>
<Spacings.Stack scale="xs">
<FieldLabel
title={this.props.title}
hint={this.props.hint}
description={this.props.description}
onInfoButtonClick={this.props.onInfoButtonClick}
hintIcon={this.props.hintIcon}
badge={this.props.badge}
hasRequiredIndicator={this.props.isRequired}
htmlFor={this.state.id}
/>
<DateInput
id={this.state.id}
name={this.props.name}
value={this.props.value}
onBlur={this.props.onBlur}
onFocus={this.props.onFocus}
minValue={this.props.minValue}
maxValue={this.props.maxValue}
onChange={this.props.onChange}
isDisabled={this.props.isDisabled}
isReadOnly={this.props.isReadOnly}
hasError={hasError}
placeholder={this.props.placeholder}
horizontalConstraint="scale"
{...filterDataAttributes(this.props)}
/>
<FieldErrors
errors={this.props.errors}
isVisible={hasError}
renderError={this.props.renderError}
/>
</Spacings.Stack>
</Constraints.Horizontal>
);
}
}
export default DateField;