Skip to content

Instantly share code, notes, and snippets.

@mmyoji
Created May 10, 2024 08:32
Show Gist options
  • Save mmyoji/85635b81385396871bada223b3958f6e to your computer and use it in GitHub Desktop.
Save mmyoji/85635b81385396871bada223b3958f6e to your computer and use it in GitHub Desktop.
Get page objects to implement pagination
import { assertEquals } from "jsr:@std/assert";
import { paginate } from "./pagination.ts";
Deno.test(function paginateTest() {
assertEquals(paginate(1, 1), [1]);
assertEquals(paginate(1, 2), [1, 2]);
assertEquals(paginate(2, 2), [1, 2]);
assertEquals(paginate(1, 3), [1, 2, 3]);
assertEquals(paginate(2, 3), [1, 2, 3]);
assertEquals(paginate(3, 3), [1, 2, 3]);
assertEquals(paginate(1, 4), [1, 2, 3, 4]);
assertEquals(paginate(2, 4), [1, 2, 3, 4]);
assertEquals(paginate(3, 4), [1, 2, 3, 4]);
assertEquals(paginate(4, 4), [1, 2, 3, 4]);
assertEquals(paginate(1, 5), [1, 2, 3, 4, 5]);
assertEquals(paginate(2, 5), [1, 2, 3, 4, 5]);
assertEquals(paginate(3, 5), [1, 2, 3, 4, 5]);
assertEquals(paginate(4, 5), [1, 2, 3, 4, 5]);
assertEquals(paginate(5, 5), [1, 2, 3, 4, 5]);
assertEquals(paginate(1, 6), [1, 2, 3, 4, 5]);
assertEquals(paginate(2, 6), [1, 2, 3, 4, 5]);
assertEquals(paginate(3, 6), [1, 2, 3, 4, 5]);
assertEquals(paginate(4, 6), [2, 3, 4, 5, 6]);
assertEquals(paginate(5, 6), [2, 3, 4, 5, 6]);
assertEquals(paginate(6, 6), [2, 3, 4, 5, 6]);
assertEquals(paginate(1, 7), [1, 2, 3, 4, 5]);
assertEquals(paginate(2, 7), [1, 2, 3, 4, 5]);
assertEquals(paginate(3, 7), [1, 2, 3, 4, 5]);
assertEquals(paginate(4, 7), [2, 3, 4, 5, 6]);
assertEquals(paginate(5, 7), [3, 4, 5, 6, 7]);
assertEquals(paginate(6, 7), [3, 4, 5, 6, 7]);
assertEquals(paginate(7, 7), [3, 4, 5, 6, 7]);
assertEquals(paginate(1, 10), [1, 2, 3, 4, 5]);
assertEquals(paginate(2, 10), [1, 2, 3, 4, 5]);
assertEquals(paginate(3, 10), [1, 2, 3, 4, 5]);
assertEquals(paginate(4, 10), [2, 3, 4, 5, 6]);
assertEquals(paginate(5, 10), [3, 4, 5, 6, 7]);
assertEquals(paginate(6, 10), [4, 5, 6, 7, 8]);
assertEquals(paginate(8, 10), [6, 7, 8, 9, 10]);
assertEquals(paginate(9, 10), [6, 7, 8, 9, 10]);
assertEquals(paginate(10, 10), [6, 7, 8, 9, 10]);
});
const LIMIT = 5;
const PREV_SIZE = 2;
/**
* When you want to render page objects like following:
* - [1] [2] [3] [4] [5]
* - [...] [2] [3] [4] [5] [6] [...]
* - [1] [2] [3]
*
* @example
* ```ts
* const page = 1;
* const limit = 20;
* const { items, total } = await fetchData({ offset: page - 1, limit });
* const maxPage = Math.ceil(total / limit);
* const pages = paginate(page, maxPage);
* ```
*/
export function paginate(current: number, max: number): number[] {
if (max <= LIMIT) {
return [...Array(max).keys()].map((n) => n + 1);
}
const pages: number[] = [];
let prev = current - 1;
const prevSize = current + PREV_SIZE <= max
? PREV_SIZE
: (PREV_SIZE * 2) - (max - current);
while (prev > 0 && pages.length < prevSize) {
pages.unshift(prev);
prev--;
}
pages.push(current);
let next = current + 1;
while (pages.length < LIMIT && next <= max) {
pages.push(next);
next++;
}
return pages;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment