UNPKG

@redocly/theme

Version:

Shared UI components lib

46 lines (38 loc) 1.5 kB
import { useEffect, useRef } from 'react'; import type { RefObject } from 'react'; export function useDialogHotKeys(ref: RefObject<HTMLElement | null>, onClose: () => void): void { const firstFocusableRef = useRef<HTMLElement>(null); const lastFocusableRef = useRef<HTMLElement>(null); const onKeyDownHandler = (event: KeyboardEvent) => { if (event.key === 'Escape') { onClose(); } else if (event.key === 'Tab') { if (!event.shiftKey && document.activeElement === lastFocusableRef.current) { event.preventDefault(); firstFocusableRef.current?.focus(); } else if (event.shiftKey && document.activeElement === firstFocusableRef.current) { event.preventDefault(); lastFocusableRef.current?.focus(); } } }; const onFocusableElementsHandler = () => { const focusableElements = ref.current?.querySelectorAll( 'input, [href], [tabindex]:not([tabindex="-1"])', ); if (focusableElements && focusableElements.length > 0) { firstFocusableRef.current = focusableElements[0] as HTMLElement; lastFocusableRef.current = focusableElements[focusableElements.length - 1] as HTMLElement; } }; useEffect(() => { document.addEventListener('keydown', onKeyDownHandler); return () => { document.removeEventListener('keydown', onKeyDownHandler); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { onFocusableElementsHandler(); }); }