]> git.immae.eu Git - github/fretlink/time-picker.git/blob - src/TimePicker.jsx
release 0.1.0
[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 placements from './util/placements';
6 import CommonMixin from './mixin/CommonMixin';
7
8 function noop() {
9 }
10
11 function refFn(field, component) {
12 this[field] = component;
13 }
14
15 const Picker = React.createClass({
16 propTypes: {
17 prefixCls: PropTypes.string,
18 panel: PropTypes.element,
19 children: PropTypes.func,
20 disabled: PropTypes.bool,
21 value: PropTypes.object,
22 open: PropTypes.bool,
23 align: PropTypes.object,
24 placement: PropTypes.any,
25 transitionName: PropTypes.string,
26 onChange: PropTypes.func,
27 onOpen: PropTypes.func,
28 onClose: PropTypes.func,
29 },
30
31 mixins: [CommonMixin],
32
33 getDefaultProps() {
34 return {
35 open: false,
36 align: {},
37 placement: 'bottomLeft',
38 onChange: noop,
39 onOpen: noop,
40 onClose: noop,
41 };
42 },
43
44 getInitialState() {
45 this.savePanelRef = refFn.bind(this, 'panelInstance');
46 const { open, value } = this.props;
47 return { open, value };
48 },
49
50 componentWillReceiveProps(nextProps) {
51 const { value, open } = nextProps;
52 if (value !== undefined) {
53 this.setState({value});
54 }
55 if (open !== undefined) {
56 this.setState({open});
57 }
58 },
59
60 onPanelChange(value) {
61 const props = this.props;
62 this.setState({
63 value: value,
64 });
65 props.onChange(value);
66 },
67
68 onPanelClear() {
69 this.setOpen(false, this.focus);
70 },
71
72 onVisibleChange(open) {
73 this.setOpen(open, () => {
74 if (open) {
75 ReactDOM.findDOMNode(this.panelInstance).focus();
76 }
77 });
78 },
79
80 getPanelElement() {
81 const panel = this.props.panel;
82 const extraProps = {
83 ref: this.savePanelRef,
84 defaultValue: this.state.value || panel.props.defaultValue,
85 onChange: createChainedFunction(panel.props.onChange, this.onPanelChange),
86 onClear: createChainedFunction(panel.props.onClear, this.onPanelClear),
87 };
88
89 return React.cloneElement(panel, extraProps);
90 },
91
92 setOpen(open, callback) {
93 const {onOpen, onClose} = this.props;
94 if (this.state.open !== open) {
95 this.setState({
96 open: open,
97 }, callback);
98 const event = {
99 open: open,
100 };
101 if (open) {
102 onOpen(event);
103 } else {
104 onClose(event);
105 }
106 }
107 },
108
109 focus() {
110 if (!this.state.open) {
111 ReactDOM.findDOMNode(this).focus();
112 }
113 },
114
115 render() {
116 const state = this.state;
117 const props = this.props;
118 const { prefixCls, placement, align, disabled, transitionName, children } = props;
119 return (
120 <Trigger
121 prefixCls={prefixCls}
122 popup={this.getPanelElement()}
123 popupAlign={align}
124 builtinPlacements={placements}
125 popupPlacement={placement}
126 action={disabled ? [] : ['click']}
127 destroyPopupOnHide
128 popupTransitionName={transitionName}
129 popupVisible={state.open}
130 onPopupVisibleChange={this.onVisibleChange}
131 >
132 <span className={`${prefixCls}-picker`}>
133 {children(state, props)}
134 </span>
135 </Trigger>
136 );
137 },
138 });
139
140 export default Picker;