GitHub

FileViewerSegments

A navigable list of document segments with page ranges and confidence, driven by shared preview and current-page state.

SegmentSidebar is the "list" surface over a page-segmented result (partition chunks or split subdocuments). Each row shows a color swatch, label, page ranges, page count, and — when present — a confidence bar.

Hovering is a temporary preview. When nothing is hovered, currentPage derives the highlighted segment. Clicking fires onSelect so the host can scroll the document to the segment's first page; it does not persist category selection. Wire it to the same useSegmentInteraction object as a legend for a coordinated layout.

6 subdocuments

In a split viewer

Mounted as the left rail of a split viewer, the sidebar shares preview and current-page state with the legend and page timeline. Hover a row to dim the others everywhere; click to scroll the document to that subdocument's first page.

an-image-is-worth-16x16-words.pdf

Architecture Boundary

FileViewerSidebar owns file-viewer placement, width, collapse state, and the accessible label for the rail. SegmentSidebar owns only the segment-row model and interaction semantics. Nesting SegmentSidebar inside FileViewerSidebar is the intended composition when segments are the file navigation content.

Internally, SegmentSidebar uses providerless SidebarList* primitives. That keeps the row grammar aligned with the sidebar system without mounting an app sidebar provider: no cookie persistence, no global shortcut, and no viewport-level sidebar ownership.

Installation

pnpm dlx shadcn@latest add @retab/segment-sidebar

Usage

Reduce a partition or split result to Segment[] with toSegments, then render the sidebar against your own interaction state:

import { toSegments } from "@/lib/segments";
import { SegmentSidebar } from "@/components/ui/segment-sidebar";
import { useSegmentInteraction } from "@/components/ui/use-segment-interaction";
 
// partition: [{ key, pages }]   split: [{ name, pages }]
const segments = toSegments(result.output);
 
export function Example() {
  const interaction = useSegmentInteraction();
  return (
    <SegmentSidebar
      segments={segments}
      interaction={interaction}
      onSelect={(segment) => scrollToPage(segment.pages[0])}
      unitLabel="subdocument"
    />
  );
}

For caller-owned preview state, build the same interaction object with useControlledSegmentInteraction; do not pass selection props to the sidebar.

API Reference

PropTypeDescription
segmentsSegment[]Labels + pages + colors (use toSegments).
interactionSegmentInteractionShared transient preview state.
onSelect(segment: Segment) => voidFired when a segment is clicked, after transient preview is cleared.
currentPagenumber | null1-based current page; owning segments highlight when no preview exists.
unitLabelstringRow noun, e.g. "chunk" or "subdocument". Defaults to "segment".
showUnusedbooleanShow segments with zero pages too. Defaults to true.
classNamestringContainer class.

Source

segment-sidebar.tsx