diff --git a/__tests__/components/common/DateAccordion.test.tsx b/__tests__/components/common/DateAccordion.test.tsx index d5ed05bf29..5a6c48062f 100644 --- a/__tests__/components/common/DateAccordion.test.tsx +++ b/__tests__/components/common/DateAccordion.test.tsx @@ -15,7 +15,7 @@ jest.mock('@fortawesome/react-fontawesome', () => ({ import DateAccordion from '../../../components/common/DateAccordion'; describe('DateAccordion', () => { - it('shows collapsed content when not expanded and triggers toggle', () => { + it('shows collapsed content when not expanded, exposes aria attributes, and triggers toggle', () => { const toggle = jest.fn(); render( info}> @@ -24,17 +24,27 @@ describe('DateAccordion', () => { ); expect(screen.getByText('info')).toBeInTheDocument(); expect(screen.queryByTestId('child')).not.toBeInTheDocument(); - fireEvent.click(screen.getByText('Title')); + const button = screen.getByRole('button', { name: /Title/ }); + expect(button).toHaveAttribute('aria-expanded', 'false'); + expect(button).toHaveAttribute('aria-controls'); + fireEvent.click(button); expect(toggle).toHaveBeenCalled(); }); - it('renders children when expanded', () => { + it('renders children when expanded and links aria-controls to the content region', () => { render( {}} collapsedContent={info}>
); + const button = screen.getByRole('button', { name: /Title/ }); + expect(button).toHaveAttribute('aria-expanded', 'true'); + const controls = button.getAttribute('aria-controls'); + expect(controls).toBeTruthy(); expect(screen.getByTestId('child')).toBeInTheDocument(); expect(screen.queryByText('info')).not.toBeInTheDocument(); + const region = controls ? document.getElementById(controls) : null; + expect(region).toBeInTheDocument(); + expect(region).toContainElement(screen.getByTestId('child')); }); }); diff --git a/components/common/DateAccordion.tsx b/components/common/DateAccordion.tsx index 3b15d1611b..f43e5434e2 100644 --- a/components/common/DateAccordion.tsx +++ b/components/common/DateAccordion.tsx @@ -1,3 +1,4 @@ +import { useId } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faChevronDown } from "@fortawesome/free-solid-svg-icons"; import { motion, AnimatePresence } from "framer-motion"; @@ -19,6 +20,8 @@ export default function DateAccordion({ children, showChevron = true, }: DateAccordionProps) { + const contentId = useId(); + return ( -
@@ -52,7 +58,7 @@ export default function DateAccordion({
)}
-
+ {isExpanded && ( @@ -61,6 +67,7 @@ export default function DateAccordion({ animate={{ height: "auto", opacity: 1 }} exit={{ height: 0, opacity: 0 }} transition={{ duration: 0.3, ease: [0.04, 0.62, 0.23, 0.98] }} + id={contentId} > {children}