payloadcms / payloadcms/payload
Admin pagination: previous/next arrow buttons have no accessible name
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
Describe the Bug
The previous/next pagination arrows in the admin list view are icon-only buttons with no accessible name. Screen-reader users hear "button" with no indication of direction or purpose. axe-core reports this as a critical button-name violation.
Rendered markup, stock admin list view:
<button class="clickable-arrow clickable-arrow--is-disabled clickable-arrow--left" disabled type="button"></button>
<button class="clickable-arrow clickable-arrow--right" type="button"><svg class="icon icon--chevron" …></svg></button>
Root cause (verified on main)
ClickableArrow's only child is <ChevronIcon />, with no aria-label and no visually-hidden text:
return (
<button
className={classes}
disabled={isDisabled}
onClick={!isDisabled ? updatePage : undefined}
type="button"
>
<ChevronIcon />
</button>
)
An icon-only button with no text content and no ARIA label has no accessible name.
Link to the code that reproduces this issue
The permalink above — this is stock admin markup, not configuration-dependent, so a scaffolded repo would only re-render Payload's own ClickableArrow. The file is unchanged on main at 6981acab5a8e15ae9d62da10672548b1616e0238. Happy to push a create-payload-app -t blank repo if you'd still like one; it would be the default template with no changes.
Reproduction Steps
pnpx create-payload-app@latest -t blank- Seed a collection with more than one page of documents.
- Open its list view and inspect the pagination arrows — or run axe-core.
- Observe neither button has an accessible name.
Which area(s) are affected?
area: ui
Environment Info
payload: 3.84.1
@payloadcms/ui: 3.84.1
Next.js: 16.2.6
Node: 25
Browser: Chrome 141 (headless)
axe-core: 4.12.1
Root cause verified present in main at 6981acab5a8e15ae9d62da10672548b1616e0238.
Possible fix
An aria-label derived from direction ("Previous page" / "Next page") would resolve it. ChevronIcon could take aria-hidden at the same time, since the label would then carry the meaning.
Happy to open a PR if the direction is welcome.
Contributor guide
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 with packages/ui/src/elements/Pagination/ClickableArrow/index.tsx and inspect how the direction reaches the button. Reproduce the admin list pagination case or run axe-core, then verify that both arrow buttons expose their direction and that the button-name violation is gone.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- accessibility, frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100