Skip to content

Pagination

Pagination aids user movement across an ordered collection of items that has been split into pages.

  • We provide infinite scrolling guidelines, as an acceptable alternative for some usecases.
  • Our pagination pattern shows a variable number of pages to accommodate mobile and desktop experiences.
  • This pattern is available via your brands Figma library and our o3-button npm package.
  • A similar legacy pagination pattern exists within our legacy o-buttons component. However, this legacy pattern does not support a mobile experience. It also is not represented in our legacy Figma UI Library.

Anatomy

  • Navigation (1, 5): Previous and next buttons to navigate relatively from the currently selected page.
  • Page (2,3): Numbers that indicate pages.
  • Truncation (4): Indicated by ellipses (…) to replace any skipped pages.

Usage Guidelines

Standard pagination

We recommend using our standard pagination pattern, which is available within your brands Figma library and our o3-button npm package. This:

  • Should be placed at the bottom of a long list that has been split up into pages.
  • Should navigate to the previous and next set of items in the paged list.
  • Indicate when users are at the first or the last page by disabling the arrows.
✅ Choose pagination when
  • A list has a significant number of items, typically more than 25. - When showing all the content on a single page makes the page take too long to load.

When all pages can be displayed

Our pagination pattern supports 4 pages on small viewports, such as mobile devices, and 7 pages on larger desktop viewports. When there are more than 7 pages, we hide pages behind an ellipsis.

When the selected page is one of the first 2 pages

Show the first 3 pages; ellipsis; and the last 1 or 3 pages, as space allows.

Example

When the selected page is one of the last 2 pages

Show the first page, or first 3 where space allows; ellipsis; and the last 3 pages.

Example

When the 3rd page is selected

Show the first 3 pages, or 4 pages where space allows; the ellipsis; and 1 or 2 more pages, as space allows.

Example

When the selected page is the 3rd from the last page

Show the first page, or first 2 pages where space allows; the ellipsis; and 3 or 4 last pages, as space allows.

Example

When the selected page is over 3 from the first and last page

Show the first page; ellipsis; the selected page, with 1 page either side if space allows; another ellipsis; and the last page.

Example

Infinite scroll

There are some cases when infinite scroll is appropriate. This is a common pattern within our iOS and Android apps. Origami does not currently provide a full pattern for this, however we recommend the following:

  • Where infinite scrolling is used, start loading items when merchants are close to the bottom, roughly 5 items from the end.
  • Show our legacy loading indicator below the list to indicate that items have been requested.
  • After more results have been fetched, they should load in below.
✅ Choose infinite scroll when
  • You’re working on a native application, with an established pattern.
❌ Avoid infinite scroll when
  • You’re working on the web, where it is not an established pattern for us, unless user research shows they improve your interface. - It interferes with access to content below, such as our footer. - Where returning to or sharing a given pages is helpful.

Themes

Our pagination pattern supports all button themes. For example:

Standard Pagination

Open in StoryBook | Open in Figma
code
<ButtonPagination previousPager={{"label":"previous","href":"#previous"}} nextPager={{"label":"next","href":"#next"}} pages={[{"href":"#1","current":false,"number":1},{"href":"#2","current":false,"number":2},{"href":"#3","current":false,"number":3},{"href":"#4","current":false,"number":4},{"href":"#5","current":true,"number":5},{"href":"#6","current":false,"number":6},{"href":"#7","current":false,"number":7},{"href":"#8","current":false,"number":8},{"href":"#9","current":false,"number":9},{"href":"#10","current":false,"number":10}]} />
<div class="o3-button-pagination"><a href="#previous" class="o3-button o3-button--secondary  o3-button-icon o3-button-icon--arrow-left o3-button-icon--icon-only o3-apply-focus-rings"><span class="o3-button-icon__label">previous</span></a><a href="#1" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide">1</a><span data-o3-button-show-when="wide" class="o3-button-pagination__ellipsis">...</span><a href="#4" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide">4</a><a href="#5" class="o3-button o3-button--secondary  o3-apply-focus-rings" aria-current="page" data-o3-button-show-when="wide">5</a><a href="#6" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide">6</a><span data-o3-button-show-when="wide" class="o3-button-pagination__ellipsis">...</span><a href="#10" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide">10</a><a href="#1" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="narrow">1</a><span data-o3-button-show-when="narrow" class="o3-button-pagination__ellipsis">...</span><a href="#5" class="o3-button o3-button--secondary  o3-apply-focus-rings" aria-current="page" data-o3-button-show-when="narrow">5</a><span data-o3-button-show-when="narrow" class="o3-button-pagination__ellipsis">...</span><a href="#10" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="narrow">10</a><a href="#next" class="o3-button o3-button--secondary  o3-button-icon o3-button-icon--arrow-right o3-button-icon--icon-only o3-apply-focus-rings"><span class="o3-button-icon__label">next</span></a></div>

Inverse Pagination

Open in StoryBook | Open in Figma
code
<ButtonPagination previousPager={{"label":"previous","href":"#previous"}} nextPager={{"label":"next","href":"#next"}} pages={[{"href":"#1","current":false,"number":1},{"href":"#2","current":false,"number":2},{"href":"#3","current":false,"number":3},{"href":"#4","current":false,"number":4},{"href":"#5","current":true,"number":5},{"href":"#6","current":false,"number":6},{"href":"#7","current":false,"number":7},{"href":"#8","current":false,"number":8},{"href":"#9","current":false,"number":9},{"href":"#10","current":false,"number":10}]} theme={"inverse"} />
<div class="o3-button-pagination"><a href="#previous" class="o3-button o3-button--secondary  o3-button-icon o3-button-icon--arrow-left o3-button-icon--icon-only o3-apply-focus-rings" data-o3-theme="inverse"><span class="o3-button-icon__label">previous</span></a><a href="#1" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide" data-o3-theme="inverse">1</a><span data-o3-button-show-when="wide" class="o3-button-pagination__ellipsis o3-button-pagination__ellipsis--inverse">...</span><a href="#4" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide" data-o3-theme="inverse">4</a><a href="#5" class="o3-button o3-button--secondary  o3-apply-focus-rings" aria-current="page" data-o3-button-show-when="wide" data-o3-theme="inverse">5</a><a href="#6" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide" data-o3-theme="inverse">6</a><span data-o3-button-show-when="wide" class="o3-button-pagination__ellipsis o3-button-pagination__ellipsis--inverse">...</span><a href="#10" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="wide" data-o3-theme="inverse">10</a><a href="#1" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="narrow" data-o3-theme="inverse">1</a><span data-o3-button-show-when="narrow" class="o3-button-pagination__ellipsis o3-button-pagination__ellipsis--inverse">...</span><a href="#5" class="o3-button o3-button--secondary  o3-apply-focus-rings" aria-current="page" data-o3-button-show-when="narrow" data-o3-theme="inverse">5</a><span data-o3-button-show-when="narrow" class="o3-button-pagination__ellipsis o3-button-pagination__ellipsis--inverse">...</span><a href="#10" class="o3-button o3-button--secondary  o3-apply-focus-rings" data-o3-button-show-when="narrow" data-o3-theme="inverse">10</a><a href="#next" class="o3-button o3-button--secondary  o3-button-icon o3-button-icon--arrow-right o3-button-icon--icon-only o3-apply-focus-rings" data-o3-theme="inverse"><span class="o3-button-icon__label">next</span></a></div>