Skip to content

Instantly share code, notes, and snippets.

@mosesoak
Last active March 6, 2021 01:49
Show Gist options
  • Save mosesoak/54f8a4e2d41d13369db5b65a3fdbf2aa to your computer and use it in GitHub Desktop.
Save mosesoak/54f8a4e2d41d13369db5b65a3fdbf2aa to your computer and use it in GitHub Desktop.
React hook that automates enabling outlines for a11y when tab is used
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