Skip to content

Commit 96c8c13

Browse files
authored
Merge input components to make them DRY (#142)
* Merge input components to make them DRY * Add support for nameForClass
1 parent 0c38c73 commit 96c8c13

4 files changed

Lines changed: 121 additions & 116 deletions

File tree

src/DateInput/DayInput.jsx

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { PureComponent } from 'react';
22
import PropTypes from 'prop-types';
3-
import mergeClassNames from 'merge-class-names';
3+
4+
import Input from './Input';
45

56
import {
67
getDay,
@@ -9,9 +10,7 @@ import {
910
getYear,
1011
} from '../shared/dates';
1112
import { isMaxDate, isMinDate } from '../shared/propTypes';
12-
import { min, max, updateInputWidth } from '../shared/utils';
13-
14-
const select = element => element && element.select();
13+
import { min, max } from '../shared/utils';
1514

1615
export default class DayInput extends PureComponent {
1716
get currentMonthMaxDays() {
@@ -42,45 +41,21 @@ export default class DayInput extends PureComponent {
4241
render() {
4342
const { maxDay, minDay } = this;
4443
const {
45-
className, disabled, itemRef, value, onChange, onKeyDown, required, showLeadingZeros,
44+
maxDate,
45+
minDate,
46+
month,
47+
year,
48+
...otherProps
4649
} = this.props;
4750

48-
const name = 'day';
49-
const hasLeadingZero = showLeadingZeros && value !== null && value < 10;
50-
51-
return [
52-
(hasLeadingZero && <span key="leadingZero" className={`${className}__leadingZero`}>0</span>),
53-
<input
54-
key="day"
55-
autoComplete="off"
56-
className={mergeClassNames(
57-
`${className}__input`,
58-
`${className}__day`,
59-
hasLeadingZero && `${className}__input--hasLeadingZero`,
60-
)}
61-
disabled={disabled}
62-
name={name}
51+
return (
52+
<Input
53+
name="day"
6354
max={maxDay}
6455
min={minDay}
65-
onChange={onChange}
66-
onFocus={event => select(event.target)}
67-
onKeyDown={onKeyDown}
68-
onKeyUp={event => updateInputWidth(event.target)}
69-
placeholder="--"
70-
ref={(ref) => {
71-
if (ref) {
72-
updateInputWidth(ref);
73-
}
74-
75-
if (itemRef) {
76-
itemRef(ref, name);
77-
}
78-
}}
79-
required={required}
80-
type="number"
81-
value={value !== null ? value : ''}
82-
/>,
83-
];
56+
{...otherProps}
57+
/>
58+
);
8459
}
8560
}
8661

src/DateInput/Input.jsx

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import mergeClassNames from 'merge-class-names';
4+
5+
import { updateInputWidth } from '../shared/utils';
6+
7+
const select = element => element && element.select();
8+
9+
const Input = ({
10+
className,
11+
disabled,
12+
itemRef,
13+
max,
14+
min,
15+
name,
16+
nameForClass,
17+
onChange,
18+
onKeyDown,
19+
placeholder,
20+
required,
21+
showLeadingZeros,
22+
step,
23+
value,
24+
}) => {
25+
const hasLeadingZero = showLeadingZeros && value !== null && value < 10;
26+
27+
return [
28+
(hasLeadingZero && <span key="leadingZero" className={`${className}__leadingZero`}>0</span>),
29+
<input
30+
key="input"
31+
autoComplete="off"
32+
className={mergeClassNames(
33+
`${className}__input`,
34+
`${className}__${nameForClass || name}`,
35+
hasLeadingZero && `${className}__input--hasLeadingZero`,
36+
)}
37+
disabled={disabled}
38+
name={name}
39+
max={max}
40+
min={min}
41+
onChange={onChange}
42+
onFocus={event => select(event.target)}
43+
onKeyDown={onKeyDown}
44+
onKeyUp={event => updateInputWidth(event.target)}
45+
placeholder={placeholder}
46+
ref={(ref) => {
47+
if (ref) {
48+
updateInputWidth(ref);
49+
}
50+
51+
if (itemRef) {
52+
itemRef(ref, name);
53+
}
54+
}}
55+
required={required}
56+
step={step}
57+
type="number"
58+
value={value !== null ? value : ''}
59+
/>,
60+
];
61+
};
62+
63+
Input.propTypes = {
64+
className: PropTypes.string.isRequired,
65+
disabled: PropTypes.bool,
66+
itemRef: PropTypes.func,
67+
max: PropTypes.number,
68+
min: PropTypes.number,
69+
onChange: PropTypes.func,
70+
onKeyDown: PropTypes.func,
71+
required: PropTypes.bool,
72+
showLeadingZeros: PropTypes.bool,
73+
step: PropTypes.number,
74+
value: PropTypes.number,
75+
};
76+
77+
Input.defaultProps = {
78+
placeholder: '--',
79+
};
80+
81+
export default Input;

src/DateInput/MonthInput.jsx

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import React, { PureComponent } from 'react';
22
import PropTypes from 'prop-types';
3-
import mergeClassNames from 'merge-class-names';
43

5-
import {
6-
getMonth,
7-
getYear,
8-
} from '../shared/dates';
9-
import { isMaxDate, isMinDate } from '../shared/propTypes';
10-
import { min, max, updateInputWidth } from '../shared/utils';
4+
import Input from './Input';
115

12-
const select = element => element && element.select();
6+
import { getMonth, getYear } from '../shared/dates';
7+
import { isMaxDate, isMinDate } from '../shared/propTypes';
8+
import { min, max } from '../shared/utils';
139

1410
export default class MonthInput extends PureComponent {
1511
get maxMonth() {
@@ -25,45 +21,20 @@ export default class MonthInput extends PureComponent {
2521
render() {
2622
const { maxMonth, minMonth } = this;
2723
const {
28-
className, disabled, itemRef, value, onChange, onKeyDown, required, showLeadingZeros,
24+
maxDate,
25+
minDate,
26+
year,
27+
...otherProps
2928
} = this.props;
3029

31-
const name = 'month';
32-
const hasLeadingZero = showLeadingZeros && value !== null && value < 10;
33-
34-
return [
35-
(hasLeadingZero && <span key="leadingZero" className={`${className}__leadingZero`}>0</span>),
36-
<input
37-
key="month"
38-
autoComplete="off"
39-
className={mergeClassNames(
40-
`${className}__input`,
41-
`${className}__month`,
42-
hasLeadingZero && `${className}__input--hasLeadingZero`,
43-
)}
44-
disabled={disabled}
45-
name={name}
30+
return (
31+
<Input
32+
name="month"
4633
max={maxMonth}
4734
min={minMonth}
48-
onChange={onChange}
49-
onFocus={event => select(event.target)}
50-
onKeyDown={onKeyDown}
51-
onKeyUp={event => updateInputWidth(event.target)}
52-
placeholder="--"
53-
ref={(ref) => {
54-
if (ref) {
55-
updateInputWidth(ref);
56-
}
57-
58-
if (itemRef) {
59-
itemRef(ref, name);
60-
}
61-
}}
62-
type="number"
63-
required={required}
64-
value={value !== null ? value : ''}
65-
/>,
66-
];
35+
{...otherProps}
36+
/>
37+
);
6738
}
6839
}
6940

src/DateInput/YearInput.jsx

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import React, { PureComponent } from 'react';
22
import PropTypes from 'prop-types';
3-
import mergeClassNames from 'merge-class-names';
43

5-
import {
6-
getYear,
7-
} from '../shared/dates';
8-
import { isMaxDate, isMinDate, isValueType } from '../shared/propTypes';
9-
import { max, min, updateInputWidth } from '../shared/utils';
4+
import Input from './Input';
105

11-
const select = element => element && element.select();
6+
import { getYear } from '../shared/dates';
7+
import { isMaxDate, isMinDate, isValueType } from '../shared/propTypes';
8+
import { max, min } from '../shared/utils';
129

1310
export default class YearInput extends PureComponent {
1411
get maxYear() {
@@ -27,46 +24,27 @@ export default class YearInput extends PureComponent {
2724
if (valueType === 'century') {
2825
return 10;
2926
}
27+
3028
return 1;
3129
}
3230

3331
render() {
3432
const { maxYear, minYear, yearStep } = this;
3533
const {
36-
className, disabled, itemRef, value, onChange, onKeyDown, required,
34+
maxDate,
35+
minDate,
36+
valueType,
37+
...otherProps
3738
} = this.props;
3839

39-
const name = 'year';
40-
4140
return (
42-
<input
43-
autoComplete="off"
44-
className={mergeClassNames(
45-
`${className}__input`,
46-
`${className}__year`,
47-
)}
48-
disabled={disabled}
49-
name={name}
41+
<Input
42+
name="year"
5043
max={maxYear}
5144
min={minYear}
52-
onChange={onChange}
53-
onFocus={event => select(event.target)}
54-
onKeyDown={onKeyDown}
55-
onKeyUp={event => updateInputWidth(event.target)}
5645
placeholder="----"
57-
ref={(ref) => {
58-
if (ref) {
59-
updateInputWidth(ref);
60-
}
61-
62-
if (itemRef) {
63-
itemRef(ref, name);
64-
}
65-
}}
66-
required={required}
6746
step={yearStep}
68-
type="number"
69-
value={value !== null ? value : ''}
47+
{...otherProps}
7048
/>
7149
);
7250
}

0 commit comments

Comments
 (0)