- Overview
- Anatomy
- Header
- Navigation
- Renderers
SegmentLegend is the "key" surface over a page-segmented result (partition
chunks or split subdocuments) — a compact map from color to label. It docks to a
document surface in three flavors: a flush bar, a floating overlay card,
or a vertical rail.
Hovering is a temporary preview. When nothing is hovered, currentPage derives
the highlighted segment. Clicking a segment only asks the host to navigate; it
does not persist category selection. Wire the legend to the same
useSegmentInteraction object as a
segment sidebar for a coordinated layout.
"use client";
import * as React from "react";
import { toSegments } from "@/lib/segments";
import { cn } from "@/lib/utils";
import {
SegmentLegend,
type SegmentLegendOrientation,
type SegmentLegendSide,In a split viewer
Docked to a split viewer over one ViT paper split result — the same legend placed three ways (a flush bar, a floating card, and a vertical rail). One shared interaction state dims the matching pages across every cell at once.
Split viewer · legend variants
One split result, three legend placements — bar, floating, and a vertical rail.
variant="bar"variant="floating"variant="plain" · vertical"use client";
import { LegendVariantsBlock } from "@/registry/new-york-v4/blocks/legend-variants-block";
// The legend on a real split viewer: one ViT paper split result rendered
// with all three placements — bar, floating, and a vertical rail — sharing one
// selection across every cell.
export function SegmentLegendSplit() {
return (
<div className="not-prose overflow-hidden rounded-xl border">Installation
pnpm dlx shadcn@latest add @retab/segment-legend
Usage
Reduce a partition or split result to Segment[] with toSegments, then render
the legend against your own interaction state:
import { toSegments } from "@/lib/segments";
import { SegmentLegend } from "@/components/ui/segment-legend";
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 (
<SegmentLegend
segments={segments}
variant="bar"
interaction={interaction}
currentPage={1}
/>
);
}The floating variant needs a relative parent to anchor against; side
controls which edge it docks to.
For caller-owned preview state, build the same interaction object with
useControlledSegmentInteraction; do not pass selection props to the legend.
API Reference
| Prop | Type | Description |
|---|---|---|
segments | Segment[] | Labels + pages + colors (use toSegments). |
interaction | SegmentInteraction | Shared transient preview state. |
variant | "bar" | "floating" | "plain" | How the legend attaches to the surface. Defaults to "bar". |
orientation | "horizontal" | "vertical" | Wrap/grid vs. rail layout. Defaults to "horizontal". |
side | "top" | "bottom" | "left" | "right" | Edge the legend docks to — drives the border (bar) or anchor (floating). |
density | "comfortable" | "compact" | Swatch + label scale. Defaults to "comfortable". |
onSelect | (segment: Segment) => void | Fired when a segment is clicked, after transient preview is cleared. |
currentPage | number | null | 1-based current page; segments that own it highlight when no preview exists. |
columns | number | Lay entries out on a grid of N columns (horizontal only). |
showUnusedToggle | boolean | Render a "Show all / Hide unused" toggle when some segments own no pages. |
showUnused | boolean | Controlled visibility of zero-page segments. |
defaultShowUnused | boolean | Initial zero-page visibility for uncontrolled usage. |
onShowUnusedChange | (showUnused: boolean) => void | Fired when the show-unused toggle changes. |
caption | ReactNode | A muted caption rendered under the entries. |
className | string | Container class. |
Source
"use client";
import * as React from "react";
import {
getSegmentInteractionState,
getSegmentSurfaceProps,
scopeSegmentInteraction,
type SegmentInteraction,
} from "@/lib/segment-interaction";
import { segmentDisplayLabel, segmentPageCount } from "@/lib/segments";
import { cn } from "@/lib/utils";