]>
Commit | Line | Data |
---|---|---|
1882f74d | 1 | import React, { PropTypes } from 'react'; |
02de449a | 2 | import Trigger from 'rc-trigger'; |
15bb18d9 | 3 | import Panel from './module/Panel'; |
02de449a | 4 | import placements from './util/placements'; |
5 | import CommonMixin from './mixin/CommonMixin'; | |
1882f74d | 6 | import { getFormatter } from './util/index'; |
02de449a | 7 | |
8 | function noop() { | |
9 | } | |
10 | ||
11 | function refFn(field, component) { | |
12 | this[field] = component; | |
13 | } | |
14 | ||
15 | const Picker = React.createClass({ | |
16 | propTypes: { | |
17 | prefixCls: PropTypes.string, | |
4acbf95c | 18 | locale: PropTypes.object, |
9f9f39e4 | 19 | value: PropTypes.object, |
02de449a | 20 | disabled: PropTypes.bool, |
8133e8cf | 21 | allowEmpty: PropTypes.bool, |
63541ed7 | 22 | defaultValue: PropTypes.object, |
02de449a | 23 | open: PropTypes.bool, |
8133e8cf | 24 | defaultOpen: PropTypes.bool, |
02de449a | 25 | align: PropTypes.object, |
26 | placement: PropTypes.any, | |
27 | transitionName: PropTypes.string, | |
8133e8cf | 28 | getPopupContainer: PropTypes.func, |
4acbf95c | 29 | placeholder: PropTypes.string, |
8133e8cf | 30 | formatter: PropTypes.any, |
31 | showHour: PropTypes.bool, | |
32 | style: PropTypes.object, | |
96d366af | 33 | className: PropTypes.string, |
8133e8cf | 34 | showSecond: PropTypes.bool, |
71bd9bc1 M |
35 | disabledHours: PropTypes.func, |
36 | disabledMinutes: PropTypes.func, | |
37 | disabledSeconds: PropTypes.func, | |
518b852e | 38 | hideDisabledOptions: PropTypes.bool, |
02de449a | 39 | onChange: PropTypes.func, |
40 | onOpen: PropTypes.func, | |
41 | onClose: PropTypes.func, | |
42 | }, | |
43 | ||
44 | mixins: [CommonMixin], | |
45 | ||
46 | getDefaultProps() { | |
47 | return { | |
04de55f8 | 48 | prefixCls: 'rc-time-picker', |
8133e8cf | 49 | defaultOpen: false, |
50 | style: {}, | |
96d366af | 51 | className: '', |
02de449a | 52 | align: {}, |
8133e8cf | 53 | allowEmpty: true, |
54 | showHour: true, | |
55 | showSecond: true, | |
71bd9bc1 M |
56 | disabledHours: noop, |
57 | disabledMinutes: noop, | |
58 | disabledSeconds: noop, | |
518b852e | 59 | hideDisabledOptions: false, |
02de449a | 60 | placement: 'bottomLeft', |
61 | onChange: noop, | |
62 | onOpen: noop, | |
63 | onClose: noop, | |
64 | }; | |
65 | }, | |
66 | ||
67 | getInitialState() { | |
68 | this.savePanelRef = refFn.bind(this, 'panelInstance'); | |
8133e8cf | 69 | const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = this.props; |
e75ed0c6 | 70 | return { |
8133e8cf | 71 | open, |
72 | value, | |
e75ed0c6 | 73 | }; |
02de449a | 74 | }, |
75 | ||
02de449a | 76 | componentWillReceiveProps(nextProps) { |
9f9f39e4 | 77 | const { value, open } = nextProps; |
6fc4e0e8 | 78 | if ('value' in nextProps) { |
9f9f39e4 | 79 | this.setState({ |
80 | value, | |
81 | }); | |
02de449a | 82 | } |
83 | if (open !== undefined) { | |
1882f74d | 84 | this.setState({ open }); |
02de449a | 85 | } |
86 | }, | |
87 | ||
02de449a | 88 | onPanelChange(value) { |
9f9f39e4 | 89 | this.setValue(value); |
02de449a | 90 | }, |
91 | ||
92 | onPanelClear() { | |
7702bb67 | 93 | this.setValue(null); |
63541ed7 | 94 | this.setOpen(false); |
02de449a | 95 | }, |
96 | ||
97 | onVisibleChange(open) { | |
8133e8cf | 98 | this.setOpen(open); |
99 | }, | |
100 | ||
101 | onEsc() { | |
102 | this.setOpen(false); | |
103 | this.refs.picker.focus(); | |
104 | }, | |
105 | ||
106 | onKeyDown(e) { | |
107 | if (e.keyCode === 40) { | |
108 | this.setOpen(true); | |
109 | } | |
02de449a | 110 | }, |
111 | ||
9f9f39e4 | 112 | setValue(value) { |
113 | if (!('value' in this.props)) { | |
114 | this.setState({ | |
115 | value, | |
116 | }); | |
117 | } | |
118 | this.props.onChange(value); | |
119 | }, | |
120 | ||
8133e8cf | 121 | getFormatter() { |
122 | const formatter = this.props.formatter; | |
123 | const locale = this.props.locale; | |
124 | if (formatter) { | |
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 | } | |
132 | if (!this.props.showSecond) { | |
133 | if (!this.notShowSecondFormatter) { | |
134 | this.notShowSecondFormatter = getFormatter('HH:mm', locale); | |
135 | } | |
136 | return this.notShowSecondFormatter; | |
137 | } | |
138 | if (!this.props.showHour) { | |
139 | if (!this.notShowHourFormatter) { | |
140 | this.notShowHourFormatter = getFormatter('mm:ss', locale); | |
141 | } | |
142 | return this.notShowHourFormatter; | |
143 | } | |
144 | if (!this.normalFormatter) { | |
145 | this.normalFormatter = getFormatter('HH:mm:ss', locale); | |
146 | } | |
147 | return this.normalFormatter; | |
148 | }, | |
149 | ||
150 | getPanelElement() { | |
1882f74d | 151 | const { |
152 | prefixCls, defaultValue, locale, placeholder, disabledHours, | |
153 | disabledMinutes, disabledSeconds, hideDisabledOptions, | |
154 | allowEmpty, showHour, showSecond, | |
155 | } = this.props; | |
4acbf95c M |
156 | return ( |
157 | <Panel | |
8133e8cf | 158 | prefixCls={`${prefixCls}-panel`} |
159 | ref={this.savePanelRef} | |
160 | value={this.state.value} | |
161 | onChange={this.onPanelChange} | |
6fc4e0e8 | 162 | gregorianCalendarLocale={locale.calendar} |
8133e8cf | 163 | onClear={this.onPanelClear} |
63541ed7 | 164 | defaultValue={defaultValue} |
8133e8cf | 165 | showHour={showHour} |
166 | onEsc={this.onEsc} | |
167 | showSecond={showSecond} | |
4acbf95c | 168 | locale={locale} |
8133e8cf | 169 | allowEmpty={allowEmpty} |
170 | formatter={this.getFormatter()} | |
4acbf95c | 171 | placeholder={placeholder} |
518b852e M |
172 | disabledHours={disabledHours} |
173 | disabledMinutes={disabledMinutes} | |
174 | disabledSeconds={disabledSeconds} | |
175 | hideDisabledOptions={hideDisabledOptions} | |
4acbf95c M |
176 | /> |
177 | ); | |
178 | }, | |
179 | ||
02de449a | 180 | setOpen(open, callback) { |
1882f74d | 181 | const { onOpen, onClose } = this.props; |
02de449a | 182 | if (this.state.open !== open) { |
183 | this.setState({ | |
8133e8cf | 184 | open, |
02de449a | 185 | }, callback); |
186 | const event = { | |
8133e8cf | 187 | open, |
02de449a | 188 | }; |
189 | if (open) { | |
190 | onOpen(event); | |
191 | } else { | |
192 | onClose(event); | |
193 | } | |
194 | } | |
195 | }, | |
196 | ||
02de449a | 197 | render() { |
96d366af | 198 | const { prefixCls, placeholder, placement, align, disabled, transitionName, style, className, showHour, showSecond, getPopupContainer } = this.props; |
4acbf95c | 199 | const { open, value } = this.state; |
8133e8cf | 200 | let popupClassName; |
201 | if (!showHour || !showSecond) { | |
5784f914 | 202 | popupClassName = `${prefixCls}-panel-narrow`; |
8133e8cf | 203 | } |
02de449a | 204 | return ( |
205 | <Trigger | |
96a4cefc | 206 | prefixCls={`${prefixCls}-panel`} |
8133e8cf | 207 | popupClassName={popupClassName} |
02de449a | 208 | popup={this.getPanelElement()} |
209 | popupAlign={align} | |
210 | builtinPlacements={placements} | |
211 | popupPlacement={placement} | |
212 | action={disabled ? [] : ['click']} | |
213 | destroyPopupOnHide | |
8133e8cf | 214 | getPopupContainer={getPopupContainer} |
02de449a | 215 | popupTransitionName={transitionName} |
4acbf95c | 216 | popupVisible={open} |
02de449a | 217 | onPopupVisibleChange={this.onVisibleChange} |
218 | > | |
96d366af | 219 | <span className={`${prefixCls} ${className}`} style={style}> |
1882f74d | 220 | <input |
221 | className={`${prefixCls}-input`} | |
222 | ref="picker" type="text" placeholder={placeholder} | |
223 | readOnly | |
224 | onKeyDown={this.onKeyDown} | |
225 | disabled={disabled} value={value && this.getFormatter().format(value) || ''} | |
226 | /> | |
9f9f39e4 | 227 | <span className={`${prefixCls}-icon`}/> |
02de449a | 228 | </span> |
229 | </Trigger> | |
230 | ); | |
231 | }, | |
232 | }); | |
233 | ||
234 | export default Picker; |