{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "description": "A page strip with ellipsis truncation and previous/next controls.",
  "docs": "Two steps after installing: import the copied stylesheet once at your app entry — it lands at `styles/liquefy-ui.css` — or `@import` it from your global CSS *before* `tailwindcss`, so Tailwind utilities keep winning over component styles. Then wrap the tree in `<LiquefyProvider>`, which is where every component reads its tokens from. Every copied file already carries its own 'use client' directive. Full documentation: https://liquefy-ui.com/#/docs/installation",
  "files": [
    {
      "content": "'use client'\n\nimport {\n  forwardRef,\n  useState,\n  type ButtonHTMLAttributes,\n  type HTMLAttributes,\n  type ReactNode,\n} from 'react'\nimport { ChevronLeftGlyph, ChevronRightGlyph } from '@/lib/internal-glyphs'\nimport { useLiquefyConfig } from '@/lib/provider'\nimport { useLiquidStyles, type LiquidStyleProps } from '@/lib/styles-prop'\nimport { useLiquidGlass } from '@/hooks/use-liquid-glass'\n\nexport type LiquidPaginationProps = Omit<HTMLAttributes<HTMLElement>, 'onChange'> & LiquidStyleProps & {\n  count: number\n  defaultPage?: number\n  label?: string\n  onPageChange?: (page: number) => void\n  page?: number\n  siblingCount?: number\n}\n\ntype PaginationButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n  children: ReactNode\n}\n\n// Same jelly springs the button family uses: pointer tilt/squish plus a release\n// overshoot fired on click, so every page control purun like a LiquidButton.\nconst PaginationButton = ({ children, className, onClick, ...props }: PaginationButtonProps) => {\n  const config = useLiquefyConfig()\n  const [glassRef, , pulse] = useLiquidGlass<HTMLButtonElement>(undefined, {\n    bounce: 0.08,\n    disabled: props.disabled,\n    glow: config.glow,\n    intensity: config.intensity,\n    lens: config.lens && config.transparency,\n    lensStrength: config.refraction,\n    motion: config.motion,\n    ripple: config.ripple,\n    shimmer: config.shimmer,\n    sparkle: config.sparkle,\n    tilt: 2.2,\n    tint: config.tint,\n    webgl: false,\n    wobbliness: config.wobbliness,\n  })\n\n  return (\n    <button\n      className={['lq-pagination__item', className].filter(Boolean).join(' ')}\n      onClick={(event) => {\n        onClick?.(event)\n        if (!props.disabled) pulse(1)\n      }}\n      ref={glassRef}\n      type=\"button\"\n      {...props}\n    >\n      {children}\n    </button>\n  )\n}\n\nconst buildRange = (count: number, page: number, siblingCount: number): Array<number | 'ellipsis'> => {\n  if (count <= 5 + siblingCount * 2) return Array.from({ length: count }, (_, index) => index + 1)\n\n  const start = Math.max(2, page - siblingCount)\n  const end = Math.min(count - 1, page + siblingCount)\n  const range: Array<number | 'ellipsis'> = [1]\n  if (start > 2) range.push('ellipsis')\n  for (let index = start; index <= end; index += 1) range.push(index)\n  if (end < count - 1) range.push('ellipsis')\n  range.push(count)\n  return range\n}\n\nexport const LiquidPagination = forwardRef<HTMLElement, LiquidPaginationProps>(({\n  className,\n  count,\n  defaultPage = 1,\n  label = 'Pagination',\n  onPageChange,\n  page,\n  siblingCount = 1,\n  style,\n  styles,\n  ...props\n}, ref) => {\n  const [internalPage, setInternalPage] = useState(defaultPage)\n  const currentPage = page ?? internalPage\n\n  const goTo = (nextPage: number) => {\n    const clamped = Math.min(count, Math.max(1, nextPage))\n    if (page === undefined) setInternalPage(clamped)\n    onPageChange?.(clamped)\n  }\n  const root = useLiquidStyles('lq-pagination', { className, style, styles })\n\n  return (\n    <nav aria-label={label} className={root.className} ref={ref} style={root.style} {...props}>\n      <PaginationButton\n        aria-label=\"Previous page\"\n        className=\"lq-pagination__item--nav\"\n        disabled={currentPage <= 1}\n        onClick={() => goTo(currentPage - 1)}\n      >\n        <ChevronLeftGlyph size={14} />\n      </PaginationButton>\n      {buildRange(count, currentPage, siblingCount).map((item, index) =>\n        item === 'ellipsis'\n          ? <span aria-hidden=\"true\" className=\"lq-pagination__ellipsis\" key={`ellipsis-${index}`}>…</span>\n          : (\n            <PaginationButton\n              aria-current={item === currentPage ? 'page' : undefined}\n              aria-label={`Page ${item}`}\n              data-active={item === currentPage}\n              key={item}\n              onClick={() => goTo(item)}\n            >\n              {item}\n            </PaginationButton>\n          ))}\n      <PaginationButton\n        aria-label=\"Next page\"\n        className=\"lq-pagination__item--nav\"\n        disabled={currentPage >= count}\n        onClick={() => goTo(currentPage + 1)}\n      >\n        <ChevronRightGlyph size={14} />\n      </PaginationButton>\n    </nav>\n  )\n})\n\nLiquidPagination.displayName = 'LiquidPagination'\n",
      "path": "registry/liquid-pagination.tsx",
      "type": "registry:ui"
    }
  ],
  "name": "liquid-pagination",
  "registryDependencies": [
    "https://liquefy-ui.com/r/liquefy-ui.json",
    "https://liquefy-ui.com/r/internal-glyphs.json",
    "https://liquefy-ui.com/r/provider.json",
    "https://liquefy-ui.com/r/styles-prop.json",
    "https://liquefy-ui.com/r/use-liquid-glass.json"
  ],
  "title": "LiquidPagination",
  "type": "registry:ui"
}
