/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
import React from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
import Week from "./week";
import * as utils from "./date_utils";
import { ScreenReaderOnly } from "./screen_reader_only";
const FIXED_HEIGHT_STANDARD_WEEK_COUNT = 6;
export default class Month extends React.Component {
static propTypes = {
disabledKeyboardNavigation: PropTypes.bool,
day: PropTypes.object.isRequired,
dayClassName: PropTypes.func,
endDate: PropTypes.object,
excludeDates: PropTypes.array,
filterDate: PropTypes.func,
fixedHeight: PropTypes.bool,
formatWeekNumber: PropTypes.func,
highlightDates: PropTypes.instanceOf(Map),
includeDates: PropTypes.array,
inline: PropTypes.bool,
maxDate: PropTypes.object,
minDate: PropTypes.object,
onDayClick: PropTypes.func,
onDayMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
onWeekSelect: PropTypes.func,
peekNextMonth: PropTypes.bool,
preSelection: PropTypes.object,
selected: PropTypes.object,
selectingDate: PropTypes.object,
selectsEnd: PropTypes.bool,
selectsStart: PropTypes.bool,
showWeekNumbers: PropTypes.bool,
startDate: PropTypes.object,
setOpen: PropTypes.func,
shouldCloseOnSelect: PropTypes.bool,
utcOffset: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
renderDayContents: PropTypes.func,
updateSelection: PropTypes.func.isRequired,
accessibleMode: PropTypes.bool
};
constructor(props) {
super(props);
this.dayFormat = "MMMM D, YYYY.";
this.state = {
readInstructions: false
};
}
handleDayClick = (day, event) => {
if (this.props.onDayClick) {
this.props.onDayClick(day, event);
}
};
handleDayMouseEnter = day => {
if (this.props.onDayMouseEnter) {
this.props.onDayMouseEnter(day);
}
};
handleMouseLeave = () => {
if (this.props.onMouseLeave) {
this.props.onMouseLeave();
}
};
onFocus = () => {
if (this.props.accessibleMode) {
this.setState({ readInstructions: true });
}
};
onBlur = () => {
if (this.props.accessibleMode) {
this.setState({ readInstructions: false });
}
};
onInputKeyDown = event => {
const eventKey = event.key;
// `preSelection` can be `null` but `day` is required. Use it as a fallback if necessary for invalid entries.
const copy = this.props.preSelection ? utils.newDate(this.props.preSelection) : utils.newDate(this.props.day);
let newSelection;
switch (eventKey) {
case "ArrowLeft":
newSelection = utils.subtractDays(copy, 1);
break;
case "ArrowRight":
newSelection = utils.addDays(copy, 1);
break;
case "ArrowUp":
newSelection = utils.subtractWeeks(copy, 1);
break;
case "ArrowDown":
newSelection = utils.addWeeks(copy, 1);
break;
case "PageUp":
newSelection = utils.subtractMonths(copy, 1);
break;
case "PageDown":
newSelection = utils.addMonths(copy, 1);
break;
case "Home":
newSelection = utils.subtractYears(copy, 1);
break;
case "End":
newSelection = utils.addYears(copy, 1);
break;
case " ":
case "Enter":
event.preventDefault();
this.handleDayClick(copy, event);
break;
}
if (!newSelection) return; // Let the input component handle this keydown
event.preventDefault();
this.props.updateSelection(newSelection);
};
isWeekInMonth = startOfWeek => {
const day = this.props.day;
const endOfWeek = utils.addDays(utils.cloneDate(startOfWeek), 6);
return (
utils.isSameMonth(startOfWeek, day) || utils.isSameMonth(endOfWeek, day)
);
};
renderWeeks = () => {
const weeks = [];
var isFixedHeight = this.props.fixedHeight;
let currentWeekStart = utils.getStartOfWeek(
utils.getStartOfMonth(utils.cloneDate(this.props.day))
);
let i = 0;
let breakAfterNextPush = false;
while (true) {
weeks.push(
You are focused on a calendar. Use the arrow keys to navigate the days in the month. Use the page up and down keys to navigate from month to month. Use the home and end keys to navigate from year to year. {this.props.preSelection ? `${utils.formatDate(this.props.preSelection, this.dayFormat)} is the currently focused date.` : `No date is currently focused.`}
); } return (