import "./itinerary.css"; import type * as React from "react"; import { type ReactNode } from "react"; import { useRender } from "@base-ui/react/use-render"; import type { ColorName } from "./colors"; import { type DayRun } from "./day_runs"; import { type LifecycleStage } from "./shape_frame"; import { type StyleProps } from "./style_props"; /** WHEN in the day a stop happens — the label the reader sees and the number it * is ordered by, because "09:00" and "9 AM" sort differently as text. */ export interface ItinerarySlot { label: string; /** Any increasing number — only the ORDER is read. */ order: number; } /** What one stop COSTS or MEASURES. `value: null` is a figure NOBODY HAS STATED * and renders as a dash: a service printed at zero reads as free. */ export interface ItineraryFigure { value: number | null; currency?: string; unit?: string; } /** WHAT KIND OF STOP IT IS, as the word and the colour the spine's node is * painted in. Both halves: a colour nobody can decode is decoration. */ export interface ItineraryKind { label: string; color: ColorName; } interface ItineraryBase extends StyleProps { /** FOLD THE STOPS INTO DAYS — a head per day with its count and its sum, a * stay drawn once and marked on the days it runs through. OFF by default, and * spans and per-day sums exist only grouped. */ grouped?: boolean; /** DRAW THE SPINE — a rail down each day with a node per stop, coloured by the * stop's `kind`, which is the only thing the node can carry. Defaults to ON * wherever any stop states one. */ spine?: boolean; /** BCP-47 tag for the day words and the figures. Defaults to the active pack's. */ locale?: string; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } export interface ItineraryComposedProps extends ItineraryBase { /** `Itinerary.Day`s, each holding its own `Itinerary.Stop`s. */ children: ReactNode; rows?: undefined; } export interface ItineraryDataProps extends ItineraryBase { rows: readonly T[]; /** A stable identity per stop — the React key. Day + slot + title would * collide the moment two things happen at one time, which on an itinerary is * the ordinary case. */ rowKey: (row: T) => string; /** THE DAY THIS STOP BELONGS TO, as an ISO date: the runs are ordered by it as * TEXT, and "1 Oct" sorts before "22 Sep". */ day: (row: T) => string; /** WHERE IN THE DAY. Stops with a slot lead the day in slot order; one with * none closes it. */ slot?: (row: T) => ItinerarySlot | null; /** What happens — the stop's name and the door's accessible name. */ title: (row: T) => string; /** One neutral qualifier. Never a problem: a problem belongs on the surface * that can fix it. */ caption?: (row: T) => string | null; /** WHERE THE STOP STANDS, in the option's colour — one qualifier on the muted * line, at the line's own size and weight. `verdict: "fail"` keeps the * emphasis: the trip did not take that stop, so it also hollows the spine's * node, strikes its figure, and drops out of every count and sum. */ stage?: (row: T) => LifecycleStage | null; /** THE CONFIRMATION — a booking code, a PNR, a waybill — which is what the * reader quotes when they ring about the stop. */ reference?: (row: T) => string | null; /** The stop's figure, right-aligned and closing its first line. */ figure?: (row: T) => ItineraryFigure | null; /** WHAT KIND OF STOP IT IS. Given on any stop, the spine is drawn. */ kind?: (row: T) => ItineraryKind | null; /** HOW MANY DAYS THIS STOP COVERS, counting the one it starts on; `1` or * `null` is an ordinary stop. Drawn ONCE, on its first day, and the days it * runs through carry a quiet continuation mark. */ span?: (row: T) => number | null; /** The door onto one stop. Given, the WHOLE stop is one press target. */ onOpen?: (row: T) => void; /** ADD A STOP TO A DAY — the verb in that day's head, handed the day it was * pressed on, so the form opens with the date already answered. */ onAdd?: (day: string) => void; /** Reading a page at a time. While more is coming there is no total: a sum * over part of a set is a figure that will change without being wrong. */ more?: { hasMore: boolean; loading?: boolean; onLoadMore: () => void; }; /** The one line an empty itinerary stands on. Defaults to the kit's own words. */ empty?: string; /** CLOSE THE LIST WITH ITS SUM — the label only; the figure is derived from the * stops on screen, and `perDay` states each day's own in its head. A FAILED * stop is in neither. Needs {@link ItineraryDataProps.figure} and one currency * and unit across the set: two denominations have no sum, so the line draws a * dash. */ total?: { label: string; perDay?: boolean; }; children?: undefined; } export type ItineraryProps = ItineraryDataProps | ItineraryComposedProps; /** * A TRIP, READ A DAY AT A TIME — an itinerary, a delivery run, a roster of * shifts, a site-visit plan. Day heads in the kit's date words, each day's stops * as two-line items beneath, optionally on a spine whose nodes carry the kind of * stop each one is. * * ONE STOP IS A TWO-LINE LIST ITEM and one press target — it carries no controls * of its own. The first line is what happens and what it costs, right-aligned on * one edge shared by every day and by the closing total; the second is the muted * run of qualifiers, held to ONE LINE at every width, the caption being the only * run that gives way. The title is never clamped. * * REORDERING A DAY IS NOT HERE: a trip being ARRANGED is a `ReorderList` of * `ReorderItem`s, whose rail this one's is. */ export declare function Itinerary(props: ItineraryProps): React.ReactElement>; /** THE STOPS FOLDED INTO THE DAYS THIS DRAWS THEM AS — days ascending, each day * in slot order with an untimed stop closing it. EXPORTED because a caller that * PAGES over these rows has to walk the order on screen. */ export declare function itineraryRuns(rows: readonly T[], day: (row: T) => string, slot?: (row: T) => ItinerarySlot | null): DayRun[]; export interface ItineraryDayProps extends StyleProps { /** The day, as an ISO date. The head states it in the kit's date words. */ date: string; /** Derived from the stops given when omitted — a FAILED stop is not one of * them, and neither is a continuation mark. */ count?: number; /** The day's own sum, stated on the figure's edge. THE CALLER SUMS it, and * leaves the failed stops out. */ total?: ItineraryFigure | null; /** Add a stop to THIS day — the verb in its head. */ onAdd?: () => void; /** The verb's own words, where "stop" is not what this list's rows are. */ addLabel?: string; children: ReactNode; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** ONE DAY OF THE RUN. The head sits on the list's OWN left edge, never indented * to the spine, and is the list's accessible name for that day. */ declare function ItineraryDay(props: ItineraryDayProps): React.ReactElement>; export interface ItineraryStopProps extends StyleProps { /** What happens. Wraps rather than clamps, at every width. */ title: string; /** The day, as an ISO date — what LEADS the muted line in the flat list, * where no day head says it. Omitted under a day head. */ date?: string; /** `null` draws the box empty so the line under every stop starts on one x; * omitted draws no box at all. */ slot?: ItinerarySlot | null; /** The only run on the muted line that gives way: it truncates so the stage * and the reference keep their place. */ caption?: string | null; /** At the muted line's own weight. `verdict: "fail"` keeps the emphasis, * hollows the spine's node and strikes the figure. */ stage?: LifecycleStage | null; reference?: string | null; figure?: ItineraryFigure | null; kind?: ItineraryKind | null; /** This stop runs on past the day it is drawn in — the rail continues below it * in the kind's colour. */ spans?: boolean; /** This line is the quiet mark of a stop that began on an earlier day: no * figure, no qualifiers, no door, and a bar rather than a node. */ continues?: boolean; onOpen?: () => void; testID?: string; } /** ONE STOP — a two-line item, and one press target. The rail is the same anatomy * `ReorderItem` draws, its end segments transparent rather than absent so every * stop keeps one geometry, and DECORATIVE: the kind's own word and the stage * state in words what it carries. */ declare function ItineraryStop(props: ItineraryStopProps): React.JSX.Element; export declare namespace Itinerary { var Day: typeof ItineraryDay; } export declare namespace Itinerary { var Stop: typeof ItineraryStop; }