Skip to content
Paste
UX Platform
GitHub

Pagination

Pagination lets users navigate through content or a dataset that’s been broken up into multiple pages.

Status
production
Version
0.1.2
Sources
Abstract
Import from
@twilio-paste/core/pagination — or — @twilio-paste/pagination

Guidelines

About Pagination#

Use Pagination to split up content when a user’s goal is "to find a specific item [in a list] and click through to that destination page" (source: Nielsen Norman Grouplink takes you to an external page). Pagination is used to communicate only where a user is in paged content. It isn’t used to show the status of each page—use a Progress Stepper (coming soon) instead.

Pagination is often paired with Tables, one of the most commonly used components in Twilio and one of the primary ways customers view content in our products. Think of Pagination as an important navigation element that helps our customers understand exactly where they are and help them decide where to go next.

The component is made up of 6 main parts:

  • Pagination: The outer pagination container with the accessible role=navigation
  • PaginationItems: A wrapper that displays the pagination contents inline.
  • PaginationArrow: Left and right arrow controls, with an option to add text labels
  • PaginationLabel: Indicates the current page in view (e.g., "Page 2", "1–10 of 50 results")
  • PaginationNumbers: A wrapper for the list of page numbers and the total page count
  • PaginationNumber: Page number controls

Accessibility Information#

  • The Pagination component supports navigation by the use of either a button or anchor. Use Pagination as an anchor if the URL changes for each page. Use it as a button if the URL doesn’t change for each page. Check out our documentation on when to use a Button vs. an Anchor.
  • Use the Pagination component when it controls a large part of the page in view, like a full-width Table. Since Pagination typically appears underneath the UI element it’s controlling, it needs to be obvious that it is controlling the element above it, rather than anything else below it. For example, if you need to let users page through a small table in a card on a dashboard page, consider letting them expand the table and show Pagination on the expanded view instead.

Examples#

Default pagination#

Use the default Pagination component for paged datasets like event logs, where the dataset is constantly increasing in size, or where the total number of pages is unknown.

At minimum, the default Pagination component shows the Pagination arrows. However whenever possible, show the current page number too, so that users know where they are in a dataset and get confirmation that they’ve moved to a new page.

Default pagination as anchor#

Use Pagination as an anchor if the URL changes for each page. Both the PaginationArrow and PaginationNumber components can be set as anchors using the as="a" prop and including an href prop.

Default pagination as button#

Use Pagination as a button if the URL doesn’t change for each page. Both the PaginationArrow and PaginationNumber components are buttons by default.

Pagination with custom labels#

Adding labels to Pagination can help give customers more information about what kind of data is in view and in what direction the pages are moving. For example, when a dataset is sorted chronologically, it might not be immediately clear whether the "Next" button takes you forward or backward in time.

Will pressing the "Next" button take you to January or March?

To give customers further clarity on where they are in a data set, you can add custom text to:

  • The current page label
  • The left and right arrow controls

Pagination with total page count#

Use the Pagination variant with total page count in cases when knowing the exact size of a dataset is crucial to a customer’s understanding of the content (e.g., knowing how many phone numbers aren’t compliant) and when you’re able to fetch the data in a performant way.

This variant also allows customers to skip ahead pages in a dataset, though this hasn't been identified as a common use case.

Considering the tradeoffs for showing the total count of a dataset

By default, Twilio APIs might not support showing current page number or the total count of a datasetlink takes you to an external page.

However, anecdotal evidence from product designers suggests that knowing the size of a dataset is important to Twilio customers in certain cases. Showing the total count of a dataset makes sense especially when the customer has more active control over total count, such as with total SIMs, but not for datasets that rapidly increase, like event logs. If the exact total count is unknown, consider indicating size in another way that gives customers an approximate idea of the size of a dataset, like showing "1–10 of 100+ results".

DateMessage count
Oct 21, 20203
Oct 20, 20206
Oct 19, 202013
Oct 18, 20209

Composition Notes#

Make sure the current page label and arrow controls in the Pagination component give customers enough clarity on where they are and where they’ll be going. Show the current page number whenever possible.

Positioning Pagination#

The Pagination component should be centered underneath the content it controls separated by a margin of $space-70.

DateSIDFrom

16:24:28 PDT

2020-09-17

SM0yc4mxi6cn4z13bte7qmflc2drc85mlp(602) 609-6747

16:24:28 PDT

2020-09-17

SMl29llgoihx286uhxfb0yc5n0sg391x5n(602) 609-6747

16:24:28 PDT

2020-09-17

SMxarke3v30fv17hauqn86a7nhgm3b5d87(602) 609-6747

16:24:28 PDT

2020-09-17

SM0yc4mxi6cn4z13bte7qmflc2drc85mlp(602) 609-6747

16:24:28 PDT

2020-09-17

SMl29llgoihx286uhxfb0yc5n0sg391x5n(602) 609-6747

Using PaginationEllipsis#

When the number of pages exceeds 7, PaginationEllipsis can be used to indicate there are remaining pages.

Double PaginationEllipsis is used when the current page is more than 3 pages from the first or last page.

Paging through chronological data#

Add custom text to the arrow controls (e.g., "Older"/"Newer", "Previous month"/"next month") for datasets sorted by time or date. This makes it clear what direction the pages are moving.

If a customer can change the sort order of the dataset, make sure you swap the labelling of the arrow controls, as well.

Determining how many items to show per page#

The default number of items in view for paged content should generally scale up based on how important the content is to the customer’s goals, and scale down with the complexity or visual size of the dataset. For example, you might want to show fewer items per page for pages of Cards, or for Tables with tall rows.

Most Twilio datasets show 10 or 50 rows per page by default. However, a generic rule doesn't always work for complex, context-dependent data. We recommend using research to reach a sensible default and solution that works best for the customer.

If a single default can’t satisfy customers’ needs, you can give customers a way to change the number of items in view. Try to keep these options limited to reduce cognitive overhead, especially if the choice isn’t critical to the customer’s main goal.

Many sites let users choose how many items they’ll see on each page. This is often overkill...It’s usually better to offer a single default number — such as 10 or 20 — [or] give users the choice between two numbers, say 10 and 50, where the second number is substantially bigger than the default. If the choice is between two relatively similar numbers (such as 10 and 20), users might as well click the Next Page button rather than suffer the cognitive overhead of trying to decide their display preference.

Consider contributing a Table Actions pattern to help standardize this across Twilio!

When to use Pagination#

Do

Use Pagination to let users page through items where a user is trying to find a specific item.

Don't

Don’t use the Pagination component to help users navigate through linear multi-step content like paged forms. In these cases, use a Progress Stepper (coming soon) or something that can communicate more about a user’s status through a flow than the Pagination component allows.

Do

Add custom, context-specific information to page labels and left and right page controls to give customers more clarity about where they are and where they’re going, when needed.

Don't

Don’t over-complicate Pagination labels with too much information about the content in view. If you can’t give succinct labels to Pagination, consider showing the information elsewhere on the page.

Do

Show current page count whenever possible so users understand where they are in a dataset, and so that they know the content in view has been updated if they navigate to a new page number.


Anatomy#

PaginationArrow#

PropertyDefault tokenModifiable?
background-color (arrow only)
  • Hover: $color-background-primary-lightest
No
border-color
  • $color-border
  • Hover: $color-border-primary
  • Focus: $color-border-primary
No
color
  • $color-text
  • Hover: $color-text-link
  • Focus: $color-text-link
No
font-size$font-size-30No
font-weight$font-weight-normalNo
line-height$line-height-30No

PaginationNumber#

PropertyDefault tokenModifiable?
background-color
  • transparent
  • Current: $color-background-primary-lightest
  • Hover: $color-background-primary-lightest
  • Focus: $color-background-primary-lightest
No
color
  • $color-text
  • Current: $color-text-link
  • Hover: $color-text-link
  • Focus: $color-text-link
No
font-size$font-size-30No
font-weight$font-weight-normalNo
line-height$line-height-30No

PaginationEllipsis#

PropertyDefault tokenModifiable?
color$color-textNo
font-size$font-size-30No
font-weight$font-weight-normalNo
line-height$line-height-30No

PaginationLabel#

PropertyDefault tokenModifiable?
color$color-text-weakNo
font-size$font-size-30No
font-weight$font-weight-normalNo
line-height$line-height-30No

Usage Guide#

API#

Installation#

yarn add @twilio-paste/pagination - or - yarn add @twilio-paste/core

Usage#

import {
Pagination,
PaginationItems,
PaginationArrow,
PaginationLabel,
PaginationNumbers,
PaginationNumber,
PaginationEllipsis,
} from '@twilio-paste/pagination';
const Component = () => {
return (
<Pagination label="pagination navigation">
<PaginationItems>
<PaginationArrow variant="back" label="Go to previous page" visibleLabel="Previous" />
<PaginationNumbers pageLabel="Page 5 of 10">
<PaginationNumber label="Go to page 1">1</PaginationNumber>
<PaginationEllipsis label="Collapsed previous pages" />
<PaginationNumber label="Go to page 4">4</PaginationNumber>
<PaginationNumber label="Go to page 5" isCurrent>
5
</PaginationNumber>
<PaginationNumber label="Go to page 6">6</PaginationNumber>
<PaginationEllipsis label="Collapsed next pages" />
<PaginationNumber label="Go to page 10">10</PaginationNumber>
</PaginationNumbers>
<PaginationArrow variant="forward" label="Go to next page" visibleLabel="Next" />
</PaginationItems>
</Pagination>
);
};

Props#

Pagination Props#

PropTypeDescriptionDefault
childrenReactNodenull
labelstringaria-label for the pagination navigation elementnull

PaginationItems Props#

PropTypeDescriptionDefault
childrenReactNodenull

PaginationLabel Props#

PropTypeDescriptionDefault
childrenReactNodenull

PaginationArrow Props#

PropTypeDescriptionDefault
as?stringa / buttonbutton
disabled?booleanSets aria-hidden to be true, and visibility: hiddennull
href?stringhref used when as anull
labelstringaria-label textnull
variantstringback / forwardnull
visibleLabel?stringVisible text of the button or anchornull

PaginationNumbers Props#

PropTypeDescriptionDefault
childrenReactNodenull
pageLabel?stringPage label text used in PaginationLabelnull

PaginationNumber Props#

PropTypeDescriptionDefault
as?stringa / buttonbutton
children?ReactNodenull
href?stringhref used when as anull
isCurrent?booleanSets the aria-current to be truenull
labelstringaria-label textnull

PaginationEllipsis Props#

PropTypeDescriptionDefault
labelstringaria-label textnull

Black lives matter.