ui icon indicating copy to clipboard operation
ui copied to clipboard

[feat]: Can automatically display "<Pagination Ellipsis />" in case of multiple "PaginationLink"

Open Bom312001 opened this issue 1 year ago • 2 comments

Feature description

can automatically display "<Pagination Ellipsis />" in case of multiple "PaginationLink". For example: image

Affected component/components

No response

Additional Context

Additional details here...

Before submitting

  • [X] I've made research efforts and searched the documentation
  • [X] I've searched for existing issues and PRs

Bom312001 avatar Sep 05 '24 09:09 Bom312001

hi @shadcn , @elliot ! can you help me problem, please ?

Bom312001 avatar Sep 09 '24 07:09 Bom312001

ezgif-3-23506cc468

interface PaginationDemoProps {
    current: number
    total: number
    siblings: number
    onPageChange: (selected: number) => void
}

export function PaginationDemo({ ...props }: PaginationDemoProps) {
    const generatePages = (
        current: number,
        total: number,
        siblings: number
    ) => {
        // current = 10
        // siblings = 1
        // total = 20

        // siblins = 1 then totalNumbers = 5
        const totalNumbers = siblings * 2 + 3
        // totalBlocks = 7
        const totalBlocks = totalNumbers + 2

        // Show all pages if total is less or equal than 7
        if (total <= totalBlocks) {
            return Array.from({ length: total }, (_, i) => i + 1)
        }

        // current = 10, so 9 is the max
        const startPage = Math.max(current - siblings, 1)
        // current + siblings = 11, total is 20, so 11 is the minimum
        const endPage = Math.min(current + siblings, total)

        // Array of pages ( considering siblings is 1 )
        const pages = [
            //startPage = 9, so starts with [1,'...']
            ...(startPage > 2 ? [1, '...'] : startPage === 1 ? [] : [1]),
            ...Array.from(
                // startPage = 9 endPage = 11 then [3 items]
                { length: endPage - startPage + 1 },
                // [9,10,11]
                (_, i) => startPage + i
            ),
            // total - 1 = 19, and endPage is 11
            ...(endPage < total - 1
                ? // show ['...', 20]
                  ['...', total]
                : // if endPage is 20, show nothing at the end
                endPage === total
                ? []
                : // show total after all that
                  [total]),
        ]

        return pages
    }

    const items = generatePages(props.current, props.total, props.siblings)

    return (
        <Pagination>
            <PaginationContent className="flex">
                <PaginationItem
                    onClick={() =>
                        props.current != 1
                            ? props.onPageChange((props.current -= 1))
                            : {}
                    }
                >
                    <PaginationPrevious href="#" />
                </PaginationItem>
                {items.map((item, i) => (
                    <PaginationItem key={i}>
                        <PaginationLink
                            href="#"
                            isActive={item == props.current}
                            onClick={() =>
                                item != '...'
                                    ? props.onPageChange(item as number)
                                    : {}
                            }
                        >
                            {item}
                        </PaginationLink>
                    </PaginationItem>
                ))}

                <PaginationItem
                    onClick={() =>
                        props.current != props.total
                            ? props.onPageChange((props.current += 1))
                            : {}
                    }
                >
                    <PaginationNext href="#" />
                </PaginationItem>
            </PaginationContent>
        </Pagination>
    )
}
function App() {
    const [current, setCurrent] = useState(2)

    return (
        <div className="py-5">
            <PaginationDemo
                current={current}
                onPageChange={(value: number) => {
                    setCurrent(value)
                }}
                siblings={1}
                total={20}
            />
        </div>
    )
}

jpedro-cf avatar Oct 05 '24 11:10 jpedro-cf

This issue has been automatically marked as stale due to two years of inactivity. It will be closed in 7 days unless there’s further input. If you believe this issue is still relevant, please leave a comment or provide updated details. Thank you.

shadcn avatar Mar 02 '25 11:03 shadcn

Not stale. Something went wrong with the stale bot.

shadcn avatar Mar 02 '25 11:03 shadcn