Skip to content
Component installs need the registry setup
VegaStack Design

Media Card

A record as a card — an image, the title, a meta line, a badge and an actions menu — where the whole card is one link.

Status
stable
Since
0.23.10
Accessibility pattern
one link named by the title, menu above the link

Last updated

Aurora Downlight
8 products · 3 sub-families3 missing specs2h ago

Install

Add Media Card from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.

pnpm dlx shadcn@latest add @vegastack/media-card

The same command installs the registry items it composes: @vegastack/thumbnail.

Usage

import { MediaCard } from "@/components/ui/media-card";

<MediaCard
  href={`/families/${f.id}`}
  linkRender={<Link href="" />}
  image={f.imageUrl}
  fallback={<BrandMark />}
  title={f.name}
  meta="8 products · 3 sub-families"
  badge={
    <Badge variant="warning">
      <TriangleAlert aria-hidden />3 missing specs
    </Badge>
  }
  timestamp={<RelativeTime date={f.updatedAt} format="suffix" />}
  actions={<RowActionsMenu label={f.name} actions={actions} />}
/>;

MediaCard is one record in a card grid: a 48px Thumbnail on the left, the title, one meta line (meta, then the badge, then the timestamp), and the ⋯ menu on the right, top-aligned with the title's first line (never centred on the text block). With href the whole card is a link — the title is the link, stretched over the card — and it never underlines. DataList's grid view renders one per row.

Aurora Downlight
8 products · 3 sub-families3 missing specs2h ago

Examples

Fallback image

A record with no image shows fallback — the app's brand mark.

Beacon Track
5 products3d ago

Large

size="lg" puts a 16:9 image on top, for records whose picture matters.

Cove Linear
12 products · 4 sub-families3 missing specs

Without an image

A card with neither image nor fallback has no image area, and surface={false} drops the card's own border for a host that owns the surface, such as a Board card.

Send quote to Arora Builders
Due today · High

API Reference

PropTypeDefaultDescription
title*React.ReactNode—The record's name — the card's link text.
actionsReact.ReactNode—The ⋯ slot on the right — a RowActionsMenu. It shows on hover and on focus, and always on a touch screen; it sits above the card's link, so it never follows it.
badgeReact.ReactNode—A badge after the meta — a status, or a warning pill (<Badge variant="warning">).
fallbackReact.ReactNode<ImageIcon />What shows when there is no image — the app's brand mark.
hrefstring—Make the whole card a link. The title is the link, stretched over the card.
imagestring—The image URL. Missing or failing to load shows fallback. A card with neither image nor fallback has no image area at all.
linkRenderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>><a />The element the link renders — a router link such as <Link href="" />. The card's href wins over the template's.
metaReact.ReactNode—One muted meta line under the title ("8 products · 3 sub-families").
size"default" | "lg""default"default puts a 48px thumbnail on the left; lg puts a 16:9 image on top.
surfacebooleantrueDraw the card's own border, padding and hover. Off when a host (a Board card) owns the surface.
timestampReact.ReactNode—A last meta item after the badge — usually a RelativeTime ("2h ago").

Data attributes and CSS variables on MediaCard

AttributeValues
data-sizemirrors a prop or state value
data-slot"media-card" | "media-card-actions" | "media-card-meta" | "media-card-title"

Accessibility

  • The card is one link, named by its title; the meta line, badge and time are read after it.
  • The ⋯ menu sits above the stretched link, so it is its own tab stop and never follows the link. It shows on hover and on keyboard focus, and always on a touch screen.
  • The image is decorative (alt="") because the title names the record.
KeyAction
TabMove to the card link, then its ⋯
EnterOpen the record
Enter / SpaceOn ⋯, open the menu
ContractStates tested
Behaviourlink, plain, lg, no-media
Accessibilitylabeled, browser-accessibility-test
Visualdefault, hover

Do / Don't

Do
Keep the meta line to one short fact line; put a status or warning in the badge slot.
Don't
Put buttons or links inside the title or meta — the whole card is already the link.

On this page