docling-studio/frontend/src/shared/composables/usePagination.ts
Pier-Jean Malandrino 102a11765a Add reusable pagination composable and PaginationBar component
Generic usePagination composable with page navigation, size control,
and auto-reset on data change. PaginationBar renders prev/next with
page size selector. Both support i18n.
2026-04-02 13:41:50 +02:00

71 lines
1.5 KiB
TypeScript

import { ref, computed, watch, type Ref } from 'vue'
export interface PaginationOptions {
pageSize?: number
}
export interface PaginationReturn<T> {
page: Ref<number>
pageSize: Ref<number>
pageCount: Ref<number>
paginatedItems: Ref<T[]>
totalItems: Ref<number>
next: () => void
prev: () => void
goTo: (target: number) => void
setPageSize: (size: number) => void
}
export function usePagination<T>(
items: Ref<T[]>,
options: PaginationOptions = {},
): PaginationReturn<T> {
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,
}
}