mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
import { useCallback, useState, useRef, RefObject } from 'react';
|
|
|
|
const useFocusVisible = (containerRef: RefObject<HTMLElement>, onFocusEnter: ()=> void) => {
|
|
const [focusVisible, setFocusVisible] = useState(false);
|
|
|
|
const onFocusEnterRef = useRef(onFocusEnter);
|
|
onFocusEnterRef.current = onFocusEnter;
|
|
const focusVisibleRef = useRef(focusVisible);
|
|
focusVisibleRef.current = focusVisible;
|
|
|
|
const onFocusVisible = useCallback(() => {
|
|
if (!focusVisibleRef.current) {
|
|
setFocusVisible(true);
|
|
onFocusEnterRef.current();
|
|
}
|
|
}, []);
|
|
|
|
const onFocus = useCallback(() => {
|
|
if (containerRef.current.matches(':focus-visible')) {
|
|
onFocusVisible();
|
|
}
|
|
}, [containerRef, onFocusVisible]);
|
|
|
|
const onKeyUp = useCallback(() => {
|
|
if (containerRef.current.contains(document.activeElement)) {
|
|
onFocusVisible();
|
|
}
|
|
}, [containerRef, onFocusVisible]);
|
|
|
|
const onBlur = useCallback(() => setFocusVisible(false), []);
|
|
|
|
return {
|
|
focusVisible,
|
|
onFocus,
|
|
|
|
// When focus becomes visible due to a key press, but the item was already
|
|
// focused, no new focus event is emitted and the browser :focus-visible doesn't
|
|
// change. As such, we need to handle this case ourselves.
|
|
onKeyUp,
|
|
|
|
onBlur,
|
|
};
|
|
};
|
|
|
|
export default useFocusVisible;
|