'use client'; import type { ButtonProps, TextProps } from '@chakra-ui/react'; import { Button, Pagination as ChakraPagination, IconButton, Text, createContext, usePaginationContext, } from '@chakra-ui/react'; import * as React from 'react'; import { HiChevronLeft, HiChevronRight, HiMiniEllipsisHorizontal } from 'react-icons/hi2'; import { LinkButton } from '@/components/ui/buttons/link-button'; interface ButtonVariantMap { current: ButtonProps['variant']; default: ButtonProps['variant']; ellipsis: ButtonProps['variant']; } type PaginationVariant = 'outline' | 'solid' | 'subtle'; interface ButtonVariantContext { size: ButtonProps['size']; variantMap: ButtonVariantMap; getHref?: (page: number) => string; } const [RootPropsProvider, useRootProps] = createContext({ name: 'RootPropsProvider', }); export interface PaginationRootProps extends Omit { size?: ButtonProps['size']; variant?: PaginationVariant; getHref?: (page: number) => string; } const variantMap: Record = { outline: { default: 'ghost', ellipsis: 'plain', current: 'outline' }, solid: { default: 'outline', ellipsis: 'outline', current: 'solid' }, subtle: { default: 'ghost', ellipsis: 'plain', current: 'subtle' }, }; export const PaginationRoot = React.forwardRef( function PaginationRoot(props, ref) { const { size = 'sm', variant = 'outline', getHref, ...rest } = props; return ( ); }, ); export const PaginationEllipsis = React.forwardRef( function PaginationEllipsis(props, ref) { const { size, variantMap } = useRootProps(); return ( ); }, ); export const PaginationItem = React.forwardRef( function PaginationItem(props, ref) { const { page } = usePaginationContext(); const { size, variantMap, getHref } = useRootProps(); const current = page === props.value; const variant = current ? variantMap.current : variantMap.default; if (getHref) { return ( {props.value} ); } return ( ); }, ); export const PaginationPrevTrigger = React.forwardRef( function PaginationPrevTrigger(props, ref) { const { size, variantMap, getHref } = useRootProps(); const { previousPage } = usePaginationContext(); if (getHref) { return ( ); } return ( ); }, ); export const PaginationNextTrigger = React.forwardRef( function PaginationNextTrigger(props, ref) { const { size, variantMap, getHref } = useRootProps(); const { nextPage } = usePaginationContext(); if (getHref) { return ( ); } return ( ); }, ); export const PaginationItems = (props: React.HTMLAttributes) => { return ( {({ pages }) => pages.map((page, index) => { return page.type === 'ellipsis' ? ( ) : ( ); }) } ); }; interface PageTextProps extends TextProps { format?: 'short' | 'compact' | 'long'; } export const PaginationPageText = React.forwardRef( function PaginationPageText(props, ref) { const { format = 'compact', ...rest } = props; const { page, totalPages, pageRange, count } = usePaginationContext(); const content = React.useMemo(() => { if (format === 'short') return `${page} / ${totalPages}`; if (format === 'compact') return `${page} of ${totalPages}`; return `${pageRange.start + 1} - ${Math.min(pageRange.end, count)} of ${count}`; }, [format, page, totalPages, pageRange, count]); return ( {content} ); }, );