39 lines
1.4 KiB
JavaScript
39 lines
1.4 KiB
JavaScript
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);
|
|
}
|
|
}
|