Generate a Pagination Number Sequence with @bramus/pagination-sequence

Introducing @bramus/pagination-sequence, a JavaScript package to generate a sequence of numbers for use in a pagination system, the clever way.

~

Faulty Paginations

On the web it’s common to include a Pagination Component underneath a list or data table. One of my pet peeves with this is the numbers that get shown in the Component, as oftentimes I encounter a sequence of numbers that just feel wrong. For example:

  • Missing first and/or last page numbers, leaving you to guess how many pages there are and preventing you to jump quickly the first or last page:

    Screenshot of a wrong pagination

  • Unnecessary gaps between numbers, where there should be none or just one single number:

    Screenshot of a wrong pagination

    Screenshot of a wrong pagination

Note that I’m not targeting the layout here, but the numbers/contents of the sequence.

☝️ Want to create a good Pagination Component? On Instagram, uiadrian shares some good tips

~

Introducing @bramus/pagination-sequence

To plug this hole, I created a function that can generate this array of numbers to show in any Pagination Component. Initially this was a PHP script (dating back to 2014), but sparked by a tweet by Sara Soueidan I took the time to convert it to a JavaScript Package published as @bramus/pagination-sequence.

The library comes as an ES Module and exposes a function/algorithm to generate the array of pagination entries to show.

import { generate } from '@bramus/pagination-sequence';

const sequence = generate(67, 74);
// ~> [1, 2, '…', 65, 66, 67, 68, 69, '…', 73, 74]

Alternatively you can use generateFromObj which accepts a options Object as an argument:

import { generateFromObj } from '@bramus/pagination-sequence';

const sequence = generateFromObj({
    curPage: 67,
    numPages: 74,
});
// ~> [1, 2, '…', 65, 66, 67, 68, 69, '…', 73, 74]

This generated array is not rendered in any way by the package itself but, instead, must be fed into your own Pagination Component for rendering. Above that this array includes no next/prev page links, as that’s the responsibility of the component consuming it.

~

Configuration / Playground

The required arguments to call this function are:

  • curPage: The current active page
  • numPages: The total number of pages

Furthermore you can tweak some other things

  • numPagesAtEdges (default: 2): The number of pages to show on the outer edges.
  • numPagesAroundCurrent (default: 2): The number of pages to show around the active page.
  • glue (default: ‘…’): The string to show when there’s a gap

You can see how these parameters behave in the interactive playground embedded below:

See the Pen
Pagination Sequence Integration Demo (React)
by Bramus (@bramus)
on CodePen.

The source of this Playground can also be found in this standalone integration example repository.

~

Algorithm Principles

Note that the algorithm is opinionated and follows these principles:

  • Stable Output

    When generating a sequence, it will always generate the same amount of entries, for any curPage value. When viewing a page at the edge of a series, this can result in numPagesAtEdges being ignored.

    For example: Instead of having generate(2, 12, 1, 1) return 01-[02]-03-..-12 (5 entries), it will return 01-[02]-03-04-05-..-12 (7 entries). This is a deliberate choice because generate(7, 12, 1, 1) will also return 7 entries: 01-..-06-[07]-08-..-12.

    With a stable amount of entries being generated, there’s no layout shift when the curPage value changes.

  • Always include links to the edges

    The algorithm will always include links to the first and last page.

    For Example: when looking at page 25 of 50, the algorithm will include a link to page 1 and page 50.

  • No unnecessary gaps

    When the algorithm detects a gap that’s only “1 item wide”, it will replace that gap with the actual number.

    For Example: A foolish take on generate(4, 9, 1, 1), would generate 01-..-03-[04]-05-..-09. The algorithm corrects the first gap to 02 and will return 01-02-03-[04]-05-..-09 instead.

~

In closing

Thank you Sara for giving me the little push to finally rework and publish this package. I’ve been meaning to do so for a long time, but it always got pushed back to some other priorities.

By keeping the package framework agnostic, I can see it being used in many places: in Pagination Components for the Modern JavaScript Frameworks Du Jour™ but also in static site generators that can benefit from it.

JavaScript Pagination Sequence Generator (GitHib) →
@bramus/pagination-sequence (NPMJS) →
@bramus/pagination-sequence React Integration Example (GitHub) →

~

🔥 Like what you see? Want to stay in the loop? Here's how:

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Join the Conversation

1 Comment

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.