Created
July 11, 2022 13:26
-
-
Save bloodf/d450a42d913c8277b55a2737d8ab4316 to your computer and use it in GitHub Desktop.
Simple pagination for Vue 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const usePagination = ({ | |
total, // Total of elements in the Query | |
numberOfElements = 12, // Number of elements per Page | |
pagesToDisplay = 6, // Pages to be displayed in the component | |
currentPage = 1, // Current Page | |
pageLinkRule = (pageNumber) => { // Function to generate the links | |
return `/page/${pageNumber}`; | |
}, | |
}: { | |
total: number; | |
numberOfElements?: number; | |
pagesToDisplay?: number; | |
currentPage?: number; | |
pageLinkRule?: (pageNumber: number) => string; | |
}) => { | |
const generatePageObj = ( | |
{ | |
number, | |
ellipsis = false, | |
active = false, | |
}: { number: number; ellipsis?: boolean; active?: boolean }, | |
linkRule: (pageNumber: number) => string, | |
) => ({ | |
page: number, | |
link: linkRule(number), | |
active, | |
ellipsis, | |
}); | |
const pagesCount = Math.ceil(total / numberOfElements); | |
const hasPrevious = currentPage !== 1; | |
const hasNext = currentPage !== pagesCount; | |
const baseData = { | |
pagesCount, | |
currentPage, | |
previousPage: hasPrevious | |
? generatePageObj({ number: currentPage - 1 }, pageLinkRule) | |
: null, | |
nextPage: hasNext | |
? generatePageObj({ number: currentPage + 1 }, pageLinkRule) | |
: null, | |
pages: [], | |
firstPage: generatePageObj({ number: 1 }, pageLinkRule), | |
lastPage: generatePageObj({ number: pagesCount }, pageLinkRule), | |
}; | |
if (baseData.currentPage < pagesToDisplay) { | |
baseData.firstPage.ellipsis = false; | |
baseData.lastPage.ellipsis = baseData.pagesCount >= pagesToDisplay; | |
new Array(pagesToDisplay).fill('').forEach((_, i) => { | |
baseData.pages.push( | |
generatePageObj( | |
{ | |
number: i + 1, | |
active: i + 1 === baseData.currentPage, | |
}, | |
pageLinkRule, | |
), | |
); | |
}); | |
} | |
if (baseData.currentPage >= pagesToDisplay) { | |
const count = Math.floor(pagesToDisplay / 2); | |
baseData.firstPage.ellipsis = baseData.currentPage - count > 1; | |
if (baseData.currentPage - count + pagesToDisplay <= baseData.pagesCount) { | |
baseData.lastPage.ellipsis = | |
baseData.currentPage - count + pagesToDisplay < baseData.pagesCount; | |
for ( | |
let j = baseData.currentPage - count; | |
j < baseData.currentPage - count + pagesToDisplay; | |
j += 1 | |
) { | |
baseData.pages.push( | |
generatePageObj( | |
{ | |
number: j, | |
active: j === baseData.currentPage, | |
}, | |
pageLinkRule, | |
), | |
); | |
} | |
} else { | |
baseData.lastPage.ellipsis = false; | |
for ( | |
let k = baseData.pagesCount - pagesToDisplay + 1; | |
k <= baseData.pagesCount; | |
k += 1 | |
) { | |
baseData.pages.push( | |
generatePageObj( | |
{ | |
number: k, | |
active: k === baseData.currentPage, | |
}, | |
pageLinkRule, | |
), | |
); | |
} | |
} | |
} | |
return baseData; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment