From 4765759beb24f9aadedfca2713b18b7459d5d26e Mon Sep 17 00:00:00 2001 From: Alex H Date: Mon, 24 Jun 2024 16:19:44 -0400 Subject: [PATCH] fix: Keep focus in calendar when changing views --- packages/react-calendar/src/Calendar.spec.tsx | 3 +++ packages/react-calendar/src/Calendar.tsx | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/react-calendar/src/Calendar.spec.tsx b/packages/react-calendar/src/Calendar.spec.tsx index 9b0a372f..ceed2abd 100644 --- a/packages/react-calendar/src/Calendar.spec.tsx +++ b/packages/react-calendar/src/Calendar.spec.tsx @@ -544,6 +544,9 @@ describe('Calendar', () => { '.react-calendar__navigation__label', ) as HTMLButtonElement; + expect(document.activeElement).toBe( + container.querySelector('.react-calendar__viewContainer'), + ); expect(label).toHaveAccessibleName('2011 – 2020'); }); diff --git a/packages/react-calendar/src/Calendar.tsx b/packages/react-calendar/src/Calendar.tsx index a2752ff4..7381be36 100644 --- a/packages/react-calendar/src/Calendar.tsx +++ b/packages/react-calendar/src/Calendar.tsx @@ -1,6 +1,6 @@ 'use client'; -import { forwardRef, useCallback, useImperativeHandle, useState } from 'react'; +import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'; import clsx from 'clsx'; import Navigation from './Calendar/Navigation.js'; @@ -669,6 +669,8 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) { : null, ); const [viewState, setViewState] = useState(defaultView); + const contentRef = useRef(null); + const setContentFocus = useRef(false); const activeStartDate = activeStartDateProps || @@ -800,6 +802,7 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) { setActiveStartDateState(nextActiveStartDate); setViewState(nextView); + setContentFocus.current = true; const args: OnArgs = { action: 'drillDown', @@ -1003,6 +1006,13 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) { [activeStartDate, drillDown, drillUp, onChange, setActiveStartDate, value, view], ); + useEffect(() => { + if (setContentFocus.current) { + setContentFocus.current = false; + contentRef.current?.focus(); + } + }); + function renderContent(next?: boolean) { const currentActiveStartDate = next ? getBeginNext(view, activeStartDate) @@ -1125,6 +1135,8 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) { className={`${baseClassName}__viewContainer`} onBlur={selectRange ? onMouseLeave : undefined} onMouseLeave={selectRange ? onMouseLeave : undefined} + tabIndex={-1} + ref={contentRef} > {renderContent()} {showDoubleView ? renderContent(true) : null}