You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Editable tabs: add and remove buttons owned by role=tablist keep aria-required-children firing #1025
After #1024 moves role="tablist" to .rc-tabs-nav-list, aria-required-children still fires for editable tabs: the add button (src/TabNavList/AddButton.tsx, rendered inside the nav list next to the tab nodes in src/TabNavList/index.tsx) is a button owned by the tablist, and a tablist may only own tab elements. axe-core flags it critical: "Element has children which are not allowed: button".
The remove button is the same class of problem, pre-existing: it renders as a sibling of the role="tab" node inside each tab wrapper, so the tablist owns it too.
Repro: <Tabs editable={{ onChange: ... }} items={...} /> through axe-core 4.13 flags the add button node with aria-required-children (critical). The same check on a non-editable Tabs is clean with #1024 applied, which is why this is carved out of that PR's scope.
What a fix likely needs:
relocate the add button outside [role=tablist] (or restructure so the tablist owns only tab nodes) while keeping the innerAddButtonRef size measurement working, it participates in the overflow calculation
move the remove button inside each role="tab" element, or give it the same restructuring
matching CSS on the antd side for both moves
Context: remaining scope of the aria-required-children failure reported in ant-design/ant-design#49502; antd currently carries a waiting for fix exemption in the tabs a11y test (ant-design/ant-design#53584) that covers this.
I'd like to work on this once #1024 is merged, since it builds on the new tablist placement.
For the add button, my plan is to render it outside .rc-tabs-nav-list and keep its position with CSS. The remove button is harder, because it sits inside each tab wrapper. Before I start, do you prefer moving it out of the wrapper as well, or keeping the DOM shape and handling it another way? Either way I'll add axe checks for the editable case to the a11y tests.
Move it out of the tablist subtree, same treatment as the add button.
Putting it inside role="tab" is the trap. WAI-ARIA 1.2 gives the tab role Children Presentational: True, so every descendant loses its semantics. The button stops being a button for assistive tech, and axe reports a different rule instead of the one you are fixing. Here is the spec line: https://www.w3.org/TR/wai-aria-1.2/#tab
Concretely: render the remove buttons in a layer after .rc-tabs-nav-list, position them from the wrapper's data-node-key, and keep the rc-tabs-tab-remove class and styles.remove so the .rc-tabs-tab-with-remove overrides in antd keep matching.
Nothing about interaction has to move. The wrapper keeps onClick at src/TabNavList/TabNode.tsx:95, role="tab" stays where it is at line 100, and the button keeps its stopPropagation, so click and keyboard behaviour are unchanged. What changes is only which element owns the button in the accessibility tree.
On your axe checks: yes, please add them, and cover the add button and the remove button in the same test. Split across two tests, the remove case can go back to red without the add case going red with it, which is exactly the shape of this bug.
Hello, a quick follow-up: #1024 is still open, and I would like to take this one once it lands, using the approach discussed above. Thank you for your time!
Checking in on the order here: I am ready to start on this as soon as #1024 lands, using the approach discussed above (remove buttons in a layer after the nav list). Let me know if you would rather I go another way.
Checking in: the earlier review on #1024 is still open, and I am ready to start this as soon as it lands. If the maintainers would rather have it done on top of #1024 now, say so and I will do that instead.
Activity
A-RYAN-1 commentedon Oct 2, 2026
I'd like to work on this once #1024 is merged, since it builds on the new tablist placement.
For the add button, my plan is to render it outside
.rc-tabs-nav-listand keep its position with CSS. The remove button is harder, because it sits inside each tab wrapper. Before I start, do you prefer moving it out of the wrapper as well, or keeping the DOM shape and handling it another way? Either way I'll add axe checks for the editable case to the a11y tests.rubenmarcus commentedon Oct 3, 2026
Move it out of the tablist subtree, same treatment as the add button.
Putting it inside
role="tab"is the trap. WAI-ARIA 1.2 gives thetabroleChildren Presentational: True, so every descendant loses its semantics. The button stops being a button for assistive tech, and axe reports a different rule instead of the one you are fixing. Here is the spec line: https://www.w3.org/TR/wai-aria-1.2/#tabConcretely: render the remove buttons in a layer after
.rc-tabs-nav-list, position them from the wrapper'sdata-node-key, and keep therc-tabs-tab-removeclass andstyles.removeso the.rc-tabs-tab-with-removeoverrides in antd keep matching.Nothing about interaction has to move. The wrapper keeps
onClickatsrc/TabNavList/TabNode.tsx:95,role="tab"stays where it is at line 100, and the button keeps itsstopPropagation, so click and keyboard behaviour are unchanged. What changes is only which element owns the button in the accessibility tree.On your axe checks: yes, please add them, and cover the add button and the remove button in the same test. Split across two tests, the remove case can go back to red without the add case going red with it, which is exactly the shape of this bug.
A-RYAN-1 commentedon Oct 18, 2026
Hello, a quick follow-up: #1024 is still open, and I would like to take this one once it lands, using the approach discussed above. Thank you for your time!
A-RYAN-1 commentedon Oct 25, 2026
The editable-tab buttons change depends on #1024. Once that is merged I will rebase this one. Thanks for the time on both.
A-RYAN-1 commentedon Nov 1, 2026
Checking in on the order here: I am ready to start on this as soon as #1024 lands, using the approach discussed above (remove buttons in a layer after the nav list). Let me know if you would rather I go another way.
A-RYAN-1 commentedon Nov 10, 2026
Checking in: the earlier review on #1024 is still open, and I am ready to start this as soon as it lands. If the maintainers would rather have it done on top of #1024 now, say so and I will do that instead.