react-component / react-component/tabs
[Accessibility] tabBarExtraContent is owned by role="tablist"
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 572
- Forks
- 241
- Avg merge
- 4d 18h
- Merged PRs (30d)
- 4
Description
Summary
tabBarExtraContent is rendered inside the element with role="tablist". When the extra content is interactive, the tablist therefore owns a non-tab control and axe reports a critical aria-required-children violation.
This is the canonical implementation behind these accepted Ant Design reports:
- https://github.com/ant-design/ant-design/issues/49502
- https://github.com/ant-design/ant-design/issues/53584
Minimal reproduction
<Tabs
items={[{ key: 'one', label: 'One', children: 'Panel one' }]}
tabBarExtraContent={<button type="button">Extra action</button>}
/>
Run axe with the aria-required-children rule enabled.
A focused probe through current Ant Design master, which uses @rc-component/tabs 1.12.0, produced this reduced structure:
<div role="tablist" aria-orientation="horizontal" class="ant-tabs-nav">
<div class="ant-tabs-nav-wrap">
<div class="ant-tabs-nav-list">
<div role="tab">One</div>
</div>
</div>
<div class="ant-tabs-extra-content">
<button type="button">Extra action</button>
</div>
</div>
Observed axe result:
aria-required-children (critical)
Element has children which are not allowed: button
Target: .ant-tabs-nav
Related node: .ant-tabs-extra-content > button
The canonical source has the same structure on current master (bf6dbda):
TabNavList/index.tsxputs bothExtraContentpositions, the tab nodes, the add control, andOperationNodeunder the element withrole="tablist".ExtraContent.tsxrenders the caller-provided content inside that tree.
Expected behavior
The tablist should own the role="tab" elements, while arbitrary interactive extra content remains visually adjacent but outside the tablist's accessibility ownership.
Possible implementation and regression boundaries
One possible direction is to put role="tablist" on an inner element that owns only the tabs, while leaving extra content and other non-tab controls outside it. The exact DOM change needs to preserve the existing tabListRef measurements, scrolling, overflow dropdown, ink bar, and layout behavior.
Regression coverage should include:
- interactive extra content at both
leftandrightpositions; - editable add/remove controls and the overflow/more operation;
- horizontal, vertical, and RTL layouts;
- existing keyboard navigation and tab measurement/overflow tests;
- an axe assertion with
aria-required-childrenenabled.
I searched the canonical repository's open and closed issues and PRs and found no duplicate for extra content under the tablist. #809 is related accessibility work, but it concerns the remove button's own role rather than tabBarExtraContent ownership.
AI assistance disclosure: Codex was used to trace canonical ownership, search existing issues and PRs, and run the focused axe reproduction. The reported DOM and axe output were verified against current source.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/TabNavList/index.tsx, especially the tablist wrapper and its placement of ExtraContent, operation controls, and tab nodes; then read src/TabNavList/ExtraContent.tsx. Run the focused axe reproduction with aria-required-children enabled and inspect existing keyboard, measurement, overflow, layout, and RTL tests. Done means extra interactive content is outside tablist ownership without breaking refs, scrolling, overflow, ink-bar behavior, or keyboard navigation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- accessibility, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100