import { type ComponentType } from "react"; import { type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.js"; import { type AvatarProps } from "../../atoms/avatar/avatar.shared.js"; import { type IconName } from "../../atoms/icon/icon.js"; export type AvatarComponent = ComponentType; /** One event in the feed. */ export interface FeedItem { /** * Stable identity for this event, used as the row's React key. Supply it for * mutable or reordered feeds (the common timeline case is prepending the * newest event): without it the rows fall back to their array index, which * desyncs per-row state and press feedback when items are inserted at the * front or reordered. */ id?: string | number; /** Actor who performed the action, rendered bold (e.g. "Rachel Chen"). */ actor?: string; /** The action text, muted (e.g. "approved the request"). */ action: string; /** Optional target of the action, muted and trailing the action. */ target?: string; /** Relative timestamp, muted and small (e.g. "2 hours ago"). */ time: string; /** Photo URL for the avatar lead; falls back to initials from the actor. */ avatar?: string; /** * Leading Canvas glyph for the CONNECTOR node, named from the kit icon set * (e.g. `"shieldCheck"`, `"gitMerge"`, `"keyRound"`). Rendered through the * `Icon` atom, muted and decorative (the row's own text carries the meaning), * and it takes precedence over the actor's initials and the actor-less dot. * Reach for it on system or automation events, where a glyph names the kind of * event better than a pair of letters. The avatar lead ignores it: that row * leads with the person's photo or initials. */ icon?: IconName; } export interface FeedProps { /** Events to render, top to bottom. */ items?: FeedItem[]; connector?: boolean; avatar?: boolean; compact?: boolean; /** When set, each event row is pressable, reporting the row index. */ onItemPress?: (index: number) => void; /** * Render the rows through a windowed `FlatList` instead of mounting every row up * front, for large lists. Give the list a bounded height (via `style`, e.g. * `{ maxHeight: 400 }`) so it can scroll; without one it warns and renders eagerly * anyway. Default (omitted) mounts all rows, unchanged. */ virtualized?: boolean; /** E2E hook forwarded to the root element. */ testID?: string; /** Outer layout composition only (width/flex within a parent), never a restyle hook. */ style?: StyleProp; } export type Lead = "connector" | "avatar"; export interface FeedSkin { /** The card surface framing the feed (shape, border, fill, max-width). */ cardSurface: (t: ColorTokens) => ViewStyle; /** Connector surface padding by density (compact vs default). */ connectorPad: (compact: boolean) => ViewStyle; /** Inter-row vertical rhythm by density for the connector lead (dropped on last). */ connectorRowGap: (compact: boolean) => ViewStyle; /** Avatar row padding by density (compact vs default). */ avatarRowPad: (compact: boolean) => ViewStyle; /** The hairline rule between avatar rows; omitted on the last row. */ avatarDivider: (t: ColorTokens) => ViewStyle; /** The leading connector node (a small bordered circle). */ node: (t: ColorTokens) => ViewStyle; /** The vertical connector line under the node center. */ connectorLine: (t: ColorTokens) => ViewStyle; /** The node's initials type. */ nodeInitials: (t: ColorTokens) => TextStyle; /** The outer wrapping line (sizing only). */ lineText: TextStyle; /** The actor name (bold, foreground). */ actorLabel: (t: ColorTokens) => TextStyle; /** The action / target text (muted). */ actionLabel: (t: ColorTokens) => TextStyle; /** The relative timestamp (muted, small). */ timeLabel: (t: ColorTokens) => TextStyle; /** iOS/web dim on press of a row; Android uses a ripple instead (null). */ pressedOpacity: number | null; /** Android ripple over pressable rows; null on iOS/web. */ ripple: ((t: ColorTokens) => { color: string; borderless: boolean; }) | null; /** * Minimum effective touch-target height for a pressable row (HIG 44pt on iOS, * Material 48dp on Android). Rows already taller than this are unaffected; it * only floors the short final connector row (~40pt) up to the platform * minimum. 0 on web (pointer input, no finger-target rule; layout unchanged). */ minTarget: number; } export declare function createFeed(skin: FeedSkin, Avatar?: AvatarComponent): (props: FeedProps) => import("react").JSX.Element; //# sourceMappingURL=feeds.shared.d.ts.map