aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/module
diff options
context:
space:
mode:
Diffstat (limited to 'src/module')
-rw-r--r--src/module/Combobox.jsx24
-rw-r--r--src/module/Header.jsx44
-rw-r--r--src/module/Panel.jsx49
-rw-r--r--src/module/Select.jsx19
4 files changed, 80 insertions, 56 deletions
diff --git a/src/module/Combobox.jsx b/src/module/Combobox.jsx
index afce675..3dfd321 100644
--- a/src/module/Combobox.jsx
+++ b/src/module/Combobox.jsx
@@ -1,5 +1,6 @@
1import React, {PropTypes} from 'react'; 1import React, {PropTypes} from 'react';
2import Select from './Select'; 2import Select from './Select';
3import GregorianCalendar from 'gregorian-calendar';
3 4
4const formatOption = (option) => { 5const formatOption = (option) => {
5 if (option < 10) { 6 if (option < 10) {
@@ -15,6 +16,7 @@ const Combobox = React.createClass({
15 value: PropTypes.object, 16 value: PropTypes.object,
16 onChange: PropTypes.func, 17 onChange: PropTypes.func,
17 showHour: PropTypes.bool, 18 showHour: PropTypes.bool,
19 gregorianCalendarLocale: PropTypes.object,
18 showSecond: PropTypes.bool, 20 showSecond: PropTypes.bool,
19 hourOptions: PropTypes.array, 21 hourOptions: PropTypes.array,
20 minuteOptions: PropTypes.array, 22 minuteOptions: PropTypes.array,
@@ -22,7 +24,13 @@ const Combobox = React.createClass({
22 }, 24 },
23 25
24 onItemChange(type, itemValue) { 26 onItemChange(type, itemValue) {
25 const { value, onChange } = this.props; 27 const { onChange } = this.props;
28 let value = this.props.value;
29 if (value) {
30 value = value.clone();
31 } else {
32 value = this.getNow().clone();
33 }
26 if (type === 'hour') { 34 if (type === 'hour') {
27 value.setHourOfDay(itemValue); 35 value.setHourOfDay(itemValue);
28 } else if (type === 'minute') { 36 } else if (type === 'minute') {
@@ -78,9 +86,19 @@ const Combobox = React.createClass({
78 ); 86 );
79 }, 87 },
80 88
81 render() { 89 getNow() {
82 const { prefixCls, value } = this.props; 90 if (this.showNow) {
91 return this.showNow;
92 }
93 const value = new GregorianCalendar(this.props.gregorianCalendarLocale);
94 value.setTime(Date.now());
95 this.showNow = value;
96 return value;
97 },
83 98
99 render() {
100 const { prefixCls } = this.props;
101 const value = this.props.value || this.getNow();
84 return ( 102 return (
85 <div className={`${prefixCls}-combobox`}> 103 <div className={`${prefixCls}-combobox`}>
86 {this.getHourSelect(value.getHourOfDay())} 104 {this.getHourSelect(value.getHourOfDay())}
diff --git a/src/module/Header.jsx b/src/module/Header.jsx
index b65fd25..962328c 100644
--- a/src/module/Header.jsx
+++ b/src/module/Header.jsx
@@ -4,7 +4,7 @@ const Header = React.createClass({
4 propTypes: { 4 propTypes: {
5 formatter: PropTypes.object, 5 formatter: PropTypes.object,
6 prefixCls: PropTypes.string, 6 prefixCls: PropTypes.string,
7 gregorianTimePickerLocale: PropTypes.object, 7 gregorianCalendarLocale: PropTypes.object,
8 locale: PropTypes.object, 8 locale: PropTypes.object,
9 disabledDate: PropTypes.func, 9 disabledDate: PropTypes.func,
10 placeholder: PropTypes.string, 10 placeholder: PropTypes.string,
@@ -14,7 +14,8 @@ const Header = React.createClass({
14 secondOptions: PropTypes.array, 14 secondOptions: PropTypes.array,
15 onChange: PropTypes.func, 15 onChange: PropTypes.func,
16 onClear: PropTypes.func, 16 onClear: PropTypes.func,
17 showClear: PropTypes.bool, 17 onEsc: PropTypes.func,
18 allowEmpty: PropTypes.bool,
18 }, 19 },
19 20
20 getInitialState() { 21 getInitialState() {
@@ -25,6 +26,12 @@ const Header = React.createClass({
25 }; 26 };
26 }, 27 },
27 28
29 componentDidMount() {
30 this.timer = setTimeout(() => {
31 this.refs.input.focus();
32 }, 0);
33 },
34
28 componentWillReceiveProps(nextProps) { 35 componentWillReceiveProps(nextProps) {
29 const value = nextProps.value; 36 const value = nextProps.value;
30 this.setState({ 37 this.setState({
@@ -33,19 +40,23 @@ const Header = React.createClass({
33 }); 40 });
34 }, 41 },
35 42
43 componentWillUnmount() {
44 clearTimeout(this.timer);
45 },
46
36 onInputChange(event) { 47 onInputChange(event) {
37 const str = event.target.value; 48 const str = event.target.value;
38 this.setState({ 49 this.setState({
39 str, 50 str,
40 }); 51 });
41 let value = null; 52 let value = null;
42 const {formatter, gregorianTimePickerLocale, hourOptions, minuteOptions, secondOptions, onChange} = this.props; 53 const {formatter, gregorianCalendarLocale, hourOptions, minuteOptions, secondOptions, onChange, allowEmpty} = this.props;
43 54
44 if (str) { 55 if (str) {
45 const originalValue = this.props.value; 56 const originalValue = this.props.value;
46 try { 57 try {
47 value = formatter.parse(str, { 58 value = formatter.parse(str, {
48 locale: gregorianTimePickerLocale, 59 locale: gregorianCalendarLocale,
49 obeyCount: true, 60 obeyCount: true,
50 }); 61 });
51 } catch (ex) { 62 } catch (ex) {
@@ -84,8 +95,13 @@ const Header = React.createClass({
84 }); 95 });
85 return; 96 return;
86 } 97 }
87 } else { 98 } else if (allowEmpty) {
88 onChange(null); 99 onChange(null);
100 } else {
101 this.setState({
102 invalid: true,
103 });
104 return;
89 } 105 }
90 106
91 this.setState({ 107 this.setState({
@@ -93,24 +109,34 @@ const Header = React.createClass({
93 }); 109 });
94 }, 110 },
95 111
112 onKeyDown(e) {
113 if (e.keyCode === 27) {
114 this.props.onEsc();
115 }
116 },
117
96 onClear() { 118 onClear() {
97 this.setState({str: ''}); 119 this.setState({str: ''});
98 this.props.onClear(); 120 this.props.onClear();
99 }, 121 },
100 122
101 getClearButton() { 123 getClearButton() {
102 const { locale, prefixCls, showClear } = this.props; 124 const { locale, prefixCls, allowEmpty } = this.props;
103 if (!showClear) { 125 if (!allowEmpty) {
104 return null; 126 return null;
105 } 127 }
106 return <a className={`${prefixCls}-clear-btn`} role="button" title={locale.clear} onMouseDown={this.onClear} />; 128 return <a className={`${prefixCls}-clear-btn`} role="button" title={locale.clear} onMouseDown={this.onClear}/>;
107 }, 129 },
108 130
109 getInput() { 131 getInput() {
110 const { prefixCls, placeholder } = this.props; 132 const { prefixCls, placeholder } = this.props;
111 const { invalid, str } = this.state; 133 const { invalid, str } = this.state;
112 const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; 134 const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
113 return <input className={`${prefixCls}-input ${invalidClass}`} value={str} placeholder={placeholder} onChange={this.onInputChange} />; 135 return (<input className={`${prefixCls}-input ${invalidClass}`}
136 ref="input"
137 onKeyDown={this.onKeyDown}
138 value={str}
139 placeholder={placeholder} onChange={this.onInputChange}/>);
114 }, 140 },
115 141
116 render() { 142 render() {
diff --git a/src/module/Panel.jsx b/src/module/Panel.jsx
index e372774..b91c6fe 100644
--- a/src/module/Panel.jsx
+++ b/src/module/Panel.jsx
@@ -1,8 +1,4 @@
1import React, {PropTypes} from 'react'; 1import React, {PropTypes} from 'react';
2import classnames from 'classnames';
3import GregorianCalendar from 'gregorian-calendar';
4import zhCn from 'gregorian-calendar/lib/locale/zh_CN';
5
6import CommonMixin from '../mixin/CommonMixin'; 2import CommonMixin from '../mixin/CommonMixin';
7import Header from './Header'; 3import Header from './Header';
8import Combobox from './Combobox'; 4import Combobox from './Combobox';
@@ -22,11 +18,16 @@ const Panel = React.createClass({
22 value: PropTypes.object, 18 value: PropTypes.object,
23 locale: PropTypes.object, 19 locale: PropTypes.object,
24 placeholder: PropTypes.string, 20 placeholder: PropTypes.string,
21 gregorianCalendarLocale: PropTypes.object,
25 formatter: PropTypes.object, 22 formatter: PropTypes.object,
26 hourOptions: PropTypes.array, 23 hourOptions: PropTypes.array,
27 minuteOptions: PropTypes.array, 24 minuteOptions: PropTypes.array,
28 secondOptions: PropTypes.array, 25 secondOptions: PropTypes.array,
29 onChange: PropTypes.func, 26 onChange: PropTypes.func,
27 onEsc: PropTypes.func,
28 allowEmpty: PropTypes.bool,
29 showHour: PropTypes.bool,
30 showSecond: PropTypes.bool,
30 onClear: PropTypes.func, 31 onClear: PropTypes.func,
31 }, 32 },
32 33
@@ -43,26 +44,11 @@ const Panel = React.createClass({
43 }, 44 },
44 45
45 getInitialState() { 46 getInitialState() {
46 let value = this.props.value;
47 if (!value) {
48 value = new GregorianCalendar(zhCn);
49 value.setTime(Date.now());
50 }
51 return { 47 return {
52 value, 48 value: this.props.value,
53 }; 49 };
54 }, 50 },
55 51
56 componentWillMount() {
57 const formatter = this.props.formatter;
58 const pattern = formatter.originalPattern;
59 if (pattern === 'HH:mm') {
60 this.showSecond = false;
61 } else if (pattern === 'mm:ss') {
62 this.showHour = false;
63 }
64 },
65
66 componentWillReceiveProps(nextProps) { 52 componentWillReceiveProps(nextProps) {
67 const value = nextProps.value; 53 const value = nextProps.value;
68 if (value) { 54 if (value) {
@@ -81,37 +67,34 @@ const Panel = React.createClass({
81 this.props.onClear(); 67 this.props.onClear();
82 }, 68 },
83 69
84 showHour: true,
85 showSecond: true,
86
87 render() { 70 render() {
88 const { locale, prefixCls, placeholder, hourOptions, minuteOptions, secondOptions } = this.props; 71 const { locale, prefixCls, placeholder, hourOptions, minuteOptions, secondOptions, allowEmpty, showHour, showSecond, formatter, gregorianCalendarLocale } = this.props;
89 const value = this.state.value; 72 const value = this.state.value;
90 const cls = classnames({ 'narrow': !this.showHour || !this.showSecond });
91
92 return ( 73 return (
93 <div className={`${prefixCls}-panel-inner ${cls}`}> 74 <div className={`${prefixCls}-inner`}>
94 <Header 75 <Header
95 prefixCls={prefixCls} 76 prefixCls={prefixCls}
96 gregorianTimePickerLocale={value.locale} 77 gregorianCalendarLocale={gregorianCalendarLocale}
97 locale={locale} 78 locale={locale}
98 value={value} 79 value={value}
99 formatter={this.getFormatter()} 80 onEsc={this.props.onEsc}
81 formatter={formatter}
100 placeholder={placeholder} 82 placeholder={placeholder}
101 hourOptions={hourOptions} 83 hourOptions={hourOptions}
102 minuteOptions={minuteOptions} 84 minuteOptions={minuteOptions}
103 secondOptions={secondOptions} 85 secondOptions={secondOptions}
104 onChange={this.onChange} 86 onChange={this.onChange}
105 onClear={this.onClear} 87 onClear={this.onClear}
106 showClear 88 allowEmpty={allowEmpty}
107 /> 89 />
108 <Combobox 90 <Combobox
109 prefixCls={prefixCls} 91 prefixCls={prefixCls}
110 value={value} 92 value={value}
111 formatter={this.getFormatter()} 93 gregorianCalendarLocale={gregorianCalendarLocale}
94 formatter={formatter}
112 onChange={this.onChange} 95 onChange={this.onChange}
113 showHour={this.showHour} 96 showHour={showHour}
114 showSecond={this.showSecond} 97 showSecond={showSecond}
115 hourOptions={hourOptions} 98 hourOptions={hourOptions}
116 minuteOptions={minuteOptions} 99 minuteOptions={minuteOptions}
117 secondOptions={secondOptions} 100 secondOptions={secondOptions}
diff --git a/src/module/Select.jsx b/src/module/Select.jsx
index 2b69623..be4c025 100644
--- a/src/module/Select.jsx
+++ b/src/module/Select.jsx
@@ -22,6 +22,7 @@ const Select = React.createClass({
22 propTypes: { 22 propTypes: {
23 prefixCls: PropTypes.string, 23 prefixCls: PropTypes.string,
24 options: PropTypes.array, 24 options: PropTypes.array,
25 gregorianCalendarLocale: PropTypes.object,
25 selectedIndex: PropTypes.number, 26 selectedIndex: PropTypes.number,
26 type: PropTypes.string, 27 type: PropTypes.string,
27 onSelect: PropTypes.func, 28 onSelect: PropTypes.func,
@@ -37,23 +38,19 @@ const Select = React.createClass({
37 this.scrollToSelected(200); 38 this.scrollToSelected(200);
38 }, 39 },
39 40
40 onSelect(event) { 41 onSelect(value) {
41 // do nothing when select selected option
42 if (event.target.getAttribute('class') === 'selected') {
43 return;
44 }
45 // change combobox selection
46 const { onSelect, type } = this.props; 42 const { onSelect, type } = this.props;
47 const value = parseInt(event.target.innerHTML, 10);
48 onSelect(type, value); 43 onSelect(type, value);
49 }, 44 },
50 45
51 getOptions() { 46 getOptions() {
52 const { options, selectedIndex } = this.props; 47 const { options, selectedIndex, prefixCls } = this.props;
53 return options.map((item, index) => { 48 return options.map((item, index) => {
54 const cls = classnames({ selected: selectedIndex === index}); 49 const selected = selectedIndex === index;
55 const ref = selectedIndex === index ? 'selected' : null; 50 const cls = classnames({
56 return <li ref={ref} className={cls} key={index} onClick={this.onSelect}>{item}</li>; 51 [`${prefixCls}-select-option-selected`]: selected,
52 });
53 return <li className={cls} key={index} onClick={this.onSelect.bind(this, +item)}>{item}</li>;
57 }); 54 });
58 }, 55 },
59 56