import "./table.css"; import { type ReactNode, type ReactElement } from "react"; import type * as React from "react"; import { useRender } from "@base-ui/react/use-render"; import { type ColorName } from "./color_tokens"; import { type AvatarSubject, type Picture } from "./avatar"; import { type DisplayFile } from "./file_thumbnail"; import { type RowLineProps } from "./row"; import { type OptionMark } from "./status"; import { type Reading } from "./reading"; import { type StyleProps } from "./style_props"; import { type SortState, type SortHeaderLabels } from "./sort_header"; import { type TableFitColumn } from "./table_fit"; import { type FoldedReading } from "./table_fold"; /** One column, shared by the header band and every row; the fit fields live on `TableFitColumn`. */ export interface TableColumn extends TableFitColumn { /** A non-word header — a ruler of positions — drawn in place of `label`, which still names the column * for the stacked overline and sort control. Never a way to restyle a label. */ header?: ReactNode; flex?: number; /** The column the register is named for, one per register. The fit may shed the column, but its owner * draws the cell elsewhere on the row (`shape_frame.tsx`), so the shed warning skips it. Unlike * `priority: "never"`, the column may leave the grid; its reading may not leave the row. */ signature?: boolean; /** The reading rides the subject's supporting line wherever no column seats it (`shape_frame.tsx`), so * shedding loses nothing and is not warned; the pile drops its line rather than say it twice. `"shed"` * rides under the subject on its own line, only when shed — for a reading the row is compared by, which * a clipped supporting line would lose. */ folded?: boolean | "shed"; /** In the pile, a short reading the row is scanned by rides the subject's line instead of its own * labelled line: stacked one per line they made a phone row four lines taller. */ piled?: "run"; /** The reading names itself — a status's dot and word, a person's face and name, a linked row, money in its * currency, a meter's bar — so folded onto the subject's line it rides without the column's label. Unmarked, * a figure (a column set right) says its label, and words say theirs only beside another of their kind. */ bare?: boolean; /** How many lines every cell in this column reserves (default one; `2` for a subject over its line). The * column's, because a centred cell with a caption otherwise lifts its first line above its neighbours'. * Not a clamp — `lines` on `CellStack`/`TextCell` bounds wrapping. */ lines?: 1 | 2; } /** Whether the register is a pile (`table_fit.ts`) — cells ask because the two modes spend opposite * resources. False outside a register. */ export declare function useRegisterStacked(): boolean; /** Whether this width shed that column — asked by a cell carrying another column's value, since the fit is * known only inside the register. False in a pile and outside a register. */ export declare function useRegisterShed(key: string): boolean; export declare function useRegisterShedOf(): (key: string) => boolean; /** Lines the enclosing column reserves ({@link TableColumn.lines}); one outside a register and in a pile, * where nothing lines up. */ export declare function useRegisterLines(): 1 | 2; /** Lines every row of the enclosing register is tall ({@link registerLines}): at two, a cell's secondary * reading takes the second line. One outside a register and in a pile. */ export declare function useRegisterRowLines(): 1 | 2; /** A statement riding a one-line supporting line is one line: at the column's two, a folded value wrapped * and centred half out of its box. */ export declare function withCellLines(lines: 1 | 2, children: ReactNode): ReactNode; /** Data, not a node: where its words may appear is the register's geometry, and one `label` names the box * in both forks (WCAG 2.5.3). */ export interface TableSelectAll { /** `"mixed"`: some rows ticked. One axis, matching `aria-checked`'s three values. */ checked: boolean | "mixed"; onChange: (checked: boolean) => void; /** The control's accessible name in both forks, and stacked also its visible text. */ label: string; /** Nothing to select — an empty page, or every row locked. */ disabled?: boolean; } export interface TableProps extends StyleProps { columns: TableColumn[]; sort?: SortState | null; /** A sortable heading pressed; pair with `cycleSort`, whose `first` says which way a press starts. */ onSort?: (key: string) => void; /** Localized a11y strings for sortable headers; English by default. */ sortLabels?: SortHeaderLabels; /** The header's bulk-select over the rows' `leading` checkboxes; set `leading` to reserve the gutter. */ selectAll?: TableSelectAll; /** Leading gutter (px) for rows with a `leading` slot. */ leading?: number; /** Counts the register: each row shows its position, and this total heads the gutter. Yours to pass, * since a paged or filtered register rarely counts its children (see `TableRowProps.ordinal`). Pass * {@link TableProps.counted} instead when the page states the total first. */ count?: number; /** Number the rows without a total heading; ignored when `count` is given. The gutter is reserved either * way. */ counted?: boolean; /** Wash the header band with the brand. Opt-in: noise on a small table inside a card. */ headerFill?: boolean; /** `false` omits the heading band, for a register awaiting its first read: an empty answer would take * headings back. */ heading?: boolean; /** Trailing gutter (px) for rows with a `trailing` slot. */ trailing?: number; /** Vertical alignment of a row's cells (default `center`, which resolves per cell). `top` aligns every * cell and gutter to one top edge, identical on single-line rows. **It is the fallback**: a ragged * register means unequal rows, fixed by {@link TableColumn.lines}. */ align?: "center" | "top"; children: ReactNode; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** The columnar register: `columns` once, so header and cell widths cannot drift; compose * `TableRow`/`TableCell`. A column the measured width cannot seat goes by `priority` onto the name's * line as its label and value, so the register never widens; only where the first column itself cannot * stand do the rows stack (`computeTableFit`). */ export declare function Table(props: TableProps): React.JSX.Element; /** Who or what a band's rows share where it has a face: a person, a row with a picture. */ export interface TableGroupFace { /** Its initials' source where it has no picture; the label names it. */ name: string; picture?: Picture | null; /** Default `person`. */ subject?: AvatarSubject; } /** The record a band's rows belong to — an invoice over the lines it covers — drawn as the kit's one row: its * file's preview leading, `label` its title, its line, stage, figure and acts. */ export interface TableGroupHead { /** The files the record holds; the first leads in the list's slot (an image, a video's frame, a paper's badge in * its tile), and a press opens them in the viewer in place. Empty, it holds none yet: the dashed tile with the * badge's ghost stands there. Omit for a record that keeps no file. */ files?: readonly DisplayFile[]; /** Its facts under the title — its date, its party — as a row's line. */ line?: RowLineProps["children"]; /** Where it stands: a status option's dot and word, or its own mark. */ stage?: { label: string; color?: ColorName; mark?: OptionMark; }; /** Preformatted, on the heading's right edge — the amount it bills. */ figure?: string; /** Its own verbs, and a verb on its rows (make one from the picked lines), last on the heading. */ acts?: ReactNode; /** The record's door: a press on the heading opens it; the file and the acts keep their own presses. */ onPress?: () => void; /** The door's name; required with `onPress`. */ accessibilityLabel?: string; } export interface TableGroupProps extends StyleProps { /** What the band's rows share — an action state, not a category; with `head`, the record's title. */ label: string; /** The face of what the label names — a band per person reads by that person's face — before the label, * at a name's rung (the label stands alone), initials where no picture. */ face?: TableGroupFace; /** The record the rows belong to, heading them as a row (`TableGroupHead`); a headed band does not fold. */ head?: TableGroupHead; /** Shown beside the label; almost always pass it, since a filter or page can cut the band. */ count?: number; /** One sentence under the label, for the consequence of being in this band that the label cannot carry. */ description?: string; /** A dot family for a band with a valence the label understates; most bands are neutral. */ color?: ColorName; /** The option the band is — its own mark (`OptionMark`) before the label in `color`'s ink, in the dot's place: * a band per payment method reads by its method's mark, as its rows' cells do. */ mark?: OptionMark; /** Controlled, since open bands are the register's state; the count keeps a folded band honest about * what it holds. */ collapsed?: boolean; /** Omit for an inert band — no chevron, no tab stop. */ onToggleCollapse?: () => void; /** A subtotal row of `TableCell`s under the band's columns; only while open, since a folded band already * carries its count. */ footer?: ReactNode; children: ReactNode; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** A titled band of rows, for states implying different actions — never a category a column already shows, * which is a sort. Separated by air, since the register keeps one line; `ordinal` restarts per band. */ export declare function TableGroup(props: TableGroupProps): ReactElement>; export type TableRowProps = StyleProps & { selected?: boolean; /** Part of a multi-select set — a resting tint the hover wash overrides. */ marked?: boolean; /** The row landed; pair with `useJustArrived`, which owns the diff. An overlay, since `background-color` * belongs to the interaction states; a read-only row washes its own box. */ justArrived?: boolean; /** Outside the door, before the cells (a checkbox); width is Table `leading`. */ leading?: ReactNode; /** The row's position, left of `leading` when the Table has `count`. Yours to compute (`offset + i + 1` * paged, restarting per band). A position, never an identity. */ ordinal?: number; /** Outside the door, after the cells: the row's ⋯ overflow. Beside `action` in the trailing gutter; * stacked, on the top line. Width is Table `trailing`. */ trailing?: ReactNode; /** The row's primary action: in the trailing gutter before `trailing`; stacked, right-aligned on the * content's bottom line. Reserve Table `trailing` for it. */ action?: ReactNode; /** A floor, not a height; stacked rows ignore it. **Only for density** — never because content did not * fit. */ minHeight?: number; /** Detail revealed beneath the row when `expanded`, for reading or light edits; outside the pressable so * its controls are not swallowed. */ detail?: ReactNode; /** Controlled: how many may be open is the caller's rule. */ expanded?: boolean; /** The rows' total under them: each cell one line, the name and its readings on the row's centre line * rather than the name set on the first of the two lines a row reserves. */ total?: boolean; children: ReactNode; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } & ({ /** Opens the record; the door and the full-row surface both call it. */ onPress: () => void; /** Required: the door is an empty overlay with no text to derive a name from. */ accessibilityLabel: string; /** The door, handed back for focus when a control inside the row removes itself: the one focusable * thing an act cannot disable, and it names the row. */ doorRef?: React.Ref; } | { onPress?: undefined; accessibilityLabel?: undefined; doorRef?: undefined; }); /** A denser floor's air: the row's own inset, capped at that floor less the pressable cell, halved. */ export declare function denseRowInset(minHeight: number): number; /** A register row: a full-bleed `PressableRow` over the cells, with an empty `RowFocusEntry` sibling as * the door — never their ancestor, since a button must not contain controls. Cells map to columns by * position; stacked, the same row renders as a pile. */ export declare function TableRow(props: TableRowProps): React.JSX.Element; export interface TableCellProps extends StyleProps { children: ReactNode; /** The row's raw value, read only in the pile, where readings wear labels. A value that says nothing * ({@link saysNothing}) draws no line — a zero in a column is its heading's answer. Unstated, the cell * is judged by what it draws. */ value?: Reading; /** What the reading says on the name's line when its column folds — a face and a name as the name * alone, say — since the line is one line of small words. Unstated, the cell's own node; a folded * form that says nothing (a no) puts nothing on the line, and no separator. */ folded?: ReactNode; /** What the folded reading adds after itself only while the line has room — a deadline's day after its * countdown — waiting behind the line's ellipsis before anything owed does. */ foldedDetail?: ReactNode; /** The words of `folded` in fewer characters, longest first — money without its fraction, then compact. * Where a phone's name leaves the reading beside it less room than its words, the first form that stands * whole is drawn: a figure is never cut inside its digits. */ shorter?: readonly string[]; /** The reading needs action now (a deadline past or close): folded, it leads the row's line. */ urgent?: boolean; /** The reading is a picture (a stack of thumbnails): folded, it leads the row's line whole, never waiting behind * its ellipsis. */ mark?: boolean; /** It holds a control: piled, its label stands on the control's line of words, at a control's height. */ control?: boolean; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; /** @internal — injected by `TableRow` from the column at this cell's position. */ _column?: TableColumn; /** @internal — injected by `TableRow`: this cell is in the capped column. */ _identity?: boolean; /** @internal — injected by `TableRow`; the Table is in stacked mode. */ _stacked?: boolean; /** @internal — injected by `TableRow`; the first cell (column 0), which heads a stacked row. */ _primary?: boolean; /** @internal — injected by `TableRow`: the cell the row is named by, which carries the fold. */ _name?: boolean; /** @internal — injected by `TableRow` on the name's cell: the columns this width folded. */ _folded?: readonly FoldedReading[]; /** @internal — injected by `TableRow` on a phone's name cell: the one reading's cell, drawn inside it. */ _beside?: ReactElement; } /** One cell; width and align come from the positional column. Stacked, a field cell is a `DetailRow` — the * drawer's own component — and the identity cell heads the row unlabelled. An empty stacked field draws * nothing, label included, or it reads as a failed load. */ export declare function TableCell(props: TableCellProps): React.JSX.Element | null;