Skip to content

Instantly share code, notes, and snippets.

@sarahbethfederman
Last active January 24, 2018 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sarahbethfederman/028efb8c3314d5555c89c4f07a357cd4 to your computer and use it in GitHub Desktop.
Save sarahbethfederman/028efb8c3314d5555c89c4f07a357cd4 to your computer and use it in GitHub Desktop.
import React from 'react';
const NAVIGATION_KEYS = [
'Tab',
'ArrowUp',
'ArrowRight',
'ArrowDown',
'ArrowLeft',
'Home',
'End',
'PageUp',
'PageDown',
'Enter',
' ',
'Escape',
/* IE9 and Firefox < 37 */
'Up',
'Right',
'Down',
'Left',
'Esc'
];
class FocusManager extends React.Component {
state = {
keyboardFocus: false,
elements: []
};
componentDidMount = () => {
this.setState({ elements: document.getElementsByClassName('focus-ring') });
document.addEventListener('keydown', this.onKeydownHandler, true);
document.addEventListener('mousedown', this.onMousedownHandler, true);
document.addEventListener('focus', this.onFocusHandler, true);
document.addEventListener('blur', this.onBlurHandler, true);
};
onKeydownHandler = event => {
if (event.ctrlKey || event.altKey || event.metaKey || NAVIGATION_KEYS.indexOf(event.key) === -1) {
return;
}
this.setState({
keyboardFocus: true
});
if (document.activeElement && document.activeElement !== document.body) {
document.activeElement.classList.add('focus-ring');
}
};
onMousedownHandler = () => {
this.setState({
keyboardFocus: false
});
if (this.state.elements.length > 0) {
for (let i = 0; i < this.state.elements.length; i++) {
// remove focus ring
this.state.elements[i].classList.remove('focus-ring');
}
}
};
onFocusHandler = event => {
if (this.state.keyboardFocus) {
event.target.classList.add('focus-ring');
}
};
onBlurHandler = event => {
event.target.classList.remove('focus-ring');
};
render() {
return (
<>
{this.props.children}
</>
);
}
}
export default FocusManager;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment