UNPKG

@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
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;