Клавиатурная навигация является важной частью доступности интерфейсов, позволяя пользователю перемещать, сортировать и взаимодействовать с элементами без использования мыши. Библиотека Shopify Draggable предоставляет встроенные возможности для интеграции управления через клавиши, делая интерфейсы более универсальными и соответствующими стандартам доступности.
Для начала работы с клавиатурной навигацией необходимо создать
экземпляр Draggable с опцией keyboard. Простейшая
конфигурация выглядит следующим образом:
import { Draggable, Plugins } from '@shopify/draggable';
const draggable = new Draggable(document.querySelectorAll('.draggable-list'), {
draggable: '.draggable-item',
plugins: [Plugins.KeyboardSensor],
keyboard: {
enabled: true
}
});
Ключевые моменты:
Plugins.KeyboardSensor — плагин, который обрабатывает
события клавиатуры и позволяет перемещать элементы.keyboard.enabled активирует отслеживание нажатий
клавиш.tabindex="0"), иначе события клавиатуры не будут
применяться.Draggable использует фокус для определения текущего элемента, которым
управляет клавиатура. Важно правильно установить атрибут
tabindex:
<ul class="draggable-list">
<li class="draggable-item" tabindex="0">Элемент 1</li>
<li class="draggable-item" tabindex="0">Элемент 2</li>
<li class="draggable-item" tabindex="0">Элемент 3</li>
</ul>
tabindex="0" включаются в естественный
порядок табуляции.Стандартные клавиши, обрабатываемые плагином
KeyboardSensor:
| Клавиша | Действие |
|---|---|
ArrowUp |
Перемещение элемента вверх по списку |
ArrowDown |
Перемещение элемента вниз по списку |
Space |
Захват или отпуск элемента (toggle drag state) |
Enter |
Аналогично Space, подтверждает выбор элемента |
Escape |
Отмена перемещения, возвращает элемент в исходное положение |
Эта схема соответствует типичным интерфейсам сортировки с клавиатуры и позволяет интегрировать Draggable в существующие списки без сложных модификаций.
Draggable генерирует события, которые помогают отслеживать состояние при навигации с клавиатуры:
draggable.on('drag:start', (event) => {
console.log('Начало перетаскивания:', event.source);
});
draggable.on('drag:stop', (event) => {
console.log('Окончание перетаскивания:', event.source);
});
draggable.on('drag:move', (event) => {
console.log('Перемещение элемента:', event.source, 'на индекс', event.newIndex);
});
drag:start срабатывает при захвате элемента через
клавиатуру или мышь.drag:move отслеживает изменения позиции в реальном
времени.drag:stop фиксирует финальное положение элемента после
завершения перемещения.Эти события позволяют интегрировать дополнительную логику, например, обновление данных на сервере или изменение состояния интерфейса.
Для сеточных интерфейсов с Draggable клавиатурная навигация может быть настроена отдельно по горизонтали и вертикали:
const draggableGrid = new Draggable(document.querySelectorAll('.grid-list'), {
draggable: '.grid-item',
plugins: [Plugins.KeyboardSensor],
keyboard: {
enabled: true,
horizontal: true,
vertical: true
}
});
horizontal: true позволяет перемещать элементы влево и
вправо с помощью ArrowLeft и ArrowRight.vertical: true добавляет управление
ArrowUp и ArrowDown.Для обеспечения полного соответствия стандартам WCAG необходимо учитывать следующие моменты:
drag:start и drag:stop можно использовать для
обновления атрибутов aria-grabbed и
aria-dropeffect.Пример установки атрибутов:
draggable.on('drag:start', (event) => {
event.source.setAttribute('aria-grabbed', 'true');
});
draggable.on('drag:stop', (event) => {
event.source.setAttribute('aria-grabbed', 'false');
});
tabindex="0") для всех draggable-объектов.Сортировка с фильтром и пагинацией Клавиатурная
навигация сохраняет корректную работу, если элементы перерисовываются
через динамический рендеринг. Важно повторно инициализировать Draggable
на новых элементах или использовать метод
draggable.destroy() перед повторной
инициализацией.
Смешанные сенсоры Можно одновременно использовать мышь, сенсорные экраны и клавиатуру, задавая соответствующие плагины в Draggable:
const draggableMixed = new Draggable(document.querySelectorAll('.multi-sensor-list'), {
draggable: '.item',
plugins: [Plugins.MouseSensor, Plugins.TouchSensor, Plugins.KeyboardSensor],
keyboard: { enabled: true }
});
mirror:move для
динамической корректировки позиции в реальном времени.Использование плагина KeyboardSensor делает Draggable
полностью совместимым с современными стандартами доступности. Настройка
фокуса, поддержка всех основных клавиш и генерация событий позволяют
создавать интерфейсы, управляемые исключительно с клавиатуры, при этом
сохраняя гибкость и масштабируемость кода.