<template>
<ul v-if="pager.pages && pager.pages.length" class="pagination" :style="ulStyles">
<li :style="liStyles">
<a
class="rounded-lg bg-red-500 text-white p-3 mx-1 text-md"
:style="[aStyles, { cursor: pager.currentPage === 1 ? 'not-allowed' : 'pointer' }]"
@click="setPage(1)"
>{{ labels.first }}</a
>
</li>
<li :style="liStyles">
<a
class="rounded-lg bg-red-500 text-white p-3 mx-1 text-md"
:style="[aStyles, { cursor: pager.currentPage === 1 ? 'not-allowed' : 'pointer' }]"
@click="setPage(pager.currentPage - 1)"
>{{ labels.previous }}</a
>
</li>
<li v-for="page in pager.pages" :key="page" :style="liStyles">
<a
class="page-link rounded-lg text-md p-3 mx-1"
:style="[
aStyles,
{
color: pager.currentPage === page ? 'white' : 'black',
backgroundColor: pager.currentPage === page ? '#ef4444' : '#f3f4f6'
}
]"
@click="setPage(page)"
>{{ page }}</a
>
</li>
<li :style="liStyles">
<a
class="rounded-lg bg-red-500 text-white p-3 mx-1 text-md"
:style="[aStyles, { cursor: pager.currentPage === pager.totalPages ? 'not-allowed' : 'pointer' }]"
@click="setPage(pager.currentPage + 1)"
>{{ labels.next }}</a
>
</li>
<li :style="liStyles">
<a
class="rounded-lg bg-red-500 text-white p-3 mx-1 text-md"
:style="[aStyles, { cursor: pager.currentPage === pager.totalPages ? 'not-allowed' : 'pointer' }]"
@click="setPage(pager.totalPages)"
>{{ labels.last }}</a
>
</li>
</ul>
</template>
<script>
import paginate from 'jw-paginate'
const defaultLabels = {
first: 'First',
last: 'Last',
previous: 'Prev',
next: 'Next'
}
const defaultStyles = {
ul: {
margin: 0,
padding: 0,
display: 'inline-block'
},
li: {
listStyle: 'none',
display: 'inline',
textAlign: 'center'
},
a: {
cursor: 'pointer',
padding: '6px 12px',
display: 'block',
float: 'left'
}
}
export default {
props: {
items: {
type: Array,
required: true
},
initialPage: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 10
},
maxPages: {
type: Number,
default: 10
},
labels: {
type: Object,
default: () => defaultLabels
},
styles: { type: Object },
disableDefaultStyles: {
type: Boolean,
default: false
}
},
data() {
return {
pager: {},
ulStyles: {},
liStyles: {},
aStyles: {},
activeColor: 'red-500',
notActiveColor: 'white-100'
}
},
watch: {
items() {
this.setPage(this.initialPage)
}
},
created() {
if (!this.$listeners.changePage) {
throw new Error('Missing required event listener: "changePage"')
}
// set default styles unless disabled
if (!this.disableDefaultStyles) {
this.ulStyles = defaultStyles.ul
this.liStyles = defaultStyles.li
this.aStyles = defaultStyles.a
}
// merge custom styles with default styles
if (this.styles) {
this.ulStyles = { ...this.ulStyles, ...this.styles.ul }
this.liStyles = { ...this.liStyles, ...this.styles.li }
this.aStyles = { ...this.aStyles, ...this.styles.a }
}
// set to initial page
this.setPage(this.initialPage)
},
methods: {
setPage(page) {
const { items, pageSize, maxPages } = this
// get new pager object for specified page
const pager = paginate(items.length, page, pageSize, maxPages)
// get new page of items from items array
const pageOfItems = items.slice(pager.startIndex, pager.endIndex + 1)
// update pager
this.pager = pager
// emit change page event to parent component
this.$emit('changePage', pageOfItems)
}
}
}
</script>