0.1.5•Updated 6 months ago
import { PrettyNumber } from "@islands/utils/pretty_number.ts";
import type { I_Pagination } from "@infinity-beyond/modules/pagination.ts";
import { ChevronLeft, ChevronRight, type LucideIcon } from "lucide-preact";
type I_PaginationOptions = {
meta: I_Pagination
entry_plural?: string
}
export function Pagination({ meta: { page, total_pages, page_size, current_item_count, total_items }, entry_plural = "entries" }: I_PaginationOptions) {
const count_start = page_size * (page - 1);
console.log('total_pages', total_pages);
console.log('total_items', total_items);
console.log('current_item_count', current_item_count);
console.log('page_size', page_size);
// deno-lint-ignore jsx-no-useless-fragment
if(total_pages == 1) return <></>;
let pagination_start = Math.max(1, page - 2);
let pagination_end = Math.min(total_pages, page + 2);
if(pagination_start < 3) pagination_end = Math.min(total_pages, 7);
if(pagination_start !== 1 && pagination_end > total_pages - 3) pagination_start = Math.max(1, total_pages - 6);
const pages_to_render = new Array(pagination_end - pagination_start + 1).fill(0).map((_, i) => pagination_start + i);
return <div class='flex items-center py-12 flex-col'>
<div class="flex gap-2">
<PaginationButton page={page - 1} disabled={page==1} icon={ChevronLeft} />
<div class="join">
{ pagination_start > 1 && <>
<PaginationButton page={1} />
{ pagination_start > 2 &&
<PaginationSpacer />
}
</>}
{ pages_to_render.map(page_index =>
<PaginationButton page_size={page_size} page={page_index} key={page_index} active={page == page_index} />
)}
{/* <PaginationButton page_size={page_size} page={page - 1} />
<PaginationButton page_size={page_size} page={page} active />
<PaginationButton page_size={page_size} page={page + 1} />
<PaginationButton page_size={page_size} page={page + 2} /> */}
{ pagination_end < total_pages && <>
{ pagination_end < total_pages - 1 &&
<PaginationSpacer />
}
<PaginationButton page={total_pages} />
</>}
</div>
<PaginationButton page={page + 1} disabled={page == total_pages} icon={ChevronRight} />
</div>
<div class="pt-4">
Showing { entry_plural } { PrettyNumber(count_start + 1) } - { PrettyNumber(count_start + current_item_count) } of { PrettyNumber(total_items) }
</div>
</div>
}
interface I_PaginationButton {
page: number
page_size?: number
active?: boolean
text?: string
icon?: LucideIcon
disabled?: boolean
}
function PaginationButton(params: I_PaginationButton) {
const { page, active, text, page_size, disabled } = params;
return <a
class={"join-item btn" + (active ? ' btn-active' : '')}
href={`?page=${page}${page_size ? `&page_size=${page_size}` : ''}`}
disabled={disabled}
>{
params.icon ?
// @ts-expect-error Lucide-Preact type issue - Working
<params.icon />
:
text || page
}
</a>
}
function PaginationSpacer() {
return <a class="join-item btn" disabled>...</a>
}