{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "segment-page-rail",
  "title": "Segment Page Rail",
  "description": "Vertical page rail for Segment[] documents with current-page following, scroll progress, and page selection.",
  "registryDependencies": [
    "@retab/segments",
    "@retab/segment-interaction",
    "@retab/page-ribbon",
    "@retab/utils"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/ui/segment-page-rail.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { type SegmentInteraction } from \"@/lib/segment-interaction\";\nimport { normalizePageCount } from \"@/lib/segments\";\nimport { cn } from \"@/lib/utils\";\n\nimport { PageRibbon } from \"./page-ribbon\";\nimport type { DocumentSegment } from \"./segmented-document-model\";\n\nexport type SegmentPageRailApi = {\n  setViewportElement: (element: HTMLElement | null) => void;\n  setPageElement: (page: number, element: HTMLElement | null) => void;\n  onPointerEnter: () => void;\n  onPointerLeave: () => void;\n  onScroll: () => void;\n};\n\nexport interface SegmentPageRailProps {\n  segments: DocumentSegment[];\n  pageCount: number;\n  currentPage?: number | null;\n  scrollProgress?: number | null;\n  interaction?: SegmentInteraction;\n  railApi: SegmentPageRailApi;\n  onSelectPage?: (page: number) => void;\n  onSelect?: (segment: DocumentSegment) => void;\n  showTicks?: boolean;\n  className?: string;\n}\n\nexport function SegmentPageRail({\n  segments,\n  pageCount,\n  currentPage,\n  scrollProgress,\n  interaction,\n  railApi,\n  onSelectPage,\n  onSelect,\n  showTicks = true,\n  className,\n}: SegmentPageRailProps) {\n  const total = normalizePageCount(pageCount);\n  if (total <= 0) return null;\n\n  const {\n    onPointerEnter,\n    onPointerLeave,\n    onScroll,\n    setPageElement,\n    setViewportElement,\n  } = railApi;\n\n  return (\n    <div\n      ref={setViewportElement}\n      data-slot=\"segment-page-rail\"\n      onPointerEnter={onPointerEnter}\n      onPointerLeave={onPointerLeave}\n      onScroll={onScroll}\n      className={cn(\n        \"border-border bg-background flex h-full min-h-0 flex-col overflow-hidden border-r px-3 py-6\",\n        className,\n      )}\n    >\n      <div\n        data-slot=\"segment-page-rail-content\"\n        className=\"relative min-h-0 flex-1\"\n      >\n        <PageRibbon\n          orientation=\"vertical\"\n          rows={[{ id: \"segment-page-rail\", segments }]}\n          pageCount={total}\n          currentPage={currentPage}\n          scrollProgress={scrollProgress}\n          interaction={interaction}\n          onSelectPage={onSelectPage}\n          onSelect={onSelect}\n          showTicks={showTicks}\n          className=\"h-full min-h-0\"\n        />\n        {Array.from({ length: total }, (_, index) => {\n          const page = index + 1;\n          const topPct = ((page - 0.5) / total) * 100;\n\n          return (\n            <span\n              key={page}\n              ref={(element) => setPageElement(page, element)}\n              aria-hidden\n              data-page-number={page}\n              data-slot=\"segment-page-rail-page-marker\"\n              className=\"pointer-events-none absolute left-0 h-px w-px opacity-0\"\n              style={{ top: `${topPct}%` }}\n            />\n          );\n        })}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/segment-page-rail.tsx"
    }
  ],
  "type": "registry:ui"
}