/
CalendarMonth.jsx
127 lines (109 loc) · 3.39 KB
/
CalendarMonth.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* eslint react/no-array-index-key: 0 */
import React, { PropTypes } from 'react';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps } from 'airbnb-prop-types';
import moment from 'moment';
import cx from 'classnames';
import CalendarDay from './CalendarDay';
import getCalendarMonthWeeks from '../utils/getCalendarMonthWeeks';
import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
import {
HORIZONTAL_ORIENTATION,
VERTICAL_ORIENTATION,
VERTICAL_SCROLLABLE,
} from '../../constants';
const propTypes = forbidExtraProps({
month: momentPropTypes.momentObj,
isVisible: PropTypes.bool,
enableOutsideDays: PropTypes.bool,
modifiers: PropTypes.object,
orientation: ScrollableOrientationShape,
onDayClick: PropTypes.func,
onDayMouseEnter: PropTypes.func,
onDayMouseLeave: PropTypes.func,
renderDay: PropTypes.func,
// i18n
monthFormat: PropTypes.string,
});
const defaultProps = {
month: moment(),
isVisible: true,
enableOutsideDays: false,
modifiers: {},
orientation: HORIZONTAL_ORIENTATION,
onDayClick() {},
onDayMouseEnter() {},
onDayMouseLeave() {},
renderDay: null,
// i18n
monthFormat: 'MMMM YYYY', // english locale
};
export default class CalendarMonth extends React.Component {
constructor(props) {
super(props);
this.state = {
weeks: getCalendarMonthWeeks(props.month, props.enableOutsideDays),
};
}
componentWillReceiveProps(nextProps) {
const { month, enableOutsideDays } = nextProps;
if (!month.isSame(this.props.month)) {
this.setState({
weeks: getCalendarMonthWeeks(month, enableOutsideDays),
});
}
}
shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}
render() {
const {
month,
monthFormat,
orientation,
isVisible,
modifiers,
onDayClick,
onDayMouseEnter,
onDayMouseLeave,
renderDay,
} = this.props;
const { weeks } = this.state;
const monthTitle = month.format(monthFormat);
const calendarMonthClasses = cx('CalendarMonth', {
'CalendarMonth--horizontal': orientation === HORIZONTAL_ORIENTATION,
'CalendarMonth--vertical': orientation === VERTICAL_ORIENTATION,
'CalendarMonth--vertical-scrollable': orientation === VERTICAL_SCROLLABLE,
});
return (
<div className={calendarMonthClasses} data-visible={isVisible}>
<table>
<caption className="CalendarMonth__caption js-CalendarMonth__caption">
<strong>{monthTitle}</strong>
</caption>
<tbody className="js-CalendarMonth__grid">
{weeks.map((week, i) => (
<tr key={i}>
{week.map((day, dayOfWeek) => (
<CalendarDay
day={day}
isOutsideDay={!day || day.month() !== month.month()}
modifiers={modifiers}
key={dayOfWeek}
onDayMouseEnter={onDayMouseEnter}
onDayMouseLeave={onDayMouseLeave}
onDayClick={onDayClick}
renderDay={renderDay}
/>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}
}
CalendarMonth.propTypes = propTypes;
CalendarMonth.defaultProps = defaultProps;