{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-pagination",
  "title": "usePagination",
  "description": "Turns a page and a page count into the list of pages and ellipses to render, keeping its length steady as the page moves.",
  "files": [
    {
      "path": "hooks/use-pagination.ts",
      "content": "import * as React from \"react\"\n\ntype PaginationItemData =\n  | { type: \"page\"; page: number }\n  | { type: \"ellipsis\"; position: \"start\" | \"end\" }\n\ntype UsePaginationOptions = {\n  page?: number\n  count: number\n  siblings?: number\n  boundaries?: number\n}\n\nfunction clampInt(value: unknown, fallback: number, min: number, max: number) {\n  const number = Math.floor(Number(value))\n  if (!Number.isFinite(number)) {\n    return fallback\n  }\n  return Math.min(max, Math.max(min, number))\n}\n\nfunction range(start: number, end: number) {\n  const pages: number[] = []\n  for (let page = start; page <= end; page++) {\n    pages.push(page)\n  }\n  return pages\n}\n\nfunction usePagination({\n  page,\n  count,\n  siblings = 1,\n  boundaries = 1,\n}: UsePaginationOptions) {\n  const total = clampInt(count, 0, 0, Number.MAX_SAFE_INTEGER)\n  const current = total === 0 ? 0 : clampInt(page, 1, 1, total)\n  const siblingCount = clampInt(siblings, 1, 0, 10)\n  const boundaryCount = clampInt(boundaries, 1, 0, 10)\n\n  const items = React.useMemo<PaginationItemData[]>(() => {\n    if (total === 0) {\n      return []\n    }\n    const start = range(1, Math.min(boundaryCount, total))\n    const end = range(\n      Math.max(total - boundaryCount + 1, boundaryCount + 1),\n      total\n    )\n    const siblingsStart = Math.max(\n      Math.min(\n        current - siblingCount,\n        total - boundaryCount - siblingCount * 2 - 1\n      ),\n      boundaryCount + 2\n    )\n    const siblingsEnd = Math.min(\n      Math.max(current + siblingCount, boundaryCount + siblingCount * 2 + 2),\n      end.length > 0 ? end[0] - 2 : total - 1\n    )\n    const pages: (number | \"start\" | \"end\")[] = [\n      ...start,\n      ...(siblingsStart > boundaryCount + 2\n        ? ([\"start\"] as const)\n        : boundaryCount + 1 < total - boundaryCount\n          ? [boundaryCount + 1]\n          : []),\n      ...range(siblingsStart, siblingsEnd),\n      ...(siblingsEnd < total - boundaryCount - 1\n        ? ([\"end\"] as const)\n        : total - boundaryCount > boundaryCount\n          ? [total - boundaryCount]\n          : []),\n      ...end,\n    ]\n    const seen = new Set<number | string>()\n    return pages\n      .filter((item) => {\n        if (seen.has(item)) {\n          return false\n        }\n        seen.add(item)\n        return typeof item === \"string\" || (item >= 1 && item <= total)\n      })\n      .map((item) =>\n        typeof item === \"string\"\n          ? { type: \"ellipsis\", position: item }\n          : { type: \"page\", page: item }\n      )\n  }, [total, current, siblingCount, boundaryCount])\n\n  return {\n    page: current,\n    count: total,\n    items,\n    hasPrevious: current > 1,\n    hasNext: current < total,\n  }\n}\n\nexport { usePagination }\nexport type { PaginationItemData, UsePaginationOptions }\n",
      "type": "registry:hook"
    }
  ],
  "type": "registry:hook"
}