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