Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIKE] Modifications to pagination component #3644

Closed
wants to merge 2 commits into from

Conversation

querkmachine
Copy link
Member

@querkmachine querkmachine commented May 17, 2023

A little bit of a self-indulgent spike refactoring how the pagination component works, in an effort to resolve #3324 and (potentially) make it a little simpler for teams to use.

Component page:
https://govuk-frontend-pr-3644.herokuapp.com/components/pagination

Temporary example page showing various pagination lengths in various states:
https://govuk-frontend-pr-3644.herokuapp.com/examples/pagination

Background

When investigating #3324 I came up with a couple of potential fixes, but ultimately it seemed (to me, at least) that the root of the problem is that the component lacks context about what information it’s handling. It currently only receives a limited set of explicitly categorised information and is told to format and spit it out again without interrogating it; so when it comes to processing the data more thoroughly (e.g. deciding which things should be hidden on mobile) it can only work off assumptions.

One solution is to allow service teams to provide that context by manually flagging what things are and in what contexts they should be visible, but this creates a burden on the implementor to get all the nuances of it right—if the service has multiple paginations, they'd need to get it right multiple times—and none of it is particularly easy to explain in documentation.

This is my first pass at a “do the hard work to make it simple” approach that brings more of the logic into the Nunjucks.

Instead of a backend (or other code) needing to decide ahead of time which pages to render in the pagination, what labels they use, where and when ellipses should appear, etc., this rewrite now only requires implementors to provide a list of (ordered) URLs and what the current page is: the component handles everything else.

Changes

...to how the component is used

  • Users now list all pagination items within the items array, rather than just the subset that they wish to show on the page. (This may reduce complexity in backend code, as the same pagination code can be used in multiple pages and contexts?)
  • The item.ellipsis parameter has been removed. Ellipsis placement and visibility is now determined automatically.
  • The item.current parameter has been replaced by a currentPage parameter.
  • The item.number parameter is no longer required. Numbers are automatically generated where not defined.
  • A new neighbouringPages parameter has been added, allowing macro users to configure how many pages 'neighbouring' the current page to show.

...to how the component works

  • Rather than expecting only the subset of pages the user wants to show, the pagination component now expects all possible pages to be provided.
  • Which pages are to be displayed (visiblePagesLower and visiblePagesUpper) are determined using a combination of currentPage and neighbouringPages parameters.
  • Every item in the items array is now looped through and has various tests ran against it to determine whether it should be output or not.
    • The first and last items are always output.
    • If the first item and currentPage are more than 1 index apart, ellipses are appended after the first item.
      • If the second item and visiblePagesLower are 1 or more indexes apart, the ellipses will only be shown on mobile.
    • If the last item and currentPage are more than 1 index apart, ellipses are prepended before the last item.
      • If the penultimate item and visiblePagesUpper are 1 or more indexes apart, the ellipses will only be shown on mobile.
    • If an item is within the range of visiblePagesLower and visiblePagesUpper, but is not the currentPage, it is rendered but will be hidden on mobile.
    • If an item's index matches currentPage, it is rendered with a 'current' class.
    • Items that do not match any of the above conditions are not rendered.
  • As the code to render pagination items is now needed in multiple places, I've refactored it into a private macro within the template.
  • If there are three or fewer items in the pagination, a special case is activated where all items are output on all viewports. This prevents the pagination being unnecessarily truncated on narrow viewports (it'll render 1 | 2 | 3 instead of 1 | … | 3).

Thoughts

This is a bit of a compromise between the current method (implementors provide an array of page, with links, optional numbering and other attribute info) and a more fully-automated approach (an implementor doesn't even provide an array and simply say there are 40 pages of results).

Whilst the latter would be even simpler to use, it has the trade-off of removing or restricting a number of features that the current pagination component is capable of, such as being able to customise the labelling of items or use non-incremental URL schemes for paging.

Todo

  • No tests have been written or updated for the new/altered functionality.
  • The full gamut of pagination lengths, currentPage selections and neighbouringPages combinations hasn't been tested. There may still be edge cases.
  • I've left the previous/next link functionality completely untouched, but we could potentially automate aspects of them given we now consume all possible pages as a set and know our position within the set.
  • Currently it's necessary for teams to provide overrides for item.visuallyHiddenText and item.attributes separately for each item. Defining a way to set these globally for all items would also seem like a nice enhancement.

@querkmachine querkmachine self-assigned this May 17, 2023
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3644 May 17, 2023 13:50 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3644 May 17, 2023 14:22 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3644 May 17, 2023 14:28 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3644 May 17, 2023 16:03 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3644 May 17, 2023 16:56 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3644 May 18, 2023 11:09 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3644 May 18, 2023 11:18 Inactive
@querkmachine querkmachine changed the title Spike modifications to pagination component [SPIKE] Modifications to pagination component Jun 14, 2023
@querkmachine
Copy link
Member Author

Whilst I still think this is intriguing, there doesn't seem to be much appetite internally or externally to change how pagination currently works. I'm going to close this down for neatness sake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pagination component numbering issue on small screens
2 participants