]> git.immae.eu Git - github/fretlink/time-picker.git/blame - src/Header.jsx
Merge branch 'master' into picker-step
[github/fretlink/time-picker.git] / src / Header.jsx
CommitLineData
3ab3a128 1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
4984ed85 3import moment from 'moment';
4
3ab3a128 5class Header extends Component {
6 static propTypes = {
4984ed85 7 format: PropTypes.string,
8 prefixCls: PropTypes.string,
9 disabledDate: PropTypes.func,
10 placeholder: PropTypes.string,
11 clearText: PropTypes.string,
12 value: PropTypes.object,
13 hourOptions: PropTypes.array,
14 minuteOptions: PropTypes.array,
15 secondOptions: PropTypes.array,
16 disabledHours: PropTypes.func,
17 disabledMinutes: PropTypes.func,
18 disabledSeconds: PropTypes.func,
19 onChange: PropTypes.func,
20 onClear: PropTypes.func,
21 onEsc: PropTypes.func,
22 allowEmpty: PropTypes.bool,
23 defaultOpenValue: PropTypes.object,
24 currentSelectPanel: PropTypes.string,
0e4fd162 25 onKeyDown: PropTypes.func,
3ab3a128 26 };
4984ed85 27
3ab3a128 28 constructor(props) {
29 super(props);
30 const { value, format } = props;
31 this.state = {
4984ed85 32 str: value && value.format(format) || '',
33 invalid: false,
34 };
3ab3a128 35 }
4984ed85 36
37 componentWillReceiveProps(nextProps) {
38 const { value, format } = nextProps;
39 this.setState({
40 str: value && value.format(format) || '',
41 invalid: false,
42 });
3ab3a128 43 }
4984ed85 44
3ab3a128 45 onInputChange = (event) => {
4984ed85 46 const str = event.target.value;
47 this.setState({
48 str,
49 });
50 const {
51 format, hourOptions, minuteOptions, secondOptions,
52 disabledHours, disabledMinutes,
53 disabledSeconds, onChange, allowEmpty,
54 } = this.props;
55
56 if (str) {
57 const originalValue = this.props.value;
58 const value = this.getProtoValue().clone();
59 const parsed = moment(str, format, true);
60 if (!parsed.isValid()) {
61 this.setState({
62 invalid: true,
63 });
64 return;
65 }
66 value.hour(parsed.hour()).minute(parsed.minute()).second(parsed.second());
67
68 // if time value not allowed, response warning.
69 if (
70 hourOptions.indexOf(value.hour()) < 0 ||
71 minuteOptions.indexOf(value.minute()) < 0 ||
72 secondOptions.indexOf(value.second()) < 0
73 ) {
74 this.setState({
75 invalid: true,
76 });
77 return;
78 }
79
80 // if time value is disabled, response warning.
81 const disabledHourOptions = disabledHours();
82 const disabledMinuteOptions = disabledMinutes(value.hour());
83 const disabledSecondOptions = disabledSeconds(value.hour(), value.minute());
84 if (
85 (disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) ||
86 (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) ||
87 (disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0)
88 ) {
89 this.setState({
90 invalid: true,
91 });
92 return;
93 }
94
95 if (originalValue) {
96 if (
97 originalValue.hour() !== value.hour() ||
98 originalValue.minute() !== value.minute() ||
99 originalValue.second() !== value.second()
100 ) {
101 // keep other fields for rc-calendar
102 const changedValue = originalValue.clone();
103 changedValue.hour(value.hour());
104 changedValue.minute(value.minute());
105 changedValue.second(value.second());
106 onChange(changedValue);
107 }
108 } else if (originalValue !== value) {
109 onChange(value);
110 }
111 } else if (allowEmpty) {
112 onChange(null);
113 } else {
114 this.setState({
115 invalid: true,
116 });
117 return;
118 }
119
120 this.setState({
121 invalid: false,
122 });
3ab3a128 123 }
4984ed85 124
3ab3a128 125 onKeyDown = (e) => {
0e4fd162 126 const { onEsc, onKeyDown } = this.props;
4984ed85 127 if (e.keyCode === 27) {
0e4fd162 128 onEsc();
4984ed85 129 }
0e4fd162 130
131 onKeyDown(e);
3ab3a128 132 }
4984ed85 133
3ab3a128 134 onClear = () => {
4984ed85 135 this.setState({ str: '' });
136 this.props.onClear();
3ab3a128 137 }
4984ed85 138
139 getClearButton() {
140 const { prefixCls, allowEmpty } = this.props;
141 if (!allowEmpty) {
142 return null;
143 }
144 return (<a
145 className={`${prefixCls}-clear-btn`}
146 role="button"
147 title={this.props.clearText}
148 onMouseDown={this.onClear}
149 />);
3ab3a128 150 }
4984ed85 151
152 getProtoValue() {
153 return this.props.value || this.props.defaultOpenValue;
3ab3a128 154 }
4984ed85 155
156 getInput() {
157 const { prefixCls, placeholder } = this.props;
158 const { invalid, str } = this.state;
159 const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
f429b4a7 160 return (
161 <input
162 className={`${prefixCls}-input ${invalidClass}`}
163 ref="input"
164 onKeyDown={this.onKeyDown}
165 value={str}
166 placeholder={placeholder}
167 onChange={this.onInputChange}
168 />
169 );
3ab3a128 170 }
4984ed85 171
172 render() {
173 const { prefixCls } = this.props;
174 return (
175 <div className={`${prefixCls}-input-wrap`}>
176 {this.getInput()}
177 {this.getClearButton()}
178 </div>
179 );
3ab3a128 180 }
181}
4984ed85 182
183export default Header;