import { ref, computed, watch, type Ref } from 'vue' export interface PaginationOptions { pageSize?: number } export interface PaginationReturn { page: Ref pageSize: Ref pageCount: Ref paginatedItems: Ref totalItems: Ref next: () => void prev: () => void goTo: (target: number) => void setPageSize: (size: number) => void } export function usePagination( items: Ref, options: PaginationOptions = {}, ): PaginationReturn { const page = ref(1) const pageSize = ref(options.pageSize ?? 20) const totalItems = computed(() => items.value.length) const pageCount = computed(() => Math.max(1, Math.ceil(totalItems.value / pageSize.value))) const paginatedItems = computed(() => { const start = (page.value - 1) * pageSize.value return items.value.slice(start, start + pageSize.value) }) // Reset to page 1 when source data or page size changes watch([items, pageSize], () => { page.value = 1 }) function clamp(target: number): number { return Math.max(1, Math.min(target, pageCount.value)) } function goTo(target: number): void { page.value = clamp(target) } function next(): void { goTo(page.value + 1) } function prev(): void { goTo(page.value - 1) } function setPageSize(size: number): void { if (size > 0) pageSize.value = size } return { page, pageSize, pageCount, paginatedItems, totalItems, next, prev, goTo, setPageSize, } }