import { useState, type ReactNode } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Pagination is presentational: the consumer owns the page and the hrefs. The Story keeps the page in local state and uses // `#page-N` hrefs with preventDefault. The representative Story shows each case on one page; the same specimens also exist as // Stories tagged `verification` (hidden from the sidebar). // Page list with ellipses: 1 … (p-1 p p+1) … total. function pageRange(page: number, total: number): (number | "start" | "end")[] { if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1) const out: (number | "start" | "end")[] = [1] const from = Math.max(2, Math.min(page - 1, total - 4)) const to = Math.min(total - 1, Math.max(page + 1, 5)) if (from > 2) out.push("start") for (let p = from; p <= to; p++) out.push(p) if (to < total - 1) out.push("end") out.push(total) return out } // `showValue={false}` hides the value readout on the representative page; the verification Stories keep it. function Specimen({ total, initial, showValue = true }: { total: number; initial: number; showValue?: boolean }) { const [page, setPage] = useState(initial) const go = (p: number) => (event: React.MouseEvent) => { event.preventDefault() setPage(p) } return (
{pageRange(page, total).map((p) => typeof p === "number" ? ( {p} ) : ( ) )} {showValue ?

{`현재 ${page} / ${total}`}

: null}
) } const wrap = (node: ReactNode) =>
{node}
const sections = [ { id: "first", label: "First page", node: }, { id: "middle", label: "Middle page", node: }, { id: "last", label: "Last page", node: }, { id: "ellipsis", label: "Long range", node: }, ] const meta = { title: "Components/Navigation/Pagination", component: Pagination, parameters: { layout: "padded" } } satisfies Meta export default meta type Story = StoryObj const board = (...ids: string[]) => ( ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: wrap(s.node) }))} /> ) // Representative Story: the common Story page; the sections group the same specimens. export const All: Story = { name: "Pagination", parameters: { layout: "fullscreen", controls: { disable: true } }, render: () => ( {board("middle")} {board("first", "last")} {board("ellipsis")} ), } export const FirstPage: Story = { tags: ["verification"], name: "First Page", render: () => wrap() } export const LastPage: Story = { tags: ["verification"], name: "Last Page", render: () => wrap() } export const LongRange: Story = { tags: ["verification"], name: "Long Range", render: () => wrap() }