Pagination

Pagination breaks up content into multiple pages with controls for navigating those pages.

Examples

<script>
export default {
  data() {
    return {
      currentPage: 3,
    };
  },
};
</script>

<template>
  <gl-pagination v-model="currentPage" :per-page="10" :total-items="200" />
</template>
<gl-keyset-pagination
  :has-previous-page="false"
  has-next-page
  start-cursor="eyJpZCI6IjE3NTg1ODciLCJyZWxlYXNlZF9hdCI6IjIwMjAtMDgtMjAgMTQ6NDc6MDguNTQ1MjE1MDAwIFVUQyJ9"
  end-cursor="eyJpZCI6IjEyNjcxNzkiLCJyZWxlYXNlZF9hdCI6IjIwMjAtMDItMTkgMjE6MDA6MDUuODU5NTQ2MDAwIFVUQyJ9"
/>

View in Pajamas UI Kit →

Structure

Offset pagination structure

Numbered diagram of pagination structure
Offset pagination structure
  1. Previous link: A link to the previous page, containing a chevron-lg-left icon. This link has an aria label to indicate navigating to the previous page.
  2. Next link: A link to the next page, containing a chevron-lg-right icon. This link has an aria label to indicate navigating to the next page.
  3. Page link: Sequential page number.
  4. Active page link: Highlights current page.
  5. Truncation: Indicates more pages exist that can't be listed due to space. See Behavior below.

Keyset pagination structure

Numbered diagram of keyset pagination structure
Keyset pagination structure
  1. Previous icon: A chevron-lg-left icon as part of the "previous page" link.
  2. Previous label: Text that indicates navigating to the previous page.
  3. Next label: Text that indicates navigating to the next page.
  4. Next icon: A chevron-lg-right icon as part of the "next page" link.

Guidelines

When to use

  • Break up a list or a large content block into multiple pages that can be navigated sequentially or by choosing a specific page within the set.
  • Lists with more than 20 items require pagination at the bottom of a page. Pagination is generally not required on lists with 20 or fewer items but can be considered depending on the context (that is, the paginated list is embedded within another component).

When not to use

  • If you need to navigate between steps in a flow, consider using the path component or buttons instead.

Appearance

  • There is 24px spacing (1.5rem, or spacing scale 6) between pagination and the element it relates to.

Types of pagination

There are two types of pagination, offset, and keyset (sometimes called cursor-based). General use is outlined below, but either can be used for any scenario since factors like performance, the number of results returned, user expectations, and how data is queried will ultimately help determine the best approach.

Offset pagination

Offset pagination allows a user to navigate page by page within a defined set of pages. The page number is visible and can be directly clicked in the pagination component. This method is good when records aren't added or subtracted to the results as a user navigates through them.

Because page numbers are visible, the first and last page links are not truncated so that a user can quickly navigate to the beginning or end of the contents.

Keyset pagination

Keyset pagination only has Previous and Next options and no page numbers. The text labels for each button are shown in Keyset pagination. It's ideal for paginating results that may have dynamic additions or subtractions as a user can only move to the previous or next set of results, regardless of where it is in the set. Keyset pagination is a good alternative to infinite scroll since it can provide a more predictive and accessible experience.

States

  • Disabled: The previous and next controls can be disabled when a user is either on the first or last page and can't navigate back or forward.
  • Active: Link that indicates the current "active" page.

Behavior

  • Truncation is shown using when the number of pages exceeds the pagination display limit. By default are shown after the 5th page on large and medium viewports and after the 2nd page on small and mobile viewports.
  • Double truncation occurs when the current page is separated by 5 or more pages from the first and last page on large and medium viewports. On small and mobile viewports, double truncation occurs when 1 or more pages separate the current page from the first and last page.

Accessibility

  • Since pagination is a form of navigation, there are a few helpful considerations:
    • Wrap the list in a <nav> element with aria-label so it can easily be navigated to as a landmark.
    • Use aria-current="page" on the active page link.
    • Each link should have aria-label to clarify what the page number means. For example, <a href="/p3" aria-label="Page 3">3</a>.
  • When navigating with pagination, the focus and scroll position should be at the top of the new page content so a user can continue moving through the results.

Code reference

GlPagination

Current page

The current page's value should be bound using v-model. For example:

<script>
export default {
  data: () => ({
    page: 2,
  }),
};
</script>

<template>
  <gl-pagination v-model="page" :per-page="10" :total-items="100" />
</template>

Limits

The limits prop is used to define pagination link limits based on Bootstrap's breakpoint sizes. It is strongly recommended you provide a default property, even if you have accounted for all breakpoint sizes. While unlikely, it is possible breakpoints could change, thus, a default property ensures a graceful fallback.

Here is limits default value:

{
  xs: 0,
  sm: 3,
  md: 9,
  default: 9,
}
NOTE: The component will not render any UI if the total items available for display is less than the max items per page.
import { GlPagination } from '@gitlab/ui';

Props

Name
Description
Default

v-model

number The current page number. Must be greater than 0.

1

perPage

number Number of items per page

20

totalItems

number Total number of items

0

limits

object The object must contain the xs, sm, md and default keys

{ xs: 0, sm: 3, md: 9, default: 9 }

linkGen

func A function that receives the page number and that returns a string representing the page URL

null

prevPage

number When using the compact pagination, use this prop to pass the previous page number

null

nextPage

number When using the compact pagination, use this prop to pass the next page number

null

ellipsisText

string Text for the ellipsis (overridden by "ellipsis-left" and "ellipsis-right" slots)

'…'

labelNav

string aria-label for the nav

translate('GlPagination.nav', 'Pagination')

labelFirstPage

string aria-label for the first page item

translate('GlPagination.labelFirstPage', 'Go to first page')

labelPrevPage

string aria-label for the previous page item

translate('GlPagination.labelPrevPage', 'Go to previous page')

labelNextPage

string aria-label for the next page item

translate('GlPagination.labelNextPage', 'Go to next page')

labelLastPage

string aria-label for the last page item

translate('GlPagination.labelLastPage', 'Go to last page')

labelPage

func|string aria-label getter for numbered page items, defaults to "Go to page <page_number>"

translate('GlPagination.labelPage', 'Go to page %{page}')

align

string Controls the component\'s horizontal alignment, value should be one of "left", "center", "right" or "fill"

alignOptions.left

Slots

Name
Description
previous

Content for the "previous" button. Overrides the default icon.

item.slot

page-number

next

Content for the "next" button. Overrides the default icon.

Events

Name
Description
input

undefined Emitted when the page changes

previous

Emitted when the "previous" button is clicked

next

Emitted when the "next" button is clicked

GlKeysetPagination

The simplest way to use GlKeysetPagination with a paginated GraphQL response is to v-bind to the PageInfo type returned by the endpoint:

<gl-keyset-pagination v-bind="pageInfo" />

This is possible because the default field names of the PageInfo type align with the props of this component.

Translatable strings

Do
Provide the prevText and nextText props with translatable strings. The default strings ("Previous" and "Next") are hardcoded in this component and can't be translated.

Example:

<gl-keyset-pagination v-bind="pageInfo" :prev-text="__('Previous')" :next-text="__('Next')" />

GraphQL

Do
Use this component for paginating GraphQL requests (or any endpoint that uses keyset pagination).
Don’t
Use this component for paginating REST requests (or any endpoint that uses offset pagination).

There's no intrinsic reason why GraphQL endpoints can't support offset pagination (in fact, the official documentation shows an example offset pagination implementation) or why REST endpoints can't support keyset pagination. This is simply how we've chosen to implement our REST and GraphQL endpoints at GitLab.

For offset pagination, use the GlPagination component instead.

For more information on the difference between offset and keyset pagination see our documentation on GraphQL pagination.

import { GlKeysetPagination } from '@gitlab/ui';

Props

Name
Description
Default

hasPreviousPage

boolean Whether or not the "Prev" button should be enabled

false

hasNextPage

boolean Whether or not the "Next" button should be enabled

false

startCursor

string A cursor that points to the first item in the current page. Will be passed as an event parameter when the "prev" event is fired.

null

endCursor

string A cursor that points to the last item in the current page. Will be passed as an event parameter when the "next" event is fired.

null

prevText

string The text that will be rendered inside the "Previous" button. It's important to provide this parameter since the default text is not translatable.

() => translate('GlKeysetPagination.prevText', 'Previous')

prevButtonLink

string A link that will be used as the "Prev" button\'s "href" attribute. If provided, the "Prev" button renders as a link button; otherwise, it is rendered as a regular button.

null

navigationLabel

string The aria-label that needs to be set for the pagination landmark region.

() => translate('GlKeysetPagination.navigationLabel', 'Pagination')

nextText

string The text that will be rendered inside the "Next" button. It's important to provide this parameter since the default text is not translatable.

() => translate('GlKeysetPagination.nextText', 'Next')

nextButtonLink

string A link that will be used as the "Next" button\'s "href" attribute. If provided, the "Next" button renders as a link button; otherwise, it is rendered as a regular button.

null

disabled

boolean Whether or not both buttons should be disabled (regardless of the "hasPreviousPage" and "hasNextPage" values).

false

Slots

Name
Description
previous-button-content

Used to customize the appearance of the "Prev" button

next-button-content

Used to customize the appearance of the "Next" button

Events

Name
Description
prev

next

Reference

TODO:
Add reference for the "more than 20" pagination item count requirements. Create an issue

Last updated at: 

Morty Proxy This is a proxified and sanitized view of the page, visit original site.