@datagouv/components-next 1.0.2-dev.188 → 1.0.2-dev.189
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Datafair.client-CWPwvNsO.js → Datafair.client-Bb3KFfHG.js} +1 -1
- package/dist/{ImagePreview.client-C0PexuUW.js → ImagePreview.client-dU0DyxhO.js} +1 -1
- package/dist/{JsonPreview.client-BFXsy93W.js → JsonPreview.client-oCcmf4Sj.js} +2 -2
- package/dist/{MapContainer.client-BnfDrxM3.js → MapContainer.client-o50vZ4p7.js} +2 -2
- package/dist/{PdfPreview.client-J6HdYgDG.js → PdfPreview.client-DXYcyV9H.js} +2 -2
- package/dist/{Pmtiles.client-DKqGSUCL.js → Pmtiles.client-D1eRUmQj.js} +1 -1
- package/dist/{PreviewWrapper.vue_vue_type_script_setup_true_lang-pEO-0WH0.js → PreviewWrapper.vue_vue_type_script_setup_true_lang-A3Ige7AN.js} +1 -1
- package/dist/{XmlPreview.client-DQIVB-4X.js → XmlPreview.client-DpaqaBjv.js} +3 -3
- package/dist/components-next.js +1 -1
- package/dist/{index-Cx-X-INq.js → index-C6RfMwqg.js} +1 -1
- package/dist/{leaflet-src-DmNI8sDg.js → leaflet-src-CezuL8aR.js} +1 -1
- package/dist/{main-BgsOe_n1.js → main-DseJBKsd.js} +6576 -6585
- package/dist/{vue3-xml-viewer.common--UeLZvgV.js → vue3-xml-viewer.common-GEec9TSv.js} +1 -1
- package/package.json +1 -1
- package/src/components/Pagination.vue +16 -54
- package/src/functions/paginate.ts +46 -0
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</li>
|
|
20
20
|
<li>
|
|
21
21
|
<a
|
|
22
|
-
:href="getHref(
|
|
22
|
+
:href="getHref(currentPage - 1)"
|
|
23
23
|
class="fr-pagination__link fr-pagination__link--prev fr-pagination__link--lg-label"
|
|
24
24
|
data-testid="previous-page"
|
|
25
25
|
@click.prevent.stop="previousPage"
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
</li>
|
|
30
30
|
<li>
|
|
31
31
|
<a
|
|
32
|
-
:aria-current="
|
|
32
|
+
:aria-current="currentPage === 1 ? 'page' : undefined"
|
|
33
33
|
:href="getHref(1)"
|
|
34
34
|
class="fr-pagination__link"
|
|
35
|
-
:class="{ 'fr-hidden fr-unhidden-sm':
|
|
35
|
+
:class="{ 'fr-hidden fr-unhidden-sm': currentPage > 1 }"
|
|
36
36
|
:title="t('Page {nb}', { nb: 1 })"
|
|
37
37
|
:data-testid="1"
|
|
38
38
|
@click.prevent.stop="onClick(1)"
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
<a
|
|
48
48
|
v-if="index"
|
|
49
49
|
class="fr-pagination__link"
|
|
50
|
-
:class="{ 'fr-hidden fr-unhidden-lg': index <
|
|
51
|
-
:aria-current="
|
|
50
|
+
:class="{ 'fr-hidden fr-unhidden-lg': index < currentPage - 1 || index > currentPage + 1 }"
|
|
51
|
+
:aria-current="currentPage === index ? 'page' : undefined"
|
|
52
52
|
:href="getHref(index)"
|
|
53
53
|
:title="t('Page {nb}', { nb: index })"
|
|
54
54
|
:data-testid="index"
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
<li>
|
|
67
67
|
<a
|
|
68
68
|
class="fr-pagination__link"
|
|
69
|
-
:aria-current="
|
|
69
|
+
:aria-current="currentPage === pageCount ? 'page' : undefined"
|
|
70
70
|
:href="getHref(pageCount)"
|
|
71
71
|
:title="t('Page {nb}', { nb: pageCount })"
|
|
72
72
|
:data-testid="pageCount"
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
<li>
|
|
79
79
|
<a
|
|
80
80
|
class="fr-pagination__link fr-pagination__link--next fr-pagination__link--lg-label"
|
|
81
|
-
:href="getHref(
|
|
81
|
+
:href="getHref(currentPage + 1)"
|
|
82
82
|
data-testid="next-page"
|
|
83
83
|
@click.prevent.stop="nextPage"
|
|
84
84
|
>
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
import { computed, useTemplateRef } from 'vue'
|
|
104
104
|
import { useRoute } from 'vue-router'
|
|
105
105
|
import { useTranslation } from '../composables/useTranslation'
|
|
106
|
+
import { clampPage, getVisiblePages } from '../functions/paginate'
|
|
106
107
|
|
|
107
108
|
type Props = {
|
|
108
109
|
/**
|
|
@@ -128,52 +129,13 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
128
129
|
pageSize: 20,
|
|
129
130
|
})
|
|
130
131
|
|
|
131
|
-
const PAGES_AROUND = 3
|
|
132
|
-
|
|
133
|
-
function range(size: number, startAt = 1) {
|
|
134
|
-
return [...Array(size).keys()].map(i => i + startAt)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function getPages(pageCount: number) {
|
|
138
|
-
return range(pageCount)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function getPagesShown(pages: { length: number }, currentPage: number) {
|
|
142
|
-
return Math.min(
|
|
143
|
-
PAGES_AROUND * 2 + 1,
|
|
144
|
-
pages.length - 2,
|
|
145
|
-
PAGES_AROUND + currentPage - 1,
|
|
146
|
-
PAGES_AROUND + pages.length - currentPage,
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function getStartPage(currentPage: number) {
|
|
151
|
-
return Math.max(
|
|
152
|
-
currentPage - PAGES_AROUND, // we want to start 3 pages before the current one
|
|
153
|
-
2, // we don't want to start below page 2
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function getVisiblePages(currentPage: number, pageCount: number) {
|
|
158
|
-
const pages = getPages(pageCount)
|
|
159
|
-
const start = getStartPage(currentPage)
|
|
160
|
-
if (pageCount <= 2) {
|
|
161
|
-
return []
|
|
162
|
-
}
|
|
163
|
-
const pagination: Array<number | null> = range(getPagesShown(pages, currentPage), start)
|
|
164
|
-
if (!pagination.includes(2)) {
|
|
165
|
-
pagination.unshift(null)
|
|
166
|
-
}
|
|
167
|
-
if (!pagination.includes(pageCount - 1)) {
|
|
168
|
-
pagination.push(null)
|
|
169
|
-
}
|
|
170
|
-
return pagination
|
|
171
|
-
}
|
|
172
|
-
|
|
173
132
|
const { t } = useTranslation()
|
|
174
133
|
const route = useRoute()
|
|
175
134
|
const pageCount = computed(() => Math.ceil(props.totalResults / props.pageSize))
|
|
176
|
-
|
|
135
|
+
// The `page` prop often comes straight from a query string, so it is normalised
|
|
136
|
+
// once here and every link below builds on an existing page.
|
|
137
|
+
const currentPage = computed(() => clampPage(props.page, pageCount.value))
|
|
138
|
+
const visiblePages = computed(() => getVisiblePages(currentPage.value, pageCount.value))
|
|
177
139
|
|
|
178
140
|
const nav = useTemplateRef('navRef')
|
|
179
141
|
function change(index: number) {
|
|
@@ -186,20 +148,20 @@ function change(index: number) {
|
|
|
186
148
|
}
|
|
187
149
|
|
|
188
150
|
function onClick(index: number) {
|
|
189
|
-
if (index !==
|
|
151
|
+
if (index !== currentPage.value) {
|
|
190
152
|
change(index)
|
|
191
153
|
}
|
|
192
154
|
}
|
|
193
155
|
|
|
194
156
|
function nextPage() {
|
|
195
|
-
const index =
|
|
157
|
+
const index = currentPage.value + 1
|
|
196
158
|
if (index <= pageCount.value) {
|
|
197
159
|
change(index)
|
|
198
160
|
}
|
|
199
161
|
}
|
|
200
162
|
|
|
201
163
|
function previousPage() {
|
|
202
|
-
const index =
|
|
164
|
+
const index = currentPage.value - 1
|
|
203
165
|
if (index > 0) {
|
|
204
166
|
change(index)
|
|
205
167
|
}
|
|
@@ -209,7 +171,7 @@ function getHref(forPage: number) {
|
|
|
209
171
|
if (forPage < 1 || forPage > pageCount.value) {
|
|
210
172
|
return undefined
|
|
211
173
|
}
|
|
212
|
-
if (
|
|
174
|
+
if (currentPage.value === forPage) {
|
|
213
175
|
return undefined
|
|
214
176
|
}
|
|
215
177
|
const search = new URLSearchParams(route.query as Record<string, string>)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export const PAGES_AROUND = 3
|
|
2
|
+
|
|
3
|
+
function range(size: number, startAt: number) {
|
|
4
|
+
return [...Array(size).keys()].map(i => i + startAt)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Brings whatever the caller holds as a current page back to a page that exists.
|
|
9
|
+
* The page number usually comes from a query string, so it can be anything:
|
|
10
|
+
* `?page=abc` (NaN), `?page=-5`, `?page=1.5`, or a stale link to a page far past
|
|
11
|
+
* the last one.
|
|
12
|
+
*/
|
|
13
|
+
export function clampPage(page: number, pageCount: number) {
|
|
14
|
+
if (!Number.isFinite(page)) {
|
|
15
|
+
return 1
|
|
16
|
+
}
|
|
17
|
+
return Math.min(Math.max(Math.trunc(page), 1), Math.max(pageCount, 1))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The middle window of the pagination: the pages around the current one, with
|
|
22
|
+
* `null` marking an ellipsis. The first and last pages are rendered by the
|
|
23
|
+
* component itself and are never part of this window.
|
|
24
|
+
*/
|
|
25
|
+
export function getVisiblePages(currentPage: number, pageCount: number) {
|
|
26
|
+
if (pageCount <= 2) {
|
|
27
|
+
return []
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const page = clampPage(currentPage, pageCount)
|
|
31
|
+
const size = Math.min(
|
|
32
|
+
PAGES_AROUND * 2 + 1,
|
|
33
|
+
pageCount - 2, // the first and last pages are rendered outside of the window
|
|
34
|
+
PAGES_AROUND + page - 1, // don't reach below page 2
|
|
35
|
+
PAGES_AROUND + pageCount - page, // don't reach past the last page
|
|
36
|
+
)
|
|
37
|
+
const pagination: Array<number | null> = range(size, Math.max(page - PAGES_AROUND, 2))
|
|
38
|
+
|
|
39
|
+
if (!pagination.includes(2)) {
|
|
40
|
+
pagination.unshift(null)
|
|
41
|
+
}
|
|
42
|
+
if (!pagination.includes(pageCount - 1)) {
|
|
43
|
+
pagination.push(null)
|
|
44
|
+
}
|
|
45
|
+
return pagination
|
|
46
|
+
}
|