Skip to content

Instantly share code, notes, and snippets.

@mbensch
Created September 23, 2019 20:35
Show Gist options
  • Select an option

  • Save mbensch/15bc5d698a640dc4fc25e860c2d809a6 to your computer and use it in GitHub Desktop.

Select an option

Save mbensch/15bc5d698a640dc4fc25e860c2d809a6 to your computer and use it in GitHub Desktop.
// @refactor
import { useState, useRef, useEffect } from 'react';
import { addEventListener } from 'consolidated-events';
import KeyCode from 'lib/constants/KeyCode';
const useKeyboardNavigation = (maxFocus = null, vimMode = false) => {
const ref = useRef(null);
const [focusedIndex, setFocusedIndex] = useState(0);
const resetFocus = () => setFocusedIndex(0);
useEffect(() => {
const node = ref.current;
if (node) {
const increaseOn = [KeyCode.DOWN, vimMode && KeyCode.J].filter(Boolean);
const decreaseOn = [KeyCode.UP, vimMode && KeyCode.K].filter(Boolean);
const increase = () =>
setFocusedIndex(currentIndex =>
maxFocus ? Math.min(currentIndex + 1, maxFocus) : currentIndex + 1,
);
const decrease = () => setFocusedIndex(currentIndex => Math.max(currentIndex - 1, 0));
const handleKeyPress = e => {
if (increaseOn.includes(e.keyCode)) {
e.preventDefault();
increase();
}
if (decreaseOn.includes(e.keyCode)) {
e.preventDefault();
decrease();
}
};
const removeEventHandler = addEventListener(node, 'keydown', handleKeyPress);
return () => removeEventHandler();
}
}, [ref.current, maxFocus, vimMode]);
return [ref, { focusedIndex, resetFocus }];
};
export default useKeyboardNavigation;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment