aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authoryiminghe <yiminghe@gmail.com>2016-08-04 19:53:55 +0800
committeryiminghe <yiminghe@gmail.com>2016-08-04 19:53:55 +0800
commit4984ed85e54f442998a335db70618d6184fa397e (patch)
tree6ae348b2cac5f48f3afb6f7b8dd0c2fd02f044fc /src
parentdeaa6062ea2e274d50d58c70251c1237c0c03c67 (diff)
downloadtime-picker-4984ed85e54f442998a335db70618d6184fa397e.tar.gz
time-picker-4984ed85e54f442998a335db70618d6184fa397e.tar.zst
time-picker-4984ed85e54f442998a335db70618d6184fa397e.zip
2.x :boom:2.0.0
Diffstat (limited to 'src')
-rw-r--r--src/Combobox.jsx (renamed from src/module/Combobox.jsx)54
-rw-r--r--src/Header.jsx175
-rw-r--r--src/Panel.jsx (renamed from src/module/Panel.jsx)42
-rw-r--r--src/Select.jsx (renamed from src/module/Select.jsx)18
-rw-r--r--src/TimePicker.jsx64
-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.js15
-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, 257 insertions, 364 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..4196ea9
--- /dev/null
+++ b/src/Header.jsx
@@ -0,0 +1,175 @@
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 (<input
155 className={`${prefixCls}-input ${invalidClass}`}
156 ref="input"
157 onKeyDown={this.onKeyDown}
158 value={str}
159 placeholder={placeholder}
160 onChange={this.onInputChange}
161 />);
162 },
163
164 render() {
165 const { prefixCls } = this.props;
166 return (
167 <div className={`${prefixCls}-input-wrap`}>
168 {this.getInput()}
169 {this.getClearButton()}
170 </div>
171 );
172 },
173});
174
175export default Header;
diff --git a/src/module/Panel.jsx b/src/Panel.jsx
index 137ec2f..f70cf38 100644
--- a/src/module/Panel.jsx
+++ b/src/Panel.jsx
@@ -1,7 +1,7 @@
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';
5 5
6function noop() { 6function noop() {
7} 7}
@@ -18,12 +18,12 @@ function generateOptions(length, disabledOptions, hideDisabledOptions) {
18 18
19const Panel = React.createClass({ 19const Panel = React.createClass({
20 propTypes: { 20 propTypes: {
21 clearText: PropTypes.string,
21 prefixCls: PropTypes.string, 22 prefixCls: PropTypes.string,
23 defaultOpenValue: PropTypes.object,
22 value: PropTypes.object, 24 value: PropTypes.object,
23 locale: PropTypes.object,
24 placeholder: PropTypes.string, 25 placeholder: PropTypes.string,
25 gregorianCalendarLocale: PropTypes.object, 26 format: PropTypes.string,
26 formatter: PropTypes.object,
27 disabledHours: PropTypes.func, 27 disabledHours: PropTypes.func,
28 disabledMinutes: PropTypes.func, 28 disabledMinutes: PropTypes.func,
29 disabledSeconds: PropTypes.func, 29 disabledSeconds: PropTypes.func,
@@ -36,13 +36,12 @@ const Panel = React.createClass({
36 onClear: PropTypes.func, 36 onClear: PropTypes.func,
37 }, 37 },
38 38
39 mixins: [CommonMixin],
40
41 getDefaultProps() { 39 getDefaultProps() {
42 return { 40 return {
43 prefixCls: 'rc-time-picker-panel', 41 prefixCls: 'rc-time-picker-panel',
44 onChange: noop, 42 onChange: noop,
45 onClear: noop, 43 onClear: noop,
44 defaultOpenValue: moment(),
46 }; 45 };
47 }, 46 },
48 47
@@ -76,11 +75,18 @@ const Panel = React.createClass({
76 }, 75 },
77 76
78 render() { 77 render() {
79 const { locale, prefixCls, placeholder, disabledHours, disabledMinutes, disabledSeconds, hideDisabledOptions, allowEmpty, showHour, showSecond, formatter, gregorianCalendarLocale } = this.props; 78 const {
80 const value = this.state.value; 79 prefixCls, placeholder, disabledHours, disabledMinutes,
80 disabledSeconds, hideDisabledOptions, allowEmpty, showHour, showSecond,
81 format, defaultOpenValue, clearText, onEsc,
82 } = this.props;
83 const {
84 value, currentSelectPanel,
85 } = this.state;
81 const disabledHourOptions = disabledHours(); 86 const disabledHourOptions = disabledHours();
82 const disabledMinuteOptions = disabledMinutes(value ? value.getHourOfDay() : null); 87 const disabledMinuteOptions = disabledMinutes(value ? value.hour() : null);
83 const disabledSecondOptions = disabledSeconds(value ? value.getHourOfDay() : null, value ? value.getMinutes() : null); 88 const disabledSecondOptions = disabledSeconds(value ? value.hour() : null,
89 value ? value.minute() : null);
84 const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions); 90 const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions);
85 const minuteOptions = generateOptions(60, disabledMinuteOptions, hideDisabledOptions); 91 const minuteOptions = generateOptions(60, disabledMinuteOptions, hideDisabledOptions);
86 const secondOptions = generateOptions(60, disabledSecondOptions, hideDisabledOptions); 92 const secondOptions = generateOptions(60, disabledSecondOptions, hideDisabledOptions);
@@ -88,13 +94,13 @@ const Panel = React.createClass({
88 return ( 94 return (
89 <div className={`${prefixCls}-inner`}> 95 <div className={`${prefixCls}-inner`}>
90 <Header 96 <Header
97 clearText={clearText}
91 prefixCls={prefixCls} 98 prefixCls={prefixCls}
92 gregorianCalendarLocale={gregorianCalendarLocale} 99 defaultOpenValue={defaultOpenValue}
93 locale={locale}
94 value={value} 100 value={value}
95 currentSelectPanel={this.state.currentSelectPanel} 101 currentSelectPanel={currentSelectPanel}
96 onEsc={this.props.onEsc} 102 onEsc={onEsc}
97 formatter={formatter} 103 format={format}
98 placeholder={placeholder} 104 placeholder={placeholder}
99 hourOptions={hourOptions} 105 hourOptions={hourOptions}
100 minuteOptions={minuteOptions} 106 minuteOptions={minuteOptions}
@@ -109,8 +115,8 @@ const Panel = React.createClass({
109 <Combobox 115 <Combobox
110 prefixCls={prefixCls} 116 prefixCls={prefixCls}
111 value={value} 117 value={value}
112 gregorianCalendarLocale={gregorianCalendarLocale} 118 defaultOpenValue={defaultOpenValue}
113 formatter={formatter} 119 format={format}
114 onChange={this.onChange} 120 onChange={this.onChange}
115 showHour={showHour} 121 showHour={showHour}
116 showSecond={showSecond} 122 showSecond={showSecond}
diff --git a/src/module/Select.jsx b/src/Select.jsx
index 2ab9e61..e25bb29 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
@@ -86,8 +92,10 @@ const Select = React.createClass({
86 const { prefixCls } = this.props; 92 const { prefixCls } = this.props;
87 93
88 return ( 94 return (
89 <div className={`${prefixCls}-select`} 95 <div
90 onMouseEnter={this.props.onMouseEnter}> 96 className={`${prefixCls}-select`}
97 onMouseEnter={this.props.onMouseEnter}
98 >
91 <ul ref="list">{this.getOptions()}</ul> 99 <ul ref="list">{this.getOptions()}</ul>
92 </div> 100 </div>
93 ); 101 );
diff --git a/src/TimePicker.jsx b/src/TimePicker.jsx
index 86faa71..58f6ea1 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,
@@ -41,15 +41,15 @@ const Picker = React.createClass({
41 onClose: PropTypes.func, 41 onClose: PropTypes.func,
42 }, 42 },
43 43
44 mixins: [CommonMixin],
45
46 getDefaultProps() { 44 getDefaultProps() {
47 return { 45 return {
46 clearText: 'clear',
48 prefixCls: 'rc-time-picker', 47 prefixCls: 'rc-time-picker',
49 defaultOpen: false, 48 defaultOpen: false,
50 style: {}, 49 style: {},
51 className: '', 50 className: '',
52 align: {}, 51 align: {},
52 defaultOpenValue: moment(),
53 allowEmpty: true, 53 allowEmpty: true,
54 showHour: true, 54 showHour: true,
55 showSecond: true, 55 showSecond: true,
@@ -118,56 +118,40 @@ const Picker = React.createClass({
118 this.props.onChange(value); 118 this.props.onChange(value);
119 }, 119 },
120 120
121 getFormatter() { 121 getFormat() {
122 const formatter = this.props.formatter; 122 const format = this.props.format;
123 const locale = this.props.locale; 123 if (format) {
124 if (formatter) { 124 return format;
125 if (formatter === this.lastFormatter) {
126 return this.normalFormatter;
127 }
128 this.normalFormatter = getFormatter(formatter, locale);
129 this.lastFormatter = formatter;
130 return this.normalFormatter;
131 } 125 }
132 if (!this.props.showSecond) { 126 if (!this.props.showSecond) {
133 if (!this.notShowSecondFormatter) { 127 return 'HH:mm';
134 this.notShowSecondFormatter = getFormatter('HH:mm', locale);
135 }
136 return this.notShowSecondFormatter;
137 } 128 }
138 if (!this.props.showHour) { 129 if (!this.props.showHour) {
139 if (!this.notShowHourFormatter) { 130 return 'mm:ss';
140 this.notShowHourFormatter = getFormatter('mm:ss', locale);
141 }
142 return this.notShowHourFormatter;
143 } 131 }
144 if (!this.normalFormatter) { 132 return 'HH:mm:ss';
145 this.normalFormatter = getFormatter('HH:mm:ss', locale);
146 }
147 return this.normalFormatter;
148 }, 133 },
149 134
150 getPanelElement() { 135 getPanelElement() {
151 const { 136 const {
152 prefixCls, defaultValue, locale, placeholder, disabledHours, 137 prefixCls, placeholder, disabledHours,
153 disabledMinutes, disabledSeconds, hideDisabledOptions, 138 disabledMinutes, disabledSeconds, hideDisabledOptions,
154 allowEmpty, showHour, showSecond, 139 allowEmpty, showHour, showSecond, defaultOpenValue, clearText,
155 } = this.props; 140 } = this.props;
156 return ( 141 return (
157 <Panel 142 <Panel
143 clearText={clearText}
158 prefixCls={`${prefixCls}-panel`} 144 prefixCls={`${prefixCls}-panel`}
159 ref={this.savePanelRef} 145 ref={this.savePanelRef}
160 value={this.state.value} 146 value={this.state.value}
161 onChange={this.onPanelChange} 147 onChange={this.onPanelChange}
162 gregorianCalendarLocale={locale.calendar}
163 onClear={this.onPanelClear} 148 onClear={this.onPanelClear}
164 defaultValue={defaultValue} 149 defaultOpenValue={defaultOpenValue}
165 showHour={showHour} 150 showHour={showHour}
166 onEsc={this.onEsc} 151 onEsc={this.onEsc}
167 showSecond={showSecond} 152 showSecond={showSecond}
168 locale={locale}
169 allowEmpty={allowEmpty} 153 allowEmpty={allowEmpty}
170 formatter={this.getFormatter()} 154 format={this.getFormat()}
171 placeholder={placeholder} 155 placeholder={placeholder}
172 disabledHours={disabledHours} 156 disabledHours={disabledHours}
173 disabledMinutes={disabledMinutes} 157 disabledMinutes={disabledMinutes}
@@ -195,7 +179,11 @@ const Picker = React.createClass({
195 }, 179 },
196 180
197 render() { 181 render() {
198 const { prefixCls, placeholder, placement, align, disabled, transitionName, style, className, showHour, showSecond, getPopupContainer } = this.props; 182 const {
183 prefixCls, placeholder, placement, align,
184 disabled, transitionName, style, className, showHour,
185 showSecond, getPopupContainer,
186 } = this.props;
199 const { open, value } = this.state; 187 const { open, value } = this.state;
200 let popupClassName; 188 let popupClassName;
201 if (!showHour || !showSecond) { 189 if (!showHour || !showSecond) {
@@ -222,7 +210,7 @@ const Picker = React.createClass({
222 ref="picker" type="text" placeholder={placeholder} 210 ref="picker" type="text" placeholder={placeholder}
223 readOnly 211 readOnly
224 onKeyDown={this.onKeyDown} 212 onKeyDown={this.onKeyDown}
225 disabled={disabled} value={value && this.getFormatter().format(value) || ''} 213 disabled={disabled} value={value && value.format(this.getFormat()) || ''}
226 /> 214 />
227 <span className={`${prefixCls}-icon`}/> 215 <span className={`${prefixCls}-icon`}/>
228 </span> 216 </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 be080fd..0000000
--- a/src/mixin/CommonMixin.js
+++ /dev/null
@@ -1,15 +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 locale: enUs,
13 };
14 },
15};
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}