Skip to content

fix: move pagination control semantics off list items - #728

Draft
yoyo837 wants to merge 2 commits into
masterfrom
fix/a11y-pagination-inner-controls
Draft

yoyo837 wants to merge 2 commits into
masterfrom
fix/a11y-pagination-inner-controls

Conversation

@yoyo837

@yoyo837 yoyo837 commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Problem

The pagination upgrade in ant-design/ant-design#58604 exposes axe aria-allowed-role and list failures: interactive li elements override their list-item role with role="button". Removing those roles alone, as proposed in #727, leaves the default focus targets without control semantics.

Solution

Keep ul/li as the list structure and move focus, labels, current-page state, click handling, and activation to the existing inner controls. Reuse native buttons and anchors returned by icons or itemRender; never add an interactive wrapper around custom content. Default page and jump anchors without href expose button semantics and retain Enter/Space support, preserving the existing tags and CSS contract used by antd. Native buttons use browser keyboard activation, avoiding duplicate callbacks. Links with href retain link semantics and disabled links cannot navigate.

Opaque custom content retains its existing delegated interaction, with the invalid li role removed. Its author remains responsible for accessible control semantics; the implementation does not assume custom components forward DOM props. Document this boundary and update the bundled focus styles for child focus. Update the quick-jumper blur guard to recognize descendants of page items, so focusing a page control does not submit a pending quick-jump value before the click.

ARIA-in-HTML permits button roles on these anchors while the outer list items retain their implicit role: https://www.w3.org/TR/html-aria/.

Validation

  • 249 tests and 130 snapshots pass; lint, TypeScript, Prettier, and git diff --check pass.
  • Add real axe checks for default controls, antd-shaped icons, first/last pages, disabled/simple/empty states, and native custom renderers. The regression suite fails against the original implementation with aria-allowed-role and list violations.
  • Test actual user keyboard activation, one focus target per item, single callbacks, disabled links, custom click handlers, and opaque-renderer compatibility.
  • At antd PR #58604 head 886c3dc6c59c1b27b20be941f5043a8cd38cfa48, map the pagination import to this source: all four enabled pagination/list/table/transfer accessibility suites pass (83 tests). The config-provider suite is skipped by its existing configuration.
  • The antd simple demo, skipped by its existing accessibility suite, also passes a separate axe check against this source.
  • No browser layout or screen-reader verification; no package release or downstream dependency bump in this PR.

The companion antd change ant-design/ant-design#59573 extends its focus styles to the inner controls. This PR is an alternative to #727, not a change to that branch.

@vercel

vercel Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
pagination Ready Ready Preview Oct 14, 2026 2:48pm UTC

@coderabbitai

coderabbitai Bot commented Oct 14, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​axe-core@​4.14.01001001009970

View full report

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

React Doctor found 2 new issues in 1 file · 2 warnings · score 81 / 100 (Needs work) · 5 fixed · vs master

2 warnings

src/PaginationItem.tsx

  • ⚠️ L8 React function has high control-flow complexity no-high-complexity-react-function
  • ⚠️ L27 Handler on non-interactive element no-noninteractive-element-interactions

Reviewed by React Doctor for commit 4144185. See inline comments for fixes.

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.72%. Comparing base (a7dd4cb) to head (4144185).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #728      +/-   ##
==========================================
+ Coverage   99.69%   99.72%   +0.02%     
==========================================
  Files           4        5       +1     
  Lines         332      364      +32     
  Branches      153      169      +16     
==========================================
+ Hits          331      363      +32     
  Misses          1        1              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

❌ Deploy failed

PR preview ❌ Failed ❌ Failed
🔗 Preview https://react-component-pagination-preview-pr-728.surge.sh (may be unavailable)
📝 Commit4144185
🪵 LogsView logs
📋 Build log (last lines)
npm error
npm error Could not resolve dependency:
npm error peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" from eslint-plugin-react@7.37.5
npm error node_modules/eslint-plugin-react
npm error   dev eslint-plugin-react@"^7.37.5" from the root project
npm error   eslint-plugin-react@"^7.32.2" from @umijs/fabric@4.0.1
npm error   node_modules/@umijs/fabric
npm error     @umijs/fabric@"^4.0.0" from rc-test@7.1.3
npm error     node_modules/rc-test
npm error       dev rc-test@"^7.1.3" from the root project
npm error
npm error Conflicting peer dependency: eslint@9.39.5
npm error node_modules/eslint
npm error   peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" from eslint-plugin-react@7.37.5
npm error   node_modules/eslint-plugin-react
npm error     dev eslint-plugin-react@"^7.37.5" from the root project
npm error     eslint-plugin-react@"^7.32.2" from @umijs/fabric@4.0.1
npm error     node_modules/@umijs/fabric
npm error       @umijs/fabric@"^4.0.0" from rc-test@7.1.3
npm error       node_modules/rc-test
npm error         dev rc-test@"^7.1.3" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /home/runner/.npm/_logs/2026-10-14T14_48_50_066Z-eresolve-report.txt
npm error A complete log of this run can be found in: /home/runner/.npm/_logs/2026-10-14T14_48_50_066Z-debug-0.log

🤖 Powered by surge-preview

Comment thread src/PaginationItem.tsx
}

/** Keep the list item structural when itemRender supplies a native control. */
const PaginationItem: React.FC<PaginationItemProps> = ({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-high-complexity-react-function (warning)

PaginationItem has cyclomatic complexity 16, cognitive complexity 15, and maximum nesting depth 2, so its React logic is hard to understand and change. Extract independent branches into components or hooks.

Fix → Extract independent render branches and state logic into focused components or hooks until the control flow is easy to follow.

Docs

Comment thread src/PaginationItem.tsx
// Arbitrary components need not forward DOM props. Preserve their existing
// content and delegated interaction instead of wrapping interactive nodes.
return (
<li

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-noninteractive-element-interactions (warning)

Keyboard & screen reader users can't trigger this <li> because it isn't interactive, so use a button or link or add an interactive role.

Fix → Put interactions on a button or link, or add an interactive role.

Docs

This branch was successfully deployed

1 active deployment
Preview – pagination — 4144185a Deployed Oct 14, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant