{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-remote-data-table",
  "title": "Remote data table",
  "description": "Adapts paginated API metadata to controlled TanStack options, preserving requested pages during loading and resetting page-size changes.",
  "dependencies": [
    "@tanstack/react-table@^9.2.4"
  ],
  "files": [
    {
      "path": "registry/familis/ui/hooks/use-remote-data-table.ts",
      "content": "\"use client\"\n\nimport type { OnChangeFn, PaginationState, SortingState } from \"@tanstack/react-table\"\n\nexport interface PaginatorMeta {\n  total: number | string\n  perPage: number | string\n  currentPage: number | string\n  lastPage: number | string\n  firstPage?: number | string\n  firstPageUrl?: string\n  lastPageUrl?: string\n  nextPageUrl?: string | null\n  previousPageUrl?: string | null\n}\n\nexport type VisitFn = (args: { page: number; perPage: number }) => void\n\nexport interface UseRemoteDataTableOptions {\n  data: { metadata: PaginatorMeta } | undefined\n  visit: VisitFn\n  sorting?: { state: SortingState; onChange: OnChangeFn<SortingState> }\n  /** Requested 1-based page and size, usually held in the URL or query state. */\n  current?: { page: number; perPage: number }\n}\n\nexport interface RemoteDataTableOptions {\n  manualPagination: true\n  manualSorting: true\n  enableSorting: boolean\n  autoResetPageIndex: false\n  rowCount?: number\n  pageCount: number\n  state: { pagination: PaginationState; sorting?: SortingState }\n  onPaginationChange: OnChangeFn<PaginationState>\n  onSortingChange?: OnChangeFn<SortingState>\n}\n\nfunction positiveInteger(value: unknown, fallback: number): number {\n  const number = Number(value)\n  return Number.isFinite(number) && number >= 1 ? Math.floor(number) : fallback\n}\n\n/**\n * Adapts API metadata to controlled TanStack options; the caller fetches through visit.\n * Current takes priority over stale response metadata while a request is in flight.\n * Page-size changes request page 1. Sorting's handler owns refetching and page resets.\n * This adapter derives options without duplicating the caller's state or fetching data.\n */\nexport function useRemoteDataTable({\n  data,\n  visit,\n  sorting,\n  current,\n}: UseRemoteDataTableOptions): RemoteDataTableOptions {\n  const metadata = data?.metadata\n  const pageIndex = positiveInteger(current?.page ?? metadata?.currentPage, 1) - 1\n  const pageSize = positiveInteger(current?.perPage ?? metadata?.perPage, 10)\n  const pageCount = Math.max(positiveInteger(metadata?.lastPage, 1), pageIndex + 1)\n  const total = metadata?.total === undefined ? undefined : Number(metadata.total)\n  const rowCount =\n    total !== undefined && Number.isFinite(total) && total >= 0 ? Math.floor(total) : undefined\n\n  return {\n    manualPagination: true,\n    manualSorting: true,\n    enableSorting: sorting !== undefined,\n    autoResetPageIndex: false,\n    rowCount,\n    pageCount,\n    state: { pagination: { pageIndex, pageSize }, ...(sorting ? { sorting: sorting.state } : {}) },\n    onPaginationChange: (updater) => {\n      const previous = { pageIndex, pageSize }\n      const next = typeof updater === \"function\" ? updater(previous) : updater\n      const perPage = positiveInteger(next.pageSize, pageSize)\n      const page = perPage !== pageSize ? 1 : positiveInteger(next.pageIndex + 1, pageIndex + 1)\n      if (page === pageIndex + 1 && perPage === pageSize) return\n      visit({ page, perPage })\n    },\n    ...(sorting ? { onSortingChange: sorting.onChange } : {}),\n  }\n}\n",
      "type": "registry:hook"
    }
  ],
  "meta": {
    "storybookId": "ui-hooks-remote-data-table--default"
  },
  "type": "registry:hook"
}