Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Pagination): handle max > 5 and max equal total pages #728

Merged
merged 11 commits into from
Sep 28, 2023
84 changes: 48 additions & 36 deletions src/runtime/components/navigation/Pagination.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,53 +127,65 @@ export default defineComponent({
const pages = computed(() => Array.from({ length: Math.ceil(props.total / props.pageCount) }, (_, i) => i + 1))

const displayedPages = computed(() => {
if (!props.max || pages.value.length <= 5) {
return pages.value
} else {
const current = currentPage.value
const max = pages.value.length
const r = Math.floor((Math.min(props.max, max) - 5) / 2)
const r1 = current - r
const r2 = current + r
const beforeWrapped = r1 - 1 > 1
const afterWrapped = r2 + 1 < max
const items: Array<number | string> = [1]

if (beforeWrapped) items.push(props.divider)

if (!afterWrapped) {
const addedItems = (current + r + 2) - max
for (let i = current - r - addedItems; i <= current - r - 1; i++) {
items.push(i)
}
const totalPages = pages.value.length
const current = currentPage.value
const maxDisplayedPages = Math.max(props.max, 5)

const r = Math.floor((Math.min(maxDisplayedPages, totalPages) - 5) / 2)
const r1 = current - r
const r2 = current + r

const beforeWrapped = r1 - 1 > 1
const afterWrapped = r2 + 1 < totalPages

const items: Array<number | string> = []

if (totalPages <= maxDisplayedPages) {
for (let i = 1; i <= totalPages; i++) {
items.push(i)
}
return items
}

items.push(1)

for (let i = r1 > 2 ? (r1) : 2; i <= Math.min(max, r2); i++) {
if (beforeWrapped) items.push(props.divider)

if (!afterWrapped) {
const addedItems = (current + r + 2) - totalPages
for (let i = current - r - addedItems; i <= current - r - 1; i++) {
items.push(i)
}
}

if (!beforeWrapped) {
const addedItems = 1 - (current - r - 2)
for (let i = current + r + 1; i <= current + r + addedItems; i++) {
items.push(i)
}
for (let i = Math.max(2, r1); i <= Math.min(totalPages, r2); i++) {
items.push(i)
}

if (!beforeWrapped) {
const addedItems = 1 - (current - r - 2)
for (let i = current + r + 1; i <= current + r + addedItems; i++) {
items.push(i)
}
}

if (afterWrapped) items.push(props.divider)
if (afterWrapped) items.push(props.divider)

if (r2 < max) items.push(max)
if (r2 < totalPages) {
items.push(totalPages)
}

// Replace divider by number on start edge case [1, '…', 3, ...]
if (items.length >= 3 && items[1] === props.divider && items[2] === 3) {
items[1] = 2
}
// Replace divider by number on end edge case [..., 48, '…', 50]
if (items.length >= 3 && items[items.length - 2] === props.divider && items[items.length - 1] === items.length) {
items[items.length - 2] = items.length - 1
}
// Replace divider by number on start edge case [1, '…', 3, ...]
if (items.length >= 3 && items[1] === props.divider && items[2] === 3) {
items[1] = 2
}

return items
// Replace divider by number on end edge case [..., 48, '…', 50]
if (items.length >= 3 && items[items.length - 2] === props.divider && items[items.length - 1] === items.length) {
items[items.length - 2] = items.length - 1
}

return items
})

const canGoPrev = computed(() => currentPage.value > 1)
Expand Down