diff --git a/src/components/layout/header/header.tsx b/src/components/layout/header/header.tsx index f404b2f17..17f27d027 100644 --- a/src/components/layout/header/header.tsx +++ b/src/components/layout/header/header.tsx @@ -137,6 +137,7 @@ const Header: React.FC = (props) => { Boolean(props.transparent), ); const [hoverWithTransition, setHoverWithTransition] = useState(true); + const burgerMenuRef = React.createRef(); const transparent = Boolean(props.transparent); @@ -186,6 +187,7 @@ const Header: React.FC = (props) => { setIsNavigationVisible(!isNavigationVisible); setHoverWithTransition(false); }} + ref={burgerMenuRef} > {!isNavigationVisible ? ( = (props) => { )} translation={props.translation} setIsNavigationVisible={setIsNavigationVisible} + burgerRef={burgerMenuRef} /> ); diff --git a/src/components/layout/header/menu-flyout.tsx b/src/components/layout/header/menu-flyout.tsx index 4c536eeb3..2e2518705 100644 --- a/src/components/layout/header/menu-flyout.tsx +++ b/src/components/layout/header/menu-flyout.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useRef } from 'react'; import styled, { createGlobalStyle } from 'styled-components'; import Navigation from '../navigation/navigation'; @@ -60,12 +60,65 @@ interface NavigationFlyoutProp { translation?: string; showLanguageSwitch?: boolean; setIsNavigationVisible: (b: boolean) => void; + burgerRef: React.RefObject; } export const NavigationFlyout: React.FC = (props) => { + const overlayRef = useRef(null); + + useEffect(() => { + const preventFocusOfNonFlyoutContent = (visible: boolean) => { + const focusableElements = overlayRef.current?.querySelectorAll( + 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])', + ) as NodeListOf; + + const firstFocusableElement = focusableElements?.[0]; + const lastFocusableElement = + focusableElements?.[focusableElements.length - 1]; + + const handleFocus = (event: KeyboardEvent) => { + if (event.key !== 'Tab') { + return; + } + const shiftKeyPressed = event.shiftKey; + const activeElement = document.activeElement; + const burgerElement = props.burgerRef.current; + if (shiftKeyPressed && activeElement === burgerElement) { + lastFocusableElement?.focus(); + event.preventDefault(); + } + if (!shiftKeyPressed && activeElement === burgerElement) { + firstFocusableElement?.focus(); + event.preventDefault(); + } + if (shiftKeyPressed && activeElement === firstFocusableElement) { + burgerElement?.focus(); + event.preventDefault(); + } + if (!shiftKeyPressed && activeElement === lastFocusableElement) { + burgerElement?.focus(); + event.preventDefault(); + } + }; + + if (visible) { + document.addEventListener('keydown', handleFocus); + } else { + document.removeEventListener('keydown', handleFocus); + } + + return () => { + document.removeEventListener('keydown', handleFocus); + }; + }; + + preventFocusOfNonFlyoutContent(props.visible); + }, [props.visible]); + return ( <>