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