import { resolveRichCardImagePresentation } from '@linktr.ee/messaging-taxonomy' import React from 'react' import BubbleTail from '../LinkAttachment/components/_shared/BubbleTail' import CardShell from '../LinkAttachment/components/_shared/CardShell' import type { LinkAttachmentVariant } from '../LinkAttachment/components/_shared/CardShell' import { useChinPalette } from '../LinkAttachment/components/_shared/useChinPalette' import RichCardBody from './RichCardBody' import RichCardImages from './RichCardImages' import type { RichCardBaseProps } from './types' export interface RichCardCardProps extends RichCardBaseProps { variant: LinkAttachmentVariant } /** * The shared internal rich-card renderer, parameterised by surface. `Sent` * (dark) and `Received` (light) are thin wrappers over it. Composes * LinkAttachment's card chrome primitives (`CardShell`, `useChinPalette`, * `BubbleTail`) with the rich-card-specific image region + multi-action chin. */ const RichCardCard: React.FC = ({ variant, title, subtitle, subtitleLines, images = [], imagePresentation, actions, appIcon, accentColor, groupPosition = 'single', }) => { const presentation = resolveRichCardImagePresentation({ imagePresentation, images, }) const hasImages = images.length > 0 const isHero = hasImages && presentation === 'hero' // Accent derives only from a single on-screen hero image — a `fan` (or // image-less) card keeps the plain fill. Passing the hero URL through // `useChinPalette` reuses its hero-failure tracking so a broken hero drops // the accent with it, exactly as LinkAttachment does. const chin = useChinPalette({ variant, accentColor, layout: 'featured', thumbnailUrl: isHero ? images[0] : undefined, }) const tailVisible = groupPosition === 'single' || groupPosition === 'end' return ( {/* No `fixedHeight`: the image region owns a fixed height and the chin flows below at its natural height, so a card with a multi-line subtitle and several stacked actions grows instead of clipping. */} {hasImages && ( )} ) } export default RichCardCard