| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <template>
- <div
- v-if="pageCount > 1"
- class="flex justify-center pt-5 text-xs md:text-base"
- >
- <nav aria-label="module-nav">
- <ul class="flex list-style-none dark:text-gray-200 text-gray-800">
- <li class="page-item">
- <button
- aria-label="Vorhergehende Seite"
- class="pagination-button"
- :disabled="currentPageIdx == 0"
- @click="
- () => {
- selectPage(Math.max(currentPageIdx - 1, 0));
- }
- "
- >
- <font-awesome-icon icon="fa-solid fa-arrow-left" />
- </button>
- </li>
- <li
- v-for="idx in paginationItems"
- :key="idx ?? -1"
- class="page-item"
- :class="[idx == null ? 'flex justify-center items-center' : '']"
- >
- <span
- v-if="idx == null"
- class="px-3 md:px-4 text-gray-600 dark:text-gray-400"
- >···</span
- >
- <!-- class="cursor-pointer py-1.5 px-3 md:px-4 rounded-sm border-0 outline-hidden transition-all duration-300 hover:bg-gray-200 dark:hover:bg-gray-700 focus:shadow-none" -->
- <button
- v-else
- :title="`Auf die ${idx}. Seite springen`"
- class="pagination-button"
- :class="[
- idx - 1 == currentPageIdx ? 'bg-gray-300 dark:bg-gray-600' : '',
- ]"
- @click="
- () => {
- selectPage(idx - 1);
- }
- "
- >
- {{ idx }}
- </button>
- </li>
- <li class="page-item">
- <button
- title="Nächste Seite"
- class="pagination-button"
- :disabled="currentPageIdx == pageCount - 1"
- @click="
- () => {
- selectPage(Math.min(currentPageIdx + 1, pageCount - 1));
- }
- "
- >
- <font-awesome-icon icon="fa-solid fa-arrow-right" />
- </button>
- </li>
- </ul>
- </nav>
- </div>
- </template>
- <script lang="ts">
- export default {
- name: "NumberedPagination",
- props: {
- pageSize: {
- required: true,
- type: Number,
- },
- resultCount: {
- required: true,
- type: Number,
- },
- modelValue: {
- required: true,
- type: Number,
- },
- },
- emits: ["update:modelValue"],
- data() {
- return {
- currentPageIdx: 0,
- };
- },
- computed: {
- pageCount() {
- return Math.ceil(this.resultCount / this.pageSize);
- },
- paginationItems() {
- const pc = this.pageCount;
- if (pc <= 9) {
- let pagination = [];
- for (let i = 1; i <= pc; i++) pagination.push(i);
- return pagination;
- }
- const cpi = this.currentPageIdx;
- if (cpi <= 4) {
- return [1, 2, 3, 4, 5, 6, null, pc - 1, pc];
- } else if (cpi >= pc - 5) {
- return [1, 2, null, pc - 5, pc - 4, pc - 3, pc - 2, pc - 1, pc];
- } else {
- return [1, 2, null, cpi, cpi + 1, cpi + 2, null, pc - 1, pc];
- }
- },
- },
- watch: {
- modelValue() {
- this.currentPageIdx = this.modelValue;
- },
- },
- methods: {
- selectPage(pageIdx: number) {
- if (this.currentPageIdx == pageIdx) return;
- this.currentPageIdx = pageIdx;
- this.$emit("update:modelValue", pageIdx);
- },
- },
- };
- </script>
- <style scoped>
- @reference "../../style.css";
- .pagination-button {
- @apply cursor-pointer
- py-1.5
- px-2.5
- mx-0.5
- md:px-4
- rounded-sm
- border-0
- outline-hidden
- transition-all
- duration-200
- hover:bg-gray-200
- active:bg-gray-300
- dark:hover:bg-gray-700
- dark:active:bg-gray-800
- focus:shadow-none;
- }
- </style>
|