Skip to content

Commit 6eea099

Browse files
committed
feat: #1449: introduce additional prop additionalLinkQueryParams and allow for prop useLinkElement to specify the type of link element, improve documentation
1 parent f754dfd commit 6eea099

File tree

2 files changed

+125
-19
lines changed

2 files changed

+125
-19
lines changed

src/components/BasePagination/BasePagination.vue

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
@click="active - 1 > 0 ? setActivePage(active - 1) : false">
99
<component
1010
:is="numberElement"
11-
:to="getLinkPath(active - 1 > 0 ? active - 1 : 1)"
11+
:to="!!useLinkElement ? getLinkPath(active - 1 > 0 ? active - 1 : 1) : false"
1212
:aria-disabled="active <= 1"
1313
:tabindex="active <= 1 ? -1 : 0"
1414
aria-label="Previous page"
@@ -28,7 +28,7 @@
2828
@click="setActivePage(1)">
2929
<component
3030
:is="numberElement"
31-
:to="useLinkElement ? getLinkPath(1) : false"
31+
:to="!!useLinkElement ? getLinkPath(1) : false"
3232
:tabindex="active === 1 ? -1 : 0"
3333
aria-label="page 1"
3434
class="base-pagination__number-inner"
@@ -46,7 +46,7 @@
4646
@click="setActivePage(n)">
4747
<component
4848
:is="numberElement"
49-
:to="getLinkPath(n)"
49+
:to="!!useLinkElement ? getLinkPath(n) : false"
5050
:tabindex="active === n ? -1 : 0"
5151
:aria-label="`Page ${n}`"
5252
class="base-pagination__number-inner"
@@ -63,7 +63,7 @@
6363
@click="setActivePage(total)">
6464
<component
6565
:is="numberElement"
66-
:to="getLinkPath(total)"
66+
:to="!!useLinkElement ? getLinkPath(total) : false"
6767
:tabindex="active === total ? -1 : 0"
6868
:aria-label="`Page ${total}`"
6969
class="base-pagination__number-inner"
@@ -82,7 +82,7 @@
8282
@click="setActivePage(n)">
8383
<component
8484
:is="numberElement"
85-
:to="useLinkElement ? getLinkPath(n) : false"
85+
:to="!!useLinkElement ? getLinkPath(n) : false"
8686
:tabindex="active === n ? -1 : 0"
8787
:aria-label="`Page ${n}`"
8888
class="base-pagination__number-inner"
@@ -99,7 +99,7 @@
9999
@click="active + 1 <= total ? setActivePage(active + 1) : false">
100100
<component
101101
:is="numberElement"
102-
:to="getLinkPath(active + 1 <= total ? active + 1 : total)"
102+
:to="!!useLinkElement ? getLinkPath(active + 1 <= total ? active + 1 : total) : false"
103103
:aria-disabled="active >= total"
104104
:tabindex="active >= total ? -1 : 0"
105105
aria-label="Next Page"
@@ -147,24 +147,65 @@ export default {
147147
default: 1,
148148
},
149149
/**
150-
* specify if pagination elements should be links
151-
* (this needs vue-router)
150+
* specify if pagination elements should be links - specify a vue link element or
151+
* set the variable false if element should not be a link
152+
* (this needs vue-router)<br>
153+
* currently only vue components (like 'router-link' or 'nuxt-link') are supported!
152154
*/
153155
useLinkElement: {
154-
type: Boolean,
155-
default: true,
156+
type: [String, Boolean],
157+
default: false,
158+
validator: val => (typeof val === 'boolean' && !val) || (typeof val === 'string' && val),
159+
},
160+
/**
161+
* if pagination elements are link-elements the default href is set as
162+
* '[currentRoute]?page=[currentPage]'. Adding properties here gives the possibility to
163+
* add additional parameters BEFORE the page parameter:<br>
164+
* '[currentRoute]?[customParam1]=[customValue1]
165+
* &[customParam2]=[customValue2]&page=[currentPage]'
166+
*/
167+
additionalLinkQueryParams: {
168+
type: Object,
169+
default: () => ({}),
156170
},
157171
},
158172
data() {
159173
return {
174+
/**
175+
* currently active page number
176+
* @type {number}
177+
*/
160178
active: this.current,
179+
/**
180+
* number the displayed pages between '...' should start with
181+
* (only relevant if not all numbers can be displayed)
182+
* @type {?number}
183+
*/
161184
start: null,
185+
/**
186+
* number the displayed pages between the '...' should end with
187+
* (only relevant if not all numbers can be displayed)
188+
* @type {?number}
189+
*/
162190
end: null,
191+
/**
192+
* total numbers to be displayed before the '...' depending on the width of the
193+
* pagination element (only relevant if not all numbers can be displayed)
194+
* @type {number}
195+
*/
163196
subsetNumber: 7,
197+
/**
198+
* max numbers to be displayed
199+
* @type {number}
200+
*/
164201
maxNumbers: 10,
165202
};
166203
},
167204
computed: {
205+
/**
206+
* calculate the actual subset page numbers to be displayed
207+
* @returns {number[]}
208+
*/
168209
subset() {
169210
// check if subset number would exceed total number of items and start
170211
// array from total - subsetNumber
@@ -173,12 +214,21 @@ export default {
173214
return Array.from({ length: this.subsetNumber },
174215
(v, k) => k + subsetStart);
175216
},
217+
/**
218+
* check if element should be displayed as a link element, otherwise make it a <span>
219+
* @returns {String|Boolean|string}
220+
*/
176221
numberElement() {
177-
return this.$route && this.useLinkElement ? 'router-link' : 'span';
222+
return this.useLinkElement ? this.useLinkElement : 'span';
178223
},
179224
},
180225
watch: {
226+
/**
227+
* if active number changes inform parent
228+
* @param {number} val - the new page number active
229+
*/
181230
active(val) {
231+
// check if new number is different from prop value
182232
if (this.current !== val) {
183233
/**
184234
* triggered on page select
@@ -188,23 +238,37 @@ export default {
188238
*/
189239
this.$emit('set-page', val);
190240
}
241+
// adjust the start and end value accordingly (if not all numbers can be displayed)
191242
this.setStartEnd();
192243
},
244+
/**
245+
* check if parent prop changes
246+
* @param {number} val - the page number provided by the parent component
247+
*/
193248
current(val) {
194249
this.active = val;
195250
},
196251
},
197252
mounted() {
253+
// initialize the start and end variable in case not all numbers can be displayed
198254
this.setStartEnd();
255+
// add an resize event listener
199256
window.addEventListener('resize', this.setStartEnd);
200257
},
201258
destroyed() {
259+
// remove the resize event listener
202260
window.removeEventListener('resize', this.setStartEnd);
203261
},
204262
methods: {
263+
/**
264+
* depending on with of the parent element of the pagination calculate
265+
* how many page numbers can be displayed
266+
*/
205267
setStartEnd() {
268+
// get parent width
206269
const parentWidth = this.$parent.$el.clientWidth
207270
|| this.$parent.clientWidth || window.innerWidth;
271+
// set the subset and the max number accordingly
208272
if (parentWidth < 390) {
209273
this.subsetNumber = 1;
210274
this.maxNumbers = 5;
@@ -214,19 +278,31 @@ export default {
214278
} else if (parentWidth < 710) {
215279
this.subsetNumber = 5;
216280
}
281+
// calc start and end number from the subset number
217282
this.start = this.active - this.subsetNumber / 2 > 0
218283
? this.active - Math.floor(this.subsetNumber / 2) : 1;
219284
this.end = this.active + this.subsetNumber / 2 < this.total
220285
? this.active + Math.floor(this.subsetNumber / 2) : this.total;
221286
},
287+
/**
288+
* function to set a new page number active
289+
* @param {number} page - the new page number
290+
*/
222291
setActivePage(page) {
292+
// set internal variable to new page number
223293
this.active = page;
224294
},
225-
getLinkPath() {
226-
// check if router in project and set link path accordingly if yes
227-
// TODO: think about adding pagination query to route
228-
return this.$route && this.useLinkElement
229-
? { path: this.$route.fullPath } : '';
295+
/**
296+
* get the correct link in case element is a link element
297+
* @param {number} page - the page number of the element in question
298+
* @returns {{path: string, query: Object}|string}
299+
*/
300+
getLinkPath(page) {
301+
// check if router in project and link element is used and set link path accordingly if yes
302+
if (!!this.useLinkElement && this.$route) {
303+
return ({ path: this.$route.fullPath, query: { ...this.additionalLinkQueryParams, page } });
304+
}
305+
return '';
230306
},
231307
},
232308
};
Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,40 @@
1+
Adjust the number of pages and resize to see differences in the display.
2+
13
```vue
4+
25
<template>
3-
<BasePagination
4-
:total="10"/>
6+
<div class="pagination-example">
7+
<BasePagination
8+
:total="total"/>
9+
<BaseInput
10+
v-model="total"
11+
field-type="number"
12+
label="Enter number of pages here"
13+
class="pagination-input" />
14+
</div>
15+
516
</template>
617
718
<script>
8-
export default {};
19+
import BaseInput from '../BaseInput/BaseInput';
20+
21+
export default {
22+
components: {BaseInput},
23+
data() {
24+
return {
25+
total: 10,
26+
};
27+
},
28+
};
929
</script>
30+
31+
<style>
32+
.pagination-example {
33+
width: 100%;
34+
}
35+
.pagination-input {
36+
margin: 16px auto 0;
37+
width: 200px;
38+
}
39+
</style>
1040
```

0 commit comments

Comments
 (0)