1 import React, { Component } from 'react';
2 import PropTypes from 'prop-types';
3 import moment from 'moment';
5 class Header extends Component {
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,
25 focusOnOpen: PropTypes.bool,
26 onKeyDown: PropTypes.func,
31 const { value, format } = props;
33 str: value && value.format(format) || '',
39 if (this.props.focusOnOpen) {
40 // Wait one frame for the panel to be positioned before focusing
41 const requestAnimationFrame = (window.requestAnimationFrame || window.setTimeout);
42 requestAnimationFrame(() => {
43 this.refs.input.focus();
44 this.refs.input.select();
49 componentWillReceiveProps(nextProps) {
50 const { value, format } = nextProps;
52 str: value && value.format(format) || '',
57 onInputChange = (event) => {
58 const str = event.target.value;
63 format, hourOptions, minuteOptions, secondOptions,
64 disabledHours, disabledMinutes,
65 disabledSeconds, onChange, allowEmpty,
69 const originalValue = this.props.value;
70 const value = this.getProtoValue().clone();
71 const parsed = moment(str, format, true);
72 if (!parsed.isValid()) {
78 value.hour(parsed.hour()).minute(parsed.minute()).second(parsed.second());
80 // if time value not allowed, response warning.
82 hourOptions.indexOf(value.hour()) < 0 ||
83 minuteOptions.indexOf(value.minute()) < 0 ||
84 secondOptions.indexOf(value.second()) < 0
92 // if time value is disabled, response warning.
93 const disabledHourOptions = disabledHours();
94 const disabledMinuteOptions = disabledMinutes(value.hour());
95 const disabledSecondOptions = disabledSeconds(value.hour(), value.minute());
97 (disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) ||
98 (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) ||
99 (disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0)
109 originalValue.hour() !== value.hour() ||
110 originalValue.minute() !== value.minute() ||
111 originalValue.second() !== value.second()
113 // keep other fields for rc-calendar
114 const changedValue = originalValue.clone();
115 changedValue.hour(value.hour());
116 changedValue.minute(value.minute());
117 changedValue.second(value.second());
118 onChange(changedValue);
120 } else if (originalValue !== value) {
123 } else if (allowEmpty) {
138 const { onEsc, onKeyDown } = this.props;
139 if (e.keyCode === 27) {
147 this.setState({ str: '' });
148 this.props.onClear();
152 const { prefixCls, allowEmpty } = this.props;
157 className={`${prefixCls}-clear-btn`}
159 title={this.props.clearText}
160 onMouseDown={this.onClear}
165 return this.props.value || this.props.defaultOpenValue;
169 const { prefixCls, placeholder } = this.props;
170 const { invalid, str } = this.state;
171 const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
174 className={`${prefixCls}-input ${invalidClass}`}
176 onKeyDown={this.onKeyDown}
178 placeholder={placeholder}
179 onChange={this.onInputChange}
185 const { prefixCls } = this.props;
187 <div className={`${prefixCls}-input-wrap`}>
189 {this.getClearButton()}
195 export default Header;