{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "pagination",
  "type": "registry:ui",
  "title": "Pagination",
  "description": "Accessible Pagination primitive with bounded and unbounded modes, deterministic page-window generation, callback and link rendering, current-page semantics, first/previous/next/last controls, compact layout, RTL-safe icons, token-backed styling, and reduced-motion-safe transitions.",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [
    "https://components.dethink.co.uk/r/dethink-base.json"
  ],
  "files": [
    {
      "path": "packages/components/src/components/pagination/pagination.tsx",
      "type": "registry:file",
      "target": "~/components/dethink/components/pagination/pagination.tsx",
      "content": "import {\n  forwardRef,\n  type AnchorHTMLAttributes,\n  type ButtonHTMLAttributes,\n  type HTMLAttributes,\n  type LiHTMLAttributes,\n  type ReactNode,\n  type Ref,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport type PaginationSize = \"sm\" | \"md\" | \"lg\";\nexport type PaginationControlType = \"first\" | \"previous\" | \"next\" | \"last\";\n\nexport interface PaginationLabels {\n  ellipsis?: string;\n  firstPage?: string;\n  lastPage?: (pageCount?: number) => string;\n  nextPage?: string;\n  nextPageShort?: string;\n  page?: (page: number, context: PaginationLabelContext) => string;\n  previousPage?: string;\n  previousPageShort?: string;\n  root?: string;\n  status?: (page: number, context: PaginationStatusContext) => string;\n}\n\nexport interface PaginationLabelContext {\n  current: boolean;\n  pageCount?: number;\n}\n\nexport interface PaginationStatusContext {\n  hasNextPage?: boolean;\n  pageCount?: number;\n}\n\nexport interface PaginationProps extends HTMLAttributes<HTMLElement> {\n  boundaryCount?: number;\n  compact?: boolean;\n  hasNextPage?: boolean;\n  hideDisabledControls?: boolean;\n  hrefForPage?: (page: number) => string | undefined;\n  labels?: PaginationLabels;\n  onPageChange?: (page: number) => void;\n  page: number;\n  pageCount?: number;\n  showFirstLast?: boolean;\n  siblingCount?: number;\n  size?: PaginationSize;\n  status?: ReactNode | false;\n}\n\nexport interface PaginationContentProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport interface PaginationListProps extends HTMLAttributes<HTMLUListElement> {}\n\nexport interface PaginationItemProps extends LiHTMLAttributes<HTMLLIElement> {\n  current?: boolean;\n  disabled?: boolean;\n}\n\nexport interface PaginationPageProps extends Omit<\n  HTMLAttributes<HTMLElement>,\n  \"children\" | \"onClick\"\n> {\n  children?: ReactNode;\n  current?: boolean;\n  disabled?: boolean;\n  href?: string;\n  label?: string;\n  onPageChange?: (page: number) => void;\n  page: number;\n  size?: PaginationSize;\n}\n\nexport interface PaginationControlProps extends Omit<\n  HTMLAttributes<HTMLElement>,\n  \"children\" | \"onClick\"\n> {\n  children?: ReactNode;\n  disabled?: boolean;\n  href?: string;\n  label: string;\n  onPageChange?: (page: number) => void;\n  page: number;\n  size?: PaginationSize;\n  type: PaginationControlType;\n}\n\nexport interface PaginationEllipsisProps extends HTMLAttributes<HTMLSpanElement> {\n  label?: string;\n  size?: PaginationSize;\n}\n\nexport interface PaginationStatusProps extends HTMLAttributes<HTMLParagraphElement> {}\n\nexport type PaginationRenderItem =\n  | {\n      current: boolean;\n      key: string;\n      page: number;\n      type: \"page\";\n    }\n  | {\n      key: string;\n      type: \"ellipsis\";\n    };\n\nexport interface PaginationWindowOptions {\n  boundaryCount?: number;\n  compact?: boolean;\n  hasNextPage?: boolean;\n  page: number;\n  pageCount?: number;\n  siblingCount?: number;\n}\n\nconst defaultLabels = {\n  ellipsis: \"More pages\",\n  firstPage: \"First page\",\n  lastPage: (pageCount?: number) =>\n    pageCount ? `Last page, page ${pageCount}` : \"Last page\",\n  nextPage: \"Next page\",\n  nextPageShort: \"Next\",\n  page: (page: number, { current, pageCount }: PaginationLabelContext) => {\n    if (current) {\n      return `Page ${page}, current page`;\n    }\n\n    return pageCount ? `Page ${page} of ${pageCount}` : `Page ${page}`;\n  },\n  previousPage: \"Previous page\",\n  previousPageShort: \"Back\",\n  root: \"Pagination\",\n  status: (\n    page: number,\n    { hasNextPage, pageCount }: PaginationStatusContext,\n  ) => {\n    if (pageCount) {\n      return `Page ${page} of ${pageCount}`;\n    }\n\n    return hasNextPage ? `Page ${page}` : `Page ${page}, end of results`;\n  },\n} satisfies Required<PaginationLabels>;\n\nconst paginationRootClasses =\n  \"flex w-full max-w-full min-w-0 flex-col text-sm text-muted-foreground @container\";\n\nconst paginationContentClasses =\n  \"flex w-full max-w-full min-w-0 flex-col items-start gap-[var(--dt-space-2)] @md:flex-row @md:items-center @md:justify-between @md:gap-[var(--dt-space-3)]\";\n\nconst paginationListClasses =\n  \"m-0 flex w-full max-w-full min-w-0 list-none flex-nowrap items-center justify-start gap-[var(--dt-space-1)] overflow-x-auto overscroll-x-contain p-0 [scrollbar-gutter:stable] [scrollbar-width:none] [-ms-overflow-style:none] @md:w-auto @md:flex-1 @md:justify-end [&::-webkit-scrollbar]:hidden\";\n\nconst paginationItemClasses =\n  \"flex min-w-0 items-center data-[current=true]:z-10 data-[disabled=true]:opacity-60\";\n\nconst paginationInteractiveBaseClasses =\n  \"inline-flex shrink-0 select-none items-center justify-center rounded-md border border-transparent bg-transparent font-medium text-muted-foreground outline-none tabular-nums no-underline motion-safe:transition-[background-color,border-color,color,box-shadow,translate] motion-safe:duration-[var(--dt-motion-fast)] motion-safe:ease-control motion-safe:ease-out motion-reduce:transition-none hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background motion-safe:active:translate-y-px data-[current=true]:border-primary/20 data-[current=true]:bg-primary data-[current=true]:text-primary-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50\";\n\nconst paginationEllipsisClasses =\n  \"inline-flex shrink-0 select-none items-center justify-center rounded-md font-medium tabular-nums text-muted-foreground\";\n\nconst paginationStatusClasses =\n  \"m-0 shrink-0 whitespace-nowrap text-sm tabular-nums text-muted-foreground\";\n\nconst paginationSizeClasses: Record<PaginationSize, string> = {\n  sm: \"h-8 min-w-8 px-[var(--dt-space-2)] text-xs\",\n  md: \"h-density-control min-w-density-control px-[var(--dt-space-2-5)] text-sm\",\n  lg: \"h-11 min-w-11 px-[var(--dt-space-3)] text-base\",\n};\n\nconst paginationIconSizeClasses: Record<PaginationSize, string> = {\n  sm: \"[&>svg]:size-3.5\",\n  md: \"[&>svg]:size-4\",\n  lg: \"[&>svg]:size-4\",\n};\n\nconst paginationSlotMinimums: Record<PaginationSize, string> = {\n  sm: \"2rem\",\n  md: \"var(--dt-density-control)\",\n  lg: \"2.75rem\",\n};\n\nconst paginationSlotPadding: Record<PaginationSize, string> = {\n  sm: \"var(--dt-space-2)\",\n  md: \"var(--dt-space-2-5)\",\n  lg: \"var(--dt-space-3)\",\n};\n\nexport function paginationClassNames({\n  className,\n}: Pick<PaginationProps, \"className\"> = {}) {\n  return cn(paginationRootClasses, className);\n}\n\nexport function paginationContentClassNames({\n  className,\n}: Pick<PaginationContentProps, \"className\"> = {}) {\n  return cn(paginationContentClasses, className);\n}\n\nexport function paginationListClassNames({\n  className,\n}: Pick<PaginationListProps, \"className\"> = {}) {\n  return cn(paginationListClasses, className);\n}\n\nexport function paginationItemClassNames({\n  className,\n}: Pick<PaginationItemProps, \"className\"> = {}) {\n  return cn(paginationItemClasses, className);\n}\n\nexport function paginationPageClassNames({\n  className,\n  size = \"md\",\n}: Pick<PaginationPageProps, \"className\" | \"size\"> = {}) {\n  return cn(\n    paginationInteractiveBaseClasses,\n    paginationSizeClasses[size],\n    paginationIconSizeClasses[size],\n    className,\n  );\n}\n\nexport function paginationControlClassNames({\n  className,\n  size = \"md\",\n}: Pick<PaginationControlProps, \"className\" | \"size\"> = {}) {\n  return cn(\n    paginationInteractiveBaseClasses,\n    paginationSizeClasses[size],\n    paginationIconSizeClasses[size],\n    className,\n  );\n}\n\nexport function paginationEllipsisClassNames({\n  className,\n  size = \"md\",\n}: Pick<PaginationEllipsisProps, \"className\" | \"size\"> = {}) {\n  return cn(paginationEllipsisClasses, paginationSizeClasses[size], className);\n}\n\nexport function paginationStatusClassNames({\n  className,\n}: Pick<PaginationStatusProps, \"className\"> = {}) {\n  return cn(paginationStatusClasses, className);\n}\n\nfunction toPositiveInteger(value: number | undefined, fallback: number) {\n  if (!Number.isFinite(value) || value === undefined) {\n    return fallback;\n  }\n\n  return Math.max(1, Math.floor(value));\n}\n\nfunction toNonNegativeInteger(value: number | undefined, fallback: number) {\n  if (!Number.isFinite(value) || value === undefined) {\n    return fallback;\n  }\n\n  return Math.max(0, Math.floor(value));\n}\n\nfunction range(start: number, end: number) {\n  const items: number[] = [];\n\n  for (let page = start; page <= end; page += 1) {\n    items.push(page);\n  }\n\n  return items;\n}\n\nfunction numbersToRenderItems(pages: number[], currentPage: number) {\n  const items: PaginationRenderItem[] = [];\n\n  for (const page of pages) {\n    const previous = items[items.length - 1];\n\n    if (previous?.type === \"page\") {\n      const gap = page - previous.page;\n\n      if (gap === 2) {\n        const missingPage = previous.page + 1;\n        items.push({\n          current: missingPage === currentPage,\n          key: `page-${missingPage}`,\n          page: missingPage,\n          type: \"page\",\n        });\n      } else if (gap > 2) {\n        items.push({\n          key: `ellipsis-${previous.page}-${page}`,\n          type: \"ellipsis\",\n        });\n      }\n    }\n\n    items.push({\n      current: page === currentPage,\n      key: `page-${page}`,\n      page,\n      type: \"page\",\n    });\n  }\n\n  return items;\n}\n\nexport function getPaginationRenderItems({\n  boundaryCount = 1,\n  compact = false,\n  hasNextPage = false,\n  page,\n  pageCount,\n  siblingCount = 1,\n}: PaginationWindowOptions): PaginationRenderItem[] {\n  const safeBoundaryCount = toNonNegativeInteger(boundaryCount, 1);\n  const safeSiblingCount = compact ? 0 : toNonNegativeInteger(siblingCount, 1);\n  const safePageCount =\n    pageCount === undefined ? undefined : toPositiveInteger(pageCount, 1);\n  const currentPage = safePageCount\n    ? Math.min(toPositiveInteger(page, 1), safePageCount)\n    : toPositiveInteger(page, 1);\n  const knownLastPage = safePageCount ?? currentPage + (hasNextPage ? 1 : 0);\n  const visiblePages = new Set<number>();\n\n  if (knownLastPage <= 0) {\n    return [];\n  }\n\n  if (safePageCount) {\n    // Fill the same number of slots at either boundary instead of shrinking\n    // the window and moving Previous/Next underneath the pointer.\n    const slotCount = 2 * safeBoundaryCount + 2 * safeSiblingCount + 3;\n    if (safePageCount <= slotCount) {\n      return numbersToRenderItems(range(1, safePageCount), currentPage);\n    }\n\n    if (safeBoundaryCount === 0) {\n      const count = 2 * safeSiblingCount + 1;\n      const start = Math.max(\n        1,\n        Math.min(currentPage - safeSiblingCount, safePageCount - count + 1),\n      );\n      return numbersToRenderItems(range(start, start + count - 1), currentPage);\n    }\n\n    const start = Math.max(\n      safeBoundaryCount + 2,\n      Math.min(\n        currentPage - safeSiblingCount,\n        safePageCount - safeBoundaryCount - 2 * safeSiblingCount - 1,\n      ),\n    );\n    const end = Math.min(\n      safePageCount - safeBoundaryCount - 1,\n      Math.max(\n        currentPage + safeSiblingCount,\n        safeBoundaryCount + 2 * safeSiblingCount + 2,\n      ),\n    );\n    return numbersToRenderItems(\n      [\n        ...range(1, safeBoundaryCount),\n        ...range(start, end),\n        ...range(safePageCount - safeBoundaryCount + 1, safePageCount),\n      ],\n      currentPage,\n    );\n  }\n\n  for (const pageNumber of range(\n    1,\n    Math.min(safeBoundaryCount, knownLastPage),\n  )) {\n    visiblePages.add(pageNumber);\n  }\n\n  for (\n    let pageNumber = Math.max(1, currentPage - safeSiblingCount);\n    pageNumber <= Math.min(knownLastPage, currentPage + safeSiblingCount);\n    pageNumber += 1\n  ) {\n    visiblePages.add(pageNumber);\n  }\n\n  if (hasNextPage) {\n    visiblePages.add(knownLastPage);\n  }\n\n  visiblePages.add(currentPage);\n\n  return numbersToRenderItems(\n    Array.from(visiblePages).sort((a, b) => a - b),\n    currentPage,\n  );\n}\n\nfunction getResolvedPage(page: number, pageCount: number | undefined) {\n  const safePage = toPositiveInteger(page, 1);\n\n  if (pageCount === undefined) {\n    return safePage;\n  }\n\n  return Math.min(safePage, toPositiveInteger(pageCount, 1));\n}\n\nfunction getPageHref(\n  hrefForPage: PaginationProps[\"hrefForPage\"] | undefined,\n  disabled: boolean,\n  page: number,\n) {\n  return disabled ? undefined : hrefForPage?.(page);\n}\n\nfunction getPaginationAction({\n  current = false,\n  disabled,\n  hrefForPage,\n  onPageChange,\n  page,\n}: {\n  current?: boolean;\n  disabled: boolean;\n  hrefForPage: PaginationProps[\"hrefForPage\"] | undefined;\n  onPageChange: PaginationProps[\"onPageChange\"] | undefined;\n  page: number;\n}) {\n  const href = getPageHref(hrefForPage, disabled, page);\n  const hasHref = href !== undefined;\n  const hasCallback = onPageChange !== undefined;\n  const resolvedDisabled = disabled || (!hasHref && (current || !hasCallback));\n\n  return {\n    disabled: resolvedDisabled,\n    href,\n    onPageChange: resolvedDisabled || hasHref ? undefined : onPageChange,\n  };\n}\n\nfunction renderControlIcon(\n  type: PaginationControlType,\n  { rotateInRtl = true }: { rotateInRtl?: boolean } = {},\n) {\n  const isPrevious = type === \"previous\" || type === \"first\";\n  const isBoundary = type === \"first\" || type === \"last\";\n\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={cn(\n        rotateInRtl && \"rtl:rotate-180\",\n        isBoundary ? \"w-4\" : \"w-3\",\n      )}\n      fill=\"none\"\n      viewBox=\"0 0 16 16\"\n    >\n      {isBoundary ? (\n        <path\n          d={\n            isPrevious\n              ? \"M4.5 3.5v9m7-8-4 3.5 4 3.5\"\n              : \"M11.5 3.5v9m-7-8 4 3.5-4 3.5\"\n          }\n          stroke=\"currentColor\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"1.7\"\n        />\n      ) : (\n        <path\n          d={isPrevious ? \"m10 4-4 4 4 4\" : \"m6 4 4 4-4 4\"}\n          stroke=\"currentColor\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"1.8\"\n        />\n      )}\n    </svg>\n  );\n}\n\nfunction renderResponsiveControlContent(\n  type: Extract<PaginationControlType, \"previous\" | \"next\">,\n  shortLabel: string,\n  size: PaginationSize,\n) {\n  return (\n    <>\n      <span\n        dir=\"ltr\"\n        className={cn(\n          \"inline-flex items-center justify-center gap-[var(--dt-space-1)] @xs:hidden\",\n          paginationIconSizeClasses[size],\n        )}\n      >\n        {type === \"previous\" ? (\n          <>\n            {renderControlIcon(type, { rotateInRtl: false })}\n            <span>{shortLabel}</span>\n          </>\n        ) : (\n          <>\n            <span>{shortLabel}</span>\n            {renderControlIcon(type, { rotateInRtl: false })}\n          </>\n        )}\n      </span>\n      <span\n        aria-hidden=\"true\"\n        className={cn(\n          \"hidden items-center justify-center @xs:inline-flex\",\n          paginationIconSizeClasses[size],\n        )}\n      >\n        {renderControlIcon(type)}\n      </span>\n    </>\n  );\n}\n\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(\n  (\n    {\n      \"aria-label\": ariaLabel,\n      \"aria-labelledby\": ariaLabelledBy,\n      boundaryCount = 1,\n      children,\n      className,\n      compact = false,\n      hasNextPage = false,\n      hideDisabledControls = false,\n      hrefForPage,\n      labels,\n      onPageChange,\n      page,\n      pageCount,\n      showFirstLast = false,\n      siblingCount = 1,\n      size = \"md\",\n      status,\n      ...props\n    },\n    ref,\n  ) => {\n    const mergedLabels = { ...defaultLabels, ...labels };\n    const currentPage = getResolvedPage(page, pageCount);\n    const safePageCount =\n      pageCount === undefined ? undefined : toPositiveInteger(pageCount, 1);\n    const canPrevious = currentPage > 1;\n    const canNext = safePageCount ? currentPage < safePageCount : hasNextPage;\n    const pageSlotWidth = safePageCount\n      ? `max(${paginationSlotMinimums[size]}, calc(${String(safePageCount).length}ch + 2 * ${paginationSlotPadding[size]} + 2px))`\n      : undefined;\n    const items = getPaginationRenderItems({\n      boundaryCount,\n      compact,\n      hasNextPage,\n      page: currentPage,\n      pageCount: safePageCount,\n      siblingCount,\n    });\n    const resolvedAriaLabel =\n      ariaLabel ??\n      (ariaLabelledBy === undefined ? mergedLabels.root : undefined);\n    const resolvedStatus =\n      status === false\n        ? null\n        : (status ??\n          mergedLabels.status(currentPage, {\n            hasNextPage,\n            pageCount: safePageCount,\n          }));\n    const firstPageAction = getPaginationAction({\n      disabled: !canPrevious,\n      hrefForPage,\n      onPageChange,\n      page: 1,\n    });\n    const previousPageAction = getPaginationAction({\n      disabled: !canPrevious,\n      hrefForPage,\n      onPageChange,\n      page: currentPage - 1,\n    });\n    const nextPageAction = getPaginationAction({\n      disabled: !canNext,\n      hrefForPage,\n      onPageChange,\n      page: currentPage + 1,\n    });\n    const lastPageAction =\n      safePageCount === undefined\n        ? undefined\n        : getPaginationAction({\n            disabled: !canNext,\n            hrefForPage,\n            onPageChange,\n            page: safePageCount,\n          });\n    const generatedContentClassName = compact\n      ? undefined\n      : \"flex-row items-center justify-between @xs:flex-col @xs:items-start @xs:justify-start @md:flex-row @md:items-center @md:justify-between\";\n    const smallWindowItemClassName = compact ? undefined : \"hidden @xs:flex\";\n    const generatedListClassName = compact\n      ? undefined\n      : \"w-auto flex-none justify-end rtl:flex-row-reverse @xs:w-full @xs:justify-start @xs:rtl:flex-row @md:w-auto @md:flex-1 @md:justify-end\";\n    const previousControlContent = compact\n      ? undefined\n      : renderResponsiveControlContent(\n          \"previous\",\n          mergedLabels.previousPageShort ?? defaultLabels.previousPageShort,\n          size,\n        );\n    const nextControlContent = compact\n      ? undefined\n      : renderResponsiveControlContent(\n          \"next\",\n          mergedLabels.nextPageShort ?? defaultLabels.nextPageShort,\n          size,\n        );\n\n    return (\n      <nav\n        {...props}\n        ref={ref}\n        aria-label={resolvedAriaLabel}\n        aria-labelledby={ariaLabelledBy}\n        data-compact={compact ? \"true\" : undefined}\n        data-slot=\"pagination\"\n        data-size={size}\n        className={paginationClassNames({ className })}\n      >\n        {children ?? (\n          <div\n            data-slot=\"pagination-content\"\n            className={paginationContentClassNames({\n              className: generatedContentClassName,\n            })}\n          >\n            {resolvedStatus ? (\n              <PaginationStatus\n                className={\n                  safePageCount && status === undefined ? \"grid\" : undefined\n                }\n              >\n                {safePageCount && status === undefined ? (\n                  <>\n                    <span\n                      aria-hidden=\"true\"\n                      data-reserved-status={mergedLabels.status(safePageCount, {\n                        pageCount: safePageCount,\n                        hasNextPage,\n                      })}\n                      className=\"invisible col-start-1 row-start-1 after:content-[attr(data-reserved-status)]\"\n                    />\n                    <span className=\"col-start-1 row-start-1\">\n                      {resolvedStatus}\n                    </span>\n                  </>\n                ) : (\n                  resolvedStatus\n                )}\n              </PaginationStatus>\n            ) : null}\n            <PaginationList className={generatedListClassName}>\n              {showFirstLast && (!hideDisabledControls || canPrevious) ? (\n                <PaginationItem\n                  className={smallWindowItemClassName}\n                  disabled={firstPageAction.disabled}\n                >\n                  <PaginationControl\n                    disabled={firstPageAction.disabled}\n                    href={firstPageAction.href}\n                    label={mergedLabels.firstPage}\n                    onPageChange={firstPageAction.onPageChange}\n                    page={1}\n                    size={size}\n                    type=\"first\"\n                  />\n                </PaginationItem>\n              ) : null}\n              {!hideDisabledControls || canPrevious ? (\n                <PaginationItem disabled={previousPageAction.disabled}>\n                  <PaginationControl\n                    disabled={previousPageAction.disabled}\n                    href={previousPageAction.href}\n                    label={mergedLabels.previousPage}\n                    onPageChange={previousPageAction.onPageChange}\n                    page={currentPage - 1}\n                    size={size}\n                    type=\"previous\"\n                  >\n                    {previousControlContent}\n                  </PaginationControl>\n                </PaginationItem>\n              ) : null}\n              {items.map((item) => {\n                if (item.type !== \"page\") {\n                  return (\n                    <PaginationItem\n                      key={item.key}\n                      className={smallWindowItemClassName}\n                    >\n                      <PaginationEllipsis\n                        style={{ inlineSize: pageSlotWidth }}\n                        label={mergedLabels.ellipsis}\n                        size={size}\n                      />\n                    </PaginationItem>\n                  );\n                }\n\n                const pageAction = getPaginationAction({\n                  current: item.current,\n                  disabled: false,\n                  hrefForPage,\n                  onPageChange,\n                  page: item.page,\n                });\n\n                return (\n                  <PaginationItem\n                    key={item.key}\n                    className={smallWindowItemClassName}\n                    current={item.current}\n                    disabled={pageAction.disabled}\n                  >\n                    <PaginationPage\n                      style={{ inlineSize: pageSlotWidth }}\n                      current={item.current}\n                      disabled={pageAction.disabled}\n                      href={pageAction.href}\n                      label={mergedLabels.page(item.page, {\n                        current: item.current,\n                        pageCount: safePageCount,\n                      })}\n                      onPageChange={pageAction.onPageChange}\n                      page={item.page}\n                      size={size}\n                    >\n                      {item.page}\n                    </PaginationPage>\n                  </PaginationItem>\n                );\n              })}\n              {!hideDisabledControls || canNext ? (\n                <PaginationItem disabled={nextPageAction.disabled}>\n                  <PaginationControl\n                    disabled={nextPageAction.disabled}\n                    href={nextPageAction.href}\n                    label={mergedLabels.nextPage}\n                    onPageChange={nextPageAction.onPageChange}\n                    page={currentPage + 1}\n                    size={size}\n                    type=\"next\"\n                  >\n                    {nextControlContent}\n                  </PaginationControl>\n                </PaginationItem>\n              ) : null}\n              {showFirstLast &&\n              safePageCount !== undefined &&\n              lastPageAction &&\n              (!hideDisabledControls || canNext) ? (\n                <PaginationItem\n                  className={smallWindowItemClassName}\n                  disabled={lastPageAction.disabled}\n                >\n                  <PaginationControl\n                    disabled={lastPageAction.disabled}\n                    href={lastPageAction.href}\n                    label={mergedLabels.lastPage(safePageCount)}\n                    onPageChange={lastPageAction.onPageChange}\n                    page={safePageCount}\n                    size={size}\n                    type=\"last\"\n                  />\n                </PaginationItem>\n              ) : null}\n            </PaginationList>\n          </div>\n        )}\n      </nav>\n    );\n  },\n);\n\nPagination.displayName = \"Pagination\";\n\nexport const PaginationList = forwardRef<HTMLUListElement, PaginationListProps>(\n  ({ className, ...props }, ref) => (\n    <ul\n      {...props}\n      ref={ref}\n      data-slot=\"pagination-list\"\n      className={paginationListClassNames({ className })}\n    />\n  ),\n);\n\nPaginationList.displayName = \"PaginationList\";\n\nexport const PaginationItem = forwardRef<HTMLLIElement, PaginationItemProps>(\n  ({ className, current = false, disabled = false, ...props }, ref) => (\n    <li\n      {...props}\n      ref={ref}\n      data-current={current ? \"true\" : undefined}\n      data-disabled={disabled ? \"true\" : undefined}\n      data-slot=\"pagination-item\"\n      className={paginationItemClassNames({ className })}\n    />\n  ),\n);\n\nPaginationItem.displayName = \"PaginationItem\";\n\nexport const PaginationPage = forwardRef<HTMLElement, PaginationPageProps>(\n  (\n    {\n      children,\n      className,\n      current = false,\n      disabled = false,\n      href,\n      label,\n      onPageChange,\n      page,\n      size = \"md\",\n      ...props\n    },\n    ref,\n  ) => {\n    const classes = paginationPageClassNames({ className, size });\n    const handleClick = () => {\n      if (!disabled && !current) {\n        onPageChange?.(page);\n      }\n    };\n\n    if (href !== undefined && !disabled) {\n      return (\n        <a\n          {...(props as AnchorHTMLAttributes<HTMLAnchorElement>)}\n          ref={ref as Ref<HTMLAnchorElement>}\n          aria-current={current ? \"page\" : undefined}\n          aria-label={label}\n          data-current={current ? \"true\" : undefined}\n          data-disabled={disabled ? \"true\" : undefined}\n          data-slot=\"pagination-page\"\n          href={href}\n          className={classes}\n          onClick={handleClick}\n        >\n          {children ?? page}\n        </a>\n      );\n    }\n\n    return (\n      <button\n        {...(props as ButtonHTMLAttributes<HTMLButtonElement>)}\n        ref={ref as Ref<HTMLButtonElement>}\n        aria-current={current ? \"page\" : undefined}\n        aria-label={label}\n        data-current={current ? \"true\" : undefined}\n        data-disabled={disabled ? \"true\" : undefined}\n        data-slot=\"pagination-page\"\n        disabled={disabled}\n        type=\"button\"\n        className={classes}\n        onClick={handleClick}\n      >\n        {children ?? page}\n      </button>\n    );\n  },\n);\n\nPaginationPage.displayName = \"PaginationPage\";\n\nexport const PaginationControl = forwardRef<\n  HTMLElement,\n  PaginationControlProps\n>(\n  (\n    {\n      children,\n      className,\n      disabled = false,\n      href,\n      label,\n      onPageChange,\n      page,\n      size = \"md\",\n      type,\n      ...props\n    },\n    ref,\n  ) => {\n    const classes = paginationControlClassNames({ className, size });\n    const handleClick = () => {\n      if (!disabled) {\n        onPageChange?.(page);\n      }\n    };\n    const content = children ?? renderControlIcon(type);\n\n    if (href !== undefined && !disabled) {\n      return (\n        <a\n          {...(props as AnchorHTMLAttributes<HTMLAnchorElement>)}\n          ref={ref as Ref<HTMLAnchorElement>}\n          aria-label={label}\n          data-control={type}\n          data-disabled={disabled ? \"true\" : undefined}\n          data-slot=\"pagination-control\"\n          href={href}\n          className={classes}\n          onClick={handleClick}\n        >\n          {content}\n        </a>\n      );\n    }\n\n    return (\n      <button\n        {...(props as ButtonHTMLAttributes<HTMLButtonElement>)}\n        ref={ref as Ref<HTMLButtonElement>}\n        aria-label={label}\n        data-control={type}\n        data-disabled={disabled ? \"true\" : undefined}\n        data-slot=\"pagination-control\"\n        disabled={disabled}\n        type=\"button\"\n        className={classes}\n        onClick={handleClick}\n      >\n        {content}\n      </button>\n    );\n  },\n);\n\nPaginationControl.displayName = \"PaginationControl\";\n\nexport const PaginationEllipsis = forwardRef<\n  HTMLSpanElement,\n  PaginationEllipsisProps\n>(\n  (\n    { className, label = defaultLabels.ellipsis, size = \"md\", ...props },\n    ref,\n  ) => (\n    <span\n      {...props}\n      ref={ref}\n      data-slot=\"pagination-ellipsis\"\n      className={paginationEllipsisClassNames({ className, size })}\n    >\n      <span aria-hidden=\"true\">...</span>\n      <span className=\"sr-only\">{label}</span>\n    </span>\n  ),\n);\n\nPaginationEllipsis.displayName = \"PaginationEllipsis\";\n\nexport const PaginationStatus = forwardRef<\n  HTMLParagraphElement,\n  PaginationStatusProps\n>(({ className, ...props }, ref) => (\n  <p\n    {...props}\n    ref={ref}\n    data-slot=\"pagination-status\"\n    className={paginationStatusClassNames({ className })}\n  />\n));\n\nPaginationStatus.displayName = \"PaginationStatus\";\n"
    },
    {
      "path": "packages/components/src/components/pagination/index.ts",
      "type": "registry:file",
      "target": "~/components/dethink/components/pagination/index.ts",
      "content": "export {\n  Pagination,\n  PaginationControl,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationList,\n  PaginationPage,\n  PaginationStatus,\n  getPaginationRenderItems,\n  paginationClassNames,\n  paginationContentClassNames,\n  paginationControlClassNames,\n  paginationEllipsisClassNames,\n  paginationItemClassNames,\n  paginationListClassNames,\n  paginationPageClassNames,\n  paginationStatusClassNames,\n  type PaginationControlProps,\n  type PaginationControlType,\n  type PaginationContentProps,\n  type PaginationEllipsisProps,\n  type PaginationItemProps,\n  type PaginationLabelContext,\n  type PaginationLabels,\n  type PaginationListProps,\n  type PaginationPageProps,\n  type PaginationProps,\n  type PaginationRenderItem,\n  type PaginationSize,\n  type PaginationStatusContext,\n  type PaginationStatusProps,\n  type PaginationWindowOptions,\n} from \"./pagination\";\n"
    },
    {
      "path": "packages/components/src/utils/cn.ts",
      "type": "registry:file",
      "target": "~/components/dethink/utils/cn.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
    }
  ]
}
