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