Skip to content

Multiple tab stops inside collection components #7121

Open
@nwidynski

Description

@nwidynski

Provide a general summary of the feature here

We are developing a rather typical e-commerce storefront with interactive product cards, recommendation carousels and facet filtering based on a custom component library on top of react-aria hooks.

In our latest design phase our team has done extensive work on an accessible <Carousel /> & <Accordion /> component leveraging react-aria's <Virtualizer /> and new collection package. These components were designed to become the base on top of which to build our <Filter />, <CardCarousel /> & <CardGrid /> components, all of which represent collection components with unknown, complex, focusable content inside each item.

As we retrospect, we would like to report on obstacles we faced while utilizing existing hooks and subsequently collect feedback on an extension to useSelectableCollection() we could see introduced into react-aria.

Since we know this hook lies at the core of react-aria we decided to open this issue to discuss potential approaches to making react-aria more suitable for complex interactive collections.

For the purpose of this issue, we will mainly narrow on focus behavior and tab sequence of collection components, hoping to gain insights into the decision process and exact accessibility requirements the Spectrum team has for collections.

🤔 Expected Behavior?

While inside the cell, tab, shift+tab and arrow keys can be used to navigate the cell content just like inside a <TabPanel />, fully contained inside the cell, not propagated and storing the last visited focusable element. A click on the cell would remain to set the focused key of the outer collection.

We would love to discuss the background in making collections single tab stop and the feasibility of integrating the proposal into the current state of react-aria, as we would save some bandwith by re-using existing hooks.

😯 Current Behavior

While implementing our use case, we noticed each focusable element inside a cell has to be stepped through to reach the next cell. When discovering a product grid, this presents rather bad UX in our opinion, calling for a way to skip to the next cell.

The issue is worsened by a loss of focus scope when leaving the cell, as the returning focus is placed on the first focusable element inside the cell rather than the last visited. Additionally, arrowup or arrowdown interactions in nested components are not discarded in the cell navigation, causing a jump in the row instead of proper interaction.

💁 Possible Solution

The likely obvious thought would be to add a new keyboard combination to jump to the next cell, but we found it to be rather infeasible as most sensible combinations are already taken up by basic cell navigation or (multi) selection of cells.

In order to solve all issues, we would like to discuss an alternative navigation mode: multi tab stop

In a similar way to the <Tabs /> component, a cell content would pose as the tab panel. While focus is on a cell, arrow key navigation can be used to move between cells. When the desired cell is reached, tab moves the focus inside the cell or outside the collection, depending on whether the cell contains a focusable element.

🔦 Context

Out of the box, react-aria collections can operate in two tab sequences: tab navigation & single tab stop

This design works wonderfully in most scenarios, but becomes rather unhandy when dealing with cells containing a large amount of focusable elements. Real world applications of such use-cases can often be seen in modern project management apps, but also in e-commerce applications, both notoriously troubled with bad accessibility.

💻 Examples

No response

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    • Status

      🏗 In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions