aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorafc163 <afc163@gmail.com>2016-11-11 12:10:26 +0800
committerafc163 <afc163@gmail.com>2016-11-11 12:10:26 +0800
commit614f6c90232d890984d0f4f2f13ff41fdb144b27 (patch)
treece1a9be06b3264fd9fc09b3c2b028646db03a322 /src
parentcb5a445c75c7117c7c705d615099086274c2b254 (diff)
parentf429b4a79df25c9eadc3901e2483716835cc7de7 (diff)
downloadtime-picker-614f6c90232d890984d0f4f2f13ff41fdb144b27.tar.gz
time-picker-614f6c90232d890984d0f4f2f13ff41fdb144b27.tar.zst
time-picker-614f6c90232d890984d0f4f2f13ff41fdb144b27.zip
Merge branch 'master' of github.com:react-component/time-picker
Diffstat (limited to 'src')
-rw-r--r--src/Combobox.jsx (renamed from src/module/Combobox.jsx)54
-rw-r--r--src/Header.jsx177
-rw-r--r--src/Panel.jsx (renamed from src/module/Panel.jsx)57
-rw-r--r--src/Select.jsx (renamed from src/module/Select.jsx)18
-rw-r--r--src/TimePicker.jsx69
-rw-r--r--src/locale/en_US.js8
-rw-r--r--src/locale/ru_RU.js8
-rw-r--r--src/locale/zh_CN.js8
-rw-r--r--src/mixin/CommonMixin.js16
-rw-r--r--src/module/Header.jsx204
-rw-r--r--src/placements.js (renamed from src/util/placements.js)0
-rw-r--r--src/util/index.js8
-rw-r--r--src/util/selection.js17
13 files changed, 278 insertions, 366 deletions
diff --git a/src/module/Combobox.jsx b/src/Combobox.jsx
index f1e7c5b..9d9da16 100644
--- a/src/module/Combobox.jsx
+++ b/src/Combobox.jsx
@@ -1,6 +1,5 @@
1import React, {PropTypes} from 'react'; 1import React, { PropTypes } from 'react';
2import Select from './Select'; 2import Select from './Select';
3import GregorianCalendar from 'gregorian-calendar';
4 3
5const formatOption = (option, disabledOptions) => { 4const formatOption = (option, disabledOptions) => {
6 let value = `${option}`; 5 let value = `${option}`;
@@ -21,12 +20,12 @@ const formatOption = (option, disabledOptions) => {
21 20
22const Combobox = React.createClass({ 21const Combobox = React.createClass({
23 propTypes: { 22 propTypes: {
24 formatter: PropTypes.object, 23 format: PropTypes.string,
24 defaultOpenValue: PropTypes.object,
25 prefixCls: PropTypes.string, 25 prefixCls: PropTypes.string,
26 value: PropTypes.object, 26 value: PropTypes.object,
27 onChange: PropTypes.func, 27 onChange: PropTypes.func,
28 showHour: PropTypes.bool, 28 showHour: PropTypes.bool,
29 gregorianCalendarLocale: PropTypes.object,
30 showSecond: PropTypes.bool, 29 showSecond: PropTypes.bool,
31 hourOptions: PropTypes.array, 30 hourOptions: PropTypes.array,
32 minuteOptions: PropTypes.array, 31 minuteOptions: PropTypes.array,
@@ -38,19 +37,14 @@ const Combobox = React.createClass({
38 }, 37 },
39 38
40 onItemChange(type, itemValue) { 39 onItemChange(type, itemValue) {
41 const { onChange } = this.props; 40 const { onChange, defaultOpenValue } = this.props;
42 let value = this.props.value; 41 const value = (this.props.value || defaultOpenValue).clone();
43 if (value) {
44 value = value.clone();
45 } else {
46 value = this.getNow().clone();
47 }
48 if (type === 'hour') { 42 if (type === 'hour') {
49 value.setHourOfDay(itemValue); 43 value.hour(itemValue);
50 } else if (type === 'minute') { 44 } else if (type === 'minute') {
51 value.setMinutes(itemValue); 45 value.minute(itemValue);
52 } else { 46 } else {
53 value.setSeconds(itemValue); 47 value.second(itemValue);
54 } 48 }
55 onChange(value); 49 onChange(value);
56 }, 50 },
@@ -79,9 +73,9 @@ const Combobox = React.createClass({
79 }, 73 },
80 74
81 getMinuteSelect(minute) { 75 getMinuteSelect(minute) {
82 const { prefixCls, minuteOptions, disabledMinutes } = this.props; 76 const { prefixCls, minuteOptions, disabledMinutes, defaultOpenValue } = this.props;
83 const value = this.props.value || this.getNow(); 77 const value = this.props.value || defaultOpenValue;
84 const disabledOptions = disabledMinutes(value.getHourOfDay()); 78 const disabledOptions = disabledMinutes(value.hour());
85 79
86 return ( 80 return (
87 <Select 81 <Select
@@ -96,12 +90,12 @@ const Combobox = React.createClass({
96 }, 90 },
97 91
98 getSecondSelect(second) { 92 getSecondSelect(second) {
99 const { prefixCls, secondOptions, disabledSeconds, showSecond } = this.props; 93 const { prefixCls, secondOptions, disabledSeconds, showSecond, defaultOpenValue } = this.props;
100 if (!showSecond) { 94 if (!showSecond) {
101 return null; 95 return null;
102 } 96 }
103 const value = this.props.value || this.getNow(); 97 const value = this.props.value || defaultOpenValue;
104 const disabledOptions = disabledSeconds(value.getHourOfDay(), value.getMinutes()); 98 const disabledOptions = disabledSeconds(value.hour(), value.minute());
105 99
106 return ( 100 return (
107 <Select 101 <Select
@@ -115,24 +109,14 @@ const Combobox = React.createClass({
115 ); 109 );
116 }, 110 },
117 111
118 getNow() {
119 if (this.showNow) {
120 return this.showNow;
121 }
122 const value = new GregorianCalendar(this.props.gregorianCalendarLocale);
123 value.setTime(Date.now());
124 this.showNow = value;
125 return value;
126 },
127
128 render() { 112 render() {
129 const { prefixCls } = this.props; 113 const { prefixCls, defaultOpenValue } = this.props;
130 const value = this.props.value || this.getNow(); 114 const value = this.props.value || defaultOpenValue;
131 return ( 115 return (
132 <div className={`${prefixCls}-combobox`}> 116 <div className={`${prefixCls}-combobox`}>
133 {this.getHourSelect(value.getHourOfDay())} 117 {this.getHourSelect(value.hour())}
134 {this.getMinuteSelect(value.getMinutes())} 118 {this.getMinuteSelect(value.minute())}
135 {this.getSecondSelect(value.getSeconds())} 119 {this.getSecondSelect(value.second())}
136 </div> 120 </div>
137 ); 121 );
138 }, 122 },
diff --git a/src/Header.jsx b/src/Header.jsx
new file mode 100644
index 0000000..2ef9827
--- /dev/null
+++ b/src/Header.jsx
@@ -0,0 +1,177 @@
1import React, { PropTypes } from 'react';
2import moment from 'moment';
3
4const Header = React.createClass({
5 propTypes: {
6 format: PropTypes.string,
7 prefixCls: PropTypes.string,
8 disabledDate: PropTypes.func,
9 placeholder: PropTypes.string,
10 clearText: PropTypes.string,
11 value: PropTypes.object,
12 hourOptions: PropTypes.array,
13 minuteOptions: PropTypes.array,
14 secondOptions: PropTypes.array,
15 disabledHours: PropTypes.func,
16 disabledMinutes: PropTypes.func,
17 disabledSeconds: PropTypes.func,
18 onChange: PropTypes.func,
19 onClear: PropTypes.func,
20 onEsc: PropTypes.func,
21 allowEmpty: PropTypes.bool,
22 defaultOpenValue: PropTypes.object,
23 currentSelectPanel: PropTypes.string,
24 },
25
26 getInitialState() {
27 const { value, format } = this.props;
28 return {
29 str: value && value.format(format) || '',
30 invalid: false,
31 };
32 },
33
34 componentWillReceiveProps(nextProps) {
35 const { value, format } = nextProps;
36 this.setState({
37 str: value && value.format(format) || '',
38 invalid: false,
39 });
40 },
41
42 onInputChange(event) {
43 const str = event.target.value;
44 this.setState({
45 str,
46 });
47 const {
48 format, hourOptions, minuteOptions, secondOptions,
49 disabledHours, disabledMinutes,
50 disabledSeconds, onChange, allowEmpty,
51 } = this.props;
52
53 if (str) {
54 const originalValue = this.props.value;
55 const value = this.getProtoValue().clone();
56 const parsed = moment(str, format, true);
57 if (!parsed.isValid()) {
58 this.setState({
59 invalid: true,
60 });
61 return;
62 }
63 value.hour(parsed.hour()).minute(parsed.minute()).second(parsed.second());
64
65 // if time value not allowed, response warning.
66 if (
67 hourOptions.indexOf(value.hour()) < 0 ||
68 minuteOptions.indexOf(value.minute()) < 0 ||
69 secondOptions.indexOf(value.second()) < 0
70 ) {
71 this.setState({
72 invalid: true,
73 });
74 return;
75 }
76
77 // if time value is disabled, response warning.
78 const disabledHourOptions = disabledHours();
79 const disabledMinuteOptions = disabledMinutes(value.hour());
80 const disabledSecondOptions = disabledSeconds(value.hour(), value.minute());
81 if (
82 (disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) ||
83 (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) ||
84 (disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0)
85 ) {
86 this.setState({
87 invalid: true,
88 });
89 return;
90 }
91
92 if (originalValue) {
93 if (
94 originalValue.hour() !== value.hour() ||
95 originalValue.minute() !== value.minute() ||
96 originalValue.second() !== value.second()
97 ) {
98 // keep other fields for rc-calendar
99 const changedValue = originalValue.clone();
100 changedValue.hour(value.hour());
101 changedValue.minute(value.minute());
102 changedValue.second(value.second());
103 onChange(changedValue);
104 }
105 } else if (originalValue !== value) {
106 onChange(value);
107 }
108 } else if (allowEmpty) {
109 onChange(null);
110 } else {
111 this.setState({
112 invalid: true,
113 });
114 return;
115 }
116
117 this.setState({
118 invalid: false,
119 });
120 },
121
122 onKeyDown(e) {
123 if (e.keyCode === 27) {
124 this.props.onEsc();
125 }
126 },
127
128 onClear() {
129 this.setState({ str: '' });
130 this.props.onClear();
131 },
132
133 getClearButton() {
134 const { prefixCls, allowEmpty } = this.props;
135 if (!allowEmpty) {
136 return null;
137 }
138 return (<a
139 className={`${prefixCls}-clear-btn`}
140 role="button"
141 title={this.props.clearText}
142 onMouseDown={this.onClear}
143 />);
144 },
145
146 getProtoValue() {
147 return this.props.value || this.props.defaultOpenValue;
148 },
149
150 getInput() {
151 const { prefixCls, placeholder } = this.props;
152 const { invalid, str } = this.state;
153 const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
154 return (
155 <input
156 className={`${prefixCls}-input ${invalidClass}`}
157 ref="input"
158 onKeyDown={this.onKeyDown}
159 value={str}
160 placeholder={placeholder}
161 onChange={this.onInputChange}
162 />
163 );
164 },
165
166 render() {
167 const { prefixCls } = this.props;
168 return (
169 <div className={`${prefixCls}-input-wrap`}>
170 {this.getInput()}
171 {this.getClearButton()}
172 </div>
173 );
174 },
175});
176
177export default Header;
diff --git a/src/module/Panel.jsx b/src/Panel.jsx
index 4c3d071..0ed60e9 100644
--- a/src/module/Panel.jsx
+++ b/src/Panel.jsx
@@ -1,7 +1,8 @@
1import React, {PropTypes} from 'react'; 1import React, { PropTypes } from 'react';
2import CommonMixin from '../mixin/CommonMixin';
3import Header from './Header'; 2import Header from './Header';
4import Combobox from './Combobox'; 3import Combobox from './Combobox';
4import moment from 'moment';
5import classNames from 'classnames';
5 6
6function noop() { 7function noop() {
7} 8}
@@ -18,12 +19,13 @@ function generateOptions(length, disabledOptions, hideDisabledOptions) {
18 19
19const Panel = React.createClass({ 20const Panel = React.createClass({
20 propTypes: { 21 propTypes: {
22 clearText: PropTypes.string,
21 prefixCls: PropTypes.string, 23 prefixCls: PropTypes.string,
24 className: PropTypes.string,
25 defaultOpenValue: PropTypes.object,
22 value: PropTypes.object, 26 value: PropTypes.object,
23 locale: PropTypes.object,
24 placeholder: PropTypes.string, 27 placeholder: PropTypes.string,
25 gregorianCalendarLocale: PropTypes.object, 28 format: PropTypes.string,
26 formatter: PropTypes.object,
27 disabledHours: PropTypes.func, 29 disabledHours: PropTypes.func,
28 disabledMinutes: PropTypes.func, 30 disabledMinutes: PropTypes.func,
29 disabledSeconds: PropTypes.func, 31 disabledSeconds: PropTypes.func,
@@ -34,14 +36,19 @@ const Panel = React.createClass({
34 showHour: PropTypes.bool, 36 showHour: PropTypes.bool,
35 showSecond: PropTypes.bool, 37 showSecond: PropTypes.bool,
36 onClear: PropTypes.func, 38 onClear: PropTypes.func,
39 addon: PropTypes.func,
37 }, 40 },
38 41
39 mixins: [CommonMixin],
40
41 getDefaultProps() { 42 getDefaultProps() {
42 return { 43 return {
44 prefixCls: 'rc-time-picker-panel',
43 onChange: noop, 45 onChange: noop,
44 onClear: noop, 46 onClear: noop,
47 disabledHours: noop,
48 disabledMinutes: noop,
49 disabledSeconds: noop,
50 defaultOpenValue: moment(),
51 addon: noop,
45 }; 52 };
46 }, 53 },
47 54
@@ -74,26 +81,37 @@ const Panel = React.createClass({
74 this.setState({ currentSelectPanel }); 81 this.setState({ currentSelectPanel });
75 }, 82 },
76 83
84 close() {
85 this.props.onEsc();
86 },
87
77 render() { 88 render() {
78 const { locale, prefixCls, placeholder, disabledHours, disabledMinutes, disabledSeconds, hideDisabledOptions, allowEmpty, showHour, showSecond, formatter, gregorianCalendarLocale } = this.props; 89 const {
79 const value = this.state.value; 90 prefixCls, className, placeholder, disabledHours, disabledMinutes,
91 disabledSeconds, hideDisabledOptions, allowEmpty, showHour, showSecond,
92 format, defaultOpenValue, clearText, onEsc, addon,
93 } = this.props;
94 const {
95 value, currentSelectPanel,
96 } = this.state;
80 const disabledHourOptions = disabledHours(); 97 const disabledHourOptions = disabledHours();
81 const disabledMinuteOptions = disabledMinutes(value ? value.getHourOfDay() : null); 98 const disabledMinuteOptions = disabledMinutes(value ? value.hour() : null);
82 const disabledSecondOptions = disabledSeconds(value ? value.getHourOfDay() : null, value ? value.getMinutes() : null); 99 const disabledSecondOptions = disabledSeconds(value ? value.hour() : null,
100 value ? value.minute() : null);
83 const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions); 101 const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions);
84 const minuteOptions = generateOptions(60, disabledMinuteOptions, hideDisabledOptions); 102 const minuteOptions = generateOptions(60, disabledMinuteOptions, hideDisabledOptions);
85 const secondOptions = generateOptions(60, disabledSecondOptions, hideDisabledOptions); 103 const secondOptions = generateOptions(60, disabledSecondOptions, hideDisabledOptions);
86 104
87 return ( 105 return (
88 <div className={`${prefixCls}-inner`}> 106 <div className={classNames({ [`${prefixCls}-inner`]: true, [className]: !!className })}>
89 <Header 107 <Header
108 clearText={clearText}
90 prefixCls={prefixCls} 109 prefixCls={prefixCls}
91 gregorianCalendarLocale={gregorianCalendarLocale} 110 defaultOpenValue={defaultOpenValue}
92 locale={locale}
93 value={value} 111 value={value}
94 currentSelectPanel={this.state.currentSelectPanel} 112 currentSelectPanel={currentSelectPanel}
95 onEsc={this.props.onEsc} 113 onEsc={onEsc}
96 formatter={formatter} 114 format={format}
97 placeholder={placeholder} 115 placeholder={placeholder}
98 hourOptions={hourOptions} 116 hourOptions={hourOptions}
99 minuteOptions={minuteOptions} 117 minuteOptions={minuteOptions}
@@ -108,8 +126,8 @@ const Panel = React.createClass({
108 <Combobox 126 <Combobox
109 prefixCls={prefixCls} 127 prefixCls={prefixCls}
110 value={value} 128 value={value}
111 gregorianCalendarLocale={gregorianCalendarLocale} 129 defaultOpenValue={defaultOpenValue}
112 formatter={formatter} 130 format={format}
113 onChange={this.onChange} 131 onChange={this.onChange}
114 showHour={showHour} 132 showHour={showHour}
115 showSecond={showSecond} 133 showSecond={showSecond}
@@ -121,6 +139,7 @@ const Panel = React.createClass({
121 disabledSeconds={disabledSeconds} 139 disabledSeconds={disabledSeconds}
122 onCurrentSelectPanelChange={this.onCurrentSelectPanelChange} 140 onCurrentSelectPanelChange={this.onCurrentSelectPanelChange}
123 /> 141 />
142 {addon(this)}
124 </div> 143 </div>
125 ); 144 );
126 }, 145 },
diff --git a/src/module/Select.jsx b/src/Select.jsx
index fa4e5c4..238a776 100644
--- a/src/module/Select.jsx
+++ b/src/Select.jsx
@@ -1,4 +1,4 @@
1import React, {PropTypes} from 'react'; 1import React, { PropTypes } from 'react';
2import ReactDom from 'react-dom'; 2import ReactDom from 'react-dom';
3import classnames from 'classnames'; 3import classnames from 'classnames';
4 4
@@ -26,7 +26,6 @@ const Select = React.createClass({
26 propTypes: { 26 propTypes: {
27 prefixCls: PropTypes.string, 27 prefixCls: PropTypes.string,
28 options: PropTypes.array, 28 options: PropTypes.array,
29 gregorianCalendarLocale: PropTypes.object,
30 selectedIndex: PropTypes.number, 29 selectedIndex: PropTypes.number,
31 type: PropTypes.string, 30 type: PropTypes.string,
32 onSelect: PropTypes.func, 31 onSelect: PropTypes.func,
@@ -61,7 +60,14 @@ const Select = React.createClass({
61 if (!item.disabled) { 60 if (!item.disabled) {
62 onclick = this.onSelect.bind(this, +item.value); 61 onclick = this.onSelect.bind(this, +item.value);
63 } 62 }
64 return <li className={cls} key={index} onClick={onclick} disabled={item.disabled}>{item.value}</li>; 63 return (<li
64 className={cls}
65 key={index}
66 onClick={onclick}
67 disabled={item.disabled}
68 >
69 {item.value}
70 </li>);
65 }); 71 });
66 }, 72 },
67 73
@@ -89,8 +95,10 @@ const Select = React.createClass({
89 const { prefixCls } = this.props; 95 const { prefixCls } = this.props;
90 96
91 return ( 97 return (
92 <div className={`${prefixCls}-select`} 98 <div
93 onMouseEnter={this.props.onMouseEnter}> 99 className={`${prefixCls}-select`}
100 onMouseEnter={this.props.onMouseEnter}
101 >
94 <ul ref="list">{this.getOptions()}</ul> 102 <ul ref="list">{this.getOptions()}</ul>
95 </div> 103 </div>
96 ); 104 );
diff --git a/src/TimePicker.jsx b/src/TimePicker.jsx
index 350eeb2..358b596 100644
--- a/src/TimePicker.jsx
+++ b/src/TimePicker.jsx
@@ -1,9 +1,8 @@
1import React, { PropTypes } from 'react'; 1import React, { PropTypes } from 'react';
2import Trigger from 'rc-trigger'; 2import Trigger from 'rc-trigger';
3import Panel from './module/Panel'; 3import Panel from './Panel';
4import placements from './util/placements'; 4import placements from './placements';
5import CommonMixin from './mixin/CommonMixin'; 5import moment from 'moment';
6import { getFormatter } from './util/index';
7 6
8function noop() { 7function noop() {
9} 8}
@@ -15,8 +14,9 @@ function refFn(field, component) {
15const Picker = React.createClass({ 14const Picker = React.createClass({
16 propTypes: { 15 propTypes: {
17 prefixCls: PropTypes.string, 16 prefixCls: PropTypes.string,
18 locale: PropTypes.object, 17 clearText: PropTypes.string,
19 value: PropTypes.object, 18 value: PropTypes.object,
19 defaultOpenValue: PropTypes.object,
20 disabled: PropTypes.bool, 20 disabled: PropTypes.bool,
21 allowEmpty: PropTypes.bool, 21 allowEmpty: PropTypes.bool,
22 defaultValue: PropTypes.object, 22 defaultValue: PropTypes.object,
@@ -27,7 +27,7 @@ const Picker = React.createClass({
27 transitionName: PropTypes.string, 27 transitionName: PropTypes.string,
28 getPopupContainer: PropTypes.func, 28 getPopupContainer: PropTypes.func,
29 placeholder: PropTypes.string, 29 placeholder: PropTypes.string,
30 formatter: PropTypes.any, 30 format: PropTypes.string,
31 showHour: PropTypes.bool, 31 showHour: PropTypes.bool,
32 style: PropTypes.object, 32 style: PropTypes.object,
33 className: PropTypes.string, 33 className: PropTypes.string,
@@ -39,16 +39,18 @@ const Picker = React.createClass({
39 onChange: PropTypes.func, 39 onChange: PropTypes.func,
40 onOpen: PropTypes.func, 40 onOpen: PropTypes.func,
41 onClose: PropTypes.func, 41 onClose: PropTypes.func,
42 addon: PropTypes.func,
42 }, 43 },
43 44
44 mixins: [CommonMixin],
45
46 getDefaultProps() { 45 getDefaultProps() {
47 return { 46 return {
47 clearText: 'clear',
48 prefixCls: 'rc-time-picker',
48 defaultOpen: false, 49 defaultOpen: false,
49 style: {}, 50 style: {},
50 className: '', 51 className: '',
51 align: {}, 52 align: {},
53 defaultOpenValue: moment(),
52 allowEmpty: true, 54 allowEmpty: true,
53 showHour: true, 55 showHour: true,
54 showSecond: true, 56 showSecond: true,
@@ -60,6 +62,7 @@ const Picker = React.createClass({
60 onChange: noop, 62 onChange: noop,
61 onOpen: noop, 63 onOpen: noop,
62 onClose: noop, 64 onClose: noop,
65 addon: noop,
63 }; 66 };
64 }, 67 },
65 68
@@ -117,61 +120,47 @@ const Picker = React.createClass({
117 this.props.onChange(value); 120 this.props.onChange(value);
118 }, 121 },
119 122
120 getFormatter() { 123 getFormat() {
121 const formatter = this.props.formatter; 124 const format = this.props.format;
122 const locale = this.props.locale; 125 if (format) {
123 if (formatter) { 126 return format;
124 if (formatter === this.lastFormatter) {
125 return this.normalFormatter;
126 }
127 this.normalFormatter = getFormatter(formatter, locale);
128 this.lastFormatter = formatter;
129 return this.normalFormatter;
130 } 127 }
131 if (!this.props.showSecond) { 128 if (!this.props.showSecond) {
132 if (!this.notShowSecondFormatter) { 129 return 'HH:mm';
133 this.notShowSecondFormatter = getFormatter('HH:mm', locale);
134 }
135 return this.notShowSecondFormatter;
136 } 130 }
137 if (!this.props.showHour) { 131 if (!this.props.showHour) {
138 if (!this.notShowHourFormatter) { 132 return 'mm:ss';
139 this.notShowHourFormatter = getFormatter('mm:ss', locale);
140 }
141 return this.notShowHourFormatter;
142 } 133 }
143 if (!this.normalFormatter) { 134 return 'HH:mm:ss';
144 this.normalFormatter = getFormatter('HH:mm:ss', locale);
145 }
146 return this.normalFormatter;
147 }, 135 },
148 136
149 getPanelElement() { 137 getPanelElement() {
150 const { 138 const {
151 prefixCls, defaultValue, locale, placeholder, disabledHours, 139 prefixCls, placeholder, disabledHours,
152 disabledMinutes, disabledSeconds, hideDisabledOptions, 140 disabledMinutes, disabledSeconds, hideDisabledOptions,
153 allowEmpty, showHour, showSecond, 141 allowEmpty, showHour, showSecond, defaultOpenValue, clearText,
142 addon,
154 } = this.props; 143 } = this.props;
155 return ( 144 return (
156 <Panel 145 <Panel
146 clearText={clearText}
157 prefixCls={`${prefixCls}-panel`} 147 prefixCls={`${prefixCls}-panel`}
158 ref={this.savePanelRef} 148 ref={this.savePanelRef}
159 value={this.state.value} 149 value={this.state.value}
160 onChange={this.onPanelChange} 150 onChange={this.onPanelChange}
161 gregorianCalendarLocale={locale.calendar}
162 onClear={this.onPanelClear} 151 onClear={this.onPanelClear}
163 defaultValue={defaultValue} 152 defaultOpenValue={defaultOpenValue}
164 showHour={showHour} 153 showHour={showHour}
165 onEsc={this.onEsc} 154 onEsc={this.onEsc}
166 showSecond={showSecond} 155 showSecond={showSecond}
167 locale={locale}
168 allowEmpty={allowEmpty} 156 allowEmpty={allowEmpty}
169 formatter={this.getFormatter()} 157 format={this.getFormat()}
170 placeholder={placeholder} 158 placeholder={placeholder}
171 disabledHours={disabledHours} 159 disabledHours={disabledHours}
172 disabledMinutes={disabledMinutes} 160 disabledMinutes={disabledMinutes}
173 disabledSeconds={disabledSeconds} 161 disabledSeconds={disabledSeconds}
174 hideDisabledOptions={hideDisabledOptions} 162 hideDisabledOptions={hideDisabledOptions}
163 addon={addon}
175 /> 164 />
176 ); 165 );
177 }, 166 },
@@ -194,7 +183,11 @@ const Picker = React.createClass({
194 }, 183 },
195 184
196 render() { 185 render() {
197 const { prefixCls, placeholder, placement, align, disabled, transitionName, style, className, showHour, showSecond, getPopupContainer } = this.props; 186 const {
187 prefixCls, placeholder, placement, align,
188 disabled, transitionName, style, className, showHour,
189 showSecond, getPopupContainer,
190 } = this.props;
198 const { open, value } = this.state; 191 const { open, value } = this.state;
199 let popupClassName; 192 let popupClassName;
200 if (!showHour || !showSecond) { 193 if (!showHour || !showSecond) {
@@ -221,7 +214,7 @@ const Picker = React.createClass({
221 ref="picker" type="text" placeholder={placeholder} 214 ref="picker" type="text" placeholder={placeholder}
222 readOnly 215 readOnly
223 onKeyDown={this.onKeyDown} 216 onKeyDown={this.onKeyDown}
224 disabled={disabled} value={value && this.getFormatter().format(value) || ''} 217 disabled={disabled} value={value && value.format(this.getFormat()) || ''}
225 /> 218 />
226 <span className={`${prefixCls}-icon`}/> 219 <span className={`${prefixCls}-icon`}/>
227 </span> 220 </span>
diff --git a/src/locale/en_US.js b/src/locale/en_US.js
deleted file mode 100644
index 506f4c9..0000000
--- a/src/locale/en_US.js
+++ /dev/null
@@ -1,8 +0,0 @@
1import enUs from 'gregorian-calendar-format/lib/locale/en_US';
2import enUsCalendar from 'gregorian-calendar/lib/locale/en_US';
3
4export default {
5 clear: 'Clear',
6 format: enUs,
7 calendar: enUsCalendar,
8};
diff --git a/src/locale/ru_RU.js b/src/locale/ru_RU.js
deleted file mode 100644
index 86746ea..0000000
--- a/src/locale/ru_RU.js
+++ /dev/null
@@ -1,8 +0,0 @@
1import ruRu from 'gregorian-calendar-format/lib/locale/ru_RU';
2import ruRuCalendar from 'gregorian-calendar/lib/locale/ru_RU';
3
4export default {
5 clear: 'Очистить',
6 format: ruRu,
7 calendar: ruRuCalendar,
8};
diff --git a/src/locale/zh_CN.js b/src/locale/zh_CN.js
deleted file mode 100644
index 1e977be..0000000
--- a/src/locale/zh_CN.js
+++ /dev/null
@@ -1,8 +0,0 @@
1import zhCn from 'gregorian-calendar-format/lib/locale/zh_CN';
2import zhCnCalendar from 'gregorian-calendar/lib/locale/zh_CN';
3
4export default {
5 clear: '清除',
6 format: zhCn,
7 calendar: zhCnCalendar,
8};
diff --git a/src/mixin/CommonMixin.js b/src/mixin/CommonMixin.js
deleted file mode 100644
index a6893b8..0000000
--- a/src/mixin/CommonMixin.js
+++ /dev/null
@@ -1,16 +0,0 @@
1import {PropTypes} from 'react';
2import enUs from '../locale/en_US';
3
4export default {
5 propTypes: {
6 prefixCls: PropTypes.string,
7 locale: PropTypes.object,
8 },
9
10 getDefaultProps() {
11 return {
12 prefixCls: 'rc-time-picker',
13 locale: enUs,
14 };
15 },
16};
diff --git a/src/module/Header.jsx b/src/module/Header.jsx
deleted file mode 100644
index a926e98..0000000
--- a/src/module/Header.jsx
+++ /dev/null
@@ -1,204 +0,0 @@
1import React, { PropTypes } from 'react';
2import createSelection from '../util/selection';
3
4const Header = React.createClass({
5 propTypes: {
6 formatter: PropTypes.object,
7 prefixCls: PropTypes.string,
8 gregorianCalendarLocale: PropTypes.object,
9 locale: PropTypes.object,
10 disabledDate: PropTypes.func,
11 placeholder: 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 currentSelectPanel: PropTypes.string,
24 },
25
26 getInitialState() {
27 const value = this.props.value;
28 return {
29 str: value && this.props.formatter.format(value) || '',
30 invalid: false,
31 };
32 },
33
34 componentDidMount() {
35 this.timer = setTimeout(this.selectRange, 0);
36 },
37
38 componentWillReceiveProps(nextProps) {
39 const value = nextProps.value;
40 this.setState({
41 str: value && nextProps.formatter.format(value) || '',
42 invalid: false,
43 });
44 },
45
46 componentDidUpdate() {
47 this.timer = setTimeout(this.selectRange, 0);
48 },
49
50 componentWillUnmount() {
51 clearTimeout(this.timer);
52 },
53
54 onInputChange(event) {
55 const str = event.target.value;
56 this.setState({
57 str,
58 });
59 let value = null;
60 const { formatter, gregorianCalendarLocale, hourOptions, minuteOptions, secondOptions, disabledHours, disabledMinutes, disabledSeconds, onChange, allowEmpty } = this.props;
61
62 if (str) {
63 const originalValue = this.props.value;
64 try {
65 value = formatter.parse(str, {
66 locale: gregorianCalendarLocale,
67 obeyCount: true,
68 });
69 } catch (ex) {
70 this.setState({
71 invalid: true,
72 });
73 return;
74 }
75
76 if (value) {
77 // if time value not allowed, response warning.
78 if (
79 hourOptions.indexOf(value.getHourOfDay()) < 0 ||
80 minuteOptions.indexOf(value.getMinutes()) < 0 ||
81 secondOptions.indexOf(value.getSeconds()) < 0
82 ) {
83 this.setState({
84 invalid: true,
85 });
86 return;
87 }
88
89 // if time value is disabled, response warning.
90 const disabledHourOptions = disabledHours();
91 const disabledMinuteOptions = disabledMinutes(value.getHourOfDay());
92 const disabledSecondOptions = disabledSeconds(value.getHourOfDay(), value.getMinutes());
93 if (
94 (disabledHourOptions && disabledHourOptions.indexOf(value.getHourOfDay()) >= 0) ||
95 (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.getMinutes()) >= 0) ||
96 (disabledSecondOptions && disabledSecondOptions.indexOf(value.getSeconds()) >= 0)
97 ) {
98 this.setState({
99 invalid: true,
100 });
101 return;
102 }
103
104 if (originalValue && value) {
105 if (
106 originalValue.getHourOfDay() !== value.getHourOfDay() ||
107 originalValue.getMinutes() !== value.getMinutes() ||
108 originalValue.getSeconds() !== value.getSeconds()
109 ) {
110 // keep other fields for rc-calendar
111 const changedValue = originalValue.clone();
112 changedValue.setHourOfDay(value.getHourOfDay());
113 changedValue.setMinutes(value.getMinutes());
114 changedValue.setSeconds(value.getSeconds());
115 onChange(changedValue);
116 }
117 } else if (originalValue !== value) {
118 onChange(value);
119 }
120 } else {
121 this.setState({
122 invalid: true,
123 });
124 return;
125 }
126 } else if (allowEmpty) {
127 onChange(null);
128 } else {
129 this.setState({
130 invalid: true,
131 });
132 return;
133 }
134
135 this.setState({
136 invalid: false,
137 });
138 },
139
140 onKeyDown(e) {
141 if (e.keyCode === 27) {
142 this.props.onEsc();
143 }
144 },
145
146 onClear() {
147 this.setState({ str: '' });
148 this.props.onClear();
149 },
150
151 getClearButton() {
152 const { locale, prefixCls, allowEmpty } = this.props;
153 if (!allowEmpty) {
154 return null;
155 }
156 return <a className={`${prefixCls}-clear-btn`} role="button" title={locale.clear} onMouseDown={this.onClear}/>;
157 },
158
159 getInput() {
160 const { prefixCls, placeholder } = this.props;
161 const { invalid, str } = this.state;
162 const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
163 return (<input
164 className={`${prefixCls}-input ${invalidClass}`}
165 ref="input"
166 onKeyDown={this.onKeyDown}
167 value={str}
168 placeholder={placeholder} onChange={this.onInputChange}
169 />);
170 },
171
172 selectRange() {
173 this.refs.input.select();
174 if (this.props.currentSelectPanel && this.refs.input.value) {
175 let selectionRangeStart = 0;
176 let selectionRangeEnd = 0;
177 if (this.props.currentSelectPanel === 'hour') {
178 selectionRangeStart = 0;
179 selectionRangeEnd = this.refs.input.value.indexOf(':');
180 } else if (this.props.currentSelectPanel === 'minute') {
181 selectionRangeStart = this.refs.input.value.indexOf(':') + 1;
182 selectionRangeEnd = this.refs.input.value.lastIndexOf(':');
183 } else if (this.props.currentSelectPanel === 'second') {
184 selectionRangeStart = this.refs.input.value.lastIndexOf(':') + 1;
185 selectionRangeEnd = this.refs.input.value.length;
186 }
187 if (selectionRangeEnd - selectionRangeStart === 2) {
188 createSelection(this.refs.input, selectionRangeStart, selectionRangeEnd);
189 }
190 }
191 },
192
193 render() {
194 const { prefixCls } = this.props;
195 return (
196 <div className={`${prefixCls}-input-wrap`}>
197 {this.getInput()}
198 {this.getClearButton()}
199 </div>
200 );
201 },
202});
203
204export default Header;
diff --git a/src/util/placements.js b/src/placements.js
index 6760286..6760286 100644
--- a/src/util/placements.js
+++ b/src/placements.js
diff --git a/src/util/index.js b/src/util/index.js
deleted file mode 100644
index 5bc0a78..0000000
--- a/src/util/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
1import DateTimeFormat from 'gregorian-calendar-format';
2
3export function getFormatter(format, locale) {
4 if (typeof format === 'string') {
5 return new DateTimeFormat(format, locale.format);
6 }
7 return format;
8}
diff --git a/src/util/selection.js b/src/util/selection.js
deleted file mode 100644
index 395901e..0000000
--- a/src/util/selection.js
+++ /dev/null
@@ -1,17 +0,0 @@
1export default function createSelection(field, start, end) {
2 if (field.createTextRange) {
3 const selRange = field.createTextRange();
4 selRange.collapse(true);
5 selRange.moveStart('character', start);
6 selRange.moveEnd('character', end);
7 selRange.select();
8 field.focus();
9 } else if (field.setSelectionRange) {
10 field.focus();
11 field.setSelectionRange(start, end);
12 } else if (typeof field.selectionStart !== 'undefined') {
13 field.selectionStart = start;
14 field.selectionEnd = end;
15 field.focus();
16 }
17}