@@ -9,14 +9,213 @@ Help users navigate forwards and backwards through a series of pages - for examp
9
9
See the [ GOV.UK Design System documentation on pagination] ( https://design-system.service.gov.uk/components/pagination/ ) for
10
10
more information on when to use this component.
11
11
12
+ ``` vue
13
+ <gv-pagination :total-pages="3"/>
14
+ ```
15
+
16
+ ## Setting and monitoring the current page number
17
+
18
+ Your page will probably need to know the number of the current page so that it can render its content. You can bind a
19
+ ref with ` v-model:current-page ` to set the current page when the pagination component is mounted and monitor when the user
20
+ selects a different page.
21
+
12
22
``` vue
13
23
<script setup lang="ts">
14
24
import { ref } from 'vue'
15
25
16
- const pageNumber = ref(2)
26
+ const currentPage = ref(1)
27
+ </script>
28
+
29
+ <template>
30
+ <gv-inset-text aria-live="polite">
31
+ You are on page {{ currentPage }}
32
+ </gv-inset-text>
33
+ <gv-pagination v-model:currentPage="currentPage" :total-pages="3"/>
34
+ </template>
35
+ ```
36
+
37
+ ## For navigating between content pages
38
+
39
+ Use the ‘block’ style of pagination to let users navigate through related content that has been split across multiple pages.
40
+
41
+ You can use link labels to give context on what the neighbouring pages are about. Use the ` previous-label ` and ` next-label ` props.
42
+
43
+ You can use block-style pagination with or without passing ` total-pages ` .
44
+
45
+ ### Without ` total-pages `
46
+ Block-style pagination will be used by default if you don't pass the ` total-pages ` prop. Listen to the ` previousClicked `
47
+ and ` nextClicked ` events to know when to change pages. Pass an empty string to ` previous-text ` and ` next-text ` to hide
48
+ the Previous/Next links as appropriate.
49
+
50
+ ``` vue
51
+ <script setup lang="ts">
52
+ import { computed } from 'vue'
53
+ import type { Ref } from 'vue'
54
+ const pages = [
55
+ { title: 'Content page A', content: 'This is content page A' },
56
+ { title: 'Content page B', content: 'This is content page B' },
57
+ { title: 'Content page C', content: 'This is content page C' },
58
+ ]
59
+
60
+ const currentPageIndex = ref(0)
61
+ const contentElement: Ref<HTMLDivElement | null> = ref(null)
62
+
63
+ const currentPage = computed(() => {
64
+ return pages[currentPageIndex.value]
65
+ })
66
+
67
+ const previousPage = computed(() => {
68
+ if(currentPageIndex.value > 0) {
69
+ return pages[currentPageIndex.value-1]
70
+ }
71
+ return null
72
+ })
73
+
74
+ const nextPage = computed(() => {
75
+ if(currentPageIndex.value < pages.length-1) {
76
+ return pages[currentPageIndex.value+1]
77
+ }
78
+ return null
79
+ })
80
+
81
+ function handlePreviousClicked() {
82
+ if(currentPageIndex.value > 0) {
83
+ currentPageIndex.value--
84
+ focusContent()
85
+ }
86
+ }
87
+
88
+ function handleNextClicked() {
89
+ if(currentPageIndex.value < pages.length-1) {
90
+ currentPageIndex.value++
91
+ focusContent()
92
+ }
93
+ }
94
+
95
+ /* When the user changes page, we focus on the main content for accessibility.
96
+ Screen reader users will hear the new page content being read, and the focus
97
+ position will be in the right place for keyboard-only users to tab through the
98
+ content.
99
+ */
100
+ function focusContent() {
101
+ if(contentElement.value) {
102
+ contentElement.value.focus()
103
+ }
104
+ }
17
105
</script>
18
106
19
107
<template>
20
- <gv-pagination v-model="pageNumber" :total-pages="3"/>
108
+ <div ref="contentElement" tabindex="-1">
109
+ <h1 class="govuk-heading-l">
110
+ {{ currentPage.title }}
111
+ </h1>
112
+ <p class="govuk-body">
113
+ {{ currentPage.content }}
114
+ </p>
115
+ </div>
116
+ <gv-pagination
117
+ :previous-text="previousPage ? 'Previous' : ''"
118
+ :previous-label="previousPage ? previousPage.title : null"
119
+ :next-text="nextPage ? 'Next' : ''"
120
+ :next-label="nextPage ? nextPage.title : null"
121
+ @previousClicked="handlePreviousClicked"
122
+ @nextClicked="handleNextClicked"
123
+ />
21
124
</template>
22
125
```
126
+
127
+ ### With ` total-pages `
128
+ If you pass a value for ` total-pages ` , the pagination will show as a list of page numbers by default. You can override
129
+ this by passing ` variant="block" ` .
130
+
131
+ ``` vue
132
+ <script setup lang="ts">
133
+ import { computed, watch } from 'vue'
134
+ import type { Ref } from 'vue'
135
+ const pages = [
136
+ { title: 'Content page A', content: 'This is content page A' },
137
+ { title: 'Content page B', content: 'This is content page B' },
138
+ { title: 'Content page C', content: 'This is content page C' },
139
+ ]
140
+
141
+ // The current-page prop is 1-indexed - we will need to account for that when accessing the pages[] array
142
+ const currentPageNumber = ref(1)
143
+ const contentElement: Ref<HTMLDivElement | null> = ref(null)
144
+
145
+ const currentPage = computed(() => {
146
+ return pages[currentPageNumber.value - 1]
147
+ })
148
+
149
+ const previousPage = computed(() => {
150
+ if(currentPageNumber.value > 1) {
151
+ return pages[currentPageNumber.value-2]
152
+ }
153
+ return null
154
+ })
155
+
156
+ const nextPage = computed(() => {
157
+ if(currentPageNumber.value < pages.length) {
158
+ return pages[currentPageNumber.value]
159
+ }
160
+ return null
161
+ })
162
+
163
+ /* When the user changes page, we focus on the main content for accessibility.
164
+ Screen reader users will hear the new page content being read, and the focus
165
+ position will be in the right place for keyboard-only users to tab through the
166
+ content.
167
+ */
168
+ watch(currentPageNumber, () => {
169
+ if(contentElement.value) {
170
+ contentElement.value.focus()
171
+ }
172
+ })
173
+ </script>
174
+
175
+ <template>
176
+ <div ref="contentElement" tabindex="-1">
177
+ <h1 class="govuk-heading-l">
178
+ {{ currentPage.title }}
179
+ </h1>
180
+ <p class="govuk-body">
181
+ {{ currentPage.content }}
182
+ </p>
183
+ </div>
184
+ <gv-pagination
185
+ variant="block"
186
+ v-model:current-page="currentPageNumber"
187
+ :total-pages="3"
188
+ :previous-label="previousPage ? previousPage.title : null"
189
+ :next-label="nextPage ? nextPage.title : null"
190
+ />
191
+ </template>
192
+ ```
193
+
194
+ ## Adding URLs to the links
195
+
196
+ We strongly recommend that you pass a URL to ` page-href ` (and ` previous-href ` /` next-href ` if using block style) so that the
197
+ pagination links can function as normal links. This will allow users to:
198
+
199
+ * open pagination links in new tabs
200
+ * use the browser back button
201
+ * share links to specific pages
202
+
203
+ Include the ` ${pageNumber} ` placeholder in the URL you pass. The placeholder will be replaced with the appropriate number
204
+ for each page, starting from ` 1 ` . It's up to you how you use the page number in the URL - it could be in the query string,
205
+ the hash or as part of the path.
206
+
207
+ Before the component is rendered, you should parse the page number from the URL and pass it to the pagination component
208
+ with ` v-model:current-page ` (not shown in this example).
209
+
210
+ ``` vue
211
+ <gv-pagination
212
+ :total-pages="3"
213
+ page-href="#page-${pageNumber}"
214
+ />
215
+ ```
216
+
217
+ If you're using block mode without passing ` total-pages ` you can also pass ` previous-href ` and ` next-href ` .
218
+
219
+ You can [ use router-link or nuxt-link] ( /get-started/using-router-link-or-nuxt-link ) for your navigation links if needed using the ` link-component ` prop.
220
+
221
+ :: gvd-options { component =" Pagination " }
0 commit comments