]>
Commit | Line | Data |
---|---|---|
1 | import React, {PropTypes} from 'react'; | |
2 | import ReactDOM from 'react-dom'; | |
3 | import Trigger from 'rc-trigger'; | |
4 | import {createChainedFunction} from 'rc-util'; | |
5 | import Panel from 'rc-time-picker/src/module/Panel'; | |
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, | |
19 | locale: PropTypes.object, | |
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, | |
27 | placeholder: PropTypes.string, | |
28 | formatter: PropTypes.object, | |
29 | hourOptions: PropTypes.array, | |
30 | minuteOptions: PropTypes.array, | |
31 | secondOptions: PropTypes.array, | |
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 | ||
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 | ||
66 | onPanelChange(value) { | |
67 | const props = this.props; | |
68 | this.setState({ | |
69 | value: value, | |
70 | }); | |
71 | props.onChange(value); | |
72 | }, | |
73 | ||
74 | onPanelClear() { | |
75 | this.setOpen(false); | |
76 | }, | |
77 | ||
78 | onVisibleChange(open) { | |
79 | this.setOpen(open, () => { | |
80 | if (open) { | |
81 | ReactDOM.findDOMNode(this.refs.picker).blur(); | |
82 | ReactDOM.findDOMNode(this.panelInstance).focus(); | |
83 | } | |
84 | }); | |
85 | }, | |
86 | ||
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 | ||
102 | getPanelElement() { | |
103 | const panel = this.getPanel(); | |
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 | ||
131 | render() { | |
132 | const { prefixCls, placement, align, disabled, transitionName, children, formatter } = this.props; | |
133 | const { open, value } = this.state; | |
134 | ||
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} | |
145 | popupVisible={open} | |
146 | onPopupVisibleChange={this.onVisibleChange} | |
147 | > | |
148 | <span className={`${prefixCls}-picker`}> | |
149 | <input ref="picker" type="text" placeholder="请选择时间" readOnly disabled={disabled} value={value && formatter.format(value)} /> | |
150 | </span> | |
151 | </Trigger> | |
152 | ); | |
153 | }, | |
154 | }); | |
155 | ||
156 | export default Picker; |