import { type ComponentType, type ReactNode } from "react"; import { type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.js"; import { type AvatarProps } from "../../atoms/avatar/avatar.shared.js"; export type AvatarComponent = ComponentType; /** * Compact density overrides for a menu-header-sized identity row: a tighter row gap, a * smaller leading icon box, and the title/description type stepped down one size. The * leading avatar shrinks via Avatar's own `small` size (28px), so it carries no field * here. Applied on top of the base skin values only when the `compact` prop is set. */ export interface MediaObjectDensity { /** Tighter row gap between the leading media, content column, and trailing slot. */ containerBase: ViewStyle; /** Smaller leading icon box: size + corner radius (the tinted fill comes from shared). */ iconBox: ViewStyle; /** Compact title type: size / line-height / weight / tracking (the color comes from shared). */ title: TextStyle; /** Compact description type: size / line-height / tracking (the color comes from shared). */ description: TextStyle; } export interface MediaObjectSkin { /** Row gap between the leading media, content column, and trailing slot. */ containerBase: ViewStyle; /** bordered card surface: corner radius + border width + padding (+ elevation). The * card fill (which reads the tokens and follows light/dark; the card stays SOLID * under glass) is supplied by shared; the skin carries the shape/density/shadow. */ borderedSurface: ViewStyle; /** bordered-card border-color resolver. web/iOS paint the hairline tokens.border; on * Android the M3 ELEVATED card separates by elevation, not an outline, so it returns * "transparent" while keeping the border WIDTH so content metrics stay identical * across platforms. Omit to default to the hairline tokens.border. */ borderedBorderColor?: (tokens: ColorTokens) => string; /** Leading icon box shape: size + corner radius (the tinted fill comes from shared). */ iconBox: ViewStyle; /** The glyph inside the icon box: type size/weight/tracking (the primary color comes from shared). */ iconGlyph: TextStyle; /** Content column layout: min-width 0 + flex + the title/description gap. */ content: ViewStyle; /** Title type: size / line-height / weight / tracking (the color comes from shared). */ title: TextStyle; /** Description type: size / line-height / tracking (the color comes from shared). */ description: TextStyle; /** Body paragraph type: size / line-height / tracking (the color comes from shared). */ body: TextStyle; /** Trailing meta type: size / line-height / tracking (the color comes from shared). */ meta: TextStyle; /** Trailing action wrapper: shrink-0. */ actionBox: ViewStyle; /** Press opacity dim for iOS/web (null on Android, where the ripple carries it). */ pressedOpacity: number; /** * Minimum effective touch height for a BARE (non-bordered) tappable row, applied as * a native minHeight so the tap target reaches the platform minimum (HIG 44pt on iOS, * Material 48dp on Android) without changing web layout (web = 0). A bordered row is * already tall enough from its padding, so this only backstops the bare row. */ minTarget: number; /** Compact-density overrides (row gap, icon box, title/description type) for the * `compact` menu-header row; applied on top of the base values when `compact` is set. */ compact: MediaObjectDensity; } export interface MediaObjectProps { /** Primary line: the bold heading (e.g. a person's name). */ title?: string; /** Secondary line: muted supporting text under the title (e.g. a role or email). */ description?: string; /** Optional longer body paragraph rendered below the description. */ body?: ReactNode; /** Trailing metadata text pinned to the right (e.g. "2h ago", "admin"). */ meta?: string; /** Initials for the leading avatar (e.g. "RC"); rendered as {avatar}. */ avatar?: string; /** Photo for the leading avatar (a URI string or a bundled `require(...)` image); takes precedence over initials. */ src?: string | number; /** A leading icon glyph rendered in a tinted square box (stands in for an SVG icon). */ icon?: ReactNode; /** A trailing action node (e.g. a