]>
Commit | Line | Data |
---|---|---|
3ab3a128 | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | |
02de449a | 3 | import Trigger from 'rc-trigger'; |
4984ed85 | 4 | import Panel from './Panel'; |
5 | import placements from './placements'; | |
6 | import moment from 'moment'; | |
02de449a | 7 | |
8 | function noop() { | |
9 | } | |
10 | ||
11 | function refFn(field, component) { | |
12 | this[field] = component; | |
13 | } | |
14 | ||
cfe8e36c | 15 | export default class Picker extends Component { |
3ab3a128 | 16 | static propTypes = { |
02de449a | 17 | prefixCls: PropTypes.string, |
4984ed85 | 18 | clearText: PropTypes.string, |
9f9f39e4 | 19 | value: PropTypes.object, |
4984ed85 | 20 | defaultOpenValue: PropTypes.object, |
4e70ea0d | 21 | inputReadOnly: PropTypes.bool, |
02de449a | 22 | disabled: PropTypes.bool, |
8133e8cf | 23 | allowEmpty: PropTypes.bool, |
63541ed7 | 24 | defaultValue: PropTypes.object, |
02de449a | 25 | open: PropTypes.bool, |
8133e8cf | 26 | defaultOpen: PropTypes.bool, |
02de449a | 27 | align: PropTypes.object, |
28 | placement: PropTypes.any, | |
29 | transitionName: PropTypes.string, | |
8133e8cf | 30 | getPopupContainer: PropTypes.func, |
4acbf95c | 31 | placeholder: PropTypes.string, |
4984ed85 | 32 | format: PropTypes.string, |
8133e8cf | 33 | showHour: PropTypes.bool, |
37c36c09 | 34 | showMinute: PropTypes.bool, |
3b3350d5 | 35 | showSecond: PropTypes.bool, |
8133e8cf | 36 | style: PropTypes.object, |
96d366af | 37 | className: PropTypes.string, |
a7c6e7bb | 38 | popupClassName: PropTypes.string, |
71bd9bc1 M |
39 | disabledHours: PropTypes.func, |
40 | disabledMinutes: PropTypes.func, | |
41 | disabledSeconds: PropTypes.func, | |
518b852e | 42 | hideDisabledOptions: PropTypes.bool, |
02de449a | 43 | onChange: PropTypes.func, |
44 | onOpen: PropTypes.func, | |
45 | onClose: PropTypes.func, | |
e30387ab CS |
46 | onFocus: PropTypes.func, |
47 | onBlur: PropTypes.func, | |
b86fe1d1 | 48 | addon: PropTypes.func, |
6d1ad104 | 49 | name: PropTypes.string, |
73e6cf78 | 50 | autoComplete: PropTypes.string, |
dd275f7d | 51 | use12Hours: PropTypes.bool, |
5827568e MP |
52 | hourStep: PropTypes.number, |
53 | minuteStep: PropTypes.number, | |
54 | secondStep: PropTypes.number, | |
d18ecfb6 | 55 | focusOnOpen: PropTypes.bool, |
3931819e | 56 | closeOnEsc: PropTypes.bool, |
0e4fd162 | 57 | onKeyDown: PropTypes.func, |
d9a9b691 | 58 | autoFocus: PropTypes.bool, |
0414a016 | 59 | id: PropTypes.string, |
3ab3a128 | 60 | }; |
61 | ||
62 | static defaultProps = { | |
63 | clearText: 'clear', | |
64 | prefixCls: 'rc-time-picker', | |
65 | defaultOpen: false, | |
4e70ea0d | 66 | inputReadOnly: false, |
3ab3a128 | 67 | style: {}, |
68 | className: '', | |
a7c6e7bb | 69 | popupClassName: '', |
4dc88036 | 70 | id: '', |
3ab3a128 | 71 | align: {}, |
72 | defaultOpenValue: moment(), | |
73 | allowEmpty: true, | |
74 | showHour: true, | |
75 | showMinute: true, | |
76 | showSecond: true, | |
77 | disabledHours: noop, | |
78 | disabledMinutes: noop, | |
79 | disabledSeconds: noop, | |
80 | hideDisabledOptions: false, | |
81 | placement: 'bottomLeft', | |
82 | onChange: noop, | |
83 | onOpen: noop, | |
84 | onClose: noop, | |
e30387ab CS |
85 | onFocus: noop, |
86 | onBlur: noop, | |
3ab3a128 | 87 | addon: noop, |
88 | use12Hours: false, | |
d18ecfb6 | 89 | focusOnOpen: false, |
3931819e | 90 | closeOnEsc: true, |
0e4fd162 | 91 | onKeyDown: noop, |
3ab3a128 | 92 | }; |
93 | ||
94 | constructor(props) { | |
95 | super(props); | |
fa912931 | 96 | this.saveInputRef = refFn.bind(this, 'picker'); |
02de449a | 97 | this.savePanelRef = refFn.bind(this, 'panelInstance'); |
3ab3a128 | 98 | const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = props; |
99 | this.state = { | |
8133e8cf | 100 | open, |
101 | value, | |
e75ed0c6 | 102 | }; |
3ab3a128 | 103 | } |
02de449a | 104 | |
02de449a | 105 | componentWillReceiveProps(nextProps) { |
9f9f39e4 | 106 | const { value, open } = nextProps; |
6fc4e0e8 | 107 | if ('value' in nextProps) { |
9f9f39e4 | 108 | this.setState({ |
109 | value, | |
110 | }); | |
02de449a | 111 | } |
112 | if (open !== undefined) { | |
1882f74d | 113 | this.setState({ open }); |
02de449a | 114 | } |
3ab3a128 | 115 | } |
02de449a | 116 | |
3ab3a128 | 117 | onPanelChange = (value) => { |
9f9f39e4 | 118 | this.setValue(value); |
3ab3a128 | 119 | } |
02de449a | 120 | |
3ab3a128 | 121 | onPanelClear = () => { |
7702bb67 | 122 | this.setValue(null); |
63541ed7 | 123 | this.setOpen(false); |
3ab3a128 | 124 | } |
02de449a | 125 | |
3ab3a128 | 126 | onVisibleChange = (open) => { |
8133e8cf | 127 | this.setOpen(open); |
3ab3a128 | 128 | } |
8133e8cf | 129 | |
3ab3a128 | 130 | onEsc = () => { |
8133e8cf | 131 | this.setOpen(false); |
ed849606 | 132 | this.focus(); |
3ab3a128 | 133 | } |
8133e8cf | 134 | |
3ab3a128 | 135 | onKeyDown = (e) => { |
8133e8cf | 136 | if (e.keyCode === 40) { |
137 | this.setOpen(true); | |
138 | } | |
3ab3a128 | 139 | } |
02de449a | 140 | |
9f9f39e4 | 141 | setValue(value) { |
142 | if (!('value' in this.props)) { | |
143 | this.setState({ | |
144 | value, | |
145 | }); | |
146 | } | |
147 | this.props.onChange(value); | |
3ab3a128 | 148 | } |
9f9f39e4 | 149 | |
4984ed85 | 150 | getFormat() { |
dd2f6abd | 151 | const { format, showHour, showMinute, showSecond, use12Hours } = this.props; |
4984ed85 | 152 | if (format) { |
153 | return format; | |
8133e8cf | 154 | } |
dd2f6abd AS |
155 | |
156 | if (use12Hours) { | |
157 | const fmtString = ([ | |
158 | showHour ? 'h' : '', | |
159 | showMinute ? 'mm' : '', | |
160 | showSecond ? 'ss' : '', | |
161 | ].filter(item => !!item).join(':')); | |
162 | ||
163 | return fmtString.concat(' a'); | |
164 | } | |
165 | ||
37c36c09 | 166 | return [ |
167 | showHour ? 'HH' : '', | |
168 | showMinute ? 'mm' : '', | |
169 | showSecond ? 'ss' : '', | |
170 | ].filter(item => !!item).join(':'); | |
3ab3a128 | 171 | } |
8133e8cf | 172 | |
173 | getPanelElement() { | |
1882f74d | 174 | const { |
4984ed85 | 175 | prefixCls, placeholder, disabledHours, |
4e70ea0d | 176 | disabledMinutes, disabledSeconds, hideDisabledOptions, inputReadOnly, |
37c36c09 | 177 | allowEmpty, showHour, showMinute, showSecond, defaultOpenValue, clearText, |
3931819e | 178 | addon, use12Hours, focusOnOpen, closeOnEsc, onKeyDown, hourStep, minuteStep, secondStep, |
1882f74d | 179 | } = this.props; |
4acbf95c M |
180 | return ( |
181 | <Panel | |
4984ed85 | 182 | clearText={clearText} |
8133e8cf | 183 | prefixCls={`${prefixCls}-panel`} |
184 | ref={this.savePanelRef} | |
185 | value={this.state.value} | |
4e70ea0d | 186 | inputReadOnly={inputReadOnly} |
8133e8cf | 187 | onChange={this.onPanelChange} |
8133e8cf | 188 | onClear={this.onPanelClear} |
4984ed85 | 189 | defaultOpenValue={defaultOpenValue} |
8133e8cf | 190 | showHour={showHour} |
37c36c09 | 191 | showMinute={showMinute} |
8133e8cf | 192 | showSecond={showSecond} |
3b3350d5 | 193 | onEsc={this.onEsc} |
8133e8cf | 194 | allowEmpty={allowEmpty} |
4984ed85 | 195 | format={this.getFormat()} |
4acbf95c | 196 | placeholder={placeholder} |
518b852e M |
197 | disabledHours={disabledHours} |
198 | disabledMinutes={disabledMinutes} | |
199 | disabledSeconds={disabledSeconds} | |
200 | hideDisabledOptions={hideDisabledOptions} | |
dd275f7d | 201 | use12Hours={use12Hours} |
5827568e MP |
202 | hourStep={hourStep} |
203 | minuteStep={minuteStep} | |
204 | secondStep={secondStep} | |
b86fe1d1 | 205 | addon={addon} |
d18ecfb6 | 206 | focusOnOpen={focusOnOpen} |
3931819e | 207 | closeOnEsc={closeOnEsc} |
0e4fd162 | 208 | onKeyDown={onKeyDown} |
4acbf95c M |
209 | /> |
210 | ); | |
3ab3a128 | 211 | } |
4acbf95c | 212 | |
a7c6e7bb | 213 | getPopupClassName() { |
214 | const { showHour, showMinute, showSecond, use12Hours, prefixCls } = this.props; | |
215 | let popupClassName = this.props.popupClassName; | |
216 | // Keep it for old compatibility | |
217 | if ((!showHour || !showMinute || !showSecond) && !use12Hours) { | |
218 | popupClassName += ` ${prefixCls}-panel-narrow`; | |
219 | } | |
220 | let selectColumnCount = 0; | |
221 | if (showHour) { | |
222 | selectColumnCount += 1; | |
223 | } | |
224 | if (showMinute) { | |
225 | selectColumnCount += 1; | |
226 | } | |
227 | if (showSecond) { | |
228 | selectColumnCount += 1; | |
229 | } | |
230 | if (use12Hours) { | |
231 | selectColumnCount += 1; | |
232 | } | |
233 | popupClassName += ` ${prefixCls}-panel-column-${selectColumnCount}`; | |
234 | return popupClassName; | |
235 | } | |
236 | ||
71c3a196 | 237 | setOpen(open) { |
1882f74d | 238 | const { onOpen, onClose } = this.props; |
02de449a | 239 | if (this.state.open !== open) { |
71c3a196 | 240 | if (!('open' in this.props)) { |
241 | this.setState({ open }); | |
242 | } | |
02de449a | 243 | if (open) { |
71c3a196 | 244 | onOpen({ open }); |
02de449a | 245 | } else { |
71c3a196 | 246 | onClose({ open }); |
02de449a | 247 | } |
248 | } | |
3ab3a128 | 249 | } |
02de449a | 250 | |
ed849606 | 251 | focus() { |
dd63e6e7 | 252 | this.picker.focus(); |
3ab3a128 | 253 | } |
ed849606 | 254 | |
d9a9b691 WZ |
255 | blur() { |
256 | this.picker.blur(); | |
257 | } | |
258 | ||
02de449a | 259 | render() { |
4984ed85 | 260 | const { |
0414a016 | 261 | prefixCls, placeholder, placement, align, id, |
a7c6e7bb | 262 | disabled, transitionName, style, className, getPopupContainer, name, autoComplete, |
543a5211 | 263 | onFocus, onBlur, autoFocus, inputReadOnly, |
4984ed85 | 264 | } = this.props; |
4acbf95c | 265 | const { open, value } = this.state; |
a7c6e7bb | 266 | const popupClassName = this.getPopupClassName(); |
02de449a | 267 | return ( |
268 | <Trigger | |
96a4cefc | 269 | prefixCls={`${prefixCls}-panel`} |
8133e8cf | 270 | popupClassName={popupClassName} |
02de449a | 271 | popup={this.getPanelElement()} |
272 | popupAlign={align} | |
273 | builtinPlacements={placements} | |
274 | popupPlacement={placement} | |
275 | action={disabled ? [] : ['click']} | |
276 | destroyPopupOnHide | |
8133e8cf | 277 | getPopupContainer={getPopupContainer} |
02de449a | 278 | popupTransitionName={transitionName} |
4acbf95c | 279 | popupVisible={open} |
02de449a | 280 | onPopupVisibleChange={this.onVisibleChange} |
281 | > | |
96d366af | 282 | <span className={`${prefixCls} ${className}`} style={style}> |
1882f74d | 283 | <input |
284 | className={`${prefixCls}-input`} | |
66c7bc36 | 285 | ref={this.saveInputRef} |
286 | type="text" | |
287 | placeholder={placeholder} | |
6d1ad104 | 288 | name={name} |
1882f74d | 289 | onKeyDown={this.onKeyDown} |
d9a9b691 WZ |
290 | disabled={disabled} |
291 | value={value && value.format(this.getFormat()) || ''} | |
73e6cf78 | 292 | autoComplete={autoComplete} |
e30387ab CS |
293 | onFocus={onFocus} |
294 | onBlur={onBlur} | |
d9a9b691 | 295 | autoFocus={autoFocus} |
fdead5ab | 296 | onChange={noop} |
b6a1d52b | 297 | readOnly={!!inputReadOnly} |
0414a016 | 298 | id={id} |
543a5211 | 299 | /> |
9f9f39e4 | 300 | <span className={`${prefixCls}-icon`}/> |
02de449a | 301 | </span> |
302 | </Trigger> | |
303 | ); | |
3ab3a128 | 304 | } |
305 | } |