Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class PaginationButton extends Component<PaginationPageProps> {
{...props}
aria-current={this.props.current ? 'page' : undefined}
elementRef={this.handleRef}
{...(this.props.screenReaderLabel
? { 'aria-label': this.props.screenReaderLabel }
: {})}
>
{this.props.children}
</BaseButton>
Expand Down
13 changes: 10 additions & 3 deletions packages/ui-pagination/src/Pagination/PaginationButton/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ type PaginationPageOwnProps = {
| React.MouseEvent<HTMLButtonElement>
| React.FocusEvent<HTMLInputElement>
) => void
/**
* The text screenreaders should say when this button is in focus (sets the
* `aria-label` attribute).
* If left undefined (default) SRs will announce text in the child node(s).
*/
screenReaderLabel?: string
}

type PropKeys = keyof PaginationPageOwnProps
Expand All @@ -65,13 +71,14 @@ type PaginationPageProps =
const propTypes: PropValidators<PropKeys> = {
children: PropTypes.node.isRequired,
current: PropTypes.bool,
onClick: PropTypes.func
onClick: PropTypes.func,
screenReaderLabel: PropTypes.string
}

const allowedProps: AllowedPropKeys = [
'children',
'current'

'current',
'screenReaderLabel'
// we don't want to pass onClick
// 'onClick'
]
Expand Down
14 changes: 11 additions & 3 deletions packages/ui-pagination/src/Pagination/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ The pagination component provides props to handle most of the pagination use-cas
render(<Example />)
```

You can set any `totalPageNumber`, the component can handle it easily. Furthermore, you can set
`siblingCount`, which indicates how many pages are visible on either side of the `currentPage` and the
`boundaryCount`, which indicates how many pages are visible in the beginning and end.
You can set any `totalPageNumber`, the component can handle it easily.\
Furthermore, you can set `siblingCount`, which indicates how many pages are visible on either side of the `currentPage` and the
`boundaryCount`, which indicates how many pages are visible in the beginning and end.\
Also, you can set `screenReaderLabelPageButton` to customize what a screenreader will announce when the button receives focus.

- ```js
class Example extends React.Component {
Expand All @@ -87,6 +88,9 @@ You can set any `totalPageNumber`, the component can handle it easily. Furthermo
onPageChange={(nextPage) => this.setState({ currentPage: nextPage })}
siblingCount={3}
boundaryCount={2}
screenReaderLabelPageButton={(currentPage, totalPageNumber) =>
`Page ${currentPage} of ${totalPageNumber}`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

add this please to the functional example too

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done

}
/>
)
}
Expand All @@ -110,6 +114,9 @@ You can set any `totalPageNumber`, the component can handle it easily. Furthermo
onPageChange={(nextPage) => setCurrentPage(nextPage)}
siblingCount={3}
boundaryCount={2}
screenReaderLabelPageButton={(currentPage, totalPageNumber) =>
`Page ${currentPage} of ${totalPageNumber}`
}
/>
)
}
Expand Down Expand Up @@ -531,6 +538,7 @@ type: embed
<Guidelines>
<Figure recommendation="a11y" title="Accessibility">
<Figure.Item>Ensure page links and the next/previous buttons are labeled correctly for screen readers</Figure.Item>
<Figure.Item>Use `screenReaderLabelPageButton` or `screenReaderLabelNumberInput` for better screenreader experience</Figure.Item>
</Figure>
</Guidelines>
```
Original file line number Diff line number Diff line change
Expand Up @@ -1128,5 +1128,26 @@ describe('<Pagination />', () => {
)
expect(container.firstChild).toHaveTextContent('12345678910Next Page')
})

it('should add aria-label when screenReaderLabelPageButton is set', async () => {
render(
<Pagination
labelNext="Next Page"
labelPrev="Previous Page"
totalPageNumber={5}
screenReaderLabelPageButton={(currentPage, totalPageNumber) =>
`Page ${currentPage} of ${totalPageNumber}`
}
/>
)
const paginationButtons = screen.getAllByRole('button', { name: /\d$/ })

for (let i: number = 0; i < paginationButtons.length; i++) {
expect(paginationButtons[i]).toHaveAttribute(
'aria-label',
`Page ${i + 1} of ${paginationButtons.length}`
)
}
})
})
})
8 changes: 8 additions & 0 deletions packages/ui-pagination/src/Pagination/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,14 @@ class Pagination extends Component<PaginationProps> {
key={i}
onClick={() => this.handleNavigation(i, currentPage)}
current={i === currentPage}
{...(this.props.screenReaderLabelPageButton
? {
screenReaderLabel: this.props.screenReaderLabelPageButton(
i,
this.props.totalPageNumber!
)
}
: {})}
>
{this.props.renderPageIndicator?.(i, currentPage)}
</Pagination.Page>
Expand Down
16 changes: 14 additions & 2 deletions packages/ui-pagination/src/Pagination/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type PaginationOwnProps = {
*
* (__only__ for `input` variant)
*/
labelNumberInput?: (numberOfPages: number) => React.ReactNode
labelNumberInput?: (totalPageNumber: number) => React.ReactNode

/**
* ScreenReaderLabel for number input
Expand All @@ -106,7 +106,17 @@ type PaginationOwnProps = {
*/
screenReaderLabelNumberInput?: (
currentPage: number,
numberOfPages: number
totalPageNumber: number
) => string

/**
* ScreenReaderLabel for page number buttons
*
* (__only__ for `full` and `compact variants)
*/
screenReaderLabelPageButton?: (
currentPage: number,
totalPageNumber: number
) => string

/**
Expand Down Expand Up @@ -212,6 +222,7 @@ const propTypes: PropValidators<PropKeys> = {
labelLast: PropTypes.string,
labelNumberInput: PropTypes.func,
screenReaderLabelNumberInput: PropTypes.func,
screenReaderLabelPageButton: PropTypes.func,
variant: PropTypes.oneOf(['full', 'compact', 'input']),
margin: PropTypes.string,
as: PropTypes.elementType,
Expand Down Expand Up @@ -239,6 +250,7 @@ const allowedProps: AllowedPropKeys = [
'labelLast',
'labelNumberInput',
'screenReaderLabelNumberInput',
'screenReaderLabelPageButton',
'variant',
'margin',
'as',
Expand Down
Loading