From a6f65bb5fbdfabcfdf1796d2953e1401a89f804c Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Sun, 1 Sep 2024 19:54:43 +0200 Subject: [PATCH] feat: Pagination + usePagination hook --- .../ui/components/base/Tooltip.module.scss | 2 +- apps/frontend/src/ui/hooks/usePagination.tsx | 104 +++++++++++++++ .../src/ui/pages/browser/BrowserPackage.tsx | 119 +++++++----------- 3 files changed, 152 insertions(+), 73 deletions(-) create mode 100644 apps/frontend/src/ui/hooks/usePagination.tsx diff --git a/apps/frontend/src/ui/components/base/Tooltip.module.scss b/apps/frontend/src/ui/components/base/Tooltip.module.scss index 591cff6b..a7adcd41 100644 --- a/apps/frontend/src/ui/components/base/Tooltip.module.scss +++ b/apps/frontend/src/ui/components/base/Tooltip.module.scss @@ -11,7 +11,7 @@ @apply opacity-0 transition-opacity; @apply absolute left-1/2 -translate-x-1/2 top-0 -translate-y-6/5; @apply w-max max-w-52; - @apply backdrop-blur-lg rounded-md bg-black/50 p-2 text-center text-sm text-wrap text-white shadow shadow-black/30; + @apply backdrop-blur-lg rounded-md bg-black/50 p-2 text-center text-sm text-wrap line-height-relaxed text-white shadow shadow-black/30; } } diff --git a/apps/frontend/src/ui/hooks/usePagination.tsx b/apps/frontend/src/ui/hooks/usePagination.tsx new file mode 100644 index 00000000..62687841 --- /dev/null +++ b/apps/frontend/src/ui/hooks/usePagination.tsx @@ -0,0 +1,104 @@ +import { ChevronLeftIcon, ChevronRightIcon } from '@untitled-theme/icons-solid'; +import { For, Show, createSignal } from 'solid-js'; +import Button from '~ui/components/base/Button'; + +interface PaginationOptions { + itemsCount: () => number; + itemsPerPage: () => number; + initialPage?: () => number; +}; + +function usePagination(options: PaginationOptions) { + const [page, setPage] = createSignal(Math.max(1, options.initialPage?.() || 1)); + + const next = () => setPage(page => page + 1); + const prev = () => setPage(page => page - 1); + + const totalPages = () => Math.ceil(options.itemsCount() / options.itemsPerPage()); + + const hasNext = () => page() < totalPages(); + const hasPrev = () => page() > 1; + + const offset = () => (page() - 1) * options.itemsPerPage(); + + // Navigation + function getVisiblePageNumbers(page: number) { + const pages: number[] = []; + + const left = page - 1 > 1 ? page - 1 : null; + const right = page + 1 < totalPages() ? page + 1 : null; + + if (left !== null) + pages.push(left); + + if (page !== 1 && page !== totalPages()) + pages.push(page); + + if (right !== null) + pages.push(right); + + return pages; + } + + function PaginationBtn(props: { page: number }) { + return ( +