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