]> git.immae.eu Git - github/fretlink/time-picker.git/blame - src/Combobox.jsx
Add id to input element
[github/fretlink/time-picker.git] / src / Combobox.jsx
CommitLineData
3ab3a128 1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
02de449a 3import Select from './Select';
4
518b852e
M
5const formatOption = (option, disabledOptions) => {
6 let value = `${option}`;
02de449a 7 if (option < 10) {
518b852e 8 value = `0${option}`;
02de449a 9 }
518b852e
M
10
11 let disabled = false;
0e62bf0b 12 if (disabledOptions && disabledOptions.indexOf(option) >= 0) {
518b852e
M
13 disabled = true;
14 }
15
16 return {
17 value,
18 disabled,
19 };
02de449a 20};
21
3ab3a128 22class Combobox extends Component {
23 static propTypes = {
4984ed85 24 format: PropTypes.string,
25 defaultOpenValue: PropTypes.object,
02de449a 26 prefixCls: PropTypes.string,
27 value: PropTypes.object,
28 onChange: PropTypes.func,
29 showHour: PropTypes.bool,
37c36c09 30 showMinute: PropTypes.bool,
02de449a 31 showSecond: PropTypes.bool,
32 hourOptions: PropTypes.array,
33 minuteOptions: PropTypes.array,
34 secondOptions: PropTypes.array,
71bd9bc1
M
35 disabledHours: PropTypes.func,
36 disabledMinutes: PropTypes.func,
37 disabledSeconds: PropTypes.func,
182e9fcc 38 onCurrentSelectPanelChange: PropTypes.func,
dd275f7d 39 use12Hours: PropTypes.bool,
7211e9ba 40 isAM: PropTypes.bool,
3ab3a128 41 };
02de449a 42
3ab3a128 43 onItemChange = (type, itemValue) => {
dd275f7d 44 const { onChange, defaultOpenValue, use12Hours } = this.props;
4984ed85 45 const value = (this.props.value || defaultOpenValue).clone();
95699887 46
11b97949 47 if (type === 'hour') {
dd275f7d 48 if (use12Hours) {
7211e9ba 49 if (this.props.isAM) {
dd2f6abd 50 value.hour(+itemValue % 12);
95699887 51 } else {
dd2f6abd 52 value.hour((+itemValue % 12) + 12);
95699887
AS
53 }
54 } else {
55 value.hour(+itemValue);
56 }
11b97949 57 } else if (type === 'minute') {
95699887
AS
58 value.minute(+itemValue);
59 } else if (type === 'ampm') {
c1b40cab 60 const ampm = itemValue.toUpperCase();
dd275f7d 61 if (use12Hours) {
c1b40cab 62 if (ampm === 'PM' && value.hour() < 12) {
2a8cf5ae 63 value.hour((value.hour() % 12) + 12);
95699887
AS
64 }
65
c1b40cab 66 if (ampm === 'AM') {
2a8cf5ae 67 if (value.hour() >= 12) {
95699887
AS
68 value.hour(value.hour() - 12);
69 }
70 }
71 }
11b97949 72 } else {
95699887 73 value.second(+itemValue);
02de449a 74 }
02de449a 75 onChange(value);
3ab3a128 76 }
02de449a 77
3ab3a128 78 onEnterSelectPanel = (range) => {
182e9fcc 79 this.props.onCurrentSelectPanelChange(range);
3ab3a128 80 }
182e9fcc 81
02de449a 82 getHourSelect(hour) {
dd275f7d 83 const { prefixCls, hourOptions, disabledHours, showHour, use12Hours } = this.props;
02de449a 84 if (!showHour) {
85 return null;
86 }
7211e9ba 87 const disabledOptions = disabledHours();
95699887 88 let hourOptionsAdj;
dd2f6abd 89 let hourAdj;
dd275f7d 90 if (use12Hours) {
dd2f6abd
AS
91 hourOptionsAdj = [12].concat(hourOptions.filter(h => h < 12 && h > 0));
92 hourAdj = (hour % 12) || 12;
95699887
AS
93 } else {
94 hourOptionsAdj = hourOptions;
dd2f6abd 95 hourAdj = hour;
95699887 96 }
71bd9bc1 97
02de449a 98 return (
99 <Select
100 prefixCls={prefixCls}
95699887
AS
101 options={hourOptionsAdj.map(option => formatOption(option, disabledOptions))}
102 selectedIndex={hourOptionsAdj.indexOf(hourAdj)}
02de449a 103 type="hour"
104 onSelect={this.onItemChange}
182e9fcc 105 onMouseEnter={this.onEnterSelectPanel.bind(this, 'hour')}
02de449a 106 />
107 );
3ab3a128 108 }
02de449a 109
110 getMinuteSelect(minute) {
37c36c09 111 const { prefixCls, minuteOptions, disabledMinutes, defaultOpenValue, showMinute } = this.props;
112 if (!showMinute) {
113 return null;
114 }
4984ed85 115 const value = this.props.value || defaultOpenValue;
116 const disabledOptions = disabledMinutes(value.hour());
71bd9bc1 117
02de449a 118 return (
119 <Select
120 prefixCls={prefixCls}
71bd9bc1 121 options={minuteOptions.map(option => formatOption(option, disabledOptions))}
02de449a 122 selectedIndex={minuteOptions.indexOf(minute)}
123 type="minute"
124 onSelect={this.onItemChange}
182e9fcc 125 onMouseEnter={this.onEnterSelectPanel.bind(this, 'minute')}
02de449a 126 />
127 );
3ab3a128 128 }
02de449a 129
182e9fcc 130 getSecondSelect(second) {
4984ed85 131 const { prefixCls, secondOptions, disabledSeconds, showSecond, defaultOpenValue } = this.props;
02de449a 132 if (!showSecond) {
133 return null;
134 }
4984ed85 135 const value = this.props.value || defaultOpenValue;
136 const disabledOptions = disabledSeconds(value.hour(), value.minute());
71bd9bc1 137
02de449a 138 return (
139 <Select
140 prefixCls={prefixCls}
71bd9bc1 141 options={secondOptions.map(option => formatOption(option, disabledOptions))}
02de449a 142 selectedIndex={secondOptions.indexOf(second)}
143 type="second"
144 onSelect={this.onItemChange}
182e9fcc 145 onMouseEnter={this.onEnterSelectPanel.bind(this, 'second')}
02de449a 146 />
147 );
3ab3a128 148 }
02de449a 149
95699887 150 getAMPMSelect() {
eb3c19e2 151 const { prefixCls, use12Hours, format } = this.props;
dd275f7d 152 if (!use12Hours) {
95699887
AS
153 return null;
154 }
eb3c19e2
AS
155
156 const AMPMOptions = ['am', 'pm'] // If format has A char, then we should uppercase AM/PM
157 .map(c => format.match(/\sA/) ? c.toUpperCase() : c)
158 .map(c => ({ value: c }));
159
7211e9ba 160 const selected = this.props.isAM ? 0 : 1;
95699887
AS
161
162 return (
163 <Select
164 prefixCls={prefixCls}
165 options={AMPMOptions}
166 selectedIndex={selected}
167 type="ampm"
168 onSelect={this.onItemChange}
169 onMouseEnter={this.onEnterSelectPanel.bind(this, 'ampm')}
170 />
171 );
3ab3a128 172 }
95699887 173
8133e8cf 174 render() {
4984ed85 175 const { prefixCls, defaultOpenValue } = this.props;
176 const value = this.props.value || defaultOpenValue;
02de449a 177 return (
178 <div className={`${prefixCls}-combobox`}>
4984ed85 179 {this.getHourSelect(value.hour())}
180 {this.getMinuteSelect(value.minute())}
181 {this.getSecondSelect(value.second())}
95699887 182 {this.getAMPMSelect(value.hour())}
02de449a 183 </div>
184 );
3ab3a128 185 }
186}
02de449a 187
188export default Combobox;