Skip to content

Instantly share code, notes, and snippets.

@mtvbrianking
Last active May 10, 2025 13:00
Show Gist options
  • Save mtvbrianking/4860a30fb48bea7359fb8de90dcfb9d3 to your computer and use it in GitHub Desktop.
Save mtvbrianking/4860a30fb48bea7359fb8de90dcfb9d3 to your computer and use it in GitHub Desktop.
Pagination generator
function paginate(
curPosition = 1,
maxPosition = 10,
listSize = 7,
minPosition = 1
) {
curPosition = Math.max(minPosition, Math.min(maxPosition, curPosition));
const half = Math.floor(listSize / 2);
let start = curPosition - half;
let end = curPosition + half;
if (start < minPosition) {
end += minPosition - start;
start = minPosition;
}
if (end > maxPosition) {
start -= end - maxPosition;
end = maxPosition;
}
start = Math.max(start, minPosition);
const result = [];
for (let i = start; i <= end && result.length < listSize; i++) {
result.push(i);
}
result[0] = minPosition;
result[result.length - 1] = maxPosition;
if ((result[1] - result[0]) > 1) {
result[1] = 0; // '...'
}
const lastIdx = result.length - 1;
if ((result[lastIdx] - result[lastIdx - 1]) > 1) {
result[lastIdx - 1] = 0; // '...'
}
const pages = result.map(function(item) {
return {
label: item !== 0 ? String(item) : '...',
value: item !== 0 ? item : null,
isCurrent: item === curPosition
};
});
pages.unshift({
label: 'Prev',
value: curPosition > minPosition ? curPosition - 1 : null,
isCurrent: false
});
pages.push({
label: 'Next',
value: curPosition < maxPosition ? curPosition + 1 : null,
isCurrent: false
});
return pages;
}
type PageItem = {
label: string;
value: number | null;
isCurrent: boolean;
};
export function paginate(
curPosition: number = 1,
maxPosition: number = 10,
listSize: number = 7,
minPosition: number = 1
): PageItem[] {
// ...
curPosition = Math.max(minPosition, Math.min(maxPosition, curPosition));
const half = Math.floor(listSize / 2);
let start = curPosition - half;
let end = curPosition + half;
if (start < minPosition) {
end += minPosition - start;
start = minPosition;
}
if (end > maxPosition) {
start -= end - maxPosition;
end = maxPosition;
}
start = Math.max(start, minPosition);
const result: (number)[] = [];
for (let i = start; i <= end && result.length < listSize; i++) {
result.push(i);
}
// ...
result[0] = minPosition;
result[result.length - 1] = maxPosition;
if ((result[1] - result[0]) > 1) {
result[1] = 0; // '...';
}
const lastIdx = result.length - 1;
if ((result[lastIdx] - result[lastIdx - 1]) > 1) {
result[lastIdx - 1] = 0; // '...';
}
// ...
const pages: PageItem[] = result.map((item): PageItem => ({
label: item !== 0 ? `${item}` : '...',
value: item !== 0 ? item : null,
isCurrent: item === curPosition
}));
pages.unshift({
label: 'Prev',
value: curPosition > minPosition ? curPosition - 1 : null,
isCurrent: false
});
pages.push({
label: 'Next',
value: curPosition < maxPosition ? curPosition + 1 : null,
isCurrent: false
});
return pages;
}
@mtvbrianking
Copy link
Author

import { paginate } from './pagination';

console.log('pagination', paginate(5, 10));
[
    {"label": "Prev", "value": 4, "isCurrent": false},
    {"label": "1", "value": 1, "isCurrent": false},
    {"label": "...", "value": null, "isCurrent": false},
    {"label": "4", "value": 4, "isCurrent": false},
    {"label": "5", "value": 5, "isCurrent": true},
    {"label": "6", "value": 6, "isCurrent": false},
    {"label": "...", "value": null, "isCurrent": false},
    {"label": "10", "value": 10, "isCurrent": false},
    {"label": "Next", "value": 6, "isCurrent": false},
]

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