feat: added table layout
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
<script setup>
|
||||
import PaginationExample from './pagination/examples/PaginationExample.vue'
|
||||
import PaginationExample from './pagination/examples/PaginationExample.vue';
|
||||
import PaginationNavigationExample from './pagination/examples/PaginationNavigationExample.vue';
|
||||
import PaginationTableExample from './pagination/examples/PaginationTableExample.vue';
|
||||
</script>
|
||||
# Vue Pagination Component - Flowbite
|
||||
|
||||
## Default pagination
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Pagination } from 'flowbite-vue'
|
||||
@@ -13,3 +17,29 @@ import { Pagination } from 'flowbite-vue'
|
||||
```
|
||||
|
||||
<PaginationExample />
|
||||
|
||||
## Pagination with navigation layout
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Pagination } from 'flowbite-vue'
|
||||
</script>
|
||||
<template>
|
||||
<Pagination layout="navigation"></Pagination>
|
||||
</template>
|
||||
```
|
||||
|
||||
<PaginationNavigationExample />
|
||||
|
||||
## Pagination with table layout
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Pagination } from 'flowbite-vue'
|
||||
</script>
|
||||
<template>
|
||||
<Pagination layout="table"></Pagination>
|
||||
</template>
|
||||
```
|
||||
|
||||
<PaginationTableExample />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="vp-raw flex flex-col">
|
||||
<Pagination v-model="currentPage" :total-pages="10"></Pagination>
|
||||
<Pagination v-model="currentPage" :total-pages="100"></Pagination>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="vp-raw flex items-center justify-center text-center">
|
||||
<Pagination v-model="currentPage" :total-pages="100" :layout="'navigation'"></Pagination>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { Pagination } from '../../../../src/index'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const currentPage = ref<number>(1)
|
||||
</script>
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="vp-raw flex items-center justify-center text-center">
|
||||
<Pagination
|
||||
v-model="currentPage"
|
||||
:total-pages="100"
|
||||
:layout="'table'"
|
||||
:total-items="998"
|
||||
></Pagination>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { Pagination } from '../../../../src/index'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const currentPage = ref<number>(1)
|
||||
</script>
|
||||
@@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<nav aria-label="Page navigation example">
|
||||
<div class="text-sm text-gray-700 dark:text-gray-400 mb-2" v-if="layout === 'table'">
|
||||
Showing
|
||||
<span class="font-semibold text-gray-900 dark:text-white">{{ startItemsCount }}</span>
|
||||
to
|
||||
<span class="font-semibold text-gray-900 dark:text-white">{{ endItemsCount }}</span>
|
||||
of
|
||||
<span class="font-semibold text-gray-900 dark:text-white">{{ computedTotalItems }}</span>
|
||||
</div>
|
||||
<ul class="inline-flex -space-x-px">
|
||||
<li>
|
||||
<button
|
||||
@@ -7,17 +15,17 @@
|
||||
@click="decreasePage"
|
||||
class="py-2 px-3 ml-0 leading-tight text-gray-500 bg-white rounded-l-lg border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||
>
|
||||
Previous
|
||||
{{ previousLabel }}
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
v-for="index in filteredPages"
|
||||
v-for="index in pagesToDisplay"
|
||||
:key="index"
|
||||
>
|
||||
<button
|
||||
:disabled="isSetPageDisabled(index)"
|
||||
@click="setPage(index)"
|
||||
class="py-2 px-3 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||
class="w-12 py-2 px-3 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||
:class="{'text-blue-600 dark:text-white bg-blue-50 dark:bg-gray-700': index === modelValue}"
|
||||
>
|
||||
{{ index }}
|
||||
@@ -29,7 +37,7 @@
|
||||
@click="increasePage"
|
||||
class="py-2 px-3 leading-tight text-gray-500 bg-white rounded-r-lg border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||
>
|
||||
Next
|
||||
{{ nextLabel }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -48,9 +56,17 @@ const props = defineProps({
|
||||
default: 1,
|
||||
},
|
||||
totalPages: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
perPage: {
|
||||
type: Number,
|
||||
default: 10,
|
||||
},
|
||||
totalItems: {
|
||||
type: Number,
|
||||
required: false,
|
||||
},
|
||||
layout: {
|
||||
type: String as PropType<PaginationLayout>, // 'navigation' | 'pagination' | 'table'
|
||||
default: 'pagination',
|
||||
@@ -63,9 +79,16 @@ const props = defineProps({
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
previousLabel: {
|
||||
type: String,
|
||||
default: 'Previous',
|
||||
},
|
||||
nextLabel: {
|
||||
type: String,
|
||||
default: 'Next',
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
const setPage = (index: number) => {
|
||||
emit('update:modelValue', index)
|
||||
}
|
||||
@@ -76,19 +99,62 @@ const increasePage = () => {
|
||||
emit('update:modelValue', props.modelValue + 1)
|
||||
}
|
||||
|
||||
const computedTotalPages = computed(() => {
|
||||
if (!props.totalItems) return props.totalPages
|
||||
if (!props.perPage) return props.totalPages
|
||||
return Math.ceil(props.totalItems / props.perPage)
|
||||
})
|
||||
|
||||
const isDecreaseDisabled = computed(() => props.modelValue <= 1)
|
||||
const isIncreaseDisabled = computed(() => props.modelValue >= props.totalPages)
|
||||
const isIncreaseDisabled = computed(() => props.modelValue >= computedTotalPages.value)
|
||||
const isSetPageDisabled = (index: number) => index === props.modelValue
|
||||
|
||||
const filteredPages = computed(() => {
|
||||
if (props.modelValue <= props.sliceLength) return [...Array(Math.abs(props.modelValue - props.sliceLength) + props.modelValue + props.sliceLength + 1).keys()].map(num => num + 1)
|
||||
const pagesToDisplay = computed(() => {
|
||||
if (props.layout === 'navigation') return []
|
||||
if (props.layout === 'table') return []
|
||||
|
||||
if (computedTotalPages.value <= props.sliceLength * 2 + 1) {
|
||||
const pages = []
|
||||
for (let page = 1; page <= computedTotalPages.value; page++) {
|
||||
pages.push(page)
|
||||
}
|
||||
return pages
|
||||
}
|
||||
if (props.modelValue <= props.sliceLength) {
|
||||
const pages = []
|
||||
const slicedLength = Math.abs(props.modelValue - props.sliceLength) + props.modelValue + props.sliceLength + 1
|
||||
for (let page = 1; page <= slicedLength; page++) {
|
||||
pages.push(page)
|
||||
}
|
||||
return pages
|
||||
}
|
||||
if (props.modelValue >= computedTotalPages.value - props.sliceLength) {
|
||||
const pages = []
|
||||
for (let page = Math.abs(computedTotalPages.value - props.sliceLength * 2); page <= computedTotalPages.value; page++) {
|
||||
pages.push(page)
|
||||
}
|
||||
return pages
|
||||
}
|
||||
|
||||
const pages = []
|
||||
|
||||
let startedPage = props.modelValue - props.sliceLength > 0 ? props.modelValue - props.sliceLength : 1
|
||||
for (let page = startedPage; page < props.modelValue + props.sliceLength + 1; page++) {
|
||||
if (page >= computedTotalPages.value) break
|
||||
pages.push(page)
|
||||
}
|
||||
return pages
|
||||
})
|
||||
|
||||
|
||||
const startItemsCount = computed(() => props.modelValue * props.perPage - props.perPage + 1)
|
||||
const endItemsCount = computed(() => {
|
||||
const count = props.modelValue * props.perPage + 1
|
||||
if (!props.totalItems) return count
|
||||
if (count > props.totalItems) return props.totalItems
|
||||
return count
|
||||
})
|
||||
const computedTotalItems = computed(() => {
|
||||
if (props.totalItems) return props.totalItems
|
||||
return computedTotalPages.value * props.perPage
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user