import React, { KeyboardEvent, Component } from 'react'; interface State { selected: number; } export interface KeyboardNavigationProps { onKeyDown: (evt: KeyboardEvent, maxSelectedIndex: number, onEnterAction: () => void) => void; onMouseEnter: (select: number) => void; selected: number; } interface Props { render: (injectProps: any) => void; } class KeyboardNavigation extends Component { constructor(props) { super(props); this.state = { selected: 0, }; } goToNext = (maxSelectedIndex: number) => { const nextIndex = this.state.selected >= maxSelectedIndex ? 0 : this.state.selected + 1; this.setState({ selected: nextIndex, }); }; goToPrev = (maxSelectedIndex: number) => { const nextIndex = this.state.selected <= 0 ? maxSelectedIndex : this.state.selected - 1; this.setState({ selected: nextIndex, }); }; onKeyDown = (evt: KeyboardEvent, maxSelectedIndex: number, onEnterAction: any) => { if (evt.key === 'ArrowDown') { evt.preventDefault(); this.goToNext(maxSelectedIndex); } if (evt.key === 'ArrowUp') { evt.preventDefault(); this.goToPrev(maxSelectedIndex); } if (evt.key === 'Enter' && onEnterAction) { onEnterAction(); } }; onMouseEnter = (mouseEnterIndex: number) => { this.setState({ selected: mouseEnterIndex, }); }; render() { const injectProps = { onKeyDown: this.onKeyDown, onMouseEnter: this.onMouseEnter, selected: this.state.selected, }; return <>{this.props.render({ ...injectProps })}; } } export default KeyboardNavigation;