{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "csv-source",
  "title": "CSV source adapter",
  "description": "Bridges the document-source model to the CSV viewer: csvAnchorToTarget and sourceToCsvCell for csv_cell anchors.",
  "registryDependencies": [
    "@retab/csv-viewer",
    "@retab/document-source"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/ui/csv-source.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport type { Source, SourceAnchor } from \"@/lib/document-source\";\nimport type {\n  CsvCellAddress,\n  CsvViewerHandle,\n} from \"@/components/ui/csv-viewer\";\n\nexport interface SourceTarget {\n  scrollTo?: (source: Source, options: { behavior: ScrollBehavior }) => void;\n}\n\n/** Spreadsheet column letter → 0-based index (\"A\" → 0, \"C\" → 2, \"AA\" → 26). */\nexport function columnLetterToIndex(letter: string): number | null {\n  if (!/^[A-Za-z]+$/.test(letter)) return null;\n  let n = 0;\n  for (const ch of letter.toUpperCase()) {\n    n = n * 26 + (ch.charCodeAt(0) - 64);\n    if (!Number.isSafeInteger(n)) return null;\n  }\n  return n - 1;\n}\n\n/**\n * A `csv_cell` anchor → 0-based data coordinates. `row` is the 1-based data\n * row (the header is not a data row); `column` is a letter.\n */\nexport function csvAnchorToTarget(anchor: SourceAnchor): CsvCellAddress | null {\n  if (anchor.kind === \"csv_cell\") {\n    const columnIndex = columnLetterToIndex(anchor.column);\n    if (\n      columnIndex == null ||\n      !Number.isInteger(anchor.row) ||\n      anchor.row < 1\n    ) {\n      return null;\n    }\n    return {\n      rowIndex: anchor.row - 1,\n      columnIndex,\n    };\n  }\n  return null;\n}\n\n/** A stable source target over a `CsvViewer` ref. */\nexport function useCsvSourceTarget(\n  viewerRef: React.RefObject<CsvViewerHandle | null>,\n): SourceTarget {\n  return React.useMemo<SourceTarget>(\n    () => ({\n      scrollTo: (source: Source, options) => {\n        const target = csvAnchorToTarget(source.anchor);\n        if (target) viewerRef.current?.scrollToCell(target, options);\n      },\n    }),\n    [viewerRef],\n  );\n}\n\n/**\n * The `activeCell` prop for `CsvViewer` derived from a source.\n */\nexport function sourceToCsvCell(\n  source: Source | undefined,\n): CsvCellAddress | null {\n  return source ? csvAnchorToTarget(source.anchor) : null;\n}\n",
      "type": "registry:ui",
      "target": "@ui/csv-source.tsx"
    }
  ],
  "type": "registry:ui"
}