import "./record_page.css"; import type * as React from "react"; import { type ReactNode } from "react"; import { useRender } from "@base-ui/react/use-render"; import { type DangerAction } from "./danger_section"; import { type IconName } from "./icon"; import { type RecordLabels } from "./locale"; import { type RecordContact, type RecordSummaryMetric } from "./record_summary"; import { type IdentityMark } from "./shape_frame"; import { type StyleProps } from "./style_props"; /** One block of the record's work — a heading, a body, and what is wrong in it. */ export interface RecordSection { key: K; label: string; /** THE SECTION'S GLYPH, AND THE RAIL IS THE ONLY PLACE IT IS DRAWN. REQUIRED, * because one item without a glyph indents its own label and the list stops * being a list (`templates.md`). */ icon: IconName; /** One clause under the heading — the section's content or a domain rule, * never how the widgets in it behave. */ description?: string; /** The ADD act for this section, on the heading row at the right edge. */ action?: ReactNode; /** What is wrong HERE. The attention band carries it with a jump; the section * still states the condition beside the fields it concerns. */ issue?: { level: "warning" | "danger"; text: string; }; children: ReactNode; } /** THE RECORD'S SUBJECT, and how big it is drawn. `mark` is the register row's * own descriptor — one subject, one spelling on both surfaces. */ export interface RecordMark extends IdentityMark { /** `mark` (the default) — the identity mark at the rung a register row marks * the same subject at, riding the title's own line. `hero` — the picture at * media scale, 16:9, on a line above the name; with no picture, the quiet * ground at that same size. */ display?: "mark" | "hero"; } export interface RecordPageProps extends StyleProps { /** Identity — the record's name, as a reader says it. */ title: string; /** THE RECORD'S PICTURE, leading the identity, drawn from the kind. A record * with no likeness passes `image: null` rather than omitting the mark, so a * subject that HAS a picture kind still reads as one. {@link RecordMark}. */ mark?: RecordMark; /** Provenance: a reference, a date. ONE string — the app joins it. Never a * metric; that is `figure`. */ subtitle?: string; /** HOW TO REACH THE SUBJECT — one wrapping row of small links under the * subtitle. Each entry's `kind` picks its glyph and, where the scheme is * universal, its destination ({@link RecordContact}). */ contacts?: readonly RecordContact[]; /** THE headline figure. At most one: a second belongs in the section that * owns it. A READING ({@link RecordSummaryMetric}); the fact that owns the * number is where it is changed. */ figure?: RecordSummaryMetric; /** The record's acts — print, export, share, edit — at the header's right * edge. */ actions?: ReactNode; /** THE RECORD'S MONEY — a `MoneyBand` under the header and above the attention * band, because the header is identity and ONE figure (`templates.md` rule * 7). Drawn only once the record IS one. */ band?: ReactNode; /** Where this record returns to, named. The rail opens with it; where there is * no rail and no bar, it is the header's own first line. */ back: { label: string; onPress: () => void; }; sections: readonly [RecordSection, ...RecordSection[]]; /** THE RECORD'S DESTRUCTIVE ACTS, fenced in a `DangerSection` last — each * DECLARED, with the `ConfirmRequest` it raises. Not a node: the standard path * has to be the one that cannot ship an unconfirmed delete under a heading * that says the act is irreversible. */ danger?: { /** ONE sentence naming the consequence — what goes with the record. The * heading says the zone is dangerous; only this says why. */ description?: string; actions: readonly [DangerAction, ...DangerAction[]]; }; loading?: boolean; error?: { message: string; onRetry?: () => void; }; /** The id names no record. */ missing?: boolean; labels?: Partial; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** * THE RECORD HALF OF `[tabs] + list → record` — one frame, so the answer to * "what does a record page look like" stops being per-app. * * It answers, in this order: WHICH record is this (the header, short) · is * anything WRONG (the attention band) · the WORK, one section under another in * ONE reading column · the way OUT (back, the danger zone). * * Beside the column, where the page can seat one ({@link RAIL_DOCK_WIDTH}), * floats a rail — NAVIGATION and nothing else — over a gutter the layout * reserves, mirrored on the other side so the column stays centred; under that * width the same `SectionNav` is one pinned bar over the page. * * It does NOT own the section bodies, the words of anything the app knows, or * which sections are in trouble — `issue` is the app's derivation. */ export declare function RecordPage(props: RecordPageProps): ReactNode;