Image Card
v0.1.2DraftA card with an image on top and a title, subtitle and meta row below, for artwork lists, artist tiles and booking previews. It composes `atoms.card` with no padding, so fill, border and corners are Card's.
A card with an image on top and a title, subtitle and meta row below, for artwork lists, artist tiles and booking previews. It composes atoms.card with no padding, so fill, border and corners are Card's.
Usage
The ```jsx block above runs live on the docs site. Imports are stripped and every registry export is in scope, so you can compose with other components too.
Behaviour
- With
href, the whole card is one link named by the title. PasslinkComponent(for examplenext/link) for client-side routing. Keepmetanon-interactive: the link covers the card. Withouthrefthe card is static, with no hover or focus stop. - The media box holds its
aspectRatio(4/5,1/1or3/2) before the image loads. Give the image its descriptivealt. - If an
<img>inmediafails to load, including before hydration, the box shows an image icon at the same ratio. The icon is labelledunavailableLabel("Image unavailable") followed by the image's alt text. A newsrcon the image clears the failure. - The title clamps at two lines and the subtitle at one. In a grid row the card fills the row's height and
metasits on its bottom edge. - The hover glow reads
--brand-glow-violetfrom@behivetech/cms.base-styles; it is transparent in Light. Glow is on the card, never on text.
Examples
Open all 5 →Properties
ImageCard props
| Prop | Type | Default | Description |
|---|---|---|---|
media* | ReactNode | — | The image, or any node that holds one (`next/image` with `fill` works). Give the image its descriptive `alt`. If an `<img>` inside fails to load, including before hydration, the media box swaps it for an image icon at the same aspect ratio, labelled with `unavailableLabel` and the alt text. A new `src` on the image clears the failure. |
title* | ReactNode | — | Card title, clamped at two lines. It names the link when `href` is set. |
aspectRatio | "4/5" | "1/1" | "3/2" | 4/5 | Aspect ratio of the media box, held before the image loads. Defaults to `4/5`. |
className | string | — | Additional class names to merge with the component root element |
headingLevel | 1 | 2 | 3 | 4 | 5 | 6 | 3 | Which heading tag (`h1`-`h6`) wraps the title. Defaults to `3`. |
href | string | — | Makes the whole card one link, named by the title. Omit for a static card with no hover and no focus stop. |
linkComponent | ElementType | a | Component that renders the link, for client-side routing (pass `next/link`). Receives `href` and `className`. Defaults to a plain `a`. |
meta | ReactNode | — | Optional row on the card's bottom edge (a price, a status badge); keep it non-interactive |
subtitle | ReactNode | — | Optional line under the title, clamped at one line |
unavailableLabel | string | Image unavailable | Label for the failed-image fallback, read before the image's alt text. Defaults to "Image unavailable"; pass your translation. |
Also accepts the native attributes of its root element (className, aria-*, event handlers, …).
Hooks
useImageStatus hook
Tracks whether the `<img>` inside a wrapper failed to load, whatever component drew it (a plain `<img>` or an app's `next/image`). `resetKey` names the image: a new key clears the failure. An image that broke before hydration fires no event, so a mount also reads `complete` and `naturalWidth`.
useImageStatus(resetKey: string): ImageFailureResult| Parameter | Type | Default | Description |
|---|---|---|---|
resetKey | string | — | — |
Returns ImageFailureResult