aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml10
-rw-r--r--HISTORY.md10
-rw-r--r--README.md27
-rw-r--r--examples/disabled.js28
-rw-r--r--examples/hidden.js30
-rw-r--r--examples/pick-time.js23
-rw-r--r--examples/value-and-defaultValue.js27
-rw-r--r--package.json26
-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
-rw-r--r--tests/Header.spec.jsx208
-rw-r--r--tests/Select.spec.jsx140
-rw-r--r--tests/TimePicker.spec.jsx65
-rw-r--r--tests/index.js (renamed from tests/index.spec.js)1
-rw-r--r--tests/runner.html1
27 files changed, 586 insertions, 656 deletions
diff --git a/.gitignore b/.gitignore
index 037d70d..3de050d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,4 +24,4 @@ dist
24*.css 24*.css
25build 25build
26lib 26lib
27 27coverage \ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 15c7ce7..e780b32 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,7 @@
1language: node_js 1language: node_js
2 2
3sudo: false
4
3notifications: 5notifications:
4 email: 6 email:
5 - yiminghe@gmail.com 7 - yiminghe@gmail.com
@@ -14,9 +16,8 @@ before_install:
14 echo "Only docs were updated, stopping build process." 16 echo "Only docs were updated, stopping build process."
15 exit 17 exit
16 fi 18 fi
17 npm install mocha-phantomjs -g 19 npm install npm@3.x -g
18 phantomjs --version 20 phantomjs --version
19
20script: 21script:
21- | 22- |
22 if [ "$TEST_TYPE" = test ]; then 23 if [ "$TEST_TYPE" = test ]; then
@@ -24,9 +25,8 @@ script:
24 else 25 else
25 npm run $TEST_TYPE 26 npm run $TEST_TYPE
26 fi 27 fi
27
28env: 28env:
29 matrix: 29 matrix:
30 - TEST_TYPE=lint 30 - TEST_TYPE=lint
31 - TEST_TYPE=browser-test 31 - TEST_TYPE=test
32 - TEST_TYPE=browser-test-cover 32 - TEST_TYPE=coverage
diff --git a/HISTORY.md b/HISTORY.md
index 00609e5..214f3bb 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -2,6 +2,16 @@
2 2
3--- 3---
4 4
52.1.0 / 2016-10-25
6---------------------------
7
8support addon prop
9
102.0.0 / 2016-08-04
11---------------------------
12
13goodbye gregorian-calendar, hello moment
14
51.1.0 / 2016-01-14 151.1.0 / 2016-01-14
6--------------------------- 16---------------------------
7 17
diff --git a/README.md b/README.md
index 483ee2b..5ec960c 100644
--- a/README.md
+++ b/README.md
@@ -51,23 +51,42 @@ API
51| Name | Type | Default | Description | 51| Name | Type | Default | Description |
52|-------------------------|-----------------------------------|-----------------------------------------------|--------------------------------------------------------------------------------------------| 52|-------------------------|-----------------------------------|-----------------------------------------------|--------------------------------------------------------------------------------------------|
53| prefixCls | String | | prefixCls of this component | 53| prefixCls | String | | prefixCls of this component |
54| locale | Object | import from 'rc-time-picker/lib/locale/en_US' | | 54| clearText | String | 'clear' | |
55| disabled | Boolean | false | whether picker is disabled | 55| disabled | Boolean | false | whether picker is disabled |
56| clearText | String | clear | clear text |
56| open | Boolean | false | current open state of picker. controlled prop | 57| open | Boolean | false | current open state of picker. controlled prop |
57| defaultValue | GregorianCalendar | null | default initial value | 58| defaultValue | moment | null | default initial value |
58| value | GregorianCalendar | null | current value | 59| defaultOpenValue | moment | moment() | default open panel value, used to set utcOffset,locale if value/defaultValue absent |
60| value | moment | null | current value |
59| placeholder | String | '' | time input's placeholder | 61| placeholder | String | '' | time input's placeholder |
60| showHour | Boolean | whether show hour | | 62| showHour | Boolean | whether show hour | |
61| showSecond | Boolean | whether show second | | 63| showSecond | Boolean | whether show second | |
62| formatter | String|GregorianCalendarFormatter | | | 64| format | String | | |
63| disabledHours | Function | disabled hour options | | 65| disabledHours | Function | disabled hour options | |
64| disabledMinutes | Function | disabled minute options | | 66| disabledMinutes | Function | disabled minute options | |
65| disabledSeconds | Function | disabled second options | | 67| disabledSeconds | Function | disabled second options | |
66| hideDisabledOptions | Boolean | whether hide disabled options | | 68| hideDisabledOptions | Boolean | whether hide disabled options | |
67| onChange | Function | null | called when select a different value | 69| onChange | Function | null | called when select a different value |
70| addon | Function | nothing | called from timepicker panel to render some addon to its bottom, like an OK button. Receives panel instance as parameter, to be able to close it like `panel.close()`.|
68| placement | String | bottomLeft | one of ['left','right','top','bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'] | 71| placement | String | bottomLeft | one of ['left','right','top','bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'] |
69| transitionName | String | '' | | 72| transitionName | String | '' | |
70 73
74
75## Test Case
76
77```
78npm test
79npm run chrome-test
80```
81
82## Coverage
83
84```
85npm run coverage
86```
87
88open coverage/ dir
89
71License 90License
72------- 91-------
73 92
diff --git a/examples/disabled.js b/examples/disabled.js
index b650448..9d74002 100644
--- a/examples/disabled.js
+++ b/examples/disabled.js
@@ -5,19 +5,14 @@ import 'rc-time-picker/assets/index.less';
5import React from 'react'; 5import React from 'react';
6import ReactDom from 'react-dom'; 6import ReactDom from 'react-dom';
7 7
8import GregorianCalendar from 'gregorian-calendar'; 8import moment from 'moment';
9import DateTimeFormat from 'gregorian-calendar-format';
10 9
11import TimePicker from 'rc-time-picker'; 10import TimePicker from 'rc-time-picker';
12import TimePickerLocale from 'rc-time-picker/src/locale/zh_CN';
13 11
14const showSecond = true; 12const showSecond = true;
15const str = showSecond ? 'HH:mm:ss' : 'HH:mm'; 13const str = showSecond ? 'HH:mm:ss' : 'HH:mm';
16 14
17const formatter = new DateTimeFormat(str); 15const now = moment().hour(14).minute(30);
18
19const now = new GregorianCalendar(TimePickerLocale.calendar);
20now.setTime(Date.now());
21 16
22function generateOptions(length, excludedOptions) { 17function generateOptions(length, excludedOptions) {
23 const arr = []; 18 const arr = [];
@@ -30,7 +25,7 @@ function generateOptions(length, excludedOptions) {
30} 25}
31 26
32function onChange(value) { 27function onChange(value) {
33 console.log(value && formatter.format(value)); 28 console.log(value && value.format(str));
34} 29}
35 30
36function disabledHours() { 31function disabledHours() {
@@ -53,13 +48,14 @@ function disabledSeconds(h, m) {
53} 48}
54 49
55ReactDom.render( 50ReactDom.render(
56 <TimePicker formatter={formatter} locale={TimePickerLocale} 51 <TimePicker
57 showSecond={showSecond} 52 showSecond={showSecond}
58 defaultValue={now} 53 defaultValue={now}
59 className="xxx" 54 className="xxx"
60 onChange={onChange} 55 onChange={onChange}
61 disabledHours={disabledHours} 56 disabledHours={disabledHours}
62 disabledMinutes={disabledMinutes} 57 disabledMinutes={disabledMinutes}
63 disabledSeconds={disabledSeconds}/>, 58 disabledSeconds={disabledSeconds}
59 />,
64 document.getElementById('__react-content') 60 document.getElementById('__react-content')
65); 61);
diff --git a/examples/hidden.js b/examples/hidden.js
index 16abd2a..90a20d2 100644
--- a/examples/hidden.js
+++ b/examples/hidden.js
@@ -5,32 +5,28 @@ import 'rc-time-picker/assets/index.less';
5import React from 'react'; 5import React from 'react';
6import ReactDom from 'react-dom'; 6import ReactDom from 'react-dom';
7 7
8import GregorianCalendar from 'gregorian-calendar'; 8import moment from 'moment';
9import DateTimeFormat from 'gregorian-calendar-format';
10 9
11import TimePicker from 'rc-time-picker'; 10import TimePicker from 'rc-time-picker';
12import TimePickerLocale from 'rc-time-picker/src/locale/zh_CN';
13 11
14const showSecond = true; 12const showSecond = true;
15const str = showSecond ? 'HH:mm:ss' : 'HH:mm'; 13const str = showSecond ? 'HH:mm:ss' : 'HH:mm';
16 14
17const formatter = new DateTimeFormat(str);
18
19const now = new GregorianCalendar(TimePickerLocale.calendar);
20now.setTime(Date.now());
21
22function onChange(value) { 15function onChange(value) {
23 console.log(value && formatter.format(value)); 16 console.log(value && value.format(str));
24} 17}
25 18
26ReactDom.render( 19ReactDom.render(
27 <TimePicker formatter={formatter} locale={TimePickerLocale} 20 <TimePicker
28 showSecond={showSecond} 21 format={str}
29 defaultValue={now} 22 showSecond={showSecond}
30 className="xxx" 23 // use to control utfOffset, locale, default open value
31 onChange={onChange} 24 defaultOpenValue={moment()}
32 disabledHours={() => [0, 1, 2, 3, 4, 5, 6, 7, 8, 22, 23]} 25 className="xxx"
33 disabledMinutes={() => [0, 2, 4, 6, 8]} 26 onChange={onChange}
34 hideDisabledOptions />, 27 disabledHours={() => [0, 1, 2, 3, 4, 5, 6, 7, 8, 22, 23]}
28 disabledMinutes={() => [0, 2, 4, 6, 8]}
29 hideDisabledOptions
30 />,
35 document.getElementById('__react-content') 31 document.getElementById('__react-content')
36); 32);
diff --git a/examples/pick-time.js b/examples/pick-time.js
index 8fa7831..835e1e1 100644
--- a/examples/pick-time.js
+++ b/examples/pick-time.js
@@ -5,30 +5,25 @@ import 'rc-time-picker/assets/index.less';
5import React from 'react'; 5import React from 'react';
6import ReactDom from 'react-dom'; 6import ReactDom from 'react-dom';
7 7
8import GregorianCalendar from 'gregorian-calendar'; 8import moment from 'moment';
9import DateTimeFormat from 'gregorian-calendar-format';
10 9
11import TimePicker from 'rc-time-picker'; 10import TimePicker from 'rc-time-picker';
12import TimePickerLocale from 'rc-time-picker/src/locale/zh_CN';
13 11
14const showSecond = true; 12const showSecond = true;
15const str = showSecond ? 'HH:mm:ss' : 'HH:mm'; 13const str = showSecond ? 'HH:mm:ss' : 'HH:mm';
16 14
17const formatter = new DateTimeFormat(str);
18
19const now = new GregorianCalendar(TimePickerLocale.calendar);
20now.setTime(Date.now());
21 15
22function onChange(value) { 16function onChange(value) {
23 console.log(value && formatter.format(value)); 17 console.log(value && value.format(str));
24} 18}
25 19
26ReactDom.render( 20ReactDom.render(
27 <TimePicker formatter={formatter} locale={TimePickerLocale} 21 <TimePicker
28 style={{width: 100}} 22 style={{ width: 100 }}
29 showSecond={showSecond} 23 showSecond={showSecond}
30 defaultValue={now} 24 defaultValue={moment()}
31 className="xxx" 25 className="xxx"
32 onChange={onChange} />, 26 onChange={onChange}
27 />,
33 document.getElementById('__react-content') 28 document.getElementById('__react-content')
34); 29);
diff --git a/examples/value-and-defaultValue.js b/examples/value-and-defaultValue.js
index 1be30cc..0e1aa14 100644
--- a/examples/value-and-defaultValue.js
+++ b/examples/value-and-defaultValue.js
@@ -4,25 +4,17 @@ import 'rc-time-picker/assets/index.less';
4 4
5import React from 'react'; 5import React from 'react';
6import ReactDom from 'react-dom'; 6import ReactDom from 'react-dom';
7 7import moment from 'moment';
8import GregorianCalendar from 'gregorian-calendar';
9import DateTimeFormat from 'gregorian-calendar-format';
10import TimePicker from 'rc-time-picker'; 8import TimePicker from 'rc-time-picker';
11import TimePickerLocale from 'rc-time-picker/src/locale/zh_CN';
12
13const formatter = new DateTimeFormat('HH:mm:ss');
14
15const now = new GregorianCalendar(TimePickerLocale.calendar);
16now.setTime(Date.now());
17 9
18const App = React.createClass({ 10const App = React.createClass({
19 getInitialState() { 11 getInitialState() {
20 return { 12 return {
21 value: now, 13 value: moment(),
22 }; 14 };
23 }, 15 },
24 handleValueChange(value) { 16 handleValueChange(value) {
25 console.log(value && formatter.format(value)); 17 console.log(value && value.format('HH:mm:ss'));
26 this.setState({ value }); 18 this.setState({ value });
27 }, 19 },
28 clear() { 20 clear() {
@@ -33,11 +25,14 @@ const App = React.createClass({
33 render() { 25 render() {
34 return ( 26 return (
35 <div> 27 <div>
36 <TimePicker formatter={formatter} locale={TimePickerLocale} 28 <TimePicker
37 defaultValue={now} /> 29 defaultValue={this.state.value}
38 <TimePicker formatter={formatter} locale={TimePickerLocale} 30 onChange={this.handleValueChange}
39 value={this.state.value} 31 />
40 onChange={this.handleValueChange}/> 32 <TimePicker
33 value={this.state.value}
34 onChange={this.handleValueChange}
35 />
41 <button onClick={this.clear}>clear</button> 36 <button onClick={this.clear}>clear</button>
42 </div> 37 </div>
43 ); 38 );
diff --git a/package.json b/package.json
index 11b2436..74066e7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
1{ 1{
2 "name": "rc-time-picker", 2 "name": "rc-time-picker",
3 "version": "1.1.5", 3 "version": "2.1.0",
4 "description": "React TimePicker", 4 "description": "React TimePicker",
5 "keywords": [ 5 "keywords": [
6 "react", 6 "react",
@@ -33,34 +33,34 @@
33 "scripts": { 33 "scripts": {
34 "build": "rc-tools run build", 34 "build": "rc-tools run build",
35 "gh-pages": "rc-tools run gh-pages", 35 "gh-pages": "rc-tools run gh-pages",
36 "start": "rc-server", 36 "start": "rc-tools run server",
37 "pub": "rc-tools run pub", 37 "pub": "rc-tools run pub --babel-runtime",
38 "lint": "rc-tools run lint", 38 "lint": "rc-tools run lint",
39 "karma": "rc-tools run karma", 39 "karma": "rc-tools run karma",
40 "saucelabs": "rc-tools run saucelabs", 40 "saucelabs": "rc-tools run saucelabs",
41 "browser-test": "rc-tools run browser-test", 41 "test": "rc-tools run test",
42 "browser-test-cover": "rc-tools run browser-test-cover" 42 "chrome-test": "rc-tools run chrome-test",
43 "coverage": "rc-tools run coverage"
43 }, 44 },
44 "devDependencies": { 45 "devDependencies": {
45 "async": "~0.9.0", 46 "async": "~0.9.0",
46 "bootstrap": "~3.3.2", 47 "bootstrap": "~3.3.2",
47 "expect.js": "~0.3.1", 48 "expect.js": "~0.3.1",
48 "jquery": "~1.11.3", 49 "jquery": "1.x",
49 "pre-commit": "1.x", 50 "pre-commit": "1.x",
50 "rc-server": "3.x", 51 "rc-tools": "5.x",
51 "rc-tools": "4.x",
52 "rc-util": "^3.1.2", 52 "rc-util": "^3.1.2",
53 "react": "0.14.x", 53 "react": "15.x",
54 "react-addons-test-utils": "0.14.x", 54 "react-addons-test-utils": "15.x",
55 "react-dom": "0.14.x" 55 "react-dom": "15.x"
56 }, 56 },
57 "pre-commit": [ 57 "pre-commit": [
58 "lint" 58 "lint"
59 ], 59 ],
60 "dependencies": { 60 "dependencies": {
61 "babel-runtime": "6.x",
61 "classnames": "2.x", 62 "classnames": "2.x",
62 "gregorian-calendar": "4.x", 63 "moment": "2.x",
63 "gregorian-calendar-format": "4.x",
64 "rc-trigger": "1.x" 64 "rc-trigger": "1.x"
65 } 65 }
66} 66}
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}
diff --git a/tests/Header.spec.jsx b/tests/Header.spec.jsx
index e992279..d5e570d 100644
--- a/tests/Header.spec.jsx
+++ b/tests/Header.spec.jsx
@@ -6,32 +6,21 @@ import TestUtils from 'react-addons-test-utils';
6const Simulate = TestUtils.Simulate; 6const Simulate = TestUtils.Simulate;
7import expect from 'expect.js'; 7import expect from 'expect.js';
8import async from 'async'; 8import async from 'async';
9import {KeyCode} from 'rc-util'; 9import { KeyCode } from 'rc-util';
10 10import moment from 'moment';
11import DateTimeFormat from 'gregorian-calendar-format';
12import zhCn from 'gregorian-calendar/lib/locale/zh_CN';
13import TimePickerLocale from '../src/locale/zh_CN';
14
15function formatTime(time, formatter) {
16 return formatter.parse(time, {
17 locale: zhCn,
18 obeyCount: true,
19 });
20}
21 11
22describe('Header', () => { 12describe('Header', () => {
23 let container; 13 let container;
24 14
25 function renderPicker(props) { 15 function renderPicker(props) {
26 const showSecond = true; 16 const showSecond = true;
27 const formatter = new DateTimeFormat('HH:mm:ss'); 17 const format = 'HH:mm:ss';
28 18
29 return ReactDOM.render( 19 return ReactDOM.render(
30 <TimePicker 20 <TimePicker
31 formatter={formatter} 21 format={format}
32 locale={TimePickerLocale}
33 showSecond={showSecond} 22 showSecond={showSecond}
34 defaultValue={formatTime('01:02:03', formatter)} 23 defaultValue={moment('01:02:03', format)}
35 {...props} 24 {...props}
36 />, container); 25 />, container);
37 } 26 }
@@ -50,25 +39,27 @@ describe('Header', () => {
50 it('input correctly', (done) => { 39 it('input correctly', (done) => {
51 const picker = renderPicker(); 40 const picker = renderPicker();
52 expect(picker.state.open).not.to.be.ok(); 41 expect(picker.state.open).not.to.be.ok();
53 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 42 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
43 'rc-time-picker-input')[0];
54 let header; 44 let header;
55 async.series([(next) => { 45 async.series([(next) => {
56 Simulate.click(input); 46 Simulate.click(input);
57 setTimeout(next, 100); 47 setTimeout(next, 100);
58 }, (next) => { 48 }, (next) => {
59 expect(picker.state.open).to.be(true); 49 expect(picker.state.open).to.be(true);
60 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 50 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
51 'rc-time-picker-panel-input')[0];
61 expect(header).to.be.ok(); 52 expect(header).to.be.ok();
62 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 53 expect((header).value).to.be('01:02:03');
63 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 54 expect((input).value).to.be('01:02:03');
64 55
65 ReactDOM.findDOMNode(header).value = '12:34:56'; 56 (header).value = '12:34:56';
66 Simulate.change(header); 57 Simulate.change(header);
67 setTimeout(next, 100); 58 setTimeout(next, 100);
68 }, (next) => { 59 }, (next) => {
69 expect(picker.state.open).to.be(true); 60 expect(picker.state.open).to.be(true);
70 expect(ReactDOM.findDOMNode(header).value).to.be('12:34:56'); 61 expect((header).value).to.be('12:34:56');
71 expect(ReactDOM.findDOMNode(input).value).to.be('12:34:56'); 62 expect((input).value).to.be('12:34:56');
72 63
73 next(); 64 next();
74 }], () => { 65 }], () => {
@@ -79,41 +70,43 @@ describe('Header', () => {
79 it('carry correctly', (done) => { 70 it('carry correctly', (done) => {
80 const picker = renderPicker(); 71 const picker = renderPicker();
81 expect(picker.state.open).not.to.be.ok(); 72 expect(picker.state.open).not.to.be.ok();
82 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 73 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
74 'rc-time-picker-input')[0];
83 let header; 75 let header;
84 async.series([(next) => { 76 async.series([(next) => {
85 Simulate.click(input); 77 Simulate.click(input);
86 setTimeout(next, 100); 78 setTimeout(next, 100);
87 }, (next) => { 79 }, (next) => {
88 expect(picker.state.open).to.be(true); 80 expect(picker.state.open).to.be(true);
89 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 81 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
82 'rc-time-picker-panel-input')[0];
90 expect(header).to.be.ok(); 83 expect(header).to.be.ok();
91 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 84 expect((header).value).to.be('01:02:03');
92 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 85 expect((input).value).to.be('01:02:03');
93 86
94 ReactDOM.findDOMNode(header).value = '33:44:55'; 87 (header).value = '33:44:55';
95 Simulate.change(header); 88 Simulate.change(header);
96 setTimeout(next, 100); 89 setTimeout(next, 100);
97 }, (next) => { 90 }, (next) => {
98 expect(picker.state.open).to.be(true); 91 expect(picker.state.open).to.be(true);
99 expect(ReactDOM.findDOMNode(header).value).to.be('09:44:55'); 92 expect((header).value).to.be('33:44:55');
100 expect(ReactDOM.findDOMNode(input).value).to.be('09:44:55'); 93 expect((input).value).to.be('01:02:03');
101 94
102 ReactDOM.findDOMNode(header).value = '10:90:30'; 95 (header).value = '10:90:30';
103 Simulate.change(header); 96 Simulate.change(header);
104 setTimeout(next, 100); 97 setTimeout(next, 100);
105 }, (next) => { 98 }, (next) => {
106 expect(picker.state.open).to.be(true); 99 expect(picker.state.open).to.be(true);
107 expect(ReactDOM.findDOMNode(header).value).to.be('11:30:30'); 100 expect((header).value).to.be('10:90:30');
108 expect(ReactDOM.findDOMNode(input).value).to.be('11:30:30'); 101 expect((input).value).to.be('01:02:03');
109 102
110 ReactDOM.findDOMNode(header).value = '34:56:78'; 103 (header).value = '34:56:78';
111 Simulate.change(header); 104 Simulate.change(header);
112 setTimeout(next, 100); 105 setTimeout(next, 100);
113 }, (next) => { 106 }, (next) => {
114 expect(picker.state.open).to.be(true); 107 expect(picker.state.open).to.be(true);
115 expect(ReactDOM.findDOMNode(header).value).to.be('10:57:18'); 108 expect((header).value).to.be('34:56:78');
116 expect(ReactDOM.findDOMNode(input).value).to.be('10:57:18'); 109 expect((input).value).to.be('01:02:03');
117 110
118 next(); 111 next();
119 }], () => { 112 }], () => {
@@ -131,51 +124,53 @@ describe('Header', () => {
131 }, 124 },
132 }); 125 });
133 expect(picker.state.open).not.to.be.ok(); 126 expect(picker.state.open).not.to.be.ok();
134 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 127 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
128 'rc-time-picker-input')[0];
135 let header; 129 let header;
136 async.series([(next) => { 130 async.series([(next) => {
137 Simulate.click(input); 131 Simulate.click(input);
138 setTimeout(next, 100); 132 setTimeout(next, 100);
139 }, (next) => { 133 }, (next) => {
140 expect(picker.state.open).to.be(true); 134 expect(picker.state.open).to.be(true);
141 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 135 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
136 'rc-time-picker-panel-input')[0];
142 expect(header).to.be.ok(); 137 expect(header).to.be.ok();
143 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 138 expect((header).value).to.be('01:02:03');
144 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 139 expect((input).value).to.be('01:02:03');
145 140
146 ReactDOM.findDOMNode(header).value = '10:09:78'; 141 (header).value = '10:09:78';
147 Simulate.change(header); 142 Simulate.change(header);
148 setTimeout(next, 100); 143 setTimeout(next, 100);
149 }, (next) => { 144 }, (next) => {
150 expect(picker.state.open).to.be(true); 145 expect(picker.state.open).to.be(true);
151 expect(ReactDOM.findDOMNode(header).className).to.contain('rc-time-picker-panel-input-invalid'); 146 expect((header).className).to.contain('rc-time-picker-panel-input-invalid');
152 expect(ReactDOM.findDOMNode(header).value).to.be('10:09:78'); 147 expect((header).value).to.be('10:09:78');
153 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 148 expect((input).value).to.be('01:02:03');
154 149
155 ReactDOM.findDOMNode(header).value = '10:10:78'; 150 (header).value = '10:10:78';
156 Simulate.change(header); 151 Simulate.change(header);
157 setTimeout(next, 100); 152 setTimeout(next, 100);
158 }, (next) => { 153 }, (next) => {
159 expect(picker.state.open).to.be(true); 154 expect(picker.state.open).to.be(true);
160 expect(ReactDOM.findDOMNode(header).value).to.be('10:11:18'); 155 expect((header).value).to.be('10:10:78');
161 expect(ReactDOM.findDOMNode(input).value).to.be('10:11:18'); 156 expect((input).value).to.be('01:02:03');
162 157
163 ReactDOM.findDOMNode(header).value = '10:09:19'; 158 (header).value = '10:09:19';
164 Simulate.change(header); 159 Simulate.change(header);
165 setTimeout(next, 100); 160 setTimeout(next, 100);
166 }, (next) => { 161 }, (next) => {
167 expect(picker.state.open).to.be(true); 162 expect(picker.state.open).to.be(true);
168 expect(ReactDOM.findDOMNode(header).className).to.contain('rc-time-picker-panel-input-invalid'); 163 expect((header).className).to.contain('rc-time-picker-panel-input-invalid');
169 expect(ReactDOM.findDOMNode(header).value).to.be('10:09:19'); 164 expect((header).value).to.be('10:09:19');
170 expect(ReactDOM.findDOMNode(input).value).to.be('10:11:18'); 165 expect((input).value).to.be('01:02:03');
171 166
172 ReactDOM.findDOMNode(header).value = '10:09:20'; 167 (header).value = '10:09:20';
173 Simulate.change(header); 168 Simulate.change(header);
174 setTimeout(next, 100); 169 setTimeout(next, 100);
175 }, (next) => { 170 }, (next) => {
176 expect(picker.state.open).to.be(true); 171 expect(picker.state.open).to.be(true);
177 expect(ReactDOM.findDOMNode(header).value).to.be('10:09:20'); 172 expect((header).value).to.be('10:09:20');
178 expect(ReactDOM.findDOMNode(input).value).to.be('10:09:20'); 173 expect((input).value).to.be('10:09:20');
179 174
180 next(); 175 next();
181 }], () => { 176 }], () => {
@@ -194,51 +189,53 @@ describe('Header', () => {
194 hideDisabledOptions: true, 189 hideDisabledOptions: true,
195 }); 190 });
196 expect(picker.state.open).not.to.be.ok(); 191 expect(picker.state.open).not.to.be.ok();
197 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 192 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
193 'rc-time-picker-input')[0];
198 let header; 194 let header;
199 async.series([(next) => { 195 async.series([(next) => {
200 Simulate.click(input); 196 Simulate.click(input);
201 setTimeout(next, 100); 197 setTimeout(next, 100);
202 }, (next) => { 198 }, (next) => {
203 expect(picker.state.open).to.be(true); 199 expect(picker.state.open).to.be(true);
204 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 200 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
201 'rc-time-picker-panel-input')[0];
205 expect(header).to.be.ok(); 202 expect(header).to.be.ok();
206 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 203 expect((header).value).to.be('01:02:03');
207 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 204 expect((input).value).to.be('01:02:03');
208 205
209 ReactDOM.findDOMNode(header).value = '10:09:78'; 206 (header).value = '10:09:78';
210 Simulate.change(header); 207 Simulate.change(header);
211 setTimeout(next, 100); 208 setTimeout(next, 100);
212 }, (next) => { 209 }, (next) => {
213 expect(picker.state.open).to.be(true); 210 expect(picker.state.open).to.be(true);
214 expect(ReactDOM.findDOMNode(header).className).to.contain('rc-time-picker-panel-input-invalid'); 211 expect((header).className).to.contain('rc-time-picker-panel-input-invalid');
215 expect(ReactDOM.findDOMNode(header).value).to.be('10:09:78'); 212 expect((header).value).to.be('10:09:78');
216 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 213 expect((input).value).to.be('01:02:03');
217 214
218 ReactDOM.findDOMNode(header).value = '10:10:78'; 215 (header).value = '10:10:78';
219 Simulate.change(header); 216 Simulate.change(header);
220 setTimeout(next, 100); 217 setTimeout(next, 100);
221 }, (next) => { 218 }, (next) => {
222 expect(picker.state.open).to.be(true); 219 expect(picker.state.open).to.be(true);
223 expect(ReactDOM.findDOMNode(header).value).to.be('10:11:18'); 220 expect((header).value).to.be('10:10:78');
224 expect(ReactDOM.findDOMNode(input).value).to.be('10:11:18'); 221 expect((input).value).to.be('01:02:03');
225 222
226 ReactDOM.findDOMNode(header).value = '10:09:19'; 223 (header).value = '10:09:19';
227 Simulate.change(header); 224 Simulate.change(header);
228 setTimeout(next, 100); 225 setTimeout(next, 100);
229 }, (next) => { 226 }, (next) => {
230 expect(picker.state.open).to.be(true); 227 expect(picker.state.open).to.be(true);
231 expect(ReactDOM.findDOMNode(header).className).to.contain('rc-time-picker-panel-input-invalid'); 228 expect((header).className).to.contain('rc-time-picker-panel-input-invalid');
232 expect(ReactDOM.findDOMNode(header).value).to.be('10:09:19'); 229 expect((header).value).to.be('10:09:19');
233 expect(ReactDOM.findDOMNode(input).value).to.be('10:11:18'); 230 expect((input).value).to.be('01:02:03');
234 231
235 ReactDOM.findDOMNode(header).value = '10:09:20'; 232 (header).value = '10:09:20';
236 Simulate.change(header); 233 Simulate.change(header);
237 setTimeout(next, 100); 234 setTimeout(next, 100);
238 }, (next) => { 235 }, (next) => {
239 expect(picker.state.open).to.be(true); 236 expect(picker.state.open).to.be(true);
240 expect(ReactDOM.findDOMNode(header).value).to.be('10:09:20'); 237 expect((header).value).to.be('10:09:20');
241 expect(ReactDOM.findDOMNode(input).value).to.be('10:09:20'); 238 expect((input).value).to.be('10:09:20');
242 239
243 next(); 240 next();
244 }], () => { 241 }], () => {
@@ -249,44 +246,46 @@ describe('Header', () => {
249 it('check correctly', (done) => { 246 it('check correctly', (done) => {
250 const picker = renderPicker(); 247 const picker = renderPicker();
251 expect(picker.state.open).not.to.be.ok(); 248 expect(picker.state.open).not.to.be.ok();
252 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 249 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
250 'rc-time-picker-input')[0];
253 let header; 251 let header;
254 async.series([(next) => { 252 async.series([(next) => {
255 Simulate.click(input); 253 Simulate.click(input);
256 setTimeout(next, 100); 254 setTimeout(next, 100);
257 }, (next) => { 255 }, (next) => {
258 expect(picker.state.open).to.be(true); 256 expect(picker.state.open).to.be(true);
259 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 257 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
258 'rc-time-picker-panel-input')[0];
260 expect(header).to.be.ok(); 259 expect(header).to.be.ok();
261 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 260 expect((header).value).to.be('01:02:03');
262 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 261 expect((input).value).to.be('01:02:03');
263 262
264 ReactDOM.findDOMNode(header).value = '3:34:56'; 263 (header).value = '3:34:56';
265 Simulate.change(header); 264 Simulate.change(header);
266 setTimeout(next, 100); 265 setTimeout(next, 100);
267 }, (next) => { 266 }, (next) => {
268 expect(picker.state.open).to.be(true); 267 expect(picker.state.open).to.be(true);
269 expect(ReactDOM.findDOMNode(header).value).to.be('3:34:56'); 268 expect((header).value).to.be('3:34:56');
270 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 269 expect((input).value).to.be('01:02:03');
271 expect(ReactDOM.findDOMNode(header).className).to.contain('rc-time-picker-panel-input-invalid'); 270 expect((header).className).to.contain('rc-time-picker-panel-input-invalid');
272 271
273 ReactDOM.findDOMNode(header).value = '13:3:56'; 272 (header).value = '13:3:56';
274 Simulate.change(header); 273 Simulate.change(header);
275 setTimeout(next, 100); 274 setTimeout(next, 100);
276 }, (next) => { 275 }, (next) => {
277 expect(picker.state.open).to.be(true); 276 expect(picker.state.open).to.be(true);
278 expect(ReactDOM.findDOMNode(header).value).to.be('13:3:56'); 277 expect((header).value).to.be('13:3:56');
279 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 278 expect((input).value).to.be('01:02:03');
280 expect(ReactDOM.findDOMNode(header).className).to.contain('rc-time-picker-panel-input-invalid'); 279 expect((header).className).to.contain('rc-time-picker-panel-input-invalid');
281 280
282 ReactDOM.findDOMNode(header).value = '13:34:5'; 281 (header).value = '13:34:5';
283 Simulate.change(header); 282 Simulate.change(header);
284 setTimeout(next, 100); 283 setTimeout(next, 100);
285 }, (next) => { 284 }, (next) => {
286 expect(picker.state.open).to.be(true); 285 expect(picker.state.open).to.be(true);
287 expect(ReactDOM.findDOMNode(header).value).to.be('13:34:5'); 286 expect((header).value).to.be('13:34:5');
288 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 287 expect((input).value).to.be('01:02:03');
289 expect(ReactDOM.findDOMNode(header).className).to.contain('rc-time-picker-panel-input-invalid'); 288 expect((header).className).to.contain('rc-time-picker-panel-input-invalid');
290 next(); 289 next();
291 }], () => { 290 }], () => {
292 done(); 291 done();
@@ -303,7 +302,8 @@ describe('Header', () => {
303 }, 302 },
304 }); 303 });
305 expect(picker.state.open).not.to.be.ok(); 304 expect(picker.state.open).not.to.be.ok();
306 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 305 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
306 'rc-time-picker-input')[0];
307 let header; 307 let header;
308 async.series([(next) => { 308 async.series([(next) => {
309 expect(picker.state.open).to.be(false); 309 expect(picker.state.open).to.be(false);
@@ -312,20 +312,22 @@ describe('Header', () => {
312 setTimeout(next, 100); 312 setTimeout(next, 100);
313 }, (next) => { 313 }, (next) => {
314 expect(picker.state.open).to.be(true); 314 expect(picker.state.open).to.be(true);
315 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 315 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
316 const clearButton = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-clear-btn')[0]; 316 'rc-time-picker-panel-input')[0];
317 const clearButton = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
318 'rc-time-picker-panel-clear-btn')[0];
317 expect(header).to.be.ok(); 319 expect(header).to.be.ok();
318 expect(clearButton).to.be.ok(); 320 expect(clearButton).to.be.ok();
319 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 321 expect((header).value).to.be('01:02:03');
320 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 322 expect((input).value).to.be('01:02:03');
321 323
322 Simulate.mouseDown(clearButton); 324 Simulate.mouseDown(clearButton);
323 setTimeout(next, 100); 325 setTimeout(next, 100);
324 }, (next) => { 326 }, (next) => {
325 expect(picker.state.open).to.be(false); 327 expect(picker.state.open).to.be(false);
326 expect(change).to.be(null); 328 expect(change).to.be(null);
327 expect(ReactDOM.findDOMNode(header).value).to.be(''); 329 expect((header).value).to.be('');
328 expect(ReactDOM.findDOMNode(input).value).to.be(''); 330 expect((input).value).to.be('');
329 331
330 next(); 332 next();
331 }], () => { 333 }], () => {
@@ -336,7 +338,8 @@ describe('Header', () => {
336 it('exit correctly', (done) => { 338 it('exit correctly', (done) => {
337 const picker = renderPicker(); 339 const picker = renderPicker();
338 expect(picker.state.open).not.to.be.ok(); 340 expect(picker.state.open).not.to.be.ok();
339 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 341 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
342 'rc-time-picker-input')[0];
340 let header; 343 let header;
341 async.series([(next) => { 344 async.series([(next) => {
342 expect(picker.state.open).to.be(false); 345 expect(picker.state.open).to.be(false);
@@ -345,19 +348,20 @@ describe('Header', () => {
345 setTimeout(next, 100); 348 setTimeout(next, 100);
346 }, (next) => { 349 }, (next) => {
347 expect(picker.state.open).to.be(true); 350 expect(picker.state.open).to.be(true);
348 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 351 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
352 'rc-time-picker-panel-input')[0];
349 expect(header).to.be.ok(); 353 expect(header).to.be.ok();
350 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 354 expect((header).value).to.be('01:02:03');
351 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 355 expect((input).value).to.be('01:02:03');
352 356
353 Simulate.keyDown(ReactDOM.findDOMNode(header), { 357 Simulate.keyDown((header), {
354 keyCode: KeyCode.ESC, 358 keyCode: KeyCode.ESC,
355 }); 359 });
356 setTimeout(next, 100); 360 setTimeout(next, 100);
357 }, (next) => { 361 }, (next) => {
358 expect(picker.state.open).to.be(false); 362 expect(picker.state.open).to.be(false);
359 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:03'); 363 expect((header).value).to.be('01:02:03');
360 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:03'); 364 expect((input).value).to.be('01:02:03');
361 365
362 next(); 366 next();
363 }], () => { 367 }], () => {
diff --git a/tests/Select.spec.jsx b/tests/Select.spec.jsx
index f7717c7..e6d32dd 100644
--- a/tests/Select.spec.jsx
+++ b/tests/Select.spec.jsx
@@ -1,35 +1,24 @@
1import ReactDOM from 'react-dom'; 1import ReactDOM from 'react-dom';
2import React from 'react'; 2import React from 'react';
3import TimePicker from '../src/TimePicker'; 3import TimePicker from '../src/TimePicker';
4
5import TestUtils from 'react-addons-test-utils'; 4import TestUtils from 'react-addons-test-utils';
6const Simulate = TestUtils.Simulate; 5const Simulate = TestUtils.Simulate;
7import expect from 'expect.js'; 6import expect from 'expect.js';
8import async from 'async'; 7import async from 'async';
9import DateTimeFormat from 'gregorian-calendar-format'; 8import moment from 'moment';
10import zhCn from 'gregorian-calendar/lib/locale/zh_CN';
11import TimePickerLocale from '../src/locale/zh_CN';
12
13function formatTime(time, formatter) {
14 return formatter.parse(time, {
15 locale: zhCn,
16 obeyCount: true,
17 });
18}
19 9
20describe('Select', () => { 10describe('Select', () => {
21 let container; 11 let container;
22 12
23 function renderPicker(props) { 13 function renderPicker(props) {
24 const showSecond = true; 14 const showSecond = true;
25 const formatter = new DateTimeFormat('HH:mm:ss'); 15 const format = 'HH:mm:ss';
26 16
27 return ReactDOM.render( 17 return ReactDOM.render(
28 <TimePicker 18 <TimePicker
29 formatter={formatter} 19 format={format}
30 locale={TimePickerLocale}
31 showSecond={showSecond} 20 showSecond={showSecond}
32 defaultValue={formatTime('01:02:04', formatter)} 21 defaultValue={moment('01:02:04', format)}
33 {...props} 22 {...props}
34 />, container); 23 />, container);
35 } 24 }
@@ -48,7 +37,8 @@ describe('Select', () => {
48 it('select number correctly', (done) => { 37 it('select number correctly', (done) => {
49 const picker = renderPicker(); 38 const picker = renderPicker();
50 expect(picker.state.open).not.to.be.ok(); 39 expect(picker.state.open).not.to.be.ok();
51 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 40 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
41 'rc-time-picker-input')[0];
52 let selector; 42 let selector;
53 async.series([(next) => { 43 async.series([(next) => {
54 expect(picker.state.open).to.be(false); 44 expect(picker.state.open).to.be(false);
@@ -57,7 +47,8 @@ describe('Select', () => {
57 setTimeout(next, 100); 47 setTimeout(next, 100);
58 }, (next) => { 48 }, (next) => {
59 expect(picker.state.open).to.be(true); 49 expect(picker.state.open).to.be(true);
60 selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select'); 50 selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
51 'rc-time-picker-panel-select');
61 52
62 setTimeout(next, 100); 53 setTimeout(next, 100);
63 }, (next) => { 54 }, (next) => {
@@ -79,7 +70,8 @@ describe('Select', () => {
79 }, 70 },
80 }); 71 });
81 expect(picker.state.open).not.to.be.ok(); 72 expect(picker.state.open).not.to.be.ok();
82 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 73 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
74 'rc-time-picker-input')[0];
83 let header; 75 let header;
84 async.series([(next) => { 76 async.series([(next) => {
85 expect(picker.state.open).to.be(false); 77 expect(picker.state.open).to.be(false);
@@ -88,20 +80,22 @@ describe('Select', () => {
88 setTimeout(next, 100); 80 setTimeout(next, 100);
89 }, (next) => { 81 }, (next) => {
90 expect(picker.state.open).to.be(true); 82 expect(picker.state.open).to.be(true);
91 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 83 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
84 'rc-time-picker-panel-input')[0];
92 expect(header).to.be.ok(); 85 expect(header).to.be.ok();
93 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:04'); 86 expect((header).value).to.be('01:02:04');
94 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:04'); 87 expect((input).value).to.be('01:02:04');
95 88
96 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[0]; 89 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
90 'rc-time-picker-panel-select')[0];
97 const option = selector.getElementsByTagName('li')[19]; 91 const option = selector.getElementsByTagName('li')[19];
98 Simulate.click(option); 92 Simulate.click(option);
99 setTimeout(next, 100); 93 setTimeout(next, 100);
100 }, (next) => { 94 }, (next) => {
101 expect(change).to.be.ok(); 95 expect(change).to.be.ok();
102 expect(change.getHourOfDay()).to.be(19); 96 expect(change.hour()).to.be(19);
103 expect(ReactDOM.findDOMNode(header).value).to.be('19:02:04'); 97 expect((header).value).to.be('19:02:04');
104 expect(ReactDOM.findDOMNode(input).value).to.be('19:02:04'); 98 expect((input).value).to.be('19:02:04');
105 expect(picker.state.open).to.be.ok(); 99 expect(picker.state.open).to.be.ok();
106 100
107 next(); 101 next();
@@ -118,7 +112,8 @@ describe('Select', () => {
118 }, 112 },
119 }); 113 });
120 expect(picker.state.open).not.to.be.ok(); 114 expect(picker.state.open).not.to.be.ok();
121 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 115 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
116 'rc-time-picker-input')[0];
122 let header; 117 let header;
123 async.series([(next) => { 118 async.series([(next) => {
124 expect(picker.state.open).to.be(false); 119 expect(picker.state.open).to.be(false);
@@ -127,20 +122,22 @@ describe('Select', () => {
127 setTimeout(next, 100); 122 setTimeout(next, 100);
128 }, (next) => { 123 }, (next) => {
129 expect(picker.state.open).to.be(true); 124 expect(picker.state.open).to.be(true);
130 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 125 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
126 'rc-time-picker-panel-input')[0];
131 expect(header).to.be.ok(); 127 expect(header).to.be.ok();
132 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:04'); 128 expect((header).value).to.be('01:02:04');
133 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:04'); 129 expect((input).value).to.be('01:02:04');
134 130
135 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[1]; 131 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
132 'rc-time-picker-panel-select')[1];
136 const option = selector.getElementsByTagName('li')[19]; 133 const option = selector.getElementsByTagName('li')[19];
137 Simulate.click(option); 134 Simulate.click(option);
138 setTimeout(next, 100); 135 setTimeout(next, 100);
139 }, (next) => { 136 }, (next) => {
140 expect(change).to.be.ok(); 137 expect(change).to.be.ok();
141 expect(change.getMinutes()).to.be(19); 138 expect(change.minute()).to.be(19);
142 expect(ReactDOM.findDOMNode(header).value).to.be('01:19:04'); 139 expect((header).value).to.be('01:19:04');
143 expect(ReactDOM.findDOMNode(input).value).to.be('01:19:04'); 140 expect((input).value).to.be('01:19:04');
144 expect(picker.state.open).to.be.ok(); 141 expect(picker.state.open).to.be.ok();
145 142
146 next(); 143 next();
@@ -157,7 +154,8 @@ describe('Select', () => {
157 }, 154 },
158 }); 155 });
159 expect(picker.state.open).not.to.be.ok(); 156 expect(picker.state.open).not.to.be.ok();
160 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 157 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
158 'rc-time-picker-input')[0];
161 let header; 159 let header;
162 async.series([(next) => { 160 async.series([(next) => {
163 expect(picker.state.open).to.be(false); 161 expect(picker.state.open).to.be(false);
@@ -166,20 +164,22 @@ describe('Select', () => {
166 setTimeout(next, 100); 164 setTimeout(next, 100);
167 }, (next) => { 165 }, (next) => {
168 expect(picker.state.open).to.be(true); 166 expect(picker.state.open).to.be(true);
169 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 167 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
168 'rc-time-picker-panel-input')[0];
170 expect(header).to.be.ok(); 169 expect(header).to.be.ok();
171 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:04'); 170 expect((header).value).to.be('01:02:04');
172 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:04'); 171 expect((input).value).to.be('01:02:04');
173 172
174 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[2]; 173 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
174 'rc-time-picker-panel-select')[2];
175 const option = selector.getElementsByTagName('li')[19]; 175 const option = selector.getElementsByTagName('li')[19];
176 Simulate.click(option); 176 Simulate.click(option);
177 setTimeout(next, 100); 177 setTimeout(next, 100);
178 }, (next) => { 178 }, (next) => {
179 expect(change).to.be.ok(); 179 expect(change).to.be.ok();
180 expect(change.getSeconds()).to.be(19); 180 expect(change.second()).to.be(19);
181 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:19'); 181 expect((header).value).to.be('01:02:19');
182 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:19'); 182 expect((input).value).to.be('01:02:19');
183 expect(picker.state.open).to.be.ok(); 183 expect(picker.state.open).to.be.ok();
184 184
185 next(); 185 next();
@@ -202,7 +202,8 @@ describe('Select', () => {
202 }, 202 },
203 }); 203 });
204 expect(picker.state.open).not.to.be.ok(); 204 expect(picker.state.open).not.to.be.ok();
205 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 205 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
206 'rc-time-picker-input')[0];
206 let header; 207 let header;
207 async.series([(next) => { 208 async.series([(next) => {
208 expect(picker.state.open).to.be(false); 209 expect(picker.state.open).to.be(false);
@@ -211,40 +212,44 @@ describe('Select', () => {
211 setTimeout(next, 100); 212 setTimeout(next, 100);
212 }, (next) => { 213 }, (next) => {
213 expect(picker.state.open).to.be(true); 214 expect(picker.state.open).to.be(true);
214 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 215 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
216 'rc-time-picker-panel-input')[0];
215 expect(header).to.be.ok(); 217 expect(header).to.be.ok();
216 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:04'); 218 expect((header).value).to.be('01:02:04');
217 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:04'); 219 expect((input).value).to.be('01:02:04');
218 220
219 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[1]; 221 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
222 'rc-time-picker-panel-select')[1];
220 const option = selector.getElementsByTagName('li')[1]; 223 const option = selector.getElementsByTagName('li')[1];
221 Simulate.click(option); 224 Simulate.click(option);
222 setTimeout(next, 100); 225 setTimeout(next, 100);
223 }, (next) => { 226 }, (next) => {
224 expect(change).not.to.be.ok(); 227 expect(change).not.to.be.ok();
225 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:04'); 228 expect((header).value).to.be('01:02:04');
226 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:04'); 229 expect((input).value).to.be('01:02:04');
227 expect(picker.state.open).to.be.ok(); 230 expect(picker.state.open).to.be.ok();
228 231
229 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[2]; 232 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
233 'rc-time-picker-panel-select')[2];
230 const option = selector.getElementsByTagName('li')[3]; 234 const option = selector.getElementsByTagName('li')[3];
231 Simulate.click(option); 235 Simulate.click(option);
232 setTimeout(next, 100); 236 setTimeout(next, 100);
233 }, (next) => { 237 }, (next) => {
234 expect(change).not.to.be.ok(); 238 expect(change).not.to.be.ok();
235 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:04'); 239 expect((header).value).to.be('01:02:04');
236 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:04'); 240 expect((input).value).to.be('01:02:04');
237 expect(picker.state.open).to.be.ok(); 241 expect(picker.state.open).to.be.ok();
238 242
239 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[1]; 243 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
244 'rc-time-picker-panel-select')[1];
240 const option = selector.getElementsByTagName('li')[7]; 245 const option = selector.getElementsByTagName('li')[7];
241 Simulate.click(option); 246 Simulate.click(option);
242 setTimeout(next, 100); 247 setTimeout(next, 100);
243 }, (next) => { 248 }, (next) => {
244 expect(change).to.be.ok(); 249 expect(change).to.be.ok();
245 expect(change.getMinutes()).to.be(7); 250 expect(change.minute()).to.be(7);
246 expect(ReactDOM.findDOMNode(header).value).to.be('01:07:04'); 251 expect((header).value).to.be('01:07:04');
247 expect(ReactDOM.findDOMNode(input).value).to.be('01:07:04'); 252 expect((input).value).to.be('01:07:04');
248 expect(picker.state.open).to.be.ok(); 253 expect(picker.state.open).to.be.ok();
249 254
250 next(); 255 next();
@@ -274,31 +279,34 @@ describe('Select', () => {
274 setTimeout(next, 100); 279 setTimeout(next, 100);
275 }, (next) => { 280 }, (next) => {
276 expect(picker.state.open).to.be(true); 281 expect(picker.state.open).to.be(true);
277 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-input')[0]; 282 header = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
283 'rc-time-picker-panel-input')[0];
278 expect(header).to.be.ok(); 284 expect(header).to.be.ok();
279 expect(ReactDOM.findDOMNode(header).value).to.be('01:02:04'); 285 expect((header).value).to.be('01:02:04');
280 expect(ReactDOM.findDOMNode(input).value).to.be('01:02:04'); 286 expect((input).value).to.be('01:02:04');
281 287
282 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[0]; 288 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
289 'rc-time-picker-panel-select')[0];
283 const option = selector.getElementsByTagName('li')[3]; 290 const option = selector.getElementsByTagName('li')[3];
284 Simulate.click(option); 291 Simulate.click(option);
285 setTimeout(next, 100); 292 setTimeout(next, 100);
286 }, (next) => { 293 }, (next) => {
287 expect(change).to.be.ok(); 294 expect(change).to.be.ok();
288 expect(change.getHourOfDay()).to.be(6); 295 expect(change.hour()).to.be(6);
289 expect(ReactDOM.findDOMNode(header).value).to.be('06:02:04'); 296 expect((header).value).to.be('06:02:04');
290 expect(ReactDOM.findDOMNode(input).value).to.be('06:02:04'); 297 expect((input).value).to.be('06:02:04');
291 expect(picker.state.open).to.be.ok(); 298 expect(picker.state.open).to.be.ok();
292 299
293 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-select')[0]; 300 const selector = TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
301 'rc-time-picker-panel-select')[0];
294 const option = selector.getElementsByTagName('li')[4]; 302 const option = selector.getElementsByTagName('li')[4];
295 Simulate.click(option); 303 Simulate.click(option);
296 setTimeout(next, 100); 304 setTimeout(next, 100);
297 }, (next) => { 305 }, (next) => {
298 expect(change).to.be.ok(); 306 expect(change).to.be.ok();
299 expect(change.getHourOfDay()).to.be(8); 307 expect(change.hour()).to.be(8);
300 expect(ReactDOM.findDOMNode(header).value).to.be('08:02:04'); 308 expect((header).value).to.be('08:02:04');
301 expect(ReactDOM.findDOMNode(input).value).to.be('08:02:04'); 309 expect((input).value).to.be('08:02:04');
302 expect(picker.state.open).to.be.ok(); 310 expect(picker.state.open).to.be.ok();
303 311
304 next(); 312 next();
diff --git a/tests/TimePicker.spec.jsx b/tests/TimePicker.spec.jsx
index 95a1fd1..150f727 100644
--- a/tests/TimePicker.spec.jsx
+++ b/tests/TimePicker.spec.jsx
@@ -6,45 +6,33 @@ import TestUtils from 'react-addons-test-utils';
6const Simulate = TestUtils.Simulate; 6const Simulate = TestUtils.Simulate;
7import expect from 'expect.js'; 7import expect from 'expect.js';
8import async from 'async'; 8import async from 'async';
9 9import moment from 'moment';
10import DateTimeFormat from 'gregorian-calendar-format';
11import zhCn from 'gregorian-calendar/lib/locale/zh_CN';
12import TimePickerLocale from '../src/locale/zh_CN';
13
14function formatTime(time, formatter) {
15 return formatter.parse(time, {
16 locale: zhCn,
17 obeyCount: true,
18 });
19}
20 10
21describe('TimePicker', () => { 11describe('TimePicker', () => {
22 let container; 12 let container;
23 13
24 function renderPicker(props) { 14 function renderPicker(props) {
25 const showSecond = true; 15 const showSecond = true;
26 const formatter = new DateTimeFormat('HH:mm:ss'); 16 const format = ('HH:mm:ss');
27 17
28 return ReactDOM.render( 18 return ReactDOM.render(
29 <TimePicker 19 <TimePicker
30 formatter={formatter} 20 format={format}
31 locale={TimePickerLocale}
32 showSecond={showSecond} 21 showSecond={showSecond}
33 defaultValue={formatTime('12:57:58', formatter)} 22 defaultValue={moment('12:57:58', format)}
34 {...props} 23 {...props}
35 />, container); 24 />, container);
36 } 25 }
37 26
38 function renderPickerWithoutSeconds(props) { 27 function renderPickerWithoutSeconds(props) {
39 const showSecond = false; 28 const showSecond = false;
40 const formatter = new DateTimeFormat('HH:mm'); 29 const format = ('HH:mm');
41 30
42 return ReactDOM.render( 31 return ReactDOM.render(
43 <TimePicker 32 <TimePicker
44 formatter={formatter} 33 format={format}
45 locale={TimePickerLocale}
46 showSecond={showSecond} 34 showSecond={showSecond}
47 defaultValue={formatTime('08:24', formatter)} 35 defaultValue={moment('08:24', format)}
48 {...props} 36 {...props}
49 />, container); 37 />, container);
50 } 38 }
@@ -68,23 +56,25 @@ describe('TimePicker', () => {
68 }, 56 },
69 }); 57 });
70 expect(picker.state.open).not.to.be.ok(); 58 expect(picker.state.open).not.to.be.ok();
71 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 59 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
72 expect(ReactDOM.findDOMNode(input).value).to.be('12:57:58'); 60 'rc-time-picker-input')[0];
61 expect((input).value).to.be('12:57:58');
73 async.series([(next) => { 62 async.series([(next) => {
74 Simulate.click(input); 63 Simulate.click(input);
75 setTimeout(next, 100); 64 setTimeout(next, 100);
76 }, (next) => { 65 }, (next) => {
77 expect(TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-inner')[0]).to.be.ok(); 66 expect(TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
67 'rc-time-picker-panel-inner')[0]).to.be.ok();
78 expect(picker.state.open).to.be(true); 68 expect(picker.state.open).to.be(true);
79 const hour = TestUtils.scryRenderedDOMComponentsWithTag(picker.panelInstance, 'li')[1]; 69 const hour = TestUtils.scryRenderedDOMComponentsWithTag(picker.panelInstance, 'li')[1];
80 Simulate.click(hour); 70 Simulate.click(hour);
81 setTimeout(next, 100); 71 setTimeout(next, 100);
82 }, (next) => { 72 }, (next) => {
83 expect(change).to.be.ok(); 73 expect(change).to.be.ok();
84 expect(change.getHourOfDay()).to.be(1); 74 expect(change.hour()).to.be(1);
85 expect(change.getMinutes()).to.be(57); 75 expect(change.minute()).to.be(57);
86 expect(change.getSeconds()).to.be(58); 76 expect(change.second()).to.be(58);
87 expect(ReactDOM.findDOMNode(input).value).to.be('01:57:58'); 77 expect((input).value).to.be('01:57:58');
88 expect(picker.state.open).to.be.ok(); 78 expect(picker.state.open).to.be.ok();
89 next(); 79 next();
90 }], () => { 80 }], () => {
@@ -95,17 +85,20 @@ describe('TimePicker', () => {
95 it('destroy correctly', (done) => { 85 it('destroy correctly', (done) => {
96 const picker = renderPicker(); 86 const picker = renderPicker();
97 expect(picker.state.open).not.to.be.ok(); 87 expect(picker.state.open).not.to.be.ok();
98 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 88 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
89 'rc-time-picker-input')[0];
99 async.series([(next) => { 90 async.series([(next) => {
100 Simulate.click(input); 91 Simulate.click(input);
101 setTimeout(next, 100); 92 setTimeout(next, 100);
102 }, (next) => { 93 }, (next) => {
103 expect(TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-panel-inner')[0]).not.to.be.ok(); 94 expect(TestUtils.scryRenderedDOMComponentsWithClass(picker,
95 'rc-time-picker-panel-inner')[0]).not.to.be.ok();
104 expect(picker.state.open).to.be(true); 96 expect(picker.state.open).to.be(true);
105 if (document.querySelectorAll) { 97 if (document.querySelectorAll) {
106 expect(document.querySelectorAll('.rc-time-picker').length).not.to.be(0); 98 expect(document.querySelectorAll('.rc-time-picker').length).not.to.be(0);
107 } 99 }
108 expect(TestUtils.scryRenderedDOMComponentsWithTag(picker.panelInstance, 'li')[0]).to.be.ok(); 100 expect(TestUtils.scryRenderedDOMComponentsWithTag(picker.panelInstance,
101 'li')[0]).to.be.ok();
109 ReactDOM.unmountComponentAtNode(container); 102 ReactDOM.unmountComponentAtNode(container);
110 setTimeout(next, 100); 103 setTimeout(next, 100);
111 }, (next) => { 104 }, (next) => {
@@ -129,22 +122,24 @@ describe('TimePicker', () => {
129 }, 122 },
130 }); 123 });
131 expect(picker.state.open).not.to.be.ok(); 124 expect(picker.state.open).not.to.be.ok();
132 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker, 'rc-time-picker-input')[0]; 125 const input = TestUtils.scryRenderedDOMComponentsWithClass(picker,
133 expect(ReactDOM.findDOMNode(input).value).to.be('08:24'); 126 'rc-time-picker-input')[0];
127 expect((input).value).to.be('08:24');
134 async.series([(next) => { 128 async.series([(next) => {
135 Simulate.click(input); 129 Simulate.click(input);
136 setTimeout(next, 100); 130 setTimeout(next, 100);
137 }, (next) => { 131 }, (next) => {
138 expect(TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance, 'rc-time-picker-panel-inner')[0]).to.be.ok(); 132 expect(TestUtils.scryRenderedDOMComponentsWithClass(picker.panelInstance,
133 'rc-time-picker-panel-inner')[0]).to.be.ok();
139 expect(picker.state.open).to.be(true); 134 expect(picker.state.open).to.be(true);
140 const hour = TestUtils.scryRenderedDOMComponentsWithTag(picker.panelInstance, 'li')[1]; 135 const hour = TestUtils.scryRenderedDOMComponentsWithTag(picker.panelInstance, 'li')[1];
141 Simulate.click(hour); 136 Simulate.click(hour);
142 setTimeout(next, 100); 137 setTimeout(next, 100);
143 }, (next) => { 138 }, (next) => {
144 expect(change).to.be.ok(); 139 expect(change).to.be.ok();
145 expect(change.getHourOfDay()).to.be(1); 140 expect(change.hour()).to.be(1);
146 expect(change.getMinutes()).to.be(24); 141 expect(change.minute()).to.be(24);
147 expect(ReactDOM.findDOMNode(input).value).to.be('01:24'); 142 expect((input).value).to.be('01:24');
148 expect(picker.state.open).to.be.ok(); 143 expect(picker.state.open).to.be.ok();
149 next(); 144 next();
150 }], () => { 145 }], () => {
diff --git a/tests/index.spec.js b/tests/index.js
index ae3918a..2900845 100644
--- a/tests/index.spec.js
+++ b/tests/index.js
@@ -1,3 +1,4 @@
1import '../assets/index.less';
1import './TimePicker.spec'; 2import './TimePicker.spec';
2import './Header.spec'; 3import './Header.spec';
3import './Select.spec'; 4import './Select.spec';
diff --git a/tests/runner.html b/tests/runner.html
deleted file mode 100644
index 39802f6..0000000
--- a/tests/runner.html
+++ /dev/null
@@ -1 +0,0 @@
1stub