import "./tabs.css"; import type * as React from "react"; import { type TabsRootProps } from "@base-ui/react/tabs"; import { type ColorName } from "./colors"; import { type PartAccessor, type StyleProps } from "./style_props"; /** ONE tab's anatomy, whichever order the strip is in. */ type TabItemPart = "tab" | "surface" | "line" | "status" | "label" | "count" | "caption"; /** * `free` — named destinations the reader picks in any order, wrapping onto a * second row. `sequence` — a lifecycle the WORK follows: a chevron between * stages, a rule before the outcomes, and one line that scrolls, because a * wrapped flow reads as two pipelines. */ export type TabsOrder = "free" | "sequence"; export interface TabOption { label: string; value: T; testID?: string; /** A small status dot before the label — set only when the tab's area needs * attention (a blocker / missing item). Omit for the resting state. */ status?: ColorName; /** How many rows the tab's band holds, shown after the label. * * A PROP, never a count formatted into `label`, which would be a second copy * of a number the screen already computes. Yours to pass because it is rarely * the child count — a paged or filtered band counts what matched. */ count?: number; /** A second line under the label — one figure the band is read by, already * formatted. Once ANY tab in a strip carries one, every tab reserves the * line. */ caption?: string; } /** * A stage of a SEQUENCE: whether the reader WALKS to this tab or LEAVES at it. * Outcomes are drawn last, past a rule and with no chevrons — they are * alternatives rather than the next step. * * `all` is the band that is not a stage. It opens the strip, fenced off the flow * by the same rule the outcomes stand behind. * * `place` is a sequence's question, so only a sequence's options can carry it. */ export interface TabStage extends TabOption { place?: "flow" | "outcome" | "all"; } interface TabsBase extends StyleProps { /** Accessible name of the tablist. */ accessibilityLabel: string; selectedTab: T; onSelectTab?: (value: T) => void; testID?: string; ref?: React.Ref; render?: TabsRootProps["render"]; } export type TabsProps = (TabsBase & { order?: "free"; options: TabOption[]; }) | (TabsBase & { order: "sequence"; options: TabStage[]; }); /** * NAMED DESTINATIONS WITHIN ONE SCREEN — a real WAI-ARIA tablist over Base UI's * Tabs, which owns the roving tabindex, the arrow/Home/End model and the * selected tab's tab stop. * * `order` is the axis. A `sequence` is the lifecycle desk: the tabs are the * stages a population is spread across, and the strip never re-ranks — the array * order is the process. * * It renders the BAR only; the panel below it is the caller's, which is why the * tabs carry no `aria-controls`. A control that changes a PARAMETER of one view * is a `ChoiceStrip`. */ export declare function Tabs({ accessibilityLabel, options, selectedTab, onSelectTab, order, testID, render, ref, ...props }: TabsProps): React.JSX.Element; /** ONE tab — the anatomy both orders share, so the two strips cannot drift. It * takes the STRIP's part accessor rather than building its own, which is what * makes every strip render `lotics-tabs__tab`. */ export declare function TabItem(props: { option: TabOption; part: PartAccessor; /** Reserve the caption line even on a tab that carries none. */ captionSlot: boolean; }): React.JSX.Element; export {};