import { type ComponentType, type ReactNode } from "react"; import { type ColorTokens, type ViewStyle, type TextStyle, type LayoutStyle } from "../../style/index.js"; import { type AvatarProps, type AvatarGroupProps } from "../../atoms/avatar/avatar.shared.js"; import { type BadgeProps } from "../../atoms/badge/badge.shared.js"; import { type ButtonProps } from "../../atoms/button/button.shared.js"; import { type Layout } from "./description-lists.styles.js"; /** One avatar in an `avatars` value row: a photo (`src`) or initials (`name`). */ export interface DescriptionListAvatar { src?: string; name?: string; } export interface DescriptionListItem { /** * The label. A string (or number) takes the layout's term type; any other node * renders as given (an icon beside a word, a Kbd), as DataTable takes node cells. */ term: ReactNode; /** * The data. A string (or number) takes the value type and the per-item forms below * (`badge`, `status`, `mono`, `copyValue`, `update`); any other node renders as given * in the value cell (a row of Badges, a link), which those forms do not restyle. */ value: ReactNode; badge?: boolean; status?: boolean; mono?: boolean; /** * Append a ghost "Copy" button after the value. Pressing it invokes the * list's `onCopy` callback with this string (the kit ships no clipboard * dependency; the consumer performs the write). */ copyValue?: string; /** Render the value as an overlapping avatar stack (composed AvatarGroup). */ avatars?: DescriptionListAvatar[]; /** Extra members beyond `avatars`, collapsed into the stack's "+N" chip. */ overflow?: number; update?: boolean; } export interface DescriptionListProps { items: DescriptionListItem[]; title?: string; subtitle?: string; inline?: boolean; twoColumn?: boolean; stacked?: boolean; divided?: boolean; /** * Rows: a 1 px top rule on every row, the first included, with the row padded 9 above * and below and the term hugging its content (a 120 floor, 14 to the value), the v4 * hand-off's accessibility-card rows. Wins over `divided`. */ ruled?: boolean; /** * Density: tightens the ruled rows to the v4 hand-off's semantics-card rows * (Component.dc.html line 263): 8 above and below the text, 12 to the value, the term a * fixed 110 column and the value at the top of its row. Only the ruled rows have a * compact step; a plain or divided list is unchanged by it. */ compact?: boolean; /** * The values as notes beside their terms: a text value in the small type and the muted * ink (400 13/19) instead of the full-weight foreground data, for a list that explains * each term (a key and its effect). A node value renders as given, and a platform skin * whose value detail is already the secondary ink keeps its type. */ muted?: boolean; card?: boolean; /** Fires when a row's inline editor commits (Enter or Save): the item index and the new value. */ onUpdate?: (index: number, value: string) => void; /** Fires with a row's `copyValue` when its "Copy" button is pressed. */ onCopy?: (value: string) => void; /** E2E hook forwarded to the root element. */ testID?: string; /** Composition within a parent only, never a restyle hook and never a width: the parent layout container provides the bounds. */ style?: LayoutStyle; } export type AvatarComponent = ComponentType; export type AvatarGroupComponent = ComponentType; export type BadgeComponent = ComponentType; export type ButtonComponent = ComponentType; export interface DescriptionListSkin { /** Card surface corner radius (the web card corner, the iOS 26 inset grouped list, the M3 card). */ cardRadius: number; /** Card corner curve: iOS continuous (superellipse); circular elsewhere (no-op off iOS). */ cardCurve: "circular" | "continuous"; /** Card surface elevation: a soft shadow on web, flat on the iOS grouped list + Material 3. */ cardShadow: (tokens: ColorTokens) => ViewStyle; /** Vertical gap between rows (and the rows-under-header group). */ rowGap: number; /** Card inner padding: all sides for a header-less card, horizontal inset for the header band + rows. */ cardPadding: number; /** Horizontal-row (inline / two-column) cross-axis alignment. */ rowAlign: "baseline" | "center"; /** Horizontal-row minimum height (iOS 52pt Lists row); omit for content height. */ rowMinHeight?: number; /** Divided-row bottom padding beneath the hairline rule. */ dividedPadBottom: number; /** Ruled-row metrics: the padding above and below the text, the term column's floor, and the term-to-value gap. */ ruled: { rowPadY: number; termMinWidth: number; gap: number; }; /** Compact ruled-row metrics: the padding above and below the text, the term's fixed column, the term-to-value gap, and the row's cross-axis alignment. */ ruledCompact: { rowPadY: number; termWidth: number; gap: number; align: "flex-start" | "center"; }; /** Horizontal-row term type (size / line-height / weight / color / tracking). */ termType: (t: ColorTokens) => TextStyle; /** Horizontal-row value type (size / line-height / weight / color / tracking). */ valueType: (t: ColorTokens) => TextStyle; /** The `muted` value type: the note beside its term. Omitted, the value keeps `valueType` (a skin whose value is already the secondary ink). */ mutedValueType?: (t: ColorTokens) => TextStyle; /** Stacked-layout term tracking (the small uppercase muted label). */ stackedTermTracking: TextStyle; /** Stacked-layout value type (full-weight foreground; per-OS tracking). */ stackedValueType: (t: ColorTokens) => TextStyle; /** Card header title type (size / line-height / weight / color / tracking). */ headerTitleType: (t: ColorTokens) => TextStyle; /** * The v4 hand-off's inset card (the web and Android skins): the card pads its whole * content, header included (`cardPadding` across, `cardPadY` down), the header's rule * runs inside that inset, and every row carries `rowPadY` above and below its text. * Omitted, the header band runs edge to edge with its own inset (the iOS grouped list). */ inset?: { cardPadY: number; rowPadY: number; headerPadBottom: number; }; /** Header subtitle type; omitted, the shared 12/16 muted line. */ headerSubtitleType?: (t: ColorTokens) => TextStyle; /** Stacked-layout term type; omitted, the shared 12/16 uppercase muted label with `stackedTermTracking`. */ stackedTermType?: (t: ColorTokens) => TextStyle; } export declare function layoutOf(p: DescriptionListProps): Layout; export type Rows = "ruled" | "divided"; export declare function rowsOf(p: Pick): Rows | null; export type Density = "compact"; export declare function densityOf(p: Pick): Density | null; export type ValueInk = "muted" | "default"; /** The value ink axis: `muted` sets a text value as a note beside its term; otherwise the full-weight data. */ export declare function valueInkOf(p: Pick): ValueInk; export declare function valueFormOf(item: Pick): "status" | "badge" | "mono" | "plain"; /** * Build a DescriptionList component from a platform skin and the platform-correct * composed atoms. * * The composed atoms (Badge / Button) are passed in by each platform's thin * `.ios`/`.android` file, so a value row's status/metadata Badge and the trailing * Update link match the list's platform on every build path. This matters for the * WEB docs 3-up preview: a bare barrel import always resolves the WEB atoms in a * browser bundler, which would paint web-styled atoms inside the iOS/Android rows; * each platform file passes its own `.ios`/`.android` atoms so the row reads * native. On a real device Metro resolves the right atoms by extension regardless, * so the defaults (the web base) are correct there too. The iOS/Android Button * skins also carry the native minimum touch target (skin.minTarget: HIG 44pt / * M3 48dp), so threading them lifts the Update affordance to a compliant target. */ export declare function createDescriptionList(skin: DescriptionListSkin, Badge?: BadgeComponent, Button?: ButtonComponent, Avatar?: AvatarComponent, AvatarGroup?: AvatarGroupComponent): (props: DescriptionListProps) => import("react").JSX.Element; //# sourceMappingURL=description-lists.shared.d.ts.map