@awsui/components-react
Version:
AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A
58 lines (57 loc) • 3.94 kB
JavaScript
import React, { useCallback, useEffect, useRef } from 'react';
import { addDays, addMonths, isSameMonth, startOfMonth } from 'date-fns';
import styles from '../styles.css.js';
import TabTrap from '../tab-trap';
import CalendarHeader from './header';
import Grid from './grid';
import moveFocusHandler from './utils/move-focus-handler';
var Calendar = function (_a) {
var locale = _a.locale, startOfWeek = _a.startOfWeek, displayedDate = _a.displayedDate, _b = _a.focusedDate, focusedDate = _b === void 0 ? null : _b, todayAriaLabel = _a.todayAriaLabel, calendarHasFocus = _a.calendarHasFocus, selectedDate = _a.selectedDate, isDateEnabled = _a.isDateEnabled, onChangeMonth = _a.onChangeMonth, onSelectDate = _a.onSelectDate, onFocusDate = _a.onFocusDate, previousMonthLabel = _a.previousMonthLabel, nextMonthLabel = _a.nextMonthLabel;
var elementRef = useRef(null);
var selectFocusedDate = useCallback(function (selected, baseDate) {
if (selected && isDateEnabled(selected) && isSameMonth(selected, baseDate)) {
return selected;
}
var today = new Date();
if (isDateEnabled(today) && isSameMonth(today, baseDate)) {
return today;
}
if (isDateEnabled(baseDate)) {
return baseDate;
}
return null;
}, []);
var getBaseDate = useCallback(function (date) {
var startDate = startOfMonth(date);
if (isDateEnabled(startDate)) {
return startDate;
}
return moveFocusHandler(startDate, isDateEnabled, function (date) { return addDays(date, 1); });
}, []);
var baseDate = getBaseDate(displayedDate);
var focusCurrentDate = function () { var _a, _b; return (_b = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("." + styles['calendar-day-focusable'])) === null || _b === void 0 ? void 0 : _b.focus(); };
var focusFirstButton = function () { var _a, _b; return (_b = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("." + styles['calendar-prev-month-btn'])) === null || _b === void 0 ? void 0 : _b.focus(); };
var onHeaderChangeMonthHandler = useCallback(function (isPrevious) { return onChangeMonth(addMonths(baseDate, isPrevious ? -1 : 1)); }, [baseDate]);
useEffect(function () {
var _a;
var hasFocusOnCalendarElement = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);
if (focusedDate instanceof Date && isSameMonth(focusedDate, baseDate) && hasFocusOnCalendarElement) {
focusCurrentDate();
}
if (calendarHasFocus && !hasFocusOnCalendarElement) {
setTimeout(function () {
focusFirstButton();
}, 0);
}
}, [calendarHasFocus, focusedDate]);
if (calendarHasFocus && !focusedDate) {
focusedDate = selectFocusedDate(selectedDate, baseDate);
}
return (React.createElement("div", { className: styles.calendar, role: "application", ref: elementRef },
calendarHasFocus && React.createElement(TabTrap, { focusNextCallback: focusCurrentDate }),
React.createElement("div", { className: styles['calendar-inner'] },
React.createElement(CalendarHeader, { baseDate: baseDate, locale: locale, onChangeMonth: onHeaderChangeMonthHandler, previousMonthLabel: previousMonthLabel, nextMonthLabel: nextMonthLabel, calendarHasFocus: calendarHasFocus }),
React.createElement(Grid, { locale: locale, baseDate: baseDate, isDateEnabled: isDateEnabled, focusedDate: focusedDate, onSelectDate: onSelectDate, onFocusDate: onFocusDate, onChangeMonth: onChangeMonth, startOfWeek: startOfWeek, todayAriaLabel: todayAriaLabel, selectedDate: selectedDate, handleFocusMove: moveFocusHandler })),
calendarHasFocus && React.createElement(TabTrap, { focusNextCallback: focusFirstButton })));
};
export default Calendar;