/** * Table — rows and columns that stay lined up. * * React Native has no table layout: no ``, no column model, nothing that * makes the third cell of one row the same width as the third cell of the next. * A table here is therefore a stack of flex rows, and the columns exist only * because every row divides its width the same way. * * `columns` is the column model that closes that gap. Give the root one entry * per column and every `Table.Head` and `Table.Cell` takes its `flex`, `width` * and `align` from the entry at its own position in the row — so a column is * described once, at the top, and a row is just its contents. Without it the * sizing has to be repeated on every head and every cell, and the column drifts * the moment two of them disagree. * * ```tsx *
* ``` * * Props set on a head or a cell still win, for the one row that has to differ. * * Everything else it does own: the hairlines between rows and the missing one * under the last, the muted header and footer, the striping, the alignment of a * numeric column, and the sort arrow that turns over rather than swapping. * * ```tsx *
* * * Invoice * Amount * * * * * INV-001 * $250.00 * * *
* ``` * * `Table.Frame` is the same table in a widget shell, with the column headings * lifted onto the tray above the card. It takes the whole table and does the * lift itself, so the columns are still declared once. * * A table wider than the phone belongs in a horizontal scroller with a * `minWidth` on the table, not squeezed until the columns are unreadable — wrap * it in `ScrollFade` and the cut edge tells you there is more to the right. * * Long tables belong in a `FlatList` rather than in `Table.Body`, which renders * every row it is given. `Table.Row` takes `index` and `last` directly for that * case, since a virtualised row has no parent to read them from. */ import { type ReactNode } from 'react'; import { View, type ViewProps } from 'react-native'; import { type VariantProps } from 'tailwind-variants'; import { type AnimatedPressableProps } from '../../primitives/animated-pressable.js'; import { type TextProps } from '../../primitives/text.js'; type TableSize = 'default' | 'sm'; type CellAlign = 'start' | 'center' | 'end'; export type TableSortDirection = 'asc' | 'desc'; declare const tableVariants: import("tailwind-variants").TVReturnType<{ variant: { /** Hairlines only — the table sits directly on the page. */ default: {}; /** Framed and clipped, for a table that reads as its own card. */ outline: { root: string; }; }; size: { default: { row: string; headLabel: string; cellLabel: string; caption: string; }; sm: { row: string; headLabel: string; cellLabel: string; caption: string; }; }; }, { root: string; row: string; head: string; headLabel: string; cell: string; cellLabel: string; caption: string; }, undefined, { variant: { /** Hairlines only — the table sits directly on the page. */ default: {}; /** Framed and clipped, for a table that reads as its own card. */ outline: { root: string; }; }; size: { default: { row: string; headLabel: string; cellLabel: string; caption: string; }; sm: { row: string; headLabel: string; cellLabel: string; caption: string; }; }; }, { root: string; row: string; head: string; headLabel: string; cell: string; cellLabel: string; caption: string; }, import("tailwind-variants").TVReturnType<{ variant: { /** Hairlines only — the table sits directly on the page. */ default: {}; /** Framed and clipped, for a table that reads as its own card. */ outline: { root: string; }; }; size: { default: { row: string; headLabel: string; cellLabel: string; caption: string; }; sm: { row: string; headLabel: string; cellLabel: string; caption: string; }; }; }, { root: string; row: string; head: string; headLabel: string; cell: string; cellLabel: string; caption: string; }, undefined, unknown, unknown, undefined>>; export interface TableColumn { /** * Share of the leftover width, relative to the other columns. Defaults to 1, * so columns divide the row evenly. */ flex?: number; /** * Fixed width in pixels, for a column that must not move — an icon, a state * dot. Wins over `flex`. */ width?: number; /** * Which edge the column's content sits against. Use `end` for numbers: a * money column reads as a column only when the digits line up. */ align?: CellAlign; } export interface TableProps extends ViewProps, VariantProps { className?: string; /** * Row density. `Table.Row`, `Table.Head` and `Table.Cell` follow it, so it * only needs setting here. */ size?: TableSize; /** * Tint every other body row. Helps the eye track across a wide row; drop it * for a short table, where the stripes are louder than the data. */ striped?: boolean; /** * The column model: one entry per column, in order. Every `Table.Head` and * `Table.Cell` takes its `flex`, `width` and `align` from the entry at its * own position in the row, so a column is described once instead of on every * row. Anything set on a head or a cell still wins. * * Declare it outside render — a new array each frame renumbers every cell. */ columns?: TableColumn[]; children?: ReactNode; } export interface TableHeaderProps extends ViewProps { className?: string; children?: ReactNode; } export interface TableBodyProps extends ViewProps { className?: string; children?: ReactNode; } export interface TableFooterProps extends ViewProps { className?: string; children?: ReactNode; } export interface TableRowProps extends Omit { className?: string; /** Marks the row as the chosen one — for a table you pick from. */ selected?: boolean; disabled?: boolean; /** * Position in the section, for a row rendered outside `Table.Body` — a * `FlatList` item, say. Decides which rows a striped table tints. */ index?: number; /** * Whether this is the section's final row, for a row rendered outside * `Table.Body`. The last row drops its hairline so it does not double up with * the table's own bottom edge. */ last?: boolean; children?: ReactNode; } export interface TableHeadProps extends Omit { className?: string; /** * Share of the leftover width, relative to the other cells in the row. * Defaults to 1, so columns divide the row evenly. Without a `columns` model * on the root it must match the `flex` on the cells beneath it. */ flex?: number; /** * Fixed width in pixels, for a column that must not move — an icon, a state * dot. Without a `columns` model on the root it must match the `width` on the * cells beneath it. */ width?: number; /** * Which edge the column's content sits against. Use `end` for numbers: a * money column reads as a column only when the digits line up. */ align?: CellAlign; /** * Show the sort arrow without committing to a direction — the column can be * sorted, but is not the one being sorted by. Implied by `sortDirection`. */ sortable?: boolean; /** The direction this column is currently sorted in. Turns the arrow over. */ sortDirection?: TableSortDirection; /** Called on a tap. Supplying it makes the header a button. */ onPress?: AnimatedPressableProps['onPress']; /** Styles the header's text. */ labelClassName?: string; children?: ReactNode; } export interface TableCellProps extends ViewProps { className?: string; /** * Share of the leftover width, relative to the other cells in the row. * Defaults to 1. Without a `columns` model on the root it must match the * `flex` on the head above it. */ flex?: number; /** * Fixed width in pixels, for a column that must not move. Without a `columns` * model on the root it must match the `width` on the head above it. */ width?: number; /** * Which edge the cell's content sits against. Without a `columns` model on * the root, match the head above it. */ align?: CellAlign; /** Styles the cell's text. */ labelClassName?: string; children?: ReactNode; } export interface TableCaptionProps extends TextProps { className?: string; } export interface TableEmptyProps extends ViewProps { className?: string; children?: ReactNode; } export interface TableFrameProps extends Omit { className?: string; /** Caption on the tray, above the column headings. */ title?: ReactNode; /** Trailing slot on the title row — a button, a badge, a menu. */ action?: ReactNode; /** A line under the title, for what the table is counting. */ description?: ReactNode; /** Row density, as on `Table`. */ size?: TableSize; /** Tint every other body row, as on `Table`. */ striped?: boolean; /** The column model, as on `Table`. */ columns?: TableColumn[]; children?: ReactNode; } export declare const Table: import("react").ForwardRefExoticComponent> & { Frame: import("react").ForwardRefExoticComponent>; Header: import("react").ForwardRefExoticComponent>; Body: import("react").ForwardRefExoticComponent>; Footer: import("react").ForwardRefExoticComponent>; Row: import("react").ForwardRefExoticComponent>; Head: import("react").ForwardRefExoticComponent>; Cell: import("react").ForwardRefExoticComponent>; Caption: import("react").ForwardRefExoticComponent>; Empty: import("react").ForwardRefExoticComponent>; }; export {}; //# sourceMappingURL=index.d.ts.map