forked from DebaucheryLibrarian/traxxx
189 lines
3.5 KiB
Vue
189 lines
3.5 KiB
Vue
<template>
|
|
<div
|
|
v-if="itemsTotal > 0 || !hideEmpty"
|
|
class="pagination"
|
|
>
|
|
<span
|
|
v-show="pageNumber > 1"
|
|
class="cursors"
|
|
>
|
|
<router-link
|
|
class="pagination-button cursor"
|
|
:to="{ params: { pageNumber: 1 } }"
|
|
><Icon icon="first2" /></router-link>
|
|
|
|
<router-link
|
|
class="pagination-button cursor"
|
|
:to="{ params: { pageNumber: pageNumber - 1 } }"
|
|
><Icon icon="arrow-left" /></router-link>
|
|
</span>
|
|
|
|
<span
|
|
v-show="pageNumber === 1"
|
|
class="cursors"
|
|
>
|
|
<span class="pagination-button cursor disabled"><Icon icon="first2" /></span>
|
|
<span class="pagination-button cursor disabled"><Icon icon="arrow-left" /></span>
|
|
</span>
|
|
|
|
<span class="pages pages-before">
|
|
<router-link
|
|
v-for="pageX in pageNumber - 1"
|
|
:key="`page-${pageX}`"
|
|
:to="{ params: { pageNumber: pageNumber - pageX } }"
|
|
class="pagination-button page"
|
|
> {{ pageNumber - pageX }} </router-link>
|
|
</span>
|
|
|
|
<router-link
|
|
:key="`page-${pageNumber}`"
|
|
:to="{ params: { pageNumber } }"
|
|
class="pagination-button page active"
|
|
> {{ pageNumber }} </router-link>
|
|
|
|
<span class="pages pages-after">
|
|
<router-link
|
|
v-for="pageX in (pageCount - pageNumber)"
|
|
:key="`page-${pageX + pageNumber}`"
|
|
:to="{ params: { pageNumber: pageX + pageNumber } }"
|
|
class="pagination-button page"
|
|
> {{ pageX + pageNumber }} </router-link>
|
|
</span>
|
|
|
|
<span
|
|
v-show="pageNumber < pageCount"
|
|
class="cursors"
|
|
>
|
|
<router-link
|
|
class="pagination-button cursor"
|
|
:to="{ params: { pageNumber: pageNumber + 1 } }"
|
|
><Icon icon="arrow-right" /></router-link>
|
|
|
|
<router-link
|
|
class="pagination-button cursor"
|
|
:to="{ params: { pageNumber: pageCount } }"
|
|
><Icon icon="last2" /></router-link>
|
|
</span>
|
|
|
|
<span
|
|
v-show="pageNumber === pageCount"
|
|
class="cursors"
|
|
>
|
|
<span class="pagination-button cursor disabled"><Icon icon="arrow-right" /></span>
|
|
<span class="pagination-button cursor disabled"><Icon icon="last2" /></span>
|
|
</span>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
function pageNumber() {
|
|
return Number(this.$route.params.pageNumber) || 1;
|
|
}
|
|
|
|
function pageCount() {
|
|
const count = Math.max(Math.ceil(this.itemsTotal / this.itemsPerPage), 1);
|
|
|
|
return count;
|
|
}
|
|
|
|
export default {
|
|
props: {
|
|
itemsTotal: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
itemsPerPage: {
|
|
type: Number,
|
|
default: 10,
|
|
},
|
|
hideEmpty: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
computed: {
|
|
pageNumber,
|
|
pageCount,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.pagination {
|
|
display: flex;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
height: 3rem;
|
|
}
|
|
|
|
.pagination-top {
|
|
margin: 0 0 1rem 0;
|
|
}
|
|
|
|
.pagination-bottom {
|
|
margin: .5rem 0 1rem 0;
|
|
}
|
|
|
|
.pagination-button {
|
|
width: 2.5rem;
|
|
height: 2.5rem;
|
|
display: inline-flex;
|
|
flex-shrink: 0;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: .1rem 0 2rem 0;
|
|
background: var(--background);
|
|
color: var(--shadow);
|
|
font-size: 1rem;
|
|
font-weight: bold;
|
|
text-decoration: none;
|
|
box-shadow: 0 0 3px var(--shadow-hint);
|
|
|
|
.icon {
|
|
width: .8rem;
|
|
height: .8rem;
|
|
margin: 0 0 .125rem 0;
|
|
fill: var(--shadow);
|
|
}
|
|
|
|
&:hover:not(.active):not(.disabled) {
|
|
color: var(--shadow-strong);
|
|
|
|
.icon {
|
|
fill: var(--shadow-strong);
|
|
}
|
|
}
|
|
|
|
&.active {
|
|
color: var(--primary);
|
|
}
|
|
|
|
&.disabled {
|
|
color: var(--shadow-weak);
|
|
|
|
.icon {
|
|
fill: var(--shadow-weak);
|
|
}
|
|
}
|
|
}
|
|
|
|
.pages {
|
|
max-width: 10rem;
|
|
display: inline-flex;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.pages-before {
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
.cursors {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.cursors {
|
|
margin: 0 .75rem;
|
|
font-size: 0;
|
|
}
|
|
</style>
|