Skip to content

Commit 4b13762

Browse files
committed
Spike modifications to pagination component
1 parent d214055 commit 4b13762

File tree

3 files changed

+204
-88
lines changed

3 files changed

+204
-88
lines changed

packages/govuk-frontend/src/govuk/components/pagination/_index.scss

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,9 @@
3737
}
3838

3939
.govuk-pagination__item {
40-
// Hide items on small screens except the prev/next items,
41-
// non-link items and the first and last items
42-
display: none;
43-
4440
// Center align pagination links in their parent list item so that they
4541
// visually sit in the middle of their touch area
4642
text-align: center;
47-
48-
@include govuk-media-query($from: tablet) {
49-
display: block;
50-
}
5143
}
5244

5345
.govuk-pagination__prev,
@@ -70,12 +62,20 @@
7062
padding-right: 0;
7163
}
7264

73-
// Only show first, last and non-link items on mobile
74-
.govuk-pagination__item--current,
75-
.govuk-pagination__item--ellipses,
76-
.govuk-pagination__item:first-child,
77-
.govuk-pagination__item:last-child {
78-
display: block;
65+
// Hide neighbouring items on mobile
66+
.govuk-pagination__item--neighbour {
67+
display: none;
68+
69+
@include govuk-media-query($from: tablet) {
70+
display: block;
71+
}
72+
}
73+
74+
// Show 'collapsed only' items only on mobile
75+
.govuk-pagination__item--collapsed-only {
76+
@include govuk-media-query($from: tablet) {
77+
display: none;
78+
}
7979
}
8080

8181
.govuk-pagination__item--current {

packages/govuk-frontend/src/govuk/components/pagination/pagination.yaml

Lines changed: 139 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ params:
1616
type: string
1717
required: true
1818
description: The link's URL.
19-
- name: current
20-
type: boolean
21-
required: false
22-
description: Set to `true` to indicate the current page the user is on.
23-
- name: ellipsis
24-
type: boolean
25-
required: false
26-
description: Use this option if you want to specify an ellipsis at a given point between numbers. If you set this option as `true`, any other options for the item are ignored.
2719
- name: attributes
2820
type: object
2921
required: false
@@ -70,6 +62,10 @@ params:
7062
type: object
7163
required: false
7264
description: The HTML attributes (for example, data attributes) you want to add to the anchor.
65+
- name: currentPage
66+
type: number
67+
required: true
68+
description: The index of the current page within the set of `items`. This is a 1-based index, so that it matches the visible number that is rendered by default.
7369
- name: landmarkLabel
7470
type: string
7571
required: false
@@ -90,29 +86,23 @@ examples:
9086
href: '/previous'
9187
next:
9288
href: '/next'
89+
currentPage: 2
9390
items:
94-
- number: 1
95-
href: '/page/1'
96-
- number: 2
97-
href: '/page/2'
98-
current: true
99-
- number: 3
100-
href: '/page/3'
91+
- href: '/page/1'
92+
- href: '/page/2'
93+
- href: '/page/3'
10194
- name: with custom navigation landmark
10295
data:
10396
previous:
10497
href: '/previous'
10598
next:
10699
href: '/next'
107100
landmarkLabel: 'search'
101+
currentPage: 2
108102
items:
109-
- number: 1
110-
href: '/page/1'
111-
- number: 2
112-
href: '/page/2'
113-
current: true
114-
- number: 3
115-
href: '/page/3'
103+
- href: '/page/1'
104+
- href: '/page/2'
105+
- href: '/page/3'
116106
- name: with custom link and item text
117107
data:
118108
previous:
@@ -121,12 +111,12 @@ examples:
121111
next:
122112
href: '/next'
123113
text: 'Next page'
114+
currentPage: 2
124115
items:
125116
- number: 'one'
126117
href: '/page/1'
127118
- number: 'two'
128119
href: '/page/2'
129-
current: true
130120
- number: 'three'
131121
href: '/page/3'
132122
- name: with custom accessible labels on item links
@@ -135,65 +125,153 @@ examples:
135125
href: '/previous'
136126
next:
137127
href: '/next'
128+
currentPage: 2
138129
items:
139-
- number: 1
140-
href: '/page/1'
130+
- href: '/page/1'
141131
visuallyHiddenText: '1st page'
142-
- number: 2
143-
href: '/page/2'
144-
current: true
132+
- href: '/page/2'
145133
visuallyHiddenText: '2nd page (you are currently on this page)'
146-
- number: 3
147-
href: '/page/3'
134+
- href: '/page/3'
148135
visuallyHiddenText: '3rd page'
149136
- name: with many pages
150137
data:
151138
previous:
152139
href: '/previous'
153140
next:
154141
href: '/next'
142+
currentPage: 10
155143
items:
156-
- number: 1
157-
href: '/page/1'
158-
- ellipsis: true
159-
- number: 8
160-
href: '/page/8'
161-
- number: 9
162-
href: '/page/9'
163-
- number: 10
164-
href: '/page/10'
165-
current: true
166-
- number: 11
167-
href: '/page/11'
168-
- number: 12
169-
href: '/page/12'
170-
- ellipsis: true
171-
- number: 40
172-
href: '/page/40'
144+
- href: '/page/1'
145+
- href: '/page/2'
146+
- href: '/page/3'
147+
- href: '/page/4'
148+
- href: '/page/5'
149+
- href: '/page/6'
150+
- href: '/page/7'
151+
- href: '/page/8'
152+
- href: '/page/9'
153+
- href: '/page/10'
154+
- href: '/page/11'
155+
- href: '/page/12'
156+
- href: '/page/13'
157+
- href: '/page/14'
158+
- href: '/page/15'
159+
- href: '/page/16'
160+
- href: '/page/17'
161+
- href: '/page/18'
162+
- href: '/page/19'
163+
- href: '/page/20'
173164
- name: first page
174165
data:
175166
next:
176167
href: '/next'
168+
currentPage: 1
177169
items:
178-
- number: 1
179-
href: '/page/1'
180-
current: true
181-
- number: 2
182-
href: '/page/2'
183-
- number: 3
184-
href: '/page/3'
170+
- href: '/page/1'
171+
- href: '/page/2'
172+
- href: '/page/3'
185173
- name: last page
186174
data:
187175
previous:
188176
href: '/previous'
177+
currentPage: 3
189178
items:
190-
- number: 1
191-
href: '/page/1'
192-
- number: 2
193-
href: '/page/2'
194-
- number: 3
195-
href: '/page/3'
196-
current: true
179+
- href: '/page/1'
180+
- href: '/page/2'
181+
- href: '/page/3'
182+
- name: bordering first page
183+
data:
184+
previous:
185+
href: '/previous'
186+
next:
187+
href: '/next'
188+
currentPage: 4
189+
items:
190+
- href: '/page/1'
191+
- href: '/page/2'
192+
- href: '/page/3'
193+
- href: '/page/4'
194+
- href: '/page/5'
195+
- href: '/page/6'
196+
- href: '/page/7'
197+
- href: '/page/8'
198+
- href: '/page/9'
199+
- href: '/page/10'
200+
- name: bordering last page
201+
data:
202+
previous:
203+
href: '/previous'
204+
next:
205+
href: '/next'
206+
currentPage: 7
207+
items:
208+
- href: '/page/1'
209+
- href: '/page/2'
210+
- href: '/page/3'
211+
- href: '/page/4'
212+
- href: '/page/5'
213+
- href: '/page/6'
214+
- href: '/page/7'
215+
- href: '/page/8'
216+
- href: '/page/9'
217+
- href: '/page/10'
218+
- name: with fewer neighbours
219+
data:
220+
previous:
221+
href: '/previous'
222+
next:
223+
href: '/next'
224+
currentPage: 4
225+
neighbouringPages: 1
226+
items:
227+
- href: '/page/1'
228+
- href: '/page/2'
229+
- href: '/page/3'
230+
- href: '/page/4'
231+
- href: '/page/5'
232+
- href: '/page/6'
233+
- href: '/page/7'
234+
- href: '/page/8'
235+
- href: '/page/9'
236+
- href: '/page/10'
237+
- name: with more neighbours
238+
data:
239+
previous:
240+
href: '/previous'
241+
next:
242+
href: '/next'
243+
currentPage: 7
244+
neighbouringPages: 4
245+
items:
246+
- href: '/page/1'
247+
- href: '/page/2'
248+
- href: '/page/3'
249+
- href: '/page/4'
250+
- href: '/page/5'
251+
- href: '/page/6'
252+
- href: '/page/7'
253+
- href: '/page/8'
254+
- href: '/page/9'
255+
- href: '/page/10'
256+
- name: with no neighbours
257+
data:
258+
previous:
259+
href: '/previous'
260+
next:
261+
href: '/next'
262+
currentPage: 7
263+
neighbouringPages: 0
264+
items:
265+
- href: '/page/1'
266+
- href: '/page/2'
267+
- href: '/page/3'
268+
- href: '/page/4'
269+
- href: '/page/5'
270+
- href: '/page/6'
271+
- href: '/page/7'
272+
- href: '/page/8'
273+
- href: '/page/9'
274+
- href: '/page/10'
197275
- name: with prev and next only
198276
data:
199277
previous:

packages/govuk-frontend/src/govuk/components/pagination/template.njk

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{% set blockLevel = not params.items and (params.next or params.previous) %}
22

3+
{% set currentPage = params.currentPage %}
4+
{% set neighbouringPages = params.neighbouringPages if params.neighbouringPages !== undefined else 2 %}
5+
6+
{% set visiblePagesLower = currentPage - neighbouringPages %}
7+
{% set visiblePagesUpper = currentPage + neighbouringPages %}
8+
9+
{% macro _paginationItem(index, item, context = {}) %}
10+
{%- set isCurrent = index == currentPage %}
11+
<li class="govuk-pagination__item {{- ' govuk-pagination__item--current' if isCurrent }} {{- ' govuk-pagination__item--neighbour' if context.neighbour }}">
12+
<a class="govuk-link govuk-pagination__link" href="{{ item.href }}" aria-label="{{ item.visuallyHiddenText | default("Page " + item.number) }}" {%- if isCurrent %} aria-current="page"{% endif %} {%- for attribute, value in item.attributes %} {{ attribute }}="{{ value }}"{% endfor %}>
13+
{{- item.number | default(index) -}}
14+
</a>
15+
</li>
16+
{% endmacro %}
17+
318
<nav class="govuk-pagination {{- ' ' + params.classes if params.classes }} {{- ' govuk-pagination--block' if blockLevel }}" role="navigation" aria-label="{{ params.landmarkLabel | default("results") }}" {%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}" {%- endfor -%}>
419
{%- if params.previous and params.previous.href -%}
520
<div class="govuk-pagination__prev">
@@ -18,21 +33,44 @@
1833
</div>
1934
{% endif %}
2035

21-
{%- if params.items -%}
36+
{# Only show numbered pagination if params.items is set #}
37+
{%- if params.items %}
2238
<ul class="govuk-pagination__list">
23-
{%- for item in params.items -%}
24-
{%- if item.ellipsis -%}
25-
<li class="govuk-pagination__item govuk-pagination__item--ellipses">&ctdot;</li>
26-
{%- elseif item.number -%}
27-
<li class="govuk-pagination__item {{- ' govuk-pagination__item--current' if item.current }}">
28-
<a class="govuk-link govuk-pagination__link" href="{{ item.href }}" aria-label="{{ item.visuallyHiddenText | default("Page " + item.number) }}" {%- if item.current %} aria-current="page" {%- endif -%} {%- for attribute, value in item.attributes %} {{ attribute }}="{{ value }}" {%- endfor -%}>
29-
{{ item.number }}
30-
</a>
31-
</li>
32-
{%- endif -%}
33-
{%- endfor -%}
39+
40+
{%- for item in params.items %}
41+
42+
{# Always show the first and last numbered option #}
43+
{%- if loop.first or loop.last %}
44+
45+
{# If the last item in the loop, and we're likely to need one, prepend an ellipsis #}
46+
{%- if loop.last and loop.index > currentPage + 1 %}
47+
<li class="govuk-pagination__item govuk-pagination__item--ellipses {{- ' govuk-pagination__item--collapsed-only' if loop.index - 1 <= visiblePagesUpper }}">&ctdot;</li>
48+
{%- endif %}
49+
50+
{{ _paginationItem(loop.index, item) }}
51+
52+
{# If the first item in the loop, and we're likely to need one, append an ellipsis #}
53+
{%- if loop.first and loop.index < currentPage - 1 %}
54+
<li class="govuk-pagination__item govuk-pagination__item--ellipses {{- ' govuk-pagination__item--collapsed-only' if loop.index + 1 >= visiblePagesLower }}">&ctdot;</li>
55+
{%- endif %}
56+
57+
{# Is this within neighbourly range of the current page? Show it! #}
58+
{%- elif loop.index >= visiblePagesLower and loop.index <= visiblePagesUpper %}
59+
60+
{# If this is a 'neighbour' page, mark it as such so we can hide it later #}
61+
{%- if loop.index != currentPage %}
62+
{{ _paginationItem(loop.index, item, { neighbour: true }) }}
63+
64+
{# Otherwise, output it normally #}
65+
{%- else %}
66+
{{ _paginationItem(loop.index, item) }}
67+
68+
{%- endif %}
69+
{%- endif %}
70+
71+
{%- endfor %}
3472
</ul>
35-
{%- endif -%}
73+
{%- endif %}
3674

3775
{%- if params.next and params.next.href -%}
3876
{%- set nextArrow -%}

0 commit comments

Comments
 (0)