traxxx/assets/components/pagination/pagination.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>