Skip to content

Instantly share code, notes, and snippets.

@Wolfr
Created April 11, 2021 18:51
Show Gist options
  • Save Wolfr/39c4457fb3abf5d370bb767b38354553 to your computer and use it in GitHub Desktop.
Save Wolfr/39c4457fb3abf5d370bb767b38354553 to your computer and use it in GitHub Desktop.
<template>
<nav role="navigation" aria-label="Pagination">
<ul class="c-pagination">
<li class="c-pagination__element">
<Button icon="arrow-left-s" layout="icon-only" :theme='internalPage === 1 ? "inactive" : "secondary"'
@click="decreasePageNumber">Previous page
</Button>
</li>
<li class="c-pagination__element" v-for="(page, index) in pages" :key="page === MORE ? -index : page">
<template v-if="page === MORE">
<span aria-hidden="true">...</span>
<span class="u-sr-only">More pages</span>
</template>
<Button v-else
:theme='internalPage === page ? "primary" : "secondary"'
:aria-current="internalPage === page ? 'page' : ''"
@click="setPage(page)"
>
<span class="u-sr-only">Page</span>
{{ page }}
</Button>
</li>
<li class="c-pagination__element">
<Button layout="icon-only" icon="arrow-right-s" @click="increasePageNumber"
:theme='internalPage === totalPages ? "inactive" : "secondary"'>Next page
</Button>
</li>
</ul>
</nav>
</template>
<script>
import {range} from "lodash";
export default {
props: {
currentPage: {
type: Number,
default: 1,
},
totalPages: {
type: Number,
default: 10,
},
pageLimit: {
type: Number,
default: 7,
validator(value) {
return value >= 3;
}
}
},
data() {
return {
internalPage: this.currentPage,
MORE: Symbol()
}
},
computed: {
pages() {
if(this.totalPages <= this.pageLimit) {
return range(1, this.totalPages + 1);
}
const rangeSize = this.pageLimit - 2;
let rangeStart = this.internalPage - Math.floor(rangeSize/2);
let rangeEnd = rangeStart + rangeSize;
if(rangeStart < 2) {
rangeStart = 2;
rangeEnd = rangeStart + rangeSize;
}
if(rangeEnd > this.totalPages) {
rangeEnd = this.totalPages;
rangeStart = rangeEnd - rangeSize;
}
return [
1,
rangeStart > 2 && this.MORE,
...range(rangeStart, rangeEnd),
rangeEnd < this.totalPages && this.MORE,
this.totalPages
].filter(Boolean);
}
},
methods: {
increasePageNumber() {
this.setPage(this.internalPage + 1);
},
decreasePageNumber() {
this.setPage(this.internalPage - 1);
},
setPage(value) {
const newPage = Math.min(Math.max(value, 1), this.totalPages);
if (newPage !== this.internalPage) {
this.internalPage = newPage;
this.$emit('pageChange', newPage);
}
}
},
watch: {
currentPage(value) {
this.setPage(value);
}
}
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment