import { useStatus } from "@charcuterie/logic" import type { ComponentPropsWithRef, ReactNode, } from "react" import { useEffect, useRef } from "react" import { UnstyledLink } from "../RouterLink/UnstyledLink.tsx" import { Skeleton } from "../Skeleton/Skeleton.tsx" import { toClassName } from "../toClassName.ts" import { mediaTransitions } from "./mediaStatus.ts" export type MediaTileRatio = "poster" | "square" | "video" export type MediaTileProps = Omit< ComponentPropsWithRef<"figure">, "children" > & { /** * Required. The one thing three hand-rolled poster grids all * omit — and a 200-tile page of unnamed images is unnavigable * rather than merely imperfect. */ alt: string aspectRatio?: MediaTileRatio /** A `Badge`, usually. Pinned inside the media box. */ badge?: ReactNode /** Shown in place of the image when it fails. */ fallback?: ReactNode /** Untruncated content beneath the title and subtitle. No nested controls in an interactive tile. */ details?: ReactNode /** Keep the entire object visible, or fill the frame. */ imageFit?: "cover" | "contain" /** Put a thumbnail beside the caption for a compact list. */ layout?: "vertical" | "horizontal" isTitleTruncated?: boolean href?: string /** * Makes the tile a button. Hover, focus-visible and * `cursor-pointer` come with it — wrapping `MediaTile` in a * bare ` ) : ( <> {media} {caption} )} ) }