# Media

Images that identify a person or illustrate content, and frames that show another page ([`media.embed`](https://www.prongs.dev/docs/intents/media/embed.md)). Without a source it shows text instead, like initials.

Renders: `img` `iframe` · Intents: [5](#intents-it-renders) · Domains: [`media.*`](https://www.prongs.dev/docs/intents/media.md)

## Examples

### People

Without `src`, a person shows their initials, taken from `alt`.

```tsx
<Layout intent="layout.group" className="flex-row items-center gap-3">
  <Media intent="media.person" alt="Ada Lovelace" size="sm" />
  <Media intent="media.person" alt="Grace Hopper" size="md" />
  <Media intent="media.person" alt="Alan Turing" size="lg" />
</Layout>
```

### An image

[`media.image`](https://www.prongs.dev/docs/intents/media/image.md) fills its width at a fixed ratio.

```tsx
<Media intent="media.image" src="/example-cover.svg" alt="An abstract gradient" width="md" />
```

### No image yet

`fallback` replaces the initials when they would not make sense.

```tsx
<Media intent="media.image" alt="Cover not uploaded yet" fallback="No cover yet" width="md" />
```

## Intents it renders

One domain, with its own page of neighbours and examples. The intent decides the element; these are the starter intents.

### Media [`media.*`](https://www.prongs.dev/docs/intents/media.md)

5 intents

| Intent | Use it for | Resolves to |
|---|---|---|
| [`media.person`](https://www.prongs.dev/docs/intents/media/person.md) | Identifies a person: their photo, or initials when there is none | `<img>` |
| [`media.enlarged`](https://www.prongs.dev/docs/intents/media/enlarged.md) | A photo shown as large as fits, in a frame of one fixed size so flipping between photos never moves anything: the photo in a dialog.media, edge to edge on its side. On small screens it is a square across the full width | `<img>` |
| [`media.image`](https://www.prongs.dev/docs/intents/media/image.md) | An image that illustrates content: an article cover, a screenshot | `<img>` |
| [`media.artwork`](https://www.prongs.dev/docs/intents/media/artwork.md) | The cover art of something people play, read or watch: an album, a book, a film poster. Taller than it is wide | `<img>` |
| [`media.embed`](https://www.prongs.dev/docs/intents/media/embed.md) | Another page shown inside this one: a video player, an article preview, a map. Its alt becomes the frame title | `<iframe>` |

## Props

Plus its element’s usual attributes (`id`, `onClick`, `aria-*`, `data-*`) and the shared layout props below. No `className` or `style`.

| Prop | Type | What it does |
|---|---|---|
| `intent` (required) | `MediaIntent` | [`media.person`](https://www.prongs.dev/docs/intents/media/person.md) or [`media.image`](https://www.prongs.dev/docs/intents/media/image.md). |
| `alt` (required) | `string` | What the image shows (for a frame, its title). Its accessible name, and the source of the default initials. |
| `src` | `string \| null` | The image URL. When it is missing, the fallback shows. |
| `fallback` | `string` | Text shown without an image. Defaults to the initials of `alt`. |
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | For people: the size of the circle. |
| `loading` | `'lazy' \| 'eager'` | When the image loads. Lazy by default. |
| `onError` | `() => void` | Called when the image fails, e.g. to clear `src` and show the fallback. |
| `vars` | `Record<`--${string}`, string \| number>` | Values that come from data, as CSS variables the intent reads: `vars={{ '--accent': user.color }}`. |
| `unsafeClassName` | `string` | Bypasses the intent. Needs a `// prongs-unsafe: <reason>` comment on the line above, and `prongs check` counts it. |

### Layout props

Where the element sits, never how it looks. Spacing between elements comes from the parent [`<Layout>`](https://www.prongs.dev/docs/components/layout.md).

| Prop | Type | What it does |
|---|---|---|
| `align` | `'start' \| 'center' \| 'end'` | On text, the text alignment. On anything else, pushes it to that end of its row or column. |
| `width` | `'auto' \| 'full' \| 'prose' \| 'sm' \| 'md' \| 'lg'` | Full width, or a maximum width. |
| `hideBelow` | `'sm' \| 'md' \| 'lg'` | Hidden on screens narrower than this breakpoint. |
| `showBelow` | `'sm' \| 'md' \| 'lg'` | Shown only on screens narrower than this breakpoint. |
| `truncate` | `boolean` | One line, cut off with an ellipsis. |
| `nowrap` | `boolean` | Keeps the text on one line. |

## Rules

- `alt` is required.
- No `className` or `style`.
