import { createKeyborg } from 'keyborg'; import { useEffect, useMemo, useRef } from 'react'; import { KEYBOARD_NAV_ATTRIBUTE } from '../focus/constants'; import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; /** * Instantiates [keyborg](https://github.com/microsoft/keyborg) and adds `data-keyboard-nav` * attribute to a referenced element to ensure keyboard navigation awareness * synced to keyborg logic without having to cause a re-render on react tree. */ export function useKeyboardNavAttribute() { const { targetDocument } = useFluent(); const keyborg = useMemo(()=>targetDocument && createKeyborg(targetDocument.defaultView), [ targetDocument ]); const ref = useRef(null); useEffect(()=>{ if (keyborg) { setBooleanAttribute(ref, KEYBOARD_NAV_ATTRIBUTE, keyborg.isNavigatingWithKeyboard()); const cb = (next)=>{ setBooleanAttribute(ref, KEYBOARD_NAV_ATTRIBUTE, next); }; keyborg.subscribe(cb); return ()=>keyborg.unsubscribe(cb); } }, [ keyborg ]); return ref; } function setBooleanAttribute(elementRef, attribute, value) { if (!elementRef.current) { return; } if (value) { elementRef.current.setAttribute(attribute, ''); } else { elementRef.current.removeAttribute(attribute); } }