import "./section_nav.css"; import type * as React from "react"; import { type ReactNode } from "react"; import { useRender } from "@base-ui/react/use-render"; import { type IconName } from "./icon"; import { type StyleProps } from "./style_props"; /** One stop on the outline. `issue` says where to look; the section still states * the condition itself beside the fields it concerns. */ export interface SectionNavItem { key: K; label: string; /** A glyph for the DESTINATION — the only place a record's section glyph is * ever drawn, the heading in the column being its words. Optional, because a * surface whose stops have no glyphs is a run of names. */ icon?: IconName; issue?: "warning" | "danger"; } export interface SectionNavProps extends StyleProps { /** In PAGE ORDER — the same order `useSectionNav` spies on. */ items: readonly SectionNavItem[]; /** From `useSectionNav().activeKey` — read by the BAR alone. No row is ever * drawn as current: a spy that follows the scroll can never reach the last * section of a page shorter than its viewport, so a highlighted row would * claim a place the reader is not in. Omit it where nothing spies the scroll. */ activeKey?: K; /** From `useSectionNav().jumpTo`. */ onJump: (key: K) => void; /** Rail when true, pinned bar when false. The CALLER decides, from its own * measured container — never from the window, which gives a drawer the page's * answer and draws the rail in a column with no gutter to hold it. */ wide: boolean; /** Where this record returns to — a `BackButton`, in both forms. Omit it where * the container already has one, because two exits are two exits. */ back?: ReactNode; /** Rail width. The gutter it floats in is the caller's arithmetic. */ railWidth?: number; /** The bar's horizontal gutter. A fill-less button shows no box, so its INK is * what lines up with the section titles below: pass the container's content * padding and the sheet subtracts the button's own text inset. */ barGutter?: number; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** * The record surface's outline, in its two forms. `useSectionNav` is the * scroll-spy half — offsets, `activeKey`, `jumpTo`; this is the CHROME half. * * Where the container affords a gutter, the outline is a RAIL floating in it. * Where it does not, the same list collapses to a pinned bar naming the CURRENT * section, which opens the list as a picker. Both render the same items. * * The rail is NAVIGATION and is rendered as one: pass `render={