Last active
March 6, 2021 01:49
-
-
Save mosesoak/54f8a4e2d41d13369db5b65a3fdbf2aa to your computer and use it in GitHub Desktop.
React hook that automates enabling outlines for a11y when tab is used
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState } from 'react'; | |
/** | |
* Workaround for outlines that flash or stick on click. | |
* | |
* In general, never globally disable the `outline` attribute for | |
* accessibility (a11y) reasons, but this can cause visual glitches | |
* when using a mouse. | |
* | |
* This hook provides two ways to automate hiding an element's outline | |
* when the mouse is active (and re-enabling it when tab is pressed): a | |
* flag for use w/classnames, and an always-defined style object. | |
* | |
* @returns A destructurable object with a `hideOutline` boolean flag | |
* and a spreadable `hideOutlineStyle` object for convenience | |
* | |
* @author itsyall.com | |
*/ | |
export const useTabOutline = () => { | |
const [hideOutline, setHideOutline] = useState(false); | |
useEffect(() => { | |
if (typeof window === 'undefined') { | |
return; | |
} | |
// Move is used to avoid flash on initial click. | |
// Outine is restored when tab is pressed. | |
const handleMoused = () => { | |
setHideOutline(true); | |
window.removeEventListener('mousemove', handleMoused); | |
window.addEventListener('keyup', handleKeyed); | |
}; | |
const handleKeyed = (e) => { | |
if (e.keyCode === 9) { | |
setHideOutline(false); | |
window.removeEventListener('keyup', handleKeyed); | |
window.addEventListener('mousemove', handleMoused); | |
} | |
}; | |
window.addEventListener('mousemove', handleMoused); | |
return () => { | |
window.removeEventListener('mousemove', handleMoused); | |
window.removeEventListener('keyup', handleKeyed); | |
}; | |
}, []); | |
return { | |
hideOutline, | |
hideOutlineStyle: hideOutline ? { outline: 'none' } : {}, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment