diff options
author | yiminghe <yiminghe@gmail.com> | 2016-08-04 19:53:55 +0800 |
---|---|---|
committer | yiminghe <yiminghe@gmail.com> | 2016-08-04 19:53:55 +0800 |
commit | 4984ed85e54f442998a335db70618d6184fa397e (patch) | |
tree | 6ae348b2cac5f48f3afb6f7b8dd0c2fd02f044fc /src | |
parent | deaa6062ea2e274d50d58c70251c1237c0c03c67 (diff) | |
download | time-picker-4984ed85e54f442998a335db70618d6184fa397e.tar.gz time-picker-4984ed85e54f442998a335db70618d6184fa397e.tar.zst time-picker-4984ed85e54f442998a335db70618d6184fa397e.zip |
2.x :boom:2.0.0
Diffstat (limited to 'src')
-rw-r--r-- | src/Combobox.jsx (renamed from src/module/Combobox.jsx) | 54 | ||||
-rw-r--r-- | src/Header.jsx | 175 | ||||
-rw-r--r-- | src/Panel.jsx (renamed from src/module/Panel.jsx) | 42 | ||||
-rw-r--r-- | src/Select.jsx (renamed from src/module/Select.jsx) | 18 | ||||
-rw-r--r-- | src/TimePicker.jsx | 64 | ||||
-rw-r--r-- | src/locale/en_US.js | 8 | ||||
-rw-r--r-- | src/locale/ru_RU.js | 8 | ||||
-rw-r--r-- | src/locale/zh_CN.js | 8 | ||||
-rw-r--r-- | src/mixin/CommonMixin.js | 15 | ||||
-rw-r--r-- | src/module/Header.jsx | 204 | ||||
-rw-r--r-- | src/placements.js (renamed from src/util/placements.js) | 0 | ||||
-rw-r--r-- | src/util/index.js | 8 | ||||
-rw-r--r-- | src/util/selection.js | 17 |
13 files changed, 257 insertions, 364 deletions
diff --git a/src/module/Combobox.jsx b/src/Combobox.jsx index f1e7c5b..9d9da16 100644 --- a/src/module/Combobox.jsx +++ b/src/Combobox.jsx | |||
@@ -1,6 +1,5 @@ | |||
1 | import React, {PropTypes} from 'react'; | 1 | import React, { PropTypes } from 'react'; |
2 | import Select from './Select'; | 2 | import Select from './Select'; |
3 | import GregorianCalendar from 'gregorian-calendar'; | ||
4 | 3 | ||
5 | const formatOption = (option, disabledOptions) => { | 4 | const formatOption = (option, disabledOptions) => { |
6 | let value = `${option}`; | 5 | let value = `${option}`; |
@@ -21,12 +20,12 @@ const formatOption = (option, disabledOptions) => { | |||
21 | 20 | ||
22 | const Combobox = React.createClass({ | 21 | const Combobox = React.createClass({ |
23 | propTypes: { | 22 | propTypes: { |
24 | formatter: PropTypes.object, | 23 | format: PropTypes.string, |
24 | defaultOpenValue: PropTypes.object, | ||
25 | prefixCls: PropTypes.string, | 25 | prefixCls: PropTypes.string, |
26 | value: PropTypes.object, | 26 | value: PropTypes.object, |
27 | onChange: PropTypes.func, | 27 | onChange: PropTypes.func, |
28 | showHour: PropTypes.bool, | 28 | showHour: PropTypes.bool, |
29 | gregorianCalendarLocale: PropTypes.object, | ||
30 | showSecond: PropTypes.bool, | 29 | showSecond: PropTypes.bool, |
31 | hourOptions: PropTypes.array, | 30 | hourOptions: PropTypes.array, |
32 | minuteOptions: PropTypes.array, | 31 | minuteOptions: PropTypes.array, |
@@ -38,19 +37,14 @@ const Combobox = React.createClass({ | |||
38 | }, | 37 | }, |
39 | 38 | ||
40 | onItemChange(type, itemValue) { | 39 | onItemChange(type, itemValue) { |
41 | const { onChange } = this.props; | 40 | const { onChange, defaultOpenValue } = this.props; |
42 | let value = this.props.value; | 41 | const value = (this.props.value || defaultOpenValue).clone(); |
43 | if (value) { | ||
44 | value = value.clone(); | ||
45 | } else { | ||
46 | value = this.getNow().clone(); | ||
47 | } | ||
48 | if (type === 'hour') { | 42 | if (type === 'hour') { |
49 | value.setHourOfDay(itemValue); | 43 | value.hour(itemValue); |
50 | } else if (type === 'minute') { | 44 | } else if (type === 'minute') { |
51 | value.setMinutes(itemValue); | 45 | value.minute(itemValue); |
52 | } else { | 46 | } else { |
53 | value.setSeconds(itemValue); | 47 | value.second(itemValue); |
54 | } | 48 | } |
55 | onChange(value); | 49 | onChange(value); |
56 | }, | 50 | }, |
@@ -79,9 +73,9 @@ const Combobox = React.createClass({ | |||
79 | }, | 73 | }, |
80 | 74 | ||
81 | getMinuteSelect(minute) { | 75 | getMinuteSelect(minute) { |
82 | const { prefixCls, minuteOptions, disabledMinutes } = this.props; | 76 | const { prefixCls, minuteOptions, disabledMinutes, defaultOpenValue } = this.props; |
83 | const value = this.props.value || this.getNow(); | 77 | const value = this.props.value || defaultOpenValue; |
84 | const disabledOptions = disabledMinutes(value.getHourOfDay()); | 78 | const disabledOptions = disabledMinutes(value.hour()); |
85 | 79 | ||
86 | return ( | 80 | return ( |
87 | <Select | 81 | <Select |
@@ -96,12 +90,12 @@ const Combobox = React.createClass({ | |||
96 | }, | 90 | }, |
97 | 91 | ||
98 | getSecondSelect(second) { | 92 | getSecondSelect(second) { |
99 | const { prefixCls, secondOptions, disabledSeconds, showSecond } = this.props; | 93 | const { prefixCls, secondOptions, disabledSeconds, showSecond, defaultOpenValue } = this.props; |
100 | if (!showSecond) { | 94 | if (!showSecond) { |
101 | return null; | 95 | return null; |
102 | } | 96 | } |
103 | const value = this.props.value || this.getNow(); | 97 | const value = this.props.value || defaultOpenValue; |
104 | const disabledOptions = disabledSeconds(value.getHourOfDay(), value.getMinutes()); | 98 | const disabledOptions = disabledSeconds(value.hour(), value.minute()); |
105 | 99 | ||
106 | return ( | 100 | return ( |
107 | <Select | 101 | <Select |
@@ -115,24 +109,14 @@ const Combobox = React.createClass({ | |||
115 | ); | 109 | ); |
116 | }, | 110 | }, |
117 | 111 | ||
118 | getNow() { | ||
119 | if (this.showNow) { | ||
120 | return this.showNow; | ||
121 | } | ||
122 | const value = new GregorianCalendar(this.props.gregorianCalendarLocale); | ||
123 | value.setTime(Date.now()); | ||
124 | this.showNow = value; | ||
125 | return value; | ||
126 | }, | ||
127 | |||
128 | render() { | 112 | render() { |
129 | const { prefixCls } = this.props; | 113 | const { prefixCls, defaultOpenValue } = this.props; |
130 | const value = this.props.value || this.getNow(); | 114 | const value = this.props.value || defaultOpenValue; |
131 | return ( | 115 | return ( |
132 | <div className={`${prefixCls}-combobox`}> | 116 | <div className={`${prefixCls}-combobox`}> |
133 | {this.getHourSelect(value.getHourOfDay())} | 117 | {this.getHourSelect(value.hour())} |
134 | {this.getMinuteSelect(value.getMinutes())} | 118 | {this.getMinuteSelect(value.minute())} |
135 | {this.getSecondSelect(value.getSeconds())} | 119 | {this.getSecondSelect(value.second())} |
136 | </div> | 120 | </div> |
137 | ); | 121 | ); |
138 | }, | 122 | }, |
diff --git a/src/Header.jsx b/src/Header.jsx new file mode 100644 index 0000000..4196ea9 --- /dev/null +++ b/src/Header.jsx | |||
@@ -0,0 +1,175 @@ | |||
1 | import React, { PropTypes } from 'react'; | ||
2 | import moment from 'moment'; | ||
3 | |||
4 | const Header = React.createClass({ | ||
5 | propTypes: { | ||
6 | format: PropTypes.string, | ||
7 | prefixCls: PropTypes.string, | ||
8 | disabledDate: PropTypes.func, | ||
9 | placeholder: PropTypes.string, | ||
10 | clearText: PropTypes.string, | ||
11 | value: PropTypes.object, | ||
12 | hourOptions: PropTypes.array, | ||
13 | minuteOptions: PropTypes.array, | ||
14 | secondOptions: PropTypes.array, | ||
15 | disabledHours: PropTypes.func, | ||
16 | disabledMinutes: PropTypes.func, | ||
17 | disabledSeconds: PropTypes.func, | ||
18 | onChange: PropTypes.func, | ||
19 | onClear: PropTypes.func, | ||
20 | onEsc: PropTypes.func, | ||
21 | allowEmpty: PropTypes.bool, | ||
22 | defaultOpenValue: PropTypes.object, | ||
23 | currentSelectPanel: PropTypes.string, | ||
24 | }, | ||
25 | |||
26 | getInitialState() { | ||
27 | const { value, format } = this.props; | ||
28 | return { | ||
29 | str: value && value.format(format) || '', | ||
30 | invalid: false, | ||
31 | }; | ||
32 | }, | ||
33 | |||
34 | componentWillReceiveProps(nextProps) { | ||
35 | const { value, format } = nextProps; | ||
36 | this.setState({ | ||
37 | str: value && value.format(format) || '', | ||
38 | invalid: false, | ||
39 | }); | ||
40 | }, | ||
41 | |||
42 | onInputChange(event) { | ||
43 | const str = event.target.value; | ||
44 | this.setState({ | ||
45 | str, | ||
46 | }); | ||
47 | const { | ||
48 | format, hourOptions, minuteOptions, secondOptions, | ||
49 | disabledHours, disabledMinutes, | ||
50 | disabledSeconds, onChange, allowEmpty, | ||
51 | } = this.props; | ||
52 | |||
53 | if (str) { | ||
54 | const originalValue = this.props.value; | ||
55 | const value = this.getProtoValue().clone(); | ||
56 | const parsed = moment(str, format, true); | ||
57 | if (!parsed.isValid()) { | ||
58 | this.setState({ | ||
59 | invalid: true, | ||
60 | }); | ||
61 | return; | ||
62 | } | ||
63 | value.hour(parsed.hour()).minute(parsed.minute()).second(parsed.second()); | ||
64 | |||
65 | // if time value not allowed, response warning. | ||
66 | if ( | ||
67 | hourOptions.indexOf(value.hour()) < 0 || | ||
68 | minuteOptions.indexOf(value.minute()) < 0 || | ||
69 | secondOptions.indexOf(value.second()) < 0 | ||
70 | ) { | ||
71 | this.setState({ | ||
72 | invalid: true, | ||
73 | }); | ||
74 | return; | ||
75 | } | ||
76 | |||
77 | // if time value is disabled, response warning. | ||
78 | const disabledHourOptions = disabledHours(); | ||
79 | const disabledMinuteOptions = disabledMinutes(value.hour()); | ||
80 | const disabledSecondOptions = disabledSeconds(value.hour(), value.minute()); | ||
81 | if ( | ||
82 | (disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) || | ||
83 | (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) || | ||
84 | (disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0) | ||
85 | ) { | ||
86 | this.setState({ | ||
87 | invalid: true, | ||
88 | }); | ||
89 | return; | ||
90 | } | ||
91 | |||
92 | if (originalValue) { | ||
93 | if ( | ||
94 | originalValue.hour() !== value.hour() || | ||
95 | originalValue.minute() !== value.minute() || | ||
96 | originalValue.second() !== value.second() | ||
97 | ) { | ||
98 | // keep other fields for rc-calendar | ||
99 | const changedValue = originalValue.clone(); | ||
100 | changedValue.hour(value.hour()); | ||
101 | changedValue.minute(value.minute()); | ||
102 | changedValue.second(value.second()); | ||
103 | onChange(changedValue); | ||
104 | } | ||
105 | } else if (originalValue !== value) { | ||
106 | onChange(value); | ||
107 | } | ||
108 | } else if (allowEmpty) { | ||
109 | onChange(null); | ||
110 | } else { | ||
111 | this.setState({ | ||
112 | invalid: true, | ||
113 | }); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | this.setState({ | ||
118 | invalid: false, | ||
119 | }); | ||
120 | }, | ||
121 | |||
122 | onKeyDown(e) { | ||
123 | if (e.keyCode === 27) { | ||
124 | this.props.onEsc(); | ||
125 | } | ||
126 | }, | ||
127 | |||
128 | onClear() { | ||
129 | this.setState({ str: '' }); | ||
130 | this.props.onClear(); | ||
131 | }, | ||
132 | |||
133 | getClearButton() { | ||
134 | const { prefixCls, allowEmpty } = this.props; | ||
135 | if (!allowEmpty) { | ||
136 | return null; | ||
137 | } | ||
138 | return (<a | ||
139 | className={`${prefixCls}-clear-btn`} | ||
140 | role="button" | ||
141 | title={this.props.clearText} | ||
142 | onMouseDown={this.onClear} | ||
143 | />); | ||
144 | }, | ||
145 | |||
146 | getProtoValue() { | ||
147 | return this.props.value || this.props.defaultOpenValue; | ||
148 | }, | ||
149 | |||
150 | getInput() { | ||
151 | const { prefixCls, placeholder } = this.props; | ||
152 | const { invalid, str } = this.state; | ||
153 | const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; | ||
154 | return (<input | ||
155 | className={`${prefixCls}-input ${invalidClass}`} | ||
156 | ref="input" | ||
157 | onKeyDown={this.onKeyDown} | ||
158 | value={str} | ||
159 | placeholder={placeholder} | ||
160 | onChange={this.onInputChange} | ||
161 | />); | ||
162 | }, | ||
163 | |||
164 | render() { | ||
165 | const { prefixCls } = this.props; | ||
166 | return ( | ||
167 | <div className={`${prefixCls}-input-wrap`}> | ||
168 | {this.getInput()} | ||
169 | {this.getClearButton()} | ||
170 | </div> | ||
171 | ); | ||
172 | }, | ||
173 | }); | ||
174 | |||
175 | export default Header; | ||
diff --git a/src/module/Panel.jsx b/src/Panel.jsx index 137ec2f..f70cf38 100644 --- a/src/module/Panel.jsx +++ b/src/Panel.jsx | |||
@@ -1,7 +1,7 @@ | |||
1 | import React, {PropTypes} from 'react'; | 1 | import React, { PropTypes } from 'react'; |
2 | import CommonMixin from '../mixin/CommonMixin'; | ||
3 | import Header from './Header'; | 2 | import Header from './Header'; |
4 | import Combobox from './Combobox'; | 3 | import Combobox from './Combobox'; |
4 | import moment from 'moment'; | ||
5 | 5 | ||
6 | function noop() { | 6 | function noop() { |
7 | } | 7 | } |
@@ -18,12 +18,12 @@ function generateOptions(length, disabledOptions, hideDisabledOptions) { | |||
18 | 18 | ||
19 | const Panel = React.createClass({ | 19 | const Panel = React.createClass({ |
20 | propTypes: { | 20 | propTypes: { |
21 | clearText: PropTypes.string, | ||
21 | prefixCls: PropTypes.string, | 22 | prefixCls: PropTypes.string, |
23 | defaultOpenValue: PropTypes.object, | ||
22 | value: PropTypes.object, | 24 | value: PropTypes.object, |
23 | locale: PropTypes.object, | ||
24 | placeholder: PropTypes.string, | 25 | placeholder: PropTypes.string, |
25 | gregorianCalendarLocale: PropTypes.object, | 26 | format: PropTypes.string, |
26 | formatter: PropTypes.object, | ||
27 | disabledHours: PropTypes.func, | 27 | disabledHours: PropTypes.func, |
28 | disabledMinutes: PropTypes.func, | 28 | disabledMinutes: PropTypes.func, |
29 | disabledSeconds: PropTypes.func, | 29 | disabledSeconds: PropTypes.func, |
@@ -36,13 +36,12 @@ const Panel = React.createClass({ | |||
36 | onClear: PropTypes.func, | 36 | onClear: PropTypes.func, |
37 | }, | 37 | }, |
38 | 38 | ||
39 | mixins: [CommonMixin], | ||
40 | |||
41 | getDefaultProps() { | 39 | getDefaultProps() { |
42 | return { | 40 | return { |
43 | prefixCls: 'rc-time-picker-panel', | 41 | prefixCls: 'rc-time-picker-panel', |
44 | onChange: noop, | 42 | onChange: noop, |
45 | onClear: noop, | 43 | onClear: noop, |
44 | defaultOpenValue: moment(), | ||
46 | }; | 45 | }; |
47 | }, | 46 | }, |
48 | 47 | ||
@@ -76,11 +75,18 @@ const Panel = React.createClass({ | |||
76 | }, | 75 | }, |
77 | 76 | ||
78 | render() { | 77 | render() { |
79 | const { locale, prefixCls, placeholder, disabledHours, disabledMinutes, disabledSeconds, hideDisabledOptions, allowEmpty, showHour, showSecond, formatter, gregorianCalendarLocale } = this.props; | 78 | const { |
80 | const value = this.state.value; | 79 | prefixCls, placeholder, disabledHours, disabledMinutes, |
80 | disabledSeconds, hideDisabledOptions, allowEmpty, showHour, showSecond, | ||
81 | format, defaultOpenValue, clearText, onEsc, | ||
82 | } = this.props; | ||
83 | const { | ||
84 | value, currentSelectPanel, | ||
85 | } = this.state; | ||
81 | const disabledHourOptions = disabledHours(); | 86 | const disabledHourOptions = disabledHours(); |
82 | const disabledMinuteOptions = disabledMinutes(value ? value.getHourOfDay() : null); | 87 | const disabledMinuteOptions = disabledMinutes(value ? value.hour() : null); |
83 | const disabledSecondOptions = disabledSeconds(value ? value.getHourOfDay() : null, value ? value.getMinutes() : null); | 88 | const disabledSecondOptions = disabledSeconds(value ? value.hour() : null, |
89 | value ? value.minute() : null); | ||
84 | const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions); | 90 | const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions); |
85 | const minuteOptions = generateOptions(60, disabledMinuteOptions, hideDisabledOptions); | 91 | const minuteOptions = generateOptions(60, disabledMinuteOptions, hideDisabledOptions); |
86 | const secondOptions = generateOptions(60, disabledSecondOptions, hideDisabledOptions); | 92 | const secondOptions = generateOptions(60, disabledSecondOptions, hideDisabledOptions); |
@@ -88,13 +94,13 @@ const Panel = React.createClass({ | |||
88 | return ( | 94 | return ( |
89 | <div className={`${prefixCls}-inner`}> | 95 | <div className={`${prefixCls}-inner`}> |
90 | <Header | 96 | <Header |
97 | clearText={clearText} | ||
91 | prefixCls={prefixCls} | 98 | prefixCls={prefixCls} |
92 | gregorianCalendarLocale={gregorianCalendarLocale} | 99 | defaultOpenValue={defaultOpenValue} |
93 | locale={locale} | ||
94 | value={value} | 100 | value={value} |
95 | currentSelectPanel={this.state.currentSelectPanel} | 101 | currentSelectPanel={currentSelectPanel} |
96 | onEsc={this.props.onEsc} | 102 | onEsc={onEsc} |
97 | formatter={formatter} | 103 | format={format} |
98 | placeholder={placeholder} | 104 | placeholder={placeholder} |
99 | hourOptions={hourOptions} | 105 | hourOptions={hourOptions} |
100 | minuteOptions={minuteOptions} | 106 | minuteOptions={minuteOptions} |
@@ -109,8 +115,8 @@ const Panel = React.createClass({ | |||
109 | <Combobox | 115 | <Combobox |
110 | prefixCls={prefixCls} | 116 | prefixCls={prefixCls} |
111 | value={value} | 117 | value={value} |
112 | gregorianCalendarLocale={gregorianCalendarLocale} | 118 | defaultOpenValue={defaultOpenValue} |
113 | formatter={formatter} | 119 | format={format} |
114 | onChange={this.onChange} | 120 | onChange={this.onChange} |
115 | showHour={showHour} | 121 | showHour={showHour} |
116 | showSecond={showSecond} | 122 | showSecond={showSecond} |
diff --git a/src/module/Select.jsx b/src/Select.jsx index 2ab9e61..e25bb29 100644 --- a/src/module/Select.jsx +++ b/src/Select.jsx | |||
@@ -1,4 +1,4 @@ | |||
1 | import React, {PropTypes} from 'react'; | 1 | import React, { PropTypes } from 'react'; |
2 | import ReactDom from 'react-dom'; | 2 | import ReactDom from 'react-dom'; |
3 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
4 | 4 | ||
@@ -26,7 +26,6 @@ const Select = React.createClass({ | |||
26 | propTypes: { | 26 | propTypes: { |
27 | prefixCls: PropTypes.string, | 27 | prefixCls: PropTypes.string, |
28 | options: PropTypes.array, | 28 | options: PropTypes.array, |
29 | gregorianCalendarLocale: PropTypes.object, | ||
30 | selectedIndex: PropTypes.number, | 29 | selectedIndex: PropTypes.number, |
31 | type: PropTypes.string, | 30 | type: PropTypes.string, |
32 | onSelect: PropTypes.func, | 31 | onSelect: PropTypes.func, |
@@ -61,7 +60,14 @@ const Select = React.createClass({ | |||
61 | if (!item.disabled) { | 60 | if (!item.disabled) { |
62 | onclick = this.onSelect.bind(this, +item.value); | 61 | onclick = this.onSelect.bind(this, +item.value); |
63 | } | 62 | } |
64 | return <li className={cls} key={index} onClick={onclick} disabled={item.disabled}>{item.value}</li>; | 63 | return (<li |
64 | className={cls} | ||
65 | key={index} | ||
66 | onClick={onclick} | ||
67 | disabled={item.disabled} | ||
68 | > | ||
69 | {item.value} | ||
70 | </li>); | ||
65 | }); | 71 | }); |
66 | }, | 72 | }, |
67 | 73 | ||
@@ -86,8 +92,10 @@ const Select = React.createClass({ | |||
86 | const { prefixCls } = this.props; | 92 | const { prefixCls } = this.props; |
87 | 93 | ||
88 | return ( | 94 | return ( |
89 | <div className={`${prefixCls}-select`} | 95 | <div |
90 | onMouseEnter={this.props.onMouseEnter}> | 96 | className={`${prefixCls}-select`} |
97 | onMouseEnter={this.props.onMouseEnter} | ||
98 | > | ||
91 | <ul ref="list">{this.getOptions()}</ul> | 99 | <ul ref="list">{this.getOptions()}</ul> |
92 | </div> | 100 | </div> |
93 | ); | 101 | ); |
diff --git a/src/TimePicker.jsx b/src/TimePicker.jsx index 86faa71..58f6ea1 100644 --- a/src/TimePicker.jsx +++ b/src/TimePicker.jsx | |||
@@ -1,9 +1,8 @@ | |||
1 | import React, { PropTypes } from 'react'; | 1 | import React, { PropTypes } from 'react'; |
2 | import Trigger from 'rc-trigger'; | 2 | import Trigger from 'rc-trigger'; |
3 | import Panel from './module/Panel'; | 3 | import Panel from './Panel'; |
4 | import placements from './util/placements'; | 4 | import placements from './placements'; |
5 | import CommonMixin from './mixin/CommonMixin'; | 5 | import moment from 'moment'; |
6 | import { getFormatter } from './util/index'; | ||
7 | 6 | ||
8 | function noop() { | 7 | function noop() { |
9 | } | 8 | } |
@@ -15,8 +14,9 @@ function refFn(field, component) { | |||
15 | const Picker = React.createClass({ | 14 | const Picker = React.createClass({ |
16 | propTypes: { | 15 | propTypes: { |
17 | prefixCls: PropTypes.string, | 16 | prefixCls: PropTypes.string, |
18 | locale: PropTypes.object, | 17 | clearText: PropTypes.string, |
19 | value: PropTypes.object, | 18 | value: PropTypes.object, |
19 | defaultOpenValue: PropTypes.object, | ||
20 | disabled: PropTypes.bool, | 20 | disabled: PropTypes.bool, |
21 | allowEmpty: PropTypes.bool, | 21 | allowEmpty: PropTypes.bool, |
22 | defaultValue: PropTypes.object, | 22 | defaultValue: PropTypes.object, |
@@ -27,7 +27,7 @@ const Picker = React.createClass({ | |||
27 | transitionName: PropTypes.string, | 27 | transitionName: PropTypes.string, |
28 | getPopupContainer: PropTypes.func, | 28 | getPopupContainer: PropTypes.func, |
29 | placeholder: PropTypes.string, | 29 | placeholder: PropTypes.string, |
30 | formatter: PropTypes.any, | 30 | format: PropTypes.string, |
31 | showHour: PropTypes.bool, | 31 | showHour: PropTypes.bool, |
32 | style: PropTypes.object, | 32 | style: PropTypes.object, |
33 | className: PropTypes.string, | 33 | className: PropTypes.string, |
@@ -41,15 +41,15 @@ const Picker = React.createClass({ | |||
41 | onClose: PropTypes.func, | 41 | onClose: PropTypes.func, |
42 | }, | 42 | }, |
43 | 43 | ||
44 | mixins: [CommonMixin], | ||
45 | |||
46 | getDefaultProps() { | 44 | getDefaultProps() { |
47 | return { | 45 | return { |
46 | clearText: 'clear', | ||
48 | prefixCls: 'rc-time-picker', | 47 | prefixCls: 'rc-time-picker', |
49 | defaultOpen: false, | 48 | defaultOpen: false, |
50 | style: {}, | 49 | style: {}, |
51 | className: '', | 50 | className: '', |
52 | align: {}, | 51 | align: {}, |
52 | defaultOpenValue: moment(), | ||
53 | allowEmpty: true, | 53 | allowEmpty: true, |
54 | showHour: true, | 54 | showHour: true, |
55 | showSecond: true, | 55 | showSecond: true, |
@@ -118,56 +118,40 @@ const Picker = React.createClass({ | |||
118 | this.props.onChange(value); | 118 | this.props.onChange(value); |
119 | }, | 119 | }, |
120 | 120 | ||
121 | getFormatter() { | 121 | getFormat() { |
122 | const formatter = this.props.formatter; | 122 | const format = this.props.format; |
123 | const locale = this.props.locale; | 123 | if (format) { |
124 | if (formatter) { | 124 | return format; |
125 | if (formatter === this.lastFormatter) { | ||
126 | return this.normalFormatter; | ||
127 | } | ||
128 | this.normalFormatter = getFormatter(formatter, locale); | ||
129 | this.lastFormatter = formatter; | ||
130 | return this.normalFormatter; | ||
131 | } | 125 | } |
132 | if (!this.props.showSecond) { | 126 | if (!this.props.showSecond) { |
133 | if (!this.notShowSecondFormatter) { | 127 | return 'HH:mm'; |
134 | this.notShowSecondFormatter = getFormatter('HH:mm', locale); | ||
135 | } | ||
136 | return this.notShowSecondFormatter; | ||
137 | } | 128 | } |
138 | if (!this.props.showHour) { | 129 | if (!this.props.showHour) { |
139 | if (!this.notShowHourFormatter) { | 130 | return 'mm:ss'; |
140 | this.notShowHourFormatter = getFormatter('mm:ss', locale); | ||
141 | } | ||
142 | return this.notShowHourFormatter; | ||
143 | } | 131 | } |
144 | if (!this.normalFormatter) { | 132 | return 'HH:mm:ss'; |
145 | this.normalFormatter = getFormatter('HH:mm:ss', locale); | ||
146 | } | ||
147 | return this.normalFormatter; | ||
148 | }, | 133 | }, |
149 | 134 | ||
150 | getPanelElement() { | 135 | getPanelElement() { |
151 | const { | 136 | const { |
152 | prefixCls, defaultValue, locale, placeholder, disabledHours, | 137 | prefixCls, placeholder, disabledHours, |
153 | disabledMinutes, disabledSeconds, hideDisabledOptions, | 138 | disabledMinutes, disabledSeconds, hideDisabledOptions, |
154 | allowEmpty, showHour, showSecond, | 139 | allowEmpty, showHour, showSecond, defaultOpenValue, clearText, |
155 | } = this.props; | 140 | } = this.props; |
156 | return ( | 141 | return ( |
157 | <Panel | 142 | <Panel |
143 | clearText={clearText} | ||
158 | prefixCls={`${prefixCls}-panel`} | 144 | prefixCls={`${prefixCls}-panel`} |
159 | ref={this.savePanelRef} | 145 | ref={this.savePanelRef} |
160 | value={this.state.value} | 146 | value={this.state.value} |
161 | onChange={this.onPanelChange} | 147 | onChange={this.onPanelChange} |
162 | gregorianCalendarLocale={locale.calendar} | ||
163 | onClear={this.onPanelClear} | 148 | onClear={this.onPanelClear} |
164 | defaultValue={defaultValue} | 149 | defaultOpenValue={defaultOpenValue} |
165 | showHour={showHour} | 150 | showHour={showHour} |
166 | onEsc={this.onEsc} | 151 | onEsc={this.onEsc} |
167 | showSecond={showSecond} | 152 | showSecond={showSecond} |
168 | locale={locale} | ||
169 | allowEmpty={allowEmpty} | 153 | allowEmpty={allowEmpty} |
170 | formatter={this.getFormatter()} | 154 | format={this.getFormat()} |
171 | placeholder={placeholder} | 155 | placeholder={placeholder} |
172 | disabledHours={disabledHours} | 156 | disabledHours={disabledHours} |
173 | disabledMinutes={disabledMinutes} | 157 | disabledMinutes={disabledMinutes} |
@@ -195,7 +179,11 @@ const Picker = React.createClass({ | |||
195 | }, | 179 | }, |
196 | 180 | ||
197 | render() { | 181 | render() { |
198 | const { prefixCls, placeholder, placement, align, disabled, transitionName, style, className, showHour, showSecond, getPopupContainer } = this.props; | 182 | const { |
183 | prefixCls, placeholder, placement, align, | ||
184 | disabled, transitionName, style, className, showHour, | ||
185 | showSecond, getPopupContainer, | ||
186 | } = this.props; | ||
199 | const { open, value } = this.state; | 187 | const { open, value } = this.state; |
200 | let popupClassName; | 188 | let popupClassName; |
201 | if (!showHour || !showSecond) { | 189 | if (!showHour || !showSecond) { |
@@ -222,7 +210,7 @@ const Picker = React.createClass({ | |||
222 | ref="picker" type="text" placeholder={placeholder} | 210 | ref="picker" type="text" placeholder={placeholder} |
223 | readOnly | 211 | readOnly |
224 | onKeyDown={this.onKeyDown} | 212 | onKeyDown={this.onKeyDown} |
225 | disabled={disabled} value={value && this.getFormatter().format(value) || ''} | 213 | disabled={disabled} value={value && value.format(this.getFormat()) || ''} |
226 | /> | 214 | /> |
227 | <span className={`${prefixCls}-icon`}/> | 215 | <span className={`${prefixCls}-icon`}/> |
228 | </span> | 216 | </span> |
diff --git a/src/locale/en_US.js b/src/locale/en_US.js deleted file mode 100644 index 506f4c9..0000000 --- a/src/locale/en_US.js +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | import enUs from 'gregorian-calendar-format/lib/locale/en_US'; | ||
2 | import enUsCalendar from 'gregorian-calendar/lib/locale/en_US'; | ||
3 | |||
4 | export 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 @@ | |||
1 | import ruRu from 'gregorian-calendar-format/lib/locale/ru_RU'; | ||
2 | import ruRuCalendar from 'gregorian-calendar/lib/locale/ru_RU'; | ||
3 | |||
4 | export 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 @@ | |||
1 | import zhCn from 'gregorian-calendar-format/lib/locale/zh_CN'; | ||
2 | import zhCnCalendar from 'gregorian-calendar/lib/locale/zh_CN'; | ||
3 | |||
4 | export default { | ||
5 | clear: '清除', | ||
6 | format: zhCn, | ||
7 | calendar: zhCnCalendar, | ||
8 | }; | ||
diff --git a/src/mixin/CommonMixin.js b/src/mixin/CommonMixin.js deleted file mode 100644 index be080fd..0000000 --- a/src/mixin/CommonMixin.js +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | import {PropTypes} from 'react'; | ||
2 | import enUs from '../locale/en_US'; | ||
3 | |||
4 | export default { | ||
5 | propTypes: { | ||
6 | prefixCls: PropTypes.string, | ||
7 | locale: PropTypes.object, | ||
8 | }, | ||
9 | |||
10 | getDefaultProps() { | ||
11 | return { | ||
12 | locale: enUs, | ||
13 | }; | ||
14 | }, | ||
15 | }; | ||
diff --git a/src/module/Header.jsx b/src/module/Header.jsx deleted file mode 100644 index a926e98..0000000 --- a/src/module/Header.jsx +++ /dev/null | |||
@@ -1,204 +0,0 @@ | |||
1 | import React, { PropTypes } from 'react'; | ||
2 | import createSelection from '../util/selection'; | ||
3 | |||
4 | const 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 | |||
204 | export 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 @@ | |||
1 | import DateTimeFormat from 'gregorian-calendar-format'; | ||
2 | |||
3 | export 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 @@ | |||
1 | export 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 | } | ||