wf-react-day-picker 0.0.1-security → 2.653.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of wf-react-day-picker might be problematic. Click here for more details.
- package/index.js +29 -0
- package/package.json +17 -3
- package/src/Caption.js +56 -0
- package/src/DateUtils.js +227 -0
- package/src/Day.js +157 -0
- package/src/DayPicker.js +601 -0
- package/src/DayPickerInput.js +611 -0
- package/src/Helpers.js +145 -0
- package/src/LocaleUtils.js +59 -0
- package/src/ModifiersUtils.js +72 -0
- package/src/Month.js +218 -0
- package/src/Navbar.js +147 -0
- package/src/Weekday.js +45 -0
- package/src/Weekdays.js +65 -0
- package/src/classNames.js +31 -0
- package/src/keys.js +8 -0
- package/README.md +0 -5
package/src/Helpers.js
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
import {clone} from './DateUtils';
|
2
|
+
import {getFirstDayOfWeek} from './LocaleUtils';
|
3
|
+
import defaultClassNames from './classNames';
|
4
|
+
|
5
|
+
export function cancelEvent(e) {
|
6
|
+
e.preventDefault();
|
7
|
+
e.stopPropagation();
|
8
|
+
}
|
9
|
+
|
10
|
+
export function getFirstDayOfMonth(d) {
|
11
|
+
return new Date(d.getFullYear(), d.getMonth(), 1);
|
12
|
+
}
|
13
|
+
|
14
|
+
export function getDaysInMonth(d) {
|
15
|
+
const resultDate = getFirstDayOfMonth(d);
|
16
|
+
|
17
|
+
resultDate.setMonth(resultDate.getMonth() + 1);
|
18
|
+
resultDate.setDate(resultDate.getDate() - 1);
|
19
|
+
|
20
|
+
return resultDate.getDate();
|
21
|
+
}
|
22
|
+
|
23
|
+
export function getModifiersFromProps(props) {
|
24
|
+
const modifiers = {...props.modifiers};
|
25
|
+
if (props.selectedDays) {
|
26
|
+
modifiers[props.classNames.selected] = props.selectedDays;
|
27
|
+
}
|
28
|
+
if (props.disabledDays) {
|
29
|
+
modifiers[props.classNames.disabled] = props.disabledDays;
|
30
|
+
}
|
31
|
+
return modifiers;
|
32
|
+
}
|
33
|
+
|
34
|
+
export function getFirstDayOfWeekFromProps(props) {
|
35
|
+
const {firstDayOfWeek, locale = 'en', localeUtils = {}} = props;
|
36
|
+
if (!isNaN(firstDayOfWeek)) {
|
37
|
+
return firstDayOfWeek;
|
38
|
+
}
|
39
|
+
if (localeUtils.getFirstDayOfWeek) {
|
40
|
+
return localeUtils.getFirstDayOfWeek(locale);
|
41
|
+
}
|
42
|
+
return 0;
|
43
|
+
}
|
44
|
+
|
45
|
+
export function isRangeOfDates(value) {
|
46
|
+
return !!(value && value.from && value.to);
|
47
|
+
}
|
48
|
+
|
49
|
+
export function getMonthsDiff(d1, d2) {
|
50
|
+
return (
|
51
|
+
d2.getMonth() - d1.getMonth() + 12 * (d2.getFullYear() - d1.getFullYear())
|
52
|
+
);
|
53
|
+
}
|
54
|
+
|
55
|
+
export function getWeekArray(
|
56
|
+
d,
|
57
|
+
firstDayOfWeek = getFirstDayOfWeek(),
|
58
|
+
fixedWeeks
|
59
|
+
) {
|
60
|
+
const daysInMonth = getDaysInMonth(d);
|
61
|
+
const dayArray = [];
|
62
|
+
|
63
|
+
let week = [];
|
64
|
+
const weekArray = [];
|
65
|
+
|
66
|
+
for (let i = 1; i <= daysInMonth; i += 1) {
|
67
|
+
dayArray.push(new Date(d.getFullYear(), d.getMonth(), i));
|
68
|
+
}
|
69
|
+
|
70
|
+
dayArray.forEach((day) => {
|
71
|
+
if (week.length > 0 && day.getDay() === firstDayOfWeek) {
|
72
|
+
weekArray.push(week);
|
73
|
+
week = [];
|
74
|
+
}
|
75
|
+
week.push(day);
|
76
|
+
if (dayArray.indexOf(day) === dayArray.length - 1) {
|
77
|
+
weekArray.push(week);
|
78
|
+
}
|
79
|
+
});
|
80
|
+
|
81
|
+
// unshift days to start the first week
|
82
|
+
const firstWeek = weekArray[0];
|
83
|
+
for (let i = 7 - firstWeek.length; i > 0; i -= 1) {
|
84
|
+
const outsideDate = clone(firstWeek[0]);
|
85
|
+
outsideDate.setDate(firstWeek[0].getDate() - 1);
|
86
|
+
firstWeek.unshift(outsideDate);
|
87
|
+
}
|
88
|
+
|
89
|
+
// push days until the end of the last week
|
90
|
+
const lastWeek = weekArray[weekArray.length - 1];
|
91
|
+
for (let i = lastWeek.length; i < 7; i += 1) {
|
92
|
+
const outsideDate = clone(lastWeek[lastWeek.length - 1]);
|
93
|
+
outsideDate.setDate(lastWeek[lastWeek.length - 1].getDate() + 1);
|
94
|
+
lastWeek.push(outsideDate);
|
95
|
+
}
|
96
|
+
|
97
|
+
// add extra weeks to reach 6 weeks
|
98
|
+
if (fixedWeeks && weekArray.length < 6) {
|
99
|
+
let lastExtraWeek;
|
100
|
+
|
101
|
+
for (let i = weekArray.length; i < 6; i += 1) {
|
102
|
+
lastExtraWeek = weekArray[weekArray.length - 1];
|
103
|
+
const lastDay = lastExtraWeek[lastExtraWeek.length - 1];
|
104
|
+
const extraWeek = [];
|
105
|
+
|
106
|
+
for (let j = 0; j < 7; j += 1) {
|
107
|
+
const outsideDate = clone(lastDay);
|
108
|
+
outsideDate.setDate(lastDay.getDate() + j + 1);
|
109
|
+
extraWeek.push(outsideDate);
|
110
|
+
}
|
111
|
+
|
112
|
+
weekArray.push(extraWeek);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
return weekArray;
|
117
|
+
}
|
118
|
+
|
119
|
+
export function startOfMonth(d) {
|
120
|
+
const newDate = clone(d);
|
121
|
+
newDate.setDate(1);
|
122
|
+
return newDate;
|
123
|
+
}
|
124
|
+
|
125
|
+
export function getDayNodes(node, classNames) {
|
126
|
+
let outsideClassName;
|
127
|
+
if (classNames === defaultClassNames) {
|
128
|
+
// When using CSS modules prefix the modifier as required by the BEM syntax
|
129
|
+
outsideClassName = `${classNames.day}--${classNames.outside}`;
|
130
|
+
} else {
|
131
|
+
outsideClassName = `${classNames.outside}`;
|
132
|
+
}
|
133
|
+
const dayQuery = classNames.day.replace(/ /g, '.');
|
134
|
+
const outsideDayQuery = outsideClassName.replace(/ /g, '.');
|
135
|
+
const selector = `.${dayQuery}:not(.${outsideDayQuery})`;
|
136
|
+
return node.querySelectorAll(selector);
|
137
|
+
}
|
138
|
+
|
139
|
+
export function nodeListToArray(nodeList) {
|
140
|
+
return Array.prototype.slice.call(nodeList, 0);
|
141
|
+
}
|
142
|
+
|
143
|
+
export function hasOwnProp(obj, prop) {
|
144
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
145
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
const WEEKDAYS_LONG = [
|
2
|
+
'Sunday',
|
3
|
+
'Monday',
|
4
|
+
'Tuesday',
|
5
|
+
'Wednesday',
|
6
|
+
'Thursday',
|
7
|
+
'Friday',
|
8
|
+
'Saturday',
|
9
|
+
];
|
10
|
+
|
11
|
+
const WEEKDAYS_SHORT = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
12
|
+
|
13
|
+
const MONTHS = [
|
14
|
+
'January',
|
15
|
+
'February',
|
16
|
+
'March',
|
17
|
+
'April',
|
18
|
+
'May',
|
19
|
+
'June',
|
20
|
+
'July',
|
21
|
+
'August',
|
22
|
+
'September',
|
23
|
+
'October',
|
24
|
+
'November',
|
25
|
+
'December',
|
26
|
+
];
|
27
|
+
|
28
|
+
export function formatDay(day) {
|
29
|
+
return day.toDateString();
|
30
|
+
}
|
31
|
+
|
32
|
+
export function formatMonthTitle(d) {
|
33
|
+
return `${MONTHS[d.getMonth()]} ${d.getFullYear()}`;
|
34
|
+
}
|
35
|
+
|
36
|
+
export function formatWeekdayShort(i) {
|
37
|
+
return WEEKDAYS_SHORT[i];
|
38
|
+
}
|
39
|
+
|
40
|
+
export function formatWeekdayLong(i) {
|
41
|
+
return WEEKDAYS_LONG[i];
|
42
|
+
}
|
43
|
+
|
44
|
+
export function getFirstDayOfWeek() {
|
45
|
+
return 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
export function getMonths() {
|
49
|
+
return MONTHS;
|
50
|
+
}
|
51
|
+
|
52
|
+
export default {
|
53
|
+
formatDay,
|
54
|
+
formatMonthTitle,
|
55
|
+
formatWeekdayShort,
|
56
|
+
formatWeekdayLong,
|
57
|
+
getFirstDayOfWeek,
|
58
|
+
getMonths,
|
59
|
+
};
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import {isDayAfter, isDayBefore, isDayInRange, isSameDay} from './DateUtils';
|
2
|
+
import {isRangeOfDates} from './Helpers';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Return `true` if a date matches the specified modifier.
|
6
|
+
*
|
7
|
+
* @export
|
8
|
+
* @param {Date} day
|
9
|
+
* @param {Any} modifier
|
10
|
+
* @return {Boolean}
|
11
|
+
*/
|
12
|
+
export function dayMatchesModifier(day, modifier) {
|
13
|
+
if (!modifier) {
|
14
|
+
return false;
|
15
|
+
}
|
16
|
+
const arr = Array.isArray(modifier) ? modifier : [modifier];
|
17
|
+
return arr.some((mod) => {
|
18
|
+
if (!mod) {
|
19
|
+
return false;
|
20
|
+
}
|
21
|
+
if (mod instanceof Date) {
|
22
|
+
return isSameDay(day, mod);
|
23
|
+
}
|
24
|
+
if (isRangeOfDates(mod)) {
|
25
|
+
return isDayInRange(day, mod);
|
26
|
+
}
|
27
|
+
if (mod.after && mod.before && isDayAfter(mod.before, mod.after)) {
|
28
|
+
return isDayAfter(day, mod.after) && isDayBefore(day, mod.before);
|
29
|
+
}
|
30
|
+
if (
|
31
|
+
mod.after &&
|
32
|
+
mod.before &&
|
33
|
+
(isDayAfter(mod.after, mod.before) || isSameDay(mod.after, mod.before))
|
34
|
+
) {
|
35
|
+
return isDayAfter(day, mod.after) || isDayBefore(day, mod.before);
|
36
|
+
}
|
37
|
+
if (mod.after) {
|
38
|
+
return isDayAfter(day, mod.after);
|
39
|
+
}
|
40
|
+
if (mod.before) {
|
41
|
+
return isDayBefore(day, mod.before);
|
42
|
+
}
|
43
|
+
if (mod.daysOfWeek) {
|
44
|
+
return mod.daysOfWeek.some((dayOfWeek) => day.getDay() === dayOfWeek);
|
45
|
+
}
|
46
|
+
if (typeof mod === 'function') {
|
47
|
+
return mod(day);
|
48
|
+
}
|
49
|
+
return false;
|
50
|
+
});
|
51
|
+
}
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Return the modifiers matching the given day for the given
|
55
|
+
* object of modifiers.
|
56
|
+
*
|
57
|
+
* @export
|
58
|
+
* @param {Date} day
|
59
|
+
* @param {Object} [modifiersObj={}]
|
60
|
+
* @return {Array}
|
61
|
+
*/
|
62
|
+
export function getModifiersForDay(day, modifiersObj = {}) {
|
63
|
+
return Object.keys(modifiersObj).reduce((modifiers, modifierName) => {
|
64
|
+
const value = modifiersObj[modifierName];
|
65
|
+
if (dayMatchesModifier(day, value)) {
|
66
|
+
modifiers.push(modifierName);
|
67
|
+
}
|
68
|
+
return modifiers;
|
69
|
+
}, []);
|
70
|
+
}
|
71
|
+
|
72
|
+
export default {dayMatchesModifier, getModifiersForDay};
|
package/src/Month.js
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
import React, {Component} from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
import Weekdays from './Weekdays';
|
5
|
+
import Day from './Day';
|
6
|
+
import {ENTER} from './keys';
|
7
|
+
|
8
|
+
import * as ModifiersUtils from './ModifiersUtils';
|
9
|
+
import * as Helpers from './Helpers';
|
10
|
+
import * as DateUtils from './DateUtils';
|
11
|
+
|
12
|
+
export default class Month extends Component {
|
13
|
+
static propTypes = {
|
14
|
+
classNames: PropTypes.shape({
|
15
|
+
body: PropTypes.string.isRequired,
|
16
|
+
month: PropTypes.string.isRequired,
|
17
|
+
outside: PropTypes.string.isRequired,
|
18
|
+
today: PropTypes.string.isRequired,
|
19
|
+
week: PropTypes.string.isRequired,
|
20
|
+
}).isRequired,
|
21
|
+
tabIndex: PropTypes.number,
|
22
|
+
|
23
|
+
month: PropTypes.instanceOf(Date).isRequired,
|
24
|
+
months: PropTypes.arrayOf(PropTypes.node),
|
25
|
+
|
26
|
+
modifiersStyles: PropTypes.object,
|
27
|
+
|
28
|
+
showWeekDays: PropTypes.bool,
|
29
|
+
showOutsideDays: PropTypes.bool,
|
30
|
+
|
31
|
+
renderDay: PropTypes.func.isRequired,
|
32
|
+
renderWeek: PropTypes.func.isRequired,
|
33
|
+
|
34
|
+
captionElement: PropTypes.oneOfType([
|
35
|
+
PropTypes.element,
|
36
|
+
PropTypes.func,
|
37
|
+
PropTypes.instanceOf(React.Component),
|
38
|
+
]).isRequired,
|
39
|
+
weekdayElement: PropTypes.oneOfType([
|
40
|
+
PropTypes.element,
|
41
|
+
PropTypes.func,
|
42
|
+
PropTypes.instanceOf(React.Component),
|
43
|
+
]),
|
44
|
+
|
45
|
+
fixedWeeks: PropTypes.bool,
|
46
|
+
showWeekNumbers: PropTypes.bool,
|
47
|
+
|
48
|
+
locale: PropTypes.string.isRequired,
|
49
|
+
localeUtils: PropTypes.object.isRequired,
|
50
|
+
weekdaysLong: PropTypes.arrayOf(PropTypes.node),
|
51
|
+
weekdaysShort: PropTypes.arrayOf(PropTypes.node),
|
52
|
+
firstDayOfWeek: PropTypes.number.isRequired,
|
53
|
+
|
54
|
+
onCaptionClick: PropTypes.func,
|
55
|
+
onDayClick: PropTypes.func,
|
56
|
+
onDayFocus: PropTypes.func,
|
57
|
+
onDayKeyDown: PropTypes.func,
|
58
|
+
onDayMouseEnter: PropTypes.func,
|
59
|
+
onDayMouseLeave: PropTypes.func,
|
60
|
+
onDayMouseDown: PropTypes.func,
|
61
|
+
onDayMouseUp: PropTypes.func,
|
62
|
+
onDayTouchEnd: PropTypes.func,
|
63
|
+
onDayTouchStart: PropTypes.func,
|
64
|
+
onWeekClick: PropTypes.func,
|
65
|
+
};
|
66
|
+
|
67
|
+
renderDay = (day) => {
|
68
|
+
const monthNumber = this.props.month.getMonth();
|
69
|
+
const propModifiers = Helpers.getModifiersFromProps(this.props);
|
70
|
+
const dayModifiers = ModifiersUtils.getModifiersForDay(day, propModifiers);
|
71
|
+
if (
|
72
|
+
DateUtils.isSameDay(day, new Date()) &&
|
73
|
+
!Object.prototype.hasOwnProperty.call(
|
74
|
+
propModifiers,
|
75
|
+
this.props.classNames.today
|
76
|
+
)
|
77
|
+
) {
|
78
|
+
dayModifiers.push(this.props.classNames.today);
|
79
|
+
}
|
80
|
+
if (day.getMonth() !== monthNumber) {
|
81
|
+
dayModifiers.push(this.props.classNames.outside);
|
82
|
+
}
|
83
|
+
|
84
|
+
const isOutside = day.getMonth() !== monthNumber;
|
85
|
+
let tabIndex = -1;
|
86
|
+
// Focus on the first day of the month
|
87
|
+
if (this.props.onDayClick && !isOutside && day.getDate() === 1) {
|
88
|
+
tabIndex = this.props.tabIndex; // eslint-disable-line prefer-destructuring
|
89
|
+
}
|
90
|
+
const key = `${day.getFullYear()}${day.getMonth()}${day.getDate()}`;
|
91
|
+
const modifiers = {};
|
92
|
+
dayModifiers.forEach((modifier) => {
|
93
|
+
modifiers[modifier] = true;
|
94
|
+
});
|
95
|
+
|
96
|
+
return (
|
97
|
+
<Day
|
98
|
+
key={`${isOutside ? 'outside-' : ''}${key}`}
|
99
|
+
classNames={this.props.classNames}
|
100
|
+
day={day}
|
101
|
+
modifiers={modifiers}
|
102
|
+
modifiersStyles={this.props.modifiersStyles}
|
103
|
+
empty={
|
104
|
+
isOutside && !this.props.showOutsideDays && !this.props.fixedWeeks
|
105
|
+
}
|
106
|
+
tabIndex={tabIndex}
|
107
|
+
ariaLabel={this.props.localeUtils.formatDay(day, this.props.locale)}
|
108
|
+
ariaDisabled={isOutside || dayModifiers.indexOf('disabled') > -1}
|
109
|
+
ariaSelected={dayModifiers.indexOf('selected') > -1}
|
110
|
+
onClick={this.props.onDayClick}
|
111
|
+
onFocus={this.props.onDayFocus}
|
112
|
+
onKeyDown={this.props.onDayKeyDown}
|
113
|
+
onMouseEnter={this.props.onDayMouseEnter}
|
114
|
+
onMouseLeave={this.props.onDayMouseLeave}
|
115
|
+
onMouseDown={this.props.onDayMouseDown}
|
116
|
+
onMouseUp={this.props.onDayMouseUp}
|
117
|
+
onTouchEnd={this.props.onDayTouchEnd}
|
118
|
+
onTouchStart={this.props.onDayTouchStart}
|
119
|
+
>
|
120
|
+
{this.props.renderDay(day, modifiers)}
|
121
|
+
</Day>
|
122
|
+
);
|
123
|
+
};
|
124
|
+
|
125
|
+
render() {
|
126
|
+
const {
|
127
|
+
classNames,
|
128
|
+
|
129
|
+
month,
|
130
|
+
months,
|
131
|
+
|
132
|
+
fixedWeeks,
|
133
|
+
captionElement,
|
134
|
+
weekdayElement,
|
135
|
+
|
136
|
+
locale,
|
137
|
+
localeUtils,
|
138
|
+
weekdaysLong,
|
139
|
+
weekdaysShort,
|
140
|
+
firstDayOfWeek,
|
141
|
+
|
142
|
+
onCaptionClick,
|
143
|
+
|
144
|
+
showWeekNumbers,
|
145
|
+
showWeekDays,
|
146
|
+
onWeekClick,
|
147
|
+
} = this.props;
|
148
|
+
|
149
|
+
const captionProps = {
|
150
|
+
date: month,
|
151
|
+
classNames,
|
152
|
+
months,
|
153
|
+
localeUtils,
|
154
|
+
locale,
|
155
|
+
onClick: onCaptionClick ? (e) => onCaptionClick(month, e) : undefined,
|
156
|
+
};
|
157
|
+
const caption = React.isValidElement(captionElement)
|
158
|
+
? React.cloneElement(captionElement, captionProps)
|
159
|
+
: React.createElement(captionElement, captionProps);
|
160
|
+
|
161
|
+
const weeks = Helpers.getWeekArray(month, firstDayOfWeek, fixedWeeks);
|
162
|
+
return (
|
163
|
+
<div className={classNames.month} role="grid">
|
164
|
+
{caption}
|
165
|
+
{showWeekDays && (
|
166
|
+
<Weekdays
|
167
|
+
classNames={classNames}
|
168
|
+
weekdaysShort={weekdaysShort}
|
169
|
+
weekdaysLong={weekdaysLong}
|
170
|
+
firstDayOfWeek={firstDayOfWeek}
|
171
|
+
showWeekNumbers={showWeekNumbers}
|
172
|
+
locale={locale}
|
173
|
+
localeUtils={localeUtils}
|
174
|
+
weekdayElement={weekdayElement}
|
175
|
+
/>
|
176
|
+
)}
|
177
|
+
<div className={classNames.body} role="rowgroup">
|
178
|
+
{weeks.map((week) => {
|
179
|
+
let weekNumber;
|
180
|
+
if (showWeekNumbers) {
|
181
|
+
weekNumber = DateUtils.getWeekNumber(week[6]);
|
182
|
+
}
|
183
|
+
return (
|
184
|
+
<div
|
185
|
+
key={week[0].getTime()}
|
186
|
+
className={classNames.week}
|
187
|
+
role="row"
|
188
|
+
>
|
189
|
+
{showWeekNumbers && (
|
190
|
+
<div
|
191
|
+
className={classNames.weekNumber}
|
192
|
+
tabIndex={0}
|
193
|
+
role="gridcell"
|
194
|
+
onClick={
|
195
|
+
onWeekClick
|
196
|
+
? (e) => onWeekClick(weekNumber, week, e)
|
197
|
+
: undefined
|
198
|
+
}
|
199
|
+
onKeyUp={
|
200
|
+
onWeekClick
|
201
|
+
? (e) =>
|
202
|
+
e.keyCode === ENTER &&
|
203
|
+
onWeekClick(weekNumber, week, e)
|
204
|
+
: undefined
|
205
|
+
}
|
206
|
+
>
|
207
|
+
{this.props.renderWeek(weekNumber, week, month)}
|
208
|
+
</div>
|
209
|
+
)}
|
210
|
+
{week.map(this.renderDay)}
|
211
|
+
</div>
|
212
|
+
);
|
213
|
+
})}
|
214
|
+
</div>
|
215
|
+
</div>
|
216
|
+
);
|
217
|
+
}
|
218
|
+
}
|
package/src/Navbar.js
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
import React, {Component} from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
import defaultClassNames from './classNames';
|
5
|
+
import {SPACE, ENTER} from './keys';
|
6
|
+
|
7
|
+
export default class Navbar extends Component {
|
8
|
+
static defaultProps = {
|
9
|
+
classNames: defaultClassNames,
|
10
|
+
dir: 'ltr',
|
11
|
+
labels: {
|
12
|
+
previousMonth: 'Previous Month',
|
13
|
+
nextMonth: 'Next Month',
|
14
|
+
},
|
15
|
+
showPreviousButton: true,
|
16
|
+
showNextButton: true,
|
17
|
+
};
|
18
|
+
|
19
|
+
static propTypes = {
|
20
|
+
classNames: PropTypes.shape({
|
21
|
+
navBar: PropTypes.string.isRequired,
|
22
|
+
navButtonPrev: PropTypes.string.isRequired,
|
23
|
+
navButtonNext: PropTypes.string.isRequired,
|
24
|
+
}),
|
25
|
+
className: PropTypes.string,
|
26
|
+
showPreviousButton: PropTypes.bool,
|
27
|
+
showNextButton: PropTypes.bool,
|
28
|
+
onPreviousClick: PropTypes.func,
|
29
|
+
onNextClick: PropTypes.func,
|
30
|
+
dir: PropTypes.string,
|
31
|
+
labels: PropTypes.shape({
|
32
|
+
previousMonth: PropTypes.string.isRequired,
|
33
|
+
nextMonth: PropTypes.string.isRequired,
|
34
|
+
}),
|
35
|
+
};
|
36
|
+
|
37
|
+
shouldComponentUpdate(nextProps) {
|
38
|
+
return (
|
39
|
+
nextProps.labels !== this.props.labels ||
|
40
|
+
nextProps.dir !== this.props.dir ||
|
41
|
+
this.props.showPreviousButton !== nextProps.showPreviousButton ||
|
42
|
+
this.props.showNextButton !== nextProps.showNextButton
|
43
|
+
);
|
44
|
+
}
|
45
|
+
|
46
|
+
handleNextClick = () => {
|
47
|
+
if (this.props.onNextClick) {
|
48
|
+
this.props.onNextClick();
|
49
|
+
}
|
50
|
+
};
|
51
|
+
|
52
|
+
handlePreviousClick = () => {
|
53
|
+
if (this.props.onPreviousClick) {
|
54
|
+
this.props.onPreviousClick();
|
55
|
+
}
|
56
|
+
};
|
57
|
+
|
58
|
+
handleNextKeyDown = (e) => {
|
59
|
+
if (e.keyCode !== ENTER && e.keyCode !== SPACE) {
|
60
|
+
return;
|
61
|
+
}
|
62
|
+
e.preventDefault();
|
63
|
+
this.handleNextClick();
|
64
|
+
};
|
65
|
+
|
66
|
+
handlePreviousKeyDown = (e) => {
|
67
|
+
if (e.keyCode !== ENTER && e.keyCode !== SPACE) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
e.preventDefault();
|
71
|
+
this.handlePreviousClick();
|
72
|
+
};
|
73
|
+
|
74
|
+
render() {
|
75
|
+
const {
|
76
|
+
classNames,
|
77
|
+
className,
|
78
|
+
showPreviousButton,
|
79
|
+
showNextButton,
|
80
|
+
labels,
|
81
|
+
dir,
|
82
|
+
} = this.props;
|
83
|
+
|
84
|
+
let previousClickHandler;
|
85
|
+
let nextClickHandler;
|
86
|
+
let previousKeyDownHandler;
|
87
|
+
let nextKeyDownHandler;
|
88
|
+
let shouldShowPrevious;
|
89
|
+
let shouldShowNext;
|
90
|
+
|
91
|
+
if (dir === 'rtl') {
|
92
|
+
previousClickHandler = this.handleNextClick;
|
93
|
+
nextClickHandler = this.handlePreviousClick;
|
94
|
+
previousKeyDownHandler = this.handleNextKeyDown;
|
95
|
+
nextKeyDownHandler = this.handlePreviousKeyDown;
|
96
|
+
shouldShowNext = showPreviousButton;
|
97
|
+
shouldShowPrevious = showNextButton;
|
98
|
+
} else {
|
99
|
+
previousClickHandler = this.handlePreviousClick;
|
100
|
+
nextClickHandler = this.handleNextClick;
|
101
|
+
previousKeyDownHandler = this.handlePreviousKeyDown;
|
102
|
+
nextKeyDownHandler = this.handleNextKeyDown;
|
103
|
+
shouldShowNext = showNextButton;
|
104
|
+
shouldShowPrevious = showPreviousButton;
|
105
|
+
}
|
106
|
+
|
107
|
+
const previousClassName = shouldShowPrevious
|
108
|
+
? classNames.navButtonPrev
|
109
|
+
: `${classNames.navButtonPrev} ${classNames.navButtonInteractionDisabled}`;
|
110
|
+
|
111
|
+
const nextClassName = shouldShowNext
|
112
|
+
? classNames.navButtonNext
|
113
|
+
: `${classNames.navButtonNext} ${classNames.navButtonInteractionDisabled}`;
|
114
|
+
|
115
|
+
const previousButton = (
|
116
|
+
<span
|
117
|
+
tabIndex="0"
|
118
|
+
role="button"
|
119
|
+
aria-label={labels.previousMonth}
|
120
|
+
key="previous"
|
121
|
+
className={previousClassName}
|
122
|
+
onKeyDown={shouldShowPrevious ? previousKeyDownHandler : undefined}
|
123
|
+
onClick={shouldShowPrevious ? previousClickHandler : undefined}
|
124
|
+
/>
|
125
|
+
);
|
126
|
+
|
127
|
+
const nextButton = (
|
128
|
+
<span
|
129
|
+
tabIndex="0"
|
130
|
+
role="button"
|
131
|
+
aria-label={labels.nextMonth}
|
132
|
+
key="right"
|
133
|
+
className={nextClassName}
|
134
|
+
onKeyDown={shouldShowNext ? nextKeyDownHandler : undefined}
|
135
|
+
onClick={shouldShowNext ? nextClickHandler : undefined}
|
136
|
+
/>
|
137
|
+
);
|
138
|
+
|
139
|
+
return (
|
140
|
+
<div className={className || classNames.navBar}>
|
141
|
+
{dir === 'rtl'
|
142
|
+
? [nextButton, previousButton]
|
143
|
+
: [previousButton, nextButton]}
|
144
|
+
</div>
|
145
|
+
);
|
146
|
+
}
|
147
|
+
}
|
package/src/Weekday.js
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
import React, {Component} from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
export default class Weekday extends Component {
|
5
|
+
static propTypes = {
|
6
|
+
weekday: PropTypes.number,
|
7
|
+
className: PropTypes.string,
|
8
|
+
locale: PropTypes.string,
|
9
|
+
localeUtils: PropTypes.object,
|
10
|
+
|
11
|
+
weekdaysLong: PropTypes.arrayOf(PropTypes.string),
|
12
|
+
weekdaysShort: PropTypes.arrayOf(PropTypes.string),
|
13
|
+
};
|
14
|
+
shouldComponentUpdate(nextProps) {
|
15
|
+
return this.props !== nextProps;
|
16
|
+
}
|
17
|
+
render() {
|
18
|
+
const {
|
19
|
+
weekday,
|
20
|
+
className,
|
21
|
+
weekdaysLong,
|
22
|
+
weekdaysShort,
|
23
|
+
localeUtils,
|
24
|
+
locale,
|
25
|
+
} = this.props;
|
26
|
+
let title;
|
27
|
+
if (weekdaysLong) {
|
28
|
+
title = weekdaysLong[weekday];
|
29
|
+
} else {
|
30
|
+
title = localeUtils.formatWeekdayLong(weekday, locale);
|
31
|
+
}
|
32
|
+
let content;
|
33
|
+
if (weekdaysShort) {
|
34
|
+
content = weekdaysShort[weekday];
|
35
|
+
} else {
|
36
|
+
content = localeUtils.formatWeekdayShort(weekday, locale);
|
37
|
+
}
|
38
|
+
|
39
|
+
return (
|
40
|
+
<div className={className} role="columnheader">
|
41
|
+
<abbr title={title}>{content}</abbr>
|
42
|
+
</div>
|
43
|
+
);
|
44
|
+
}
|
45
|
+
}
|