@codecademy/gamut
68.2.268.2.3-alpha.794432.0
dist/DatePicker/Calendar/utils/keyHandler.js+
dist/DatePicker/Calendar/utils/keyHandler.jsNew file+126
Index: package/dist/DatePicker/Calendar/utils/keyHandler.js
===================================================================
--- package/dist/DatePicker/Calendar/utils/keyHandler.js
+++ package/dist/DatePicker/Calendar/utils/keyHandler.js
@@ -0,0 +1,126 @@
+import { isDateDisabled } from './dateGrid';
+
+/** Calendar grid props and callbacks used by `keyHandler`, aligned with `CalendarBodyProps`. */
+
+/**
+ * Clamp a day to the last day of the given month (e.g. Jan 31 -> Feb 28).
+ */
+const clampToMonth = (year, month, day) => {
+ const last = new Date(year, month + 1, 0).getDate();
+ return new Date(year, month, Math.min(day, last));
+};
+export const keyHandler = ({
+ e,
+ date,
+ onFocusedDateChange,
+ datesWithRow,
+ month,
+ year,
+ disabledDates = [],
+ onDateSelect,
+ onEscapeKeyPress,
+ onDisplayDateChange,
+ hasAdjacentMonthRight,
+ hasAdjacentMonthLeft
+}) => {
+ const idx = datesWithRow.findIndex(({
+ date: dateWithRow
+ }) => dateWithRow.getTime() === date.getTime());
+ if (idx < 0) return;
+ const currentRow = datesWithRow[idx].rowIndex;
+ const day = date.getDate();
+ const hasRight = !!hasAdjacentMonthRight;
+ const hasLeft = !!hasAdjacentMonthLeft;
+ let newDate = null;
+ let newDisplayDate = null;
+ switch (e.key) {
+ case 'ArrowLeft':
+ e.preventDefault();
+ if (idx > 0) {
+ newDate = datesWithRow[idx - 1].date;
+ } else {
+ const lastDayPrevMonth = new Date(year, month, 0);
+ newDate = lastDayPrevMonth;
+ if (!hasLeft) {
+ newDisplayDate = new Date(year, month - 1, 1);
+ }
+ }
+ break;
+ case 'ArrowRight':
+ e.preventDefault();
+ if (idx < datesWithRow.length - 1) {
+ newDate = datesWithRow[idx + 1].date;
+ } else {
+ newDate = new Date(year, month + 1, 1);
+ if (!hasRight) {
+ newDisplayDate = new Date(year, month + 1, 1);
+ }
+ }
+ break;
+ case 'ArrowUp':
+ e.preventDefault();
+ newDate = new Date(date);
+ newDate.setDate(newDate.getDate() - 7);
+ if (newDate.getMonth() !== month || newDate.getFullYear() !== year) {
+ if (!hasLeft) {
+ newDisplayDate = new Date(newDate.getFullYear(), newDate.getMonth(), 1);
+ }
+ }
+ break;
+ case 'ArrowDown':
+ e.preventDefault();
+ newDate = new Date(date);
+ newDate.setDate(newDate.getDate() + 7);
+ if (newDate.getMonth() !== month || newDate.getFullYear() !== year) {
+ if (!hasRight) {
+ newDisplayDate = new Date(newDate.getFullYear(), newDate.getMonth(), 1);
+ }
+ }
+ break;
+ case 'Home':
+ e.preventDefault();
+ newDate = datesWithRow.find(({
+ rowIndex
+ }) => rowIndex === currentRow)?.date ?? date;
+ break;
+ case 'End':
+ e.preventDefault();
+ newDate = [...datesWithRow].reverse().find(({
+ rowIndex
+ }) => rowIndex === currentRow)?.date ?? date;
+ break;
+ case 'PageDown':
+ e.preventDefault();
+ if (e.shiftKey) {
+ newDate = clampToMonth(year + 1, month, day);
+ } else {
+ newDate = clampToMonth(year, month + 1, day);
+ }
+ newDisplayDate = new Date(newDate.getFullYear(), newDate.getMonth(), 1);
+ break;
+ case 'PageUp':
+ e.preventDefault();
+ if (e.shiftKey) {
+ newDate = clampToMonth(year - 1, month, day);
+ } else {
+ newDate = clampToMonth(year, month - 1, day);
+ }
+ newDisplayDate = new Date(newDate.getFullYear(), newDate.getMonth(), 1);
+ break;
+ case 'Enter':
+ case ' ':
+ e.preventDefault();
+ if (!isDateDisabled(date, disabledDates)) onDateSelect(date);
+ return;
+ case 'Escape':
+ e.preventDefault();
+ onEscapeKeyPress?.();
+ return;
+ default:
+ return;
+ }
+ if (newDate !== null) {
+ onFocusedDateChange(newDate);
+ if (newDisplayDate !== null) onDisplayDateChange?.(newDisplayDate);
+ }
+};
\ No newline at end of file