]>
Commit | Line | Data |
---|---|---|
02de449a | 1 | import React, {PropTypes} from 'react'; |
2 | import ReactDOM from 'react-dom'; | |
3 | import Trigger from 'rc-trigger'; | |
4 | import {createChainedFunction} from 'rc-util'; | |
4acbf95c | 5 | import Panel from 'rc-time-picker/src/module/Panel'; |
02de449a | 6 | import placements from './util/placements'; |
7 | import CommonMixin from './mixin/CommonMixin'; | |
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, |
02de449a | 20 | children: PropTypes.func, |
21 | disabled: PropTypes.bool, | |
22 | value: PropTypes.object, | |
23 | open: PropTypes.bool, | |
24 | align: PropTypes.object, | |
25 | placement: PropTypes.any, | |
26 | transitionName: PropTypes.string, | |
4acbf95c M |
27 | placeholder: PropTypes.string, |
28 | formatter: PropTypes.object, | |
29 | hourOptions: PropTypes.array, | |
30 | minuteOptions: PropTypes.array, | |
31 | secondOptions: PropTypes.array, | |
02de449a | 32 | onChange: PropTypes.func, |
33 | onOpen: PropTypes.func, | |
34 | onClose: PropTypes.func, | |
35 | }, | |
36 | ||
37 | mixins: [CommonMixin], | |
38 | ||
39 | getDefaultProps() { | |
40 | return { | |
41 | open: false, | |
42 | align: {}, | |
43 | placement: 'bottomLeft', | |
44 | onChange: noop, | |
45 | onOpen: noop, | |
46 | onClose: noop, | |
47 | }; | |
48 | }, | |
49 | ||
50 | getInitialState() { | |
51 | this.savePanelRef = refFn.bind(this, 'panelInstance'); | |
52 | const { open, value } = this.props; | |
53 | return { open, value }; | |
54 | }, | |
55 | ||
02de449a | 56 | componentWillReceiveProps(nextProps) { |
57 | const { value, open } = nextProps; | |
58 | if (value !== undefined) { | |
59 | this.setState({value}); | |
60 | } | |
61 | if (open !== undefined) { | |
62 | this.setState({open}); | |
63 | } | |
64 | }, | |
65 | ||
02de449a | 66 | onPanelChange(value) { |
67 | const props = this.props; | |
68 | this.setState({ | |
69 | value: value, | |
70 | }); | |
71 | props.onChange(value); | |
72 | }, | |
73 | ||
74 | onPanelClear() { | |
4acbf95c | 75 | this.setOpen(false); |
02de449a | 76 | }, |
77 | ||
78 | onVisibleChange(open) { | |
79 | this.setOpen(open, () => { | |
80 | if (open) { | |
4acbf95c | 81 | ReactDOM.findDOMNode(this.refs.picker).blur(); |
02de449a | 82 | ReactDOM.findDOMNode(this.panelInstance).focus(); |
83 | } | |
84 | }); | |
85 | }, | |
86 | ||
4acbf95c M |
87 | getPanel() { |
88 | const { value, locale, formatter, placeholder, hourOptions, minuteOptions, secondOptions } = this.props; | |
89 | return ( | |
90 | <Panel | |
91 | defaultValue={value} | |
92 | locale={locale} | |
93 | formatter={formatter} | |
94 | placeholder={placeholder} | |
95 | hourOptions={hourOptions} | |
96 | minuteOptions={minuteOptions} | |
97 | secondOptions={secondOptions} | |
98 | /> | |
99 | ); | |
100 | }, | |
101 | ||
02de449a | 102 | getPanelElement() { |
4acbf95c | 103 | const panel = this.getPanel(); |
02de449a | 104 | const extraProps = { |
105 | ref: this.savePanelRef, | |
106 | defaultValue: this.state.value || panel.props.defaultValue, | |
107 | onChange: createChainedFunction(panel.props.onChange, this.onPanelChange), | |
108 | onClear: createChainedFunction(panel.props.onClear, this.onPanelClear), | |
109 | }; | |
110 | ||
111 | return React.cloneElement(panel, extraProps); | |
112 | }, | |
113 | ||
114 | setOpen(open, callback) { | |
115 | const {onOpen, onClose} = this.props; | |
116 | if (this.state.open !== open) { | |
117 | this.setState({ | |
118 | open: open, | |
119 | }, callback); | |
120 | const event = { | |
121 | open: open, | |
122 | }; | |
123 | if (open) { | |
124 | onOpen(event); | |
125 | } else { | |
126 | onClose(event); | |
127 | } | |
128 | } | |
129 | }, | |
130 | ||
02de449a | 131 | render() { |
4acbf95c M |
132 | const { prefixCls, placement, align, disabled, transitionName, children, formatter } = this.props; |
133 | const { open, value } = this.state; | |
134 | ||
02de449a | 135 | return ( |
136 | <Trigger | |
137 | prefixCls={prefixCls} | |
138 | popup={this.getPanelElement()} | |
139 | popupAlign={align} | |
140 | builtinPlacements={placements} | |
141 | popupPlacement={placement} | |
142 | action={disabled ? [] : ['click']} | |
143 | destroyPopupOnHide | |
144 | popupTransitionName={transitionName} | |
4acbf95c | 145 | popupVisible={open} |
02de449a | 146 | onPopupVisibleChange={this.onVisibleChange} |
147 | > | |
148 | <span className={`${prefixCls}-picker`}> | |
4acbf95c | 149 | <input ref="picker" type="text" placeholder="请选择时间" readOnly disabled={disabled} value={value && formatter.format(value)} /> |
02de449a | 150 | </span> |
151 | </Trigger> | |
152 | ); | |
153 | }, | |
154 | }); | |
155 | ||
156 | export default Picker; |