Reputation: 395
Take the following React (17.0.2) component:
const Grid = () => {
return (
<div id='grid' style={{display: 'flex', flexDirection: 'column'}}>
<div style={{display: 'flex'}}>
<div>
1
</div>
<div>
2
</div>
<div>
3
</div>
</div>
<div style={{display: 'flex'}}>
<div>
4
</div>
<div>
5
</div>
<div>
6
</div>
</div>
<div style={{display: 'flex'}}>
<div>
7
</div>
<div>
8
</div>
<div>
9
</div>
</div>
</div>
)
}
It's just a simple grid with some simple data. It's easy enough to add event listeners to it that allow you to scroll with arrow keys if you tap them. How do I make it so holding down the arrow keys will scroll continually?
The main thing I've tried to far is:
This suffers from the problem that it is really inconsistent - the interval is only sometimes cleared and sometimes scrolling just continues!
Bonus points if you can make the grid bigger, and then keep the element that is scrolled in the viewport!
Upvotes: 2
Views: 1726
Reputation: 314
Just simple with this - use ref to handle current element focus and user press keydown
const myRef = useRef();
useEffect(() => {
const node = myRef.current;
node.addEventListener('keydown',(e) => {
const active = document.activeElement;
if(e.keyCode === 40 && active.nextSibling) {
active.nextSibling.focus();
}
if(e.keyCode === 38 && active.previousSibling) {
active.previousSibling.focus();
}
});
} , [])
<div id='grid' ref={myRef} style={{display: 'flex', flexDirection: 'column'}}>
Upvotes: 2