Skip to content

Instantly share code, notes, and snippets.

@gynekolog
Last active November 26, 2024 14:44
Show Gist options
  • Save gynekolog/9807f68819fd9732a129912509d58c73 to your computer and use it in GitHub Desktop.
Save gynekolog/9807f68819fd9732a129912509d58c73 to your computer and use it in GitHub Desktop.
Pagination generator
// The code is based on https://gist.github.com/kottenator/9d936eb3e4e3c3e02598#gistcomment-3238804
type PageItem = number | "...";
export const getRange = (start: number, end: number): PageItem[] => {
if (end < start) throw Error(`End number must be higher then start number: start ${start}, end ${start}`);
const rangeLength = end - start + 1;
return Array(rangeLength)
.fill(0)
.map((_, i) => i + start);
};
const clamp = (value: number, lower: number, upper: number) => Math.min(Math.max(value, lower), upper);
export const calculatePages = (currentPage: number, pageCount: number, size: number): PageItem[] => {
if (pageCount < 1) {
console.warn("Page count has negative value. Returning empty array.");
return [];
}
if (currentPage < 1) {
console.warn("Current page has negative value. Current page will be set to 1");
currentPage = 1;
}
if (currentPage > pageCount) {
console.warn("Current page is higher than page count. Current page will be set to page count:", pageCount);
currentPage = pageCount;
}
if (size % 2 === 0) {
console.warn("The size must be odd. The size will be increased by 1");
size += 1;
}
if (size < 5) {
console.warn("The minimum size is 5. The size will be increased to 5");
size = 5;
}
const offset = (size - 1) / 2;
const shouldAddDots = pageCount > size;
const rangeConfig = {
start: clamp(currentPage - offset, 1, shouldAddDots ? pageCount - size + 1 : 1),
end: clamp(currentPage + offset, size, pageCount),
};
const pages = getRange(rangeConfig.start, rangeConfig.end);
if (shouldAddDots && pages[0] !== 1) {
pages[0] = 1;
pages[1] = "...";
}
if (shouldAddDots && pages[pages.length - 1] !== pageCount) {
pages[pages.length - 1] = pageCount;
pages[pages.length - 2] = "...";
}
return pages;
};
@gynekolog
Copy link
Author

// biome-ignore lint/style/noParameterAssign: This is a valid use case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment