React навигация с помощью клавиатуры ul и table как реализовать?
Подскажите пожалуйста есть ли какой-нибудь стандартный способ указать возможность навигации с помощью клавиатуры внутри элементов ul и table ? Как это реализовать ?
Ответы (1 шт):
Автор решения: Август
→ Ссылка
это просто Вам как пример, не больше. этот код совсем не адаптивный.
const myList = [...Array(9)]; // это типа пропса (массив для <li>)
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [],
activeId: null
};
this.checkKeys = this.checkKeys.bind(this);
}
static getDerivedStateFromProps({ items }, state) {
const store = items.map((i, n) => ({ id: n, isActive: false }));
return state.list.length ? null : { list: store };
}
checkKeys(e) {
e.persist(); // это чтобы объект событий работал как надо (гугл поможет)
const { list, activeId } = this.state;
let nextActiveId = activeId;
if (activeId === null) { // проверяем если ли уже выбранные блоки клавиатурой
const newList = list.map(i => i.id == 0 ? { ...i, isActive: true } : i);
return this.setState({ list: newList, activeId: 0 });
}
switch (e.keyCode) { // проверяем какую клавишу нажали
case 40: {
nextActiveId += 3;
break;
}
case 38: {
nextActiveId -= 3;
break;
}
case 39: {
nextActiveId += 1;
break;
}
case 37: {
nextActiveId -= 1;
break;
}
case 13: {
alert(`Вы выбрали lolipop номер ${activeId + 1}`);
break;
}
}
// проверяем не вышли ли мы за границы блоков
if (nextActiveId < 0 || nextActiveId > list.length - 1) return;
this.setState({
list: list.map(i => ({ ...i, isActive: (i.id === nextActiveId) })),
activeId: nextActiveId
});
}
render() {
return (
<ul onKeyDown={this.checkKeys} tabIndex="0">
{
this.state.list.map((i, n) =>
<li className={ i.isActive ? 'active' : '' } key={n}>lolipop</li>
)
}
</ul>
)
}
};
ReactDOM.render(<App items={myList} />, document.getElementById('root'));
ul {
display: grid;
grid-template-columns: repeat(3, 50px);
grid-auto-rows: 50px;
grid-gap: 10px;
}
li {
list-style-type: none;
background-color: red;
display: flex;
justify-content: center;
align-items: center;
transition: transform .5s, border .5s;
font-size: 12px;
}
li.active {
transform: scale(1.2);
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
здесь главная мысль в том, что state.list - это модель приложения (хранит состояния всех блоков - кто из них выбран, а кто - нет)