import "./row.css"; import type * as React from "react"; import { type ReactElement, type ReactNode } from "react"; import { useRender } from "@base-ui/react/use-render"; import { type StyleProps, type TriggerProps } from "./style_props"; import { type TextProps, type TextSize, type TextWeight } from "./text"; import { type TextColor } from "./text_ink"; /** * How tall the band stands — the surface's statement, since one anatomy reads at several rhythms. * - `beat` — a subject in a list (`--lotics-row-beat`), keeping its own air once it outgrows the beat. * - `air` — a stack whose rows touch: no floor, only the row's own air (`--lotics-row-inset`). * - `band` — a register cell (`--lotics-register-row`). * - `line` — a statement line, at the control's content height. * - `rung` — a position in a run: no floor, the run's gap spaces it. */ export type RowDensity = "beat" | "air" | "band" | "line" | "rung"; /** The band is the press target and names where it goes; controls ride `Row.Lead` and `Row.Acts`, above * the door. */ type RowDoor = { onPress: () => void; /** The door is empty, so it names the destination ("Open ORD-1042"). */ accessibilityLabel: string; /** The open record — the persistent ground. */ selected?: boolean; /** Part of a ticked set — the same ground; the tick tells them apart. */ marked?: boolean; /** The door toggles an in-place reveal, announced open or shut; unstated, it goes somewhere. */ expanded?: boolean; /** The row read IN FULL on a tile of its own — a message, a note, a signal: its long text whole in * `Row.Body`, its short facts on its line, its acts as buttons on it — never a table row one opens to * read. The tile's hairline and inset; a list of them stands `CARD_GAP` apart. */ card?: boolean; expected?: never; } | { onPress?: never; accessibilityLabel?: never; selected?: never; marked?: never; expanded?: never; card?: never; /** A slot the list expects and no row fills yet — a fee by its type, a paper by its kind: the title * names the key, quiet (muted, regular), and the row opens nothing; the caller seats the inputs that * fill it in the row's own places. */ expected?: boolean; }; /** A row may be an overlay trigger, so `TriggerProps` reach its element. */ export type RowProps = StyleProps & Omit & RowDoor & { density: RowDensity; /** A register cell under a right-aligned heading keeps the right edge. */ align?: "left" | "right" | "center"; /** The controls are columns (editors, a derived figure), so a narrow band folds them under the pair; a * lone verb stays beside it, two stand under it on a phone. Stage and figure fold on every row (`row.css`, * THE FOLD). */ fold?: boolean; children: ReactNode; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; }; /** `--lotics-lead-gap`, for a column budgeting a row before it is drawn. */ export declare const ROW_GAP = 10; /** Between two `card` rows of a list — the card grid's gap, more than a card's own inset air. */ export declare const CARD_GAP = 16; /** * One row anatomy — lead, title, supporting line, stage, figure, acts and body. Every row-shaped * surface is this: it states layout and data, and the parts, alignment and gaps come from here * (`dev/row_geometry.ts` is the proof). * * ```tsx * * * Northwind * {["Hà Nội", "Wholesale"]} * * 1.200.000 ₫ * * ``` */ export declare function Row(props: RowProps): React.JSX.Element; /** The register's pressable surface, so wash and states match; the empty door carries keyboard and name. */ declare function RowDoor(props: RowProps & { onPress: () => void; }): React.JSX.Element; /** @internal — what a folded reading adds after itself only while the line has room (a deadline's day). */ interface Detail { detail: ReactNode; } type Said = ReactNode | Reference | Attention | Detail | LineMark; export declare function isReference(entry: unknown): entry is Reference; interface RowPartProps extends StyleProps { children?: ReactNode; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** Top-set, so a wrapping title does not slide it; a mark with no `size` takes its block's rung * (`identityRung`). */ declare function RowLead({ dense, picture, ...props }: RowPartProps & { /** A register cell's lead. */ dense?: boolean; /** The lead is the row's picture — its image, a video's frame, a paper's tile, its placeholder, or the face of the * person or organisation it is: in a list every lead stands in the list's one slot, each mark at its natural * size in it (`markInSlot`), centred. */ picture?: boolean; }): React.JSX.Element; export interface RowTitleProps extends Omit { /** Words, a node, or a run of words and references read as one title (`Issued to` + `PO-0412`). */ children?: ReactNode | Reference | readonly Statement[]; size?: TextSize; weight?: TextWeight; color?: TextColor; /** Unstated, the subject wraps rather than lose a word; `"container"` as `Text`'s. */ lines?: TextProps["lines"]; decoration?: "line-through"; align?: "left" | "right" | "center"; } /** Words take the row's type; a node draws itself. */ declare function RowTitle(props: RowTitleProps): React.JSX.Element; /** A code — a document number, a record key — drawn as one unbreakable run so `PO-` and `0412` never * split; a door where it opens what it names. */ export interface Reference { reference: string; onPress?: () => void; } export type Statement = string | Reference; /** Words needing action (`8 days overdue`, a check standing on the row): the muted line would bury them, * so they take their tone's ink — danger unless stated — and they are owed, never shed: on a register's * one line they never wait behind its ellipsis, cut as prose at worst. */ export interface Attention { attention: string; tone?: "danger" | "warning" | "muted"; /** How many more stand behind these words, said after them (`+2`). */ more?: number; /** What the short words stand for, whole (`Expired` for the sentence saying since when): a tab stop whose * tooltip it is at a desk, on hover and keyboard focus, and its accessible name; a line break starts a * line. Where a register's line cannot seat the words whole, they shorten to the tone's mark and `more`. */ tooltip?: string; } /** A picture on the line — a stack of thumbnails, never words: it cannot be cut as words are, so on a register's * one line it never waits behind the ellipsis, the runs after it giving way first. */ export interface LineMark { mark: ReactElement; } export type LineStatement = Statement | Attention | LineMark; /** Kept as a run so a narrow width drops whole statements rather than clipping a joined string. */ export type LineStatements = LineStatement | readonly LineStatement[]; export interface RowLineProps extends StyleProps { /** Words take the line's rung and ink, a reference is unbreakable, a node keeps its own; a silent * statement draws nothing and no separator. */ children?: Said | readonly Said[]; size?: TextSize; /** A statement carries a mark, so the line box is the mark's height and the mark sits inside the clip. */ marked?: boolean; /** Keeps the empty line's box, so a column of two-line cells shares one height. */ hold?: boolean; /** What the columns say beside the pair, repeated first on the line once the band is too narrow to seat * them. */ folded?: ReactNode | readonly ReactNode[]; /** Readings the register had no column for, after the line's own: while one draws, the line hides none * whole, since a hidden reading reads as absent — it takes the lines they need, or with `oneLine` keeps * to one line that ends in an ellipsis. */ kept?: Said | readonly Said[]; /** A register's row: every statement keeps to this one line, run together as words and cut by an * ellipsis inside the last it reaches — never a statement dropped whole, never a bare ellipsis. */ oneLine?: boolean; testID?: string; } /** One line at every width with whole statements: the box clips and an unseatable statement wraps out * entire — unless it has `kept` statements, when it takes the lines they need — or, in a register's row * (`oneLine`), every statement runs on as words on one line cut by an ellipsis inside the last it * reaches. The `·` is the sheet's. */ declare function RowLine(props: RowLineProps): React.JSX.Element | null; declare function RowStage(props: RowPartProps): React.JSX.Element; export interface RowFigureProps extends RowPartProps { size?: TextSize; weight?: TextWeight; color?: TextColor; decoration?: "line-through"; /** Struck and muted but kept, so the column still adds up by eye. */ struck?: boolean; } /** On the subject's line at the right edge; a money string never wraps. */ declare function RowFigure(props: RowFigureProps): React.JSX.Element; /** On the trailing edge above the door, so each keeps its press: centred on the row across every line of the pair, as * the stage and the figure are (`row.css`). */ declare function RowActs(props: RowPartProps): React.JSX.Element; /** The row's longer content under the pair — long text read whole, a line's annotations — on the title's left edge, * held to no line, even in a register's cell; on a phone it runs the row's width as its line does. */ declare function RowBody(props: RowPartProps): ReactElement>; export declare namespace Row { var Lead: typeof RowLead; } export declare namespace Row { var Title: typeof RowTitle; } export declare namespace Row { var Line: typeof RowLine; } export declare namespace Row { var Stage: typeof RowStage; } export declare namespace Row { var Figure: typeof RowFigure; } export declare namespace Row { var Acts: typeof RowActs; } export declare namespace Row { var Body: typeof RowBody; }