Implemented keyboard (arrow/vim) navigation
Add Comprehensive Keyboard Navigation
Summary
Adds full keyboard navigation support for managing cards and lanes without requiring mouse interaction.
Important
Please note that web (js/ts) programming is not my forte, so I relied heavily on Claude 4.5 for much of this implementation, but with very heavy and thorough guidance and dozens of iterative local builds and testing. That said, if you are not interested in this PR, I can understand. It was fully intended for my own personal use on my local machine via PWA install (using Firefox).
Changes
Navigation
- Arrow keys / vim keys (h/j/k/l): Navigate between cards and lanes
- Auto-focus: First card in first lane is focused on app load
- Empty lane handling: Navigation skips empty lanes when moving left/right
Card Movement
- Alt+Arrow keys: Move cards between lanes (left/right) or reorder within lanes (up/down)
- Focus preservation: Card remains focused after being moved
Focus Management
- Auto-restore: Focus returns to card after creating, renaming, or closing expanded view
- Escape key: Clears focus and returns to main board
- Expanded card: Escape key closes dialog
Help Dialog
- ? key: Opens styled keyboard shortcuts dialog
Modified Files
-
frontend/src/App.jsx: Main keyboard navigation logic, card movement functions, help dialog -
frontend/src/components/card.jsx: Modified key handler to allow arrow keys to bubble up -
frontend/src/components/expanded-card.jsx: Added Escape key handler -
KEYBOARD_SHORTCUTS.md: Updated documentation with new shortcuts
Testing
- [x] Navigation works in all directions
- [x] Alt+Arrow keys move cards correctly
- [x] Empty lanes are skipped during navigation
- [x] Focus is preserved after card operations
- [x] Help dialog displays correctly
- [x] Escape key closes dialogs and clears focus
Breaking Changes
None found. Bulk operations still operate as expected in my testing.
Example of usage:
Video clip of "in action"
https://github.com/user-attachments/assets/c37f7e2a-9de5-4e38-9a15-dab55ac44d2b
"?" triggered shortcut menu
Hey, thanks for the work! I'm actually really interested in that PR. Improving accessibility was always a goal and full keyboard navigation is definitely a huge improvement, I actually see myself fully using it.
I'm going to test and review it soon, hopefully we can have it merged and available in next release within this week
Also, the vim keys and shortcuts panel are amazing, thanks a lot for that inclusion
Awesome, glad to hear. You will have to forgive the lack of finesse with the styling of the panel. I wanted it to match a bit better than just an alert box, but my css skills leave something to be desired, lol.
Hey, after testing I found some issues that should be addressed before merging with main branch:
In the board
- Focused card does not need to have the isFocused prop with the blue outline, the standard "focus" style is enough and should mix better with the standard focused elements (consider that users may also move the focus with tab key);
- Most of the new move functions code is duplicated from the existing handleCardsSortChange function that is triggered when a card is moved within a same lane or between lanes. It requires a single parameter with format { id, targetLane, index }, where id is the card id ("card-${cardName}"), targetLane is the card lane after moved, and index is its index in lane after moved. Those new functions could be highly reduced by calling this function;
- Make lane focusable (this can be done by simply adding tabIndex={0} to the
in the lane div) and add shortcuts (alt + arrows/h-l) to be able to move them too
Keyboard shortcuts dialog
- All styling from html should be moved to the css index file;
- Close button on top right should look the same as the one in the expanded-card component;
If you can work on any of those things it would be great, most of it should be pretty simple to do. If not, I can work on it later.
Yeah, sure thing. I will try and get that handled if not tomorrow, then Saturday.
I am working on getting the changes committed, but here is what the updates are looking like.
https://github.com/user-attachments/assets/ae7d98d0-4119-4542-848f-d208492a5c25