{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "image-sources-block",
  "title": "Image Sources",
  "description": "Extracted fields linked to a scanned page image — hover to highlight the image_bbox region.",
  "registryDependencies": [
    "@retab/image-viewer",
    "@retab/image-source",
    "@retab/document-source",
    "@retab/segmented-document",
    "@retab/source-segmented-document",
    "@retab/source-field-list",
    "@retab/source-field-link",
    "@retab/source-indicator"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/blocks/image-sources-block.tsx",
      "content": "\"use client\";\n\nimport type { Source } from \"@/lib/document-source\";\nimport {\n  FileViewer,\n  FileViewerContent,\n  FileViewerHeader,\n  FileViewerTitle,\n  FileViewerProvider,\n  FileViewerSidebar,\n  FileViewerSidebarContent,\n  FileViewerInset,\n  FileViewerControls,\n  FileViewerViewport,\n} from \"@/components/ui/file-viewer\";\nimport { ImageViewer } from \"@/components/ui/image-viewer\";\nimport {\n  SegmentedDocumentProvider,\n  useSegmentedDocumentViewport,\n} from \"@/components/ui/segmented-document-provider\";\nimport { useSegmentedSourceFieldLink } from \"@/components/ui/source-field-link\";\nimport {\n  SourceFieldList,\n  type SourceField,\n} from \"@/components/ui/source-field-list\";\nimport { createSourcesSegmentedDocumentModel } from \"@/components/ui/source-segmented-document-model\";\nimport {\n  useSegmentedImageSourceOverlay,\n  useSegmentedImageViewerHandle,\n} from \"@/components/ui/source-segmented-document-overlays\";\nimport imageSample from \"@/components/viewers/sample-data/image-sources.json\";\n\nconst IMAGE_URL = \"/samples/an-image-is-worth-16x16-words-page-1.png\";\nconst IMAGE_SOURCE = {\n  kind: \"url\" as const,\n  url: IMAGE_URL,\n  fileName: \"an-image-is-worth-16x16-words-page-1.png\",\n};\n\ntype ImageField = SourceField & { source: Source };\n\n// Real values read off the scanned page with normalized image_bbox anchors.\nconst FIELDS = imageSample as ImageField[];\nconst SEGMENTED_DOCUMENT = createSourcesSegmentedDocumentModel(\n  FIELDS.map((field) => ({\n    id: field.key,\n    label: field.label,\n    source: field.source,\n  })),\n);\n\n/**\n * Image sources block — extracted fields beside a scanned page image. Hovering a\n * field highlights its image_bbox region and scrolls to it through the segmented\n * document provider.\n */\nexport function ImageSourcesBlock() {\n  return (\n    <SegmentedDocumentProvider model={SEGMENTED_DOCUMENT}>\n      <ImageSourcesContent />\n    </SegmentedDocumentProvider>\n  );\n}\n\nfunction ImageSourcesContent() {\n  const link = useSegmentedSourceFieldLink({\n    initialSourcePath: FIELDS[0]?.key,\n  });\n  const { documentHandlers } = useSegmentedDocumentViewport();\n  const renderFrameOverlay = useSegmentedImageSourceOverlay(link);\n  const setImageViewerHandle = useSegmentedImageViewerHandle();\n\n  return (\n    <FileViewerProvider\n      source={IMAGE_SOURCE}\n      fallbackFrameSize={{ width: 1224, height: 1584 }}\n      defaultSidebarOpen\n    >\n      <FileViewer\n        className=\"bg-background h-full min-h-[680px]\"\n       \n      >\n        <FileViewerHeader>\n            <FileViewerTitle />\n            <FileViewerControls />\n        </FileViewerHeader>\n        <FileViewerContent>\n          <FileViewerInset>\n            <FileViewerViewport>\n              <ImageViewer\n                ref={setImageViewerHandle}\n                source={IMAGE_SOURCE}\n                bare\n                className=\"h-full\"\n                controls={false}\n                fallbackFrameSize={{ width: 1224, height: 1584 }}\n                onScrollProgressChange={documentHandlers.onScrollProgressChange}\n                onVisibleFrameChange={documentHandlers.onCurrentPageChange}\n                renderFrameOverlay={renderFrameOverlay}\n              />\n            </FileViewerViewport>\n          </FileViewerInset>\n          <FileViewerSidebar\n            aria-label=\"Source fields\"\n            side=\"right\"\n            collapsible=\"none\"\n            width=\"360px\"\n            className=\"border-l\"\n          >\n            <FileViewerSidebarContent>\n              <SourceFieldList fields={FIELDS} link={link} />\n            </FileViewerSidebarContent>\n          </FileViewerSidebar>\n        </FileViewerContent>\n      </FileViewer>\n    </FileViewerProvider>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/blocks/image-sources-block.tsx"
    },
    {
      "path": "components/viewers/sample-data/image-sources.json",
      "content": "[\n  {\n    \"key\": \"title\",\n    \"label\": \"Title\",\n    \"value\": \"An Image is Worth 16x16 Words\",\n    \"source\": {\n      \"content\": \"An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.1772,\n        \"top\": 0.1034,\n        \"width\": 0.6457,\n        \"height\": 0.0446\n      }\n    }\n  },\n  {\n    \"key\": \"firstAuthor\",\n    \"label\": \"First author\",\n    \"value\": \"Alexey Dosovitskiy\",\n    \"source\": {\n      \"content\": \"Alexey Dosovitskiy\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.2313,\n        \"top\": 0.1739,\n        \"width\": 0.1314,\n        \"height\": 0.0113\n      }\n    }\n  },\n  {\n    \"key\": \"affiliation\",\n    \"label\": \"Affiliation\",\n    \"value\": \"Google Research, Brain Team\",\n    \"source\": {\n      \"content\": \"Google Research, Brain Team\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.4118,\n        \"top\": 0.2417,\n        \"width\": 0.196,\n        \"height\": 0.0112\n      }\n    }\n  },\n  {\n    \"key\": \"firstAuthorEmail\",\n    \"label\": \"First author email\",\n    \"value\": \"adosovitskiy@google.com\",\n    \"source\": {\n      \"content\": \"{adosovitskiy, neilhoulsby}@google.com\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.3258,\n        \"top\": 0.2575,\n        \"width\": 0.3679,\n        \"height\": 0.0119\n      }\n    }\n  },\n  {\n    \"key\": \"secondAuthor\",\n    \"label\": \"Second author\",\n    \"value\": \"Lucas Beyer\",\n    \"source\": {\n      \"content\": \"Lucas Beyer\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.3882,\n        \"top\": 0.1739,\n        \"width\": 0.0862,\n        \"height\": 0.0113\n      }\n    }\n  },\n  {\n    \"key\": \"model\",\n    \"label\": \"Proposed model\",\n    \"value\": \"Vision Transformer (ViT)\",\n    \"source\": {\n      \"content\": \"Vision Transformer (ViT)\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.4868,\n        \"top\": 0.4533,\n        \"width\": 0.1682,\n        \"height\": 0.0112\n      }\n    }\n  },\n  {\n    \"key\": \"benchmark\",\n    \"label\": \"Benchmarks\",\n    \"value\": \"ImageNet, CIFAR-100, VTAB\",\n    \"source\": {\n      \"content\": \"ImageNet, CIFAR-100, VTAB\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.2349,\n        \"top\": 0.4533,\n        \"width\": 0.2481,\n        \"height\": 0.0112\n      }\n    }\n  },\n  {\n    \"key\": \"venue\",\n    \"label\": \"Venue\",\n    \"value\": \"ICLR 2021\",\n    \"source\": {\n      \"content\": \"Published as a conference paper at ICLR 2021\",\n      \"anchor\": {\n        \"kind\": \"image_bbox\",\n        \"left\": 0.1765,\n        \"top\": 0.0361,\n        \"width\": 0.3024,\n        \"height\": 0.0112\n      }\n    }\n  }\n]\n",
      "type": "registry:file",
      "target": "@components/viewers/sample-data/image-sources.json"
    }
  ],
  "categories": [
    "primitives"
  ],
  "type": "registry:block"
}