Creating a pointer-friendly submenu experience
We are excited to announce support of submenus in the latest release of React Spectrum and React Aria! In the process of adding this feature, we found ourselves solving some unique challenges while working to make submenus user-friendly and accessible across an array of devices and input types. In doing so, we wanted to share our thought process in solving one of the challenges we faced along the way.
The Shortest Path
Submenus (or nested menus) enable multi-level exploration of menus, and even with a large number of options, users should be able to quickly find their desired option. A user should be able to hover over an item to see its submenu. Then, they should be able to move their pointer directly to any item in the newly opened submenu, following the shortest path. While doing so, the pointer may leave the original item entirely and hover an unrelated item in its path towards the submenu, causing the submenu to close. We need a way to know when they're moving their pointer to that submenu, so we can keep it open until they reach the submenu.
Predicting User Intent
We can predict the user's intent by tracking:
- Pointer movement direction
- Pointer movement speed
We can do this by listening for pointermove events and analyzing the changes in the pointer's position (also called delta).
Valid Movements
Imagine two lines: one from the pointer to the top of the submenu, and one from the pointer to the bottom of the submenu. We now have an area where the user might move their pointer on its path to the submenu. Any movement outside of this range should be considered invalid and should close the submenu.