Skip to content

fix(pagination): add aria attributes for screen reader accessibility#47

Merged
mattrothenberg merged 4 commits intocloudflare:mainfrom
msmps:fix/pagination-aria-navigation
Apr 14, 2026
Merged

fix(pagination): add aria attributes for screen reader accessibility#47
mattrothenberg merged 4 commits intocloudflare:mainfrom
msmps:fix/pagination-aria-navigation

Conversation

@msmps
Copy link
Copy Markdown
Contributor

@msmps msmps commented Feb 8, 2026

Description

  • Wrap pagination controls in <nav aria-label="Pagination">
  • Add aria-live="polite" and aria-atomic="true" to "Showing X-Y of Z" text for page change announcements
  • Add navigation to PaginationLabels for i18n support
  • Resolves WCAG 2.1 SC 1.3.1 (Info and Relationships) and SC 4.1.3 (Status Messages) violations

Problem

  1. Controls were wrapped in a generic <div>
  2. The "Showing X-Y of Z" status text wasn't announced when pages changed

Solution

Add semantic HTML and ARIA attributes:

  • <nav aria-label={labels.navigation}> (defaults to "Pagination", customizable for i18n)
  • aria-live="polite" - Announces page range changes without interrupting user
  • aria-atomic="true" - Ensures the entire status text is announced as a whole

Testing

Verified with VoiceOver on macOS:

  1. Enable VoiceOver (Cmd + F5)
  2. Use rotor (Ctrl + Option + U) to open landmarks menu
  3. Confirm "Pagination, navigation" appears in the list
  4. Navigate between pages and confirm "Showing X-Y of Z" is announced

  • Reviews
    • bonk has reviewed the change
    • automated review not possible because: accessibility/ARIA changes require manual screen reader testing
  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows: VoiceOver testing on macOS as described above
    • Additional testing not necessary because:

@msmps msmps changed the title fix(pagination): add ARIA attributes for screen reader accessibility fix(pagination): add aria attributes for screen reader accessibility Feb 8, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Feb 26, 2026

npm i https://pkg.pr.new/@cloudflare/kumo@47

commit: 73f3ee2

@mattrothenberg
Copy link
Copy Markdown
Collaborator

@msmps small merge conflict in this one FYI

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 26, 2026

Docs Preview

View docs preview

Commit: 73f3ee2

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 26, 2026

Visual Regression Report — 9 changed, 2 unchanged

9 screenshot(s) with visual changes:

Pagination / Pagination Basic

278 px (0.27%) changed

Before After Diff
Before After Diff

Pagination / Pagination Full

259 px (0.26%) changed

Before After Diff
Before After Diff

Pagination / Pagination Simple

456 px (0.45%) changed

Before After Diff
Before After Diff

Pagination / Pagination Mid Page

534 px (0.53%) changed

Before After Diff
Before After Diff

Pagination / Pagination Custom Text

691 px (0.68%) changed

Before After Diff
Before After Diff

Pagination / Pagination Custom Page Size Options

722 px (0.71%) changed

Before After Diff
Before After Diff

Pagination / Pagination Compound Custom Info

240 px (0.24%) changed

Before After Diff
Before After Diff

Pagination / Pagination Page Size Right

407 px (0.4%) changed

Before After Diff
Before After Diff

Pagination / Pagination I18n

568 px (0.56%) changed

Before After Diff
Before After Diff
2 screenshot(s) unchanged
  • Pagination / Pagination Large Dataset
  • Pagination / Pagination Page Size Selector

Generated by Kumo Visual Regression

Copy link
Copy Markdown
Collaborator

@geoquant geoquant left a comment

Choose a reason for hiding this comment

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

// instead of:
<div role="status" aria-live="polite" className="...">

// use:
<div aria-live="polite" aria-atomic="true" className="...">

@msmps msmps force-pushed the fix/pagination-aria-navigation branch from 6a06ca0 to 18c3966 Compare April 10, 2026 11:35
@msmps msmps requested a review from geoquant April 10, 2026 11:37
@stritt
Copy link
Copy Markdown
Collaborator

stritt commented Apr 10, 2026

/bonk please review

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Apr 10, 2026

@stritt Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

@stritt
Copy link
Copy Markdown
Collaborator

stritt commented Apr 10, 2026

/bigbonk your turn to review

ask-bonk[bot]
ask-bonk bot previously requested changes Apr 10, 2026
Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

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

Good accessibility improvement overall — wrapping controls in <nav> and adding aria-live for status announcements are the right moves. However, the aria-live / aria-atomic attributes are only applied in the legacy rendering path. The compound component Pagination.Info (the recommended API) doesn't get the same treatment, which means most new consumers won't benefit from this fix.

Specifically, the PaginationInfo component (line ~117-124) renders a plain <div> without aria-live or aria-atomic. Since the compound API is the recommended approach going forward, that's the more important place to add these attributes:

// In PaginationInfo (~line 118)
<div
  data-slot="pagination-info"
  aria-live="polite"
  aria-atomic="true"
  className={cn("text-sm text-kumo-strong", className)}
>

Also, to answer the question in the PR description: yes, <nav> is preferred over <div role="navigation"> — using semantic HTML is the right call here.

Comment thread packages/kumo/src/components/pagination/pagination.tsx
Comment thread packages/kumo/src/components/pagination/pagination.tsx Outdated
@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Apr 10, 2026

Review submitted successfully. Here's a summary of what I flagged:

Request Changes on PR #47 with two key points:

  1. Main issue: Compound Pagination.Info missing ARIA attributes — The aria-live="polite" and aria-atomic="true" attributes were only added to the legacy rendering path (line 519-521). The compound PaginationInfo component (~line 118), which is the recommended API for new code, still renders a plain <div> without these attributes. Most consumers using the modern API won't get screen reader announcements.

  2. Minor consideration on <nav> labeling — If multiple Pagination instances exist on the same page (e.g. top/bottom of a table), they'll produce duplicate <nav aria-label="Pagination"> landmarks. Suggested considering an optional aria-label prop on PaginationControls for differentiation in a follow-up.

I also confirmed that <nav> is the right choice over <div role="navigation"> as the PR author asked.

github run

Copy link
Copy Markdown
Collaborator

@stritt stritt left a comment

Choose a reason for hiding this comment

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

looks good, thanks for addressing the feedback! 👍

@mattrothenberg mattrothenberg force-pushed the fix/pagination-aria-navigation branch from 73f3ee2 to 735f1b6 Compare April 14, 2026 15:21
@mattrothenberg mattrothenberg merged commit 2682319 into cloudflare:main Apr 14, 2026
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.

4 participants