]> git.immae.eu Git - github/fretlink/time-picker.git/blame - src/Combobox.jsx
Merge pull request #87 from vahnag/master
[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,
3ab3a128 40 };
02de449a 41
3ab3a128 42 onItemChange = (type, itemValue) => {
dd275f7d 43 const { onChange, defaultOpenValue, use12Hours } = this.props;
4984ed85 44 const value = (this.props.value || defaultOpenValue).clone();
95699887 45
11b97949 46 if (type === 'hour') {
dd275f7d 47 if (use12Hours) {
dd2f6abd
AS
48 if (this.isAM()) {
49 value.hour(+itemValue % 12);
95699887 50 } else {
dd2f6abd 51 value.hour((+itemValue % 12) + 12);
95699887
AS
52 }
53 } else {
54 value.hour(+itemValue);
55 }
11b97949 56 } else if (type === 'minute') {
95699887
AS
57 value.minute(+itemValue);
58 } else if (type === 'ampm') {
c1b40cab 59 const ampm = itemValue.toUpperCase();
dd275f7d 60 if (use12Hours) {
c1b40cab 61 if (ampm === 'PM' && value.hour() < 12) {
2a8cf5ae 62 value.hour((value.hour() % 12) + 12);
95699887
AS
63 }
64
c1b40cab 65 if (ampm === 'AM') {
2a8cf5ae 66 if (value.hour() >= 12) {
95699887
AS
67 value.hour(value.hour() - 12);
68 }
69 }
70 }
11b97949 71 } else {
95699887 72 value.second(+itemValue);
02de449a 73 }
02de449a 74 onChange(value);
3ab3a128 75 }
02de449a 76
3ab3a128 77 onEnterSelectPanel = (range) => {
182e9fcc 78 this.props.onCurrentSelectPanelChange(range);
3ab3a128 79 }
182e9fcc 80
02de449a 81 getHourSelect(hour) {
dd275f7d 82 const { prefixCls, hourOptions, disabledHours, showHour, use12Hours } = this.props;
02de449a 83 if (!showHour) {
84 return null;
85 }
f30361fe 86 let disabledOptions = disabledHours();
95699887 87 let hourOptionsAdj;
dd2f6abd 88 let hourAdj;
dd275f7d 89 if (use12Hours) {
dd2f6abd
AS
90 hourOptionsAdj = [12].concat(hourOptions.filter(h => h < 12 && h > 0));
91 hourAdj = (hour % 12) || 12;
f30361fe 92
ab128c3d
VA
93 if (Array.isArray(disabledOptions)) {
94 if (this.isAM()) {
95 disabledOptions = disabledOptions.filter(h => h < 12).map(h => (h === 0 ? 12 : h));
96 } else {
97 disabledOptions = disabledOptions.map(h => (h === 12 ? 12 : h - 12));
98 }
f30361fe 99 }
95699887
AS
100 } else {
101 hourOptionsAdj = hourOptions;
dd2f6abd 102 hourAdj = hour;
95699887 103 }
71bd9bc1 104
02de449a 105 return (
106 <Select
107 prefixCls={prefixCls}
95699887
AS
108 options={hourOptionsAdj.map(option => formatOption(option, disabledOptions))}
109 selectedIndex={hourOptionsAdj.indexOf(hourAdj)}
02de449a 110 type="hour"
111 onSelect={this.onItemChange}
182e9fcc 112 onMouseEnter={this.onEnterSelectPanel.bind(this, 'hour')}
02de449a 113 />
114 );
3ab3a128 115 }
02de449a 116
117 getMinuteSelect(minute) {
37c36c09 118 const { prefixCls, minuteOptions, disabledMinutes, defaultOpenValue, showMinute } = this.props;
119 if (!showMinute) {
120 return null;
121 }
4984ed85 122 const value = this.props.value || defaultOpenValue;
123 const disabledOptions = disabledMinutes(value.hour());
71bd9bc1 124
02de449a 125 return (
126 <Select
127 prefixCls={prefixCls}
71bd9bc1 128 options={minuteOptions.map(option => formatOption(option, disabledOptions))}
02de449a 129 selectedIndex={minuteOptions.indexOf(minute)}
130 type="minute"
131 onSelect={this.onItemChange}
182e9fcc 132 onMouseEnter={this.onEnterSelectPanel.bind(this, 'minute')}
02de449a 133 />
134 );
3ab3a128 135 }
02de449a 136
182e9fcc 137 getSecondSelect(second) {
4984ed85 138 const { prefixCls, secondOptions, disabledSeconds, showSecond, defaultOpenValue } = this.props;
02de449a 139 if (!showSecond) {
140 return null;
141 }
4984ed85 142 const value = this.props.value || defaultOpenValue;
143 const disabledOptions = disabledSeconds(value.hour(), value.minute());
71bd9bc1 144
02de449a 145 return (
146 <Select
147 prefixCls={prefixCls}
71bd9bc1 148 options={secondOptions.map(option => formatOption(option, disabledOptions))}
02de449a 149 selectedIndex={secondOptions.indexOf(second)}
150 type="second"
151 onSelect={this.onItemChange}
182e9fcc 152 onMouseEnter={this.onEnterSelectPanel.bind(this, 'second')}
02de449a 153 />
154 );
3ab3a128 155 }
02de449a 156
95699887 157 getAMPMSelect() {
eb3c19e2 158 const { prefixCls, use12Hours, format } = this.props;
dd275f7d 159 if (!use12Hours) {
95699887
AS
160 return null;
161 }
eb3c19e2
AS
162
163 const AMPMOptions = ['am', 'pm'] // If format has A char, then we should uppercase AM/PM
164 .map(c => format.match(/\sA/) ? c.toUpperCase() : c)
165 .map(c => ({ value: c }));
166
dd2f6abd 167 const selected = this.isAM() ? 0 : 1;
95699887
AS
168
169 return (
170 <Select
171 prefixCls={prefixCls}
172 options={AMPMOptions}
173 selectedIndex={selected}
174 type="ampm"
175 onSelect={this.onItemChange}
176 onMouseEnter={this.onEnterSelectPanel.bind(this, 'ampm')}
177 />
178 );
3ab3a128 179 }
95699887 180
dd2f6abd 181 isAM() {
4f26f23b 182 const value = (this.props.value || this.props.defaultOpenValue);
dd2f6abd 183 return value.hour() >= 0 && value.hour() < 12;
3ab3a128 184 }
dd2f6abd 185
8133e8cf 186 render() {
4984ed85 187 const { prefixCls, defaultOpenValue } = this.props;
188 const value = this.props.value || defaultOpenValue;
02de449a 189 return (
190 <div className={`${prefixCls}-combobox`}>
4984ed85 191 {this.getHourSelect(value.hour())}
192 {this.getMinuteSelect(value.minute())}
193 {this.getSecondSelect(value.second())}
95699887 194 {this.getAMPMSelect(value.hour())}
02de449a 195 </div>
196 );
3ab3a128 197 }
198}
02de449a 199
200export default Combobox;