Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit 8209072

Browse files
Merge pull request #157 from dmtrKovalenko/avoid-anonymous-functions
Avoid passing anonymous functions as props
2 parents f140944 + a15a932 commit 8209072

16 files changed

+316
-103
lines changed

.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"rules": {
55
"react/forbid-prop-types": 0,
66
"react/jsx-filename-extension": 0,
7+
"react/no-find-dom-node": 0,
78
"no-param-reassign": 0,
89
"import/no-named-as-default": 0,
910
"import/no-extraneous-dependencies": 0

lib/src/DatePicker/Calendar.jsx

Lines changed: 19 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import React, { Component, Fragment } from 'react';
22
import PropTypes from 'prop-types';
3-
import { withStyles, IconButton } from 'material-ui';
3+
import { withStyles } from 'material-ui';
44

55
import Moment from 'moment';
66
import { extendMoment } from 'moment-range';
7-
import classnames from 'classnames';
87
import CalendarHeader from './CalendarHeader';
98
import DomainPropTypes from '../constants/prop-types';
109
import * as defaultUtils from '../utils/utils';
10+
import DayWrapper from './DayWrapper';
11+
import Day from './Day';
1112

1213
const moment = extendMoment(Moment);
1314

@@ -90,45 +91,42 @@ export class Calendar extends Component {
9091

9192
renderDays = (week) => {
9293
const {
93-
classes, date, renderDay, utils,
94+
date, renderDay, utils,
9495
} = this.props;
9596

9697
const selectedDate = date.clone().startOf('day');
9798
const currentMonthNumber = utils.getMonthNumber(this.state.currentMonth);
9899
const now = moment();
99100

100101
return week.map((day) => {
101-
// should be applied both for wrapper and button
102-
const disabledClass = classnames({ [classes.disabled]: this.shouldDisableDate(day) });
102+
const disabled = this.shouldDisableDate(day);
103103
const dayInCurrentMonth = utils.getMonthNumber(day) === currentMonthNumber;
104-
const isHidden = !dayInCurrentMonth;
105-
106-
const dayClass = classnames(classes.day, disabledClass, {
107-
[classes.hidden]: isHidden,
108-
[classes.current]: day.isSame(now, 'day'),
109-
[classes.selected]: selectedDate.isSame(day, 'day'),
110-
});
111104

112105
let dayComponent = (
113-
<IconButton className={dayClass} tabIndex={isHidden ? -1 : 0}>
114-
<span> {utils.getDayText(day)} </span>
115-
</IconButton>
106+
<Day
107+
current={day.isSame(now, 'day')}
108+
hidden={!dayInCurrentMonth}
109+
disabled={disabled}
110+
selected={selectedDate.isSame(day, 'day')}
111+
>
112+
{utils.getDayText(day)}
113+
</Day>
116114
);
117115

118116
if (renderDay) {
119117
dayComponent = renderDay(day, selectedDate, dayInCurrentMonth, dayComponent);
120118
}
121119

122120
return (
123-
<div
121+
<DayWrapper
124122
key={day.toString()}
125-
onClick={() => dayInCurrentMonth && this.onDateSelect(day)}
126-
onKeyPress={() => dayInCurrentMonth && this.onDateSelect(day)}
127-
className={disabledClass}
128-
role="presentation"
123+
value={day}
124+
dayInCurrentMonth={dayInCurrentMonth}
125+
disabled={disabled}
126+
onSelect={this.onDateSelect}
129127
>
130128
{dayComponent}
131-
</div>
129+
</DayWrapper>
132130
);
133131
});
134132
}
@@ -160,31 +158,6 @@ const styles = theme => ({
160158
height: 36 * 6,
161159
marginTop: theme.spacing.unit * 1.5,
162160
},
163-
hidden: {
164-
opacity: 0,
165-
pointerEvents: 'none',
166-
},
167-
day: {
168-
width: 36,
169-
height: 36,
170-
fontSize: theme.typography.caption.fontSize,
171-
margin: '0 2px',
172-
color: theme.palette.text.primary,
173-
fontWeight: theme.typography.fontWeightMedium,
174-
},
175-
current: {
176-
color: theme.palette.primary[500],
177-
fontWeight: 600,
178-
},
179-
selected: {
180-
color: theme.palette.common.white,
181-
backgroundColor: theme.palette.primary[500],
182-
fontWeight: theme.typography.fontWeightMedium,
183-
},
184-
disabled: {
185-
pointerEvents: 'none',
186-
color: theme.palette.text.hint,
187-
},
188161
week: {
189162
display: 'flex',
190163
justifyContent: 'center',

lib/src/DatePicker/DatePickerWrapper.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export default class DatePickerWrapper extends PickerBase {
9393

9494
return (
9595
<ModalWrapper
96-
ref={(node) => { this.wrapper = node; }}
96+
ref={this.getRef}
9797
value={value}
9898
format={format}
9999
onClear={this.handleClear}

lib/src/DatePicker/Day.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ComponentClass, ReactNode } from 'react';
2+
3+
export interface DayProps {
4+
children: ReactNode;
5+
current?: boolean;
6+
disabled?: boolean;
7+
hidden?: boolean;
8+
selected?: boolean;
9+
}
10+
11+
declare const Day: ComponentClass<DayProps>;
12+
13+
export default Day;

lib/src/DatePicker/Day.jsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import React, { PureComponent } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import { IconButton, withStyles } from 'material-ui';
5+
import classnames from 'classnames';
6+
7+
class Day extends PureComponent {
8+
static propTypes = {
9+
children: PropTypes.node.isRequired,
10+
classes: PropTypes.object.isRequired,
11+
current: PropTypes.bool,
12+
disabled: PropTypes.bool,
13+
hidden: PropTypes.bool,
14+
selected: PropTypes.bool,
15+
}
16+
17+
static defaultProps = {
18+
disabled: false,
19+
hidden: false,
20+
current: false,
21+
selected: false,
22+
}
23+
24+
render() {
25+
const {
26+
children, classes, disabled, hidden, current, selected, ...other
27+
} = this.props;
28+
29+
const className = classnames(classes.day, {
30+
[classes.hidden]: hidden,
31+
[classes.current]: current,
32+
[classes.selected]: selected,
33+
[classes.disabled]: disabled,
34+
});
35+
36+
return (
37+
<IconButton
38+
className={className}
39+
tabIndex={hidden || disabled ? -1 : 0}
40+
{...other}
41+
>
42+
<span> {children} </span>
43+
</IconButton>
44+
);
45+
}
46+
}
47+
48+
const styles = theme => ({
49+
day: {
50+
width: 36,
51+
height: 36,
52+
fontSize: theme.typography.caption.fontSize,
53+
margin: '0 2px',
54+
color: theme.palette.text.primary,
55+
fontWeight: theme.typography.fontWeightMedium,
56+
},
57+
hidden: {
58+
opacity: 0,
59+
pointerEvents: 'none',
60+
},
61+
current: {
62+
color: theme.palette.primary[500],
63+
fontWeight: 600,
64+
},
65+
selected: {
66+
color: theme.palette.common.white,
67+
backgroundColor: theme.palette.primary[500],
68+
fontWeight: theme.typography.fontWeightMedium,
69+
},
70+
disabled: {
71+
pointerEvents: 'none',
72+
color: theme.palette.text.hint,
73+
},
74+
});
75+
76+
export default withStyles(styles)(Day);

lib/src/DatePicker/DayWrapper.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ComponentClass, ReactNode } from 'react';
2+
3+
export interface DayWrapperProps {
4+
children: ReactNode;
5+
dayInCurrentMonth?: boolean,
6+
disabled?: boolean;
7+
onSelect: (value: any) => void;
8+
value: any;
9+
}
10+
11+
declare const DayWrapper: ComponentClass<DayWrapperProps>;
12+
13+
export default DayWrapper;

lib/src/DatePicker/DayWrapper.jsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { PureComponent } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
class DayWrapper extends PureComponent {
5+
static propTypes = {
6+
children: PropTypes.node.isRequired,
7+
dayInCurrentMonth: PropTypes.bool,
8+
disabled: PropTypes.bool,
9+
onSelect: PropTypes.func.isRequired,
10+
value: PropTypes.any.isRequired,
11+
}
12+
13+
static defaultProps = {
14+
dayInCurrentMonth: true,
15+
disabled: false,
16+
}
17+
18+
handleClick = () => {
19+
this.props.onSelect(this.props.value);
20+
}
21+
22+
render() {
23+
const {
24+
children, value, dayInCurrentMonth, disabled, onSelect, ...other
25+
} = this.props;
26+
return (
27+
<div
28+
onClick={dayInCurrentMonth && !disabled ? this.handleClick : undefined}
29+
onKeyPress={dayInCurrentMonth && !disabled ? this.handleClick : undefined}
30+
role="presentation"
31+
{...other}
32+
>
33+
{children}
34+
</div>
35+
);
36+
}
37+
}
38+
39+
export default DayWrapper;

lib/src/DatePicker/Year.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ComponentClass, ReactNode } from 'react';
2+
3+
export interface YearProps {
4+
children: ReactNode;
5+
disabled?: boolean;
6+
onSelect: (value: any) => void;
7+
selected?: boolean;
8+
value: any;
9+
}
10+
11+
declare const Year: ComponentClass<YearProps>;
12+
13+
export default Year;

lib/src/DatePicker/Year.jsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { PureComponent } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import { withStyles, Typography } from 'material-ui';
5+
import classnames from 'classnames';
6+
7+
class Year extends PureComponent {
8+
static propTypes = {
9+
children: PropTypes.node.isRequired,
10+
classes: PropTypes.object.isRequired,
11+
disabled: PropTypes.bool,
12+
onSelect: PropTypes.func.isRequired,
13+
selected: PropTypes.bool,
14+
value: PropTypes.any.isRequired,
15+
}
16+
17+
static defaultProps = {
18+
selected: false,
19+
disabled: false,
20+
}
21+
22+
handleClick = () => {
23+
this.props.onSelect(this.props.value);
24+
}
25+
26+
render() {
27+
const {
28+
classes, selected, disabled, value, children, ...other
29+
} = this.props;
30+
31+
return (
32+
<Typography
33+
role="button"
34+
component="div"
35+
className={classnames(classes.root, {
36+
[classes.selected]: selected,
37+
[classes.disabled]: disabled,
38+
})}
39+
tabIndex={disabled ? -1 : 0}
40+
onClick={this.handleClick}
41+
onKeyPress={this.handleClick}
42+
color={selected ? 'primary' : 'default'}
43+
type={selected ? 'headline' : 'subheading'}
44+
{...other}
45+
>
46+
{children}
47+
</Typography>
48+
);
49+
}
50+
}
51+
52+
const styles = theme => ({
53+
root: {
54+
height: theme.spacing.unit * 5,
55+
display: 'flex',
56+
alignItems: 'center',
57+
justifyContent: 'center',
58+
cursor: 'pointer',
59+
outline: 'none',
60+
'&:focus': {
61+
color: theme.palette.primary[500],
62+
fontWeight: theme.typography.fontWeightMedium,
63+
},
64+
},
65+
selected: {
66+
margin: '10px 0',
67+
fontWeight: theme.typography.fontWeightMedium,
68+
},
69+
disabled: {
70+
pointerEvents: 'none',
71+
color: theme.palette.text.hint,
72+
},
73+
});
74+
75+
export default withStyles(styles)(Year);

0 commit comments

Comments
 (0)