Skip to content

Components: Introduce a more composable V2 of the TabPanel #52997

@chad1008

Description

@chad1008

What?

The new V2 of TabPanel will be a more modular/composable approach to the component, utilizing Ariakit internals. Some of the initial work here has already begun in #52133. That PR focuses on updated the existing component to use Ariakit, while maintaining the same functionality and API surface.

The new component will most likely be named Tabs, as that's a bit more descriptive of the component's function and it will help avoid confusion with the tabpanel role that gets assigned to specific elements within the component.

Requirements of the new component

Some specific features/capabilities this new component must have. A few of these are current blockers of a faux tab replacement

  • Controlled Mode. Specifically, this will allow consumers to set the selected tab when necessary.
  • The ability to place the tablist and tabpanel subcomponents in arbitrary locations within the DOM.
  • tablist design flexibilty
    • Placing an auxiliary button (or other element?) such as a "Close" button beside the tablist
    • Optional full-width tabs
  • Limit onSelect calls to intentional user selections. Currently, the consumer-provided onSelect callback is triggered when the initial tab is selected during the first render. In V2, we intend to only trigger this callback when the user actively selects a tab, not when the component does so automatically.

Nice-to-haves of the new component

tabpanel tab stop/focus behavior

There are no tab stops on the individual tabpanel elements of the current TabPanel component. (...this is when I start looking forward to renaming this component to Tabs in the future 😉). This is something we're changing in the previously mentioned Ariakit migration to better align with ARIA guidance:

When the tab list contains the focus, moves focus to the next element in the page tab sequence outside the tablist, which is the tabpanel unless the first element containing meaningful content inside the tabpanel is focusable.

When that PR merges, all of the tabpanels will get a tab stop, but there's a second part of this guidance for cases dealing with focusable and meaningful content within the tabpanel.

For obvious reasons, our component won't be in a good position to determine which focusable elements contain "meaningful content". We would, however, like to expose a prop (or props, depending on the final approach to this) allowing consumers to specify whether or not focus should go to the tabpanel itself, or to the first focusable element. In cases where the author of a particular implementation knows that the first element in the tabpanel is both focusable and meaningful, this prop will give them the flexibility necessary to streamline the tab flow for end users.

TODOs/Migrations

There may be migrations necessary, if there are implementations that are simulating a tabs pattern without actually using TabPanel. I've included the two of these that I know of, but if anyone is familiar with or comes across more, please let me know!

Related:

Metadata

Metadata

Assignees

Labels

Needs Dev NoteRequires a developer note for a major WordPress release cycle[Feature] UI ComponentsImpacts or related to the UI component system[Focus] Accessibility (a11y)Changes that impact accessibility and need corresponding review (e.g. markup changes).[Package] Components/packages/components[Type] EnhancementA suggestion for improvement.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions