diff --git a/.changeset/lemon-pigs-mix.md b/.changeset/lemon-pigs-mix.md
new file mode 100644
index 00000000000..616ae88d36e
--- /dev/null
+++ b/.changeset/lemon-pigs-mix.md
@@ -0,0 +1,5 @@
+---
+'@primer/react': patch
+---
+
+Adds new a11y improvements to Pagination.
diff --git a/src/Pagination/model.tsx b/src/Pagination/model.tsx
index 1ba6f323b18..914ab52d24f 100644
--- a/src/Pagination/model.tsx
+++ b/src/Pagination/model.tsx
@@ -65,6 +65,12 @@ export function buildPaginationModel(
for (let idx = 0; idx < sorted.length; idx++) {
const num = sorted[idx]
const selected = num === currentPage
+ const last = sorted[idx - 1]
+ const next = sorted[idx + 1]
+ const lastDelta = num - last
+ const nextDelta = num - next
+ const precedesBreak = nextDelta !== -1
+
if (idx === 0) {
if (num !== 1) {
// If the first page isn't page one,
@@ -78,15 +84,15 @@ export function buildPaginationModel(
type: 'NUM',
num,
selected,
+ precedesBreak,
})
} else {
- const last = sorted[idx - 1]
- const delta = num - last
- if (delta === 1) {
+ if (lastDelta === 1) {
pages.push({
type: 'NUM',
num,
selected,
+ precedesBreak,
})
} else {
// We skipped some, so add a break
@@ -98,6 +104,7 @@ export function buildPaginationModel(
type: 'NUM',
num,
selected,
+ precedesBreak: false,
})
}
}
@@ -124,6 +131,7 @@ type PageType = {
num: number
disabled?: boolean
selected?: boolean
+ precedesBreak?: boolean
}
export function buildComponentData(
@@ -169,11 +177,15 @@ export function buildComponentData(
case 'NUM': {
key = `page-${page.num}`
content = String(page.num)
- if (page.selected) {
- Object.assign(props, {as: 'em', 'aria-current': 'page'})
- } else {
- Object.assign(props, {href: hrefBuilder(page.num), 'aria-label': `Page ${page.num}`, onClick})
- }
+ Object.assign(props, {
+ href: hrefBuilder(page.num),
+ // We append "..." to the aria-label for pages that preceed a break because screen readers will
+ // change the tone the text is read in.
+ // This is a slightly nicer experience than skipping a bunch of numbers unexpectedly.
+ 'aria-label': `Page ${page.num}${page.precedesBreak ? '...' : ''}`,
+ onClick,
+ 'aria-current': page.selected ? 'page' : undefined,
+ })
break
}
case 'BREAK': {
diff --git a/src/__tests__/Pagination/PaginationModel.test.tsx b/src/__tests__/Pagination/PaginationModel.test.tsx
index a119873f346..3a3ba2e6273 100644
--- a/src/__tests__/Pagination/PaginationModel.test.tsx
+++ b/src/__tests__/Pagination/PaginationModel.test.tsx
@@ -60,7 +60,7 @@ describe('Pagination model', () => {
const slice = last(model, 5)
const expected = [
- {type: 'NUM'},
+ {type: 'NUM', precedesBreak: true},
{type: 'BREAK'},
{type: 'NUM', num: 9},
{type: 'NUM', num: 10},
@@ -74,11 +74,11 @@ describe('Pagination model', () => {
const model = buildPaginationModel(10, 5, true, 1, 1)
const expected = [
{type: 'PREV', num: 4},
- {type: 'NUM', num: 1},
+ {type: 'NUM', num: 1, precedesBreak: true},
{type: 'BREAK'},
{type: 'NUM', num: 4},
{type: 'NUM', num: 5, selected: true},
- {type: 'NUM', num: 6},
+ {type: 'NUM', num: 6, precedesBreak: true},
{type: 'BREAK'},
{type: 'NUM', num: 10},
{type: 'NEXT', num: 6},
@@ -95,7 +95,7 @@ describe('Pagination model', () => {
{type: 'NUM', num: 3},
// normally with a surround of 1, only 1 and 3 would be shown
// however, since 1 was already shown, we extend to 4
- {type: 'NUM', num: 4},
+ {type: 'NUM', num: 4, precedesBreak: true},
{type: 'BREAK'},
]
expect(first(model, 6)).toMatchObject(expected)
@@ -123,7 +123,7 @@ describe('Pagination model', () => {
{type: 'BREAK', num: 1},
{type: 'NUM', num: 4},
{type: 'NUM', num: 5, selected: true},
- {type: 'NUM', num: 6},
+ {type: 'NUM', num: 6, precedesBreak: true},
{type: 'BREAK', num: 10},
{type: 'NEXT'},
]
diff --git a/src/__tests__/Pagination/__snapshots__/Pagination.test.tsx.snap b/src/__tests__/Pagination/__snapshots__/Pagination.test.tsx.snap
index 7197e07d306..889609579e2 100644
--- a/src/__tests__/Pagination/__snapshots__/Pagination.test.tsx.snap
+++ b/src/__tests__/Pagination/__snapshots__/Pagination.test.tsx.snap
@@ -129,12 +129,15 @@ exports[`Pagination renders consistently 1`] = `
>
Previous
-
1
-
+