Media

Images that identify a person or illustrate content, and frames that show another page (media.embed). Without a source it shows text instead, like initials.

Renders

imgiframe

Intents

Domains

Examples

People

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

Preview
ALGHAT
<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 fills its width at a fixed ratio.

Preview
An abstract gradient
<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.

Preview
No cover yet
<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.*

5 intents
  • media.person

    Identifies a person: their photo, or initials when there is none

    <img>
  • media.enlarged

    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

    An image that illustrates content: an article cover, a screenshot

    <img>
  • media.artwork

    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

    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.

  • intent required

    media.person or media.image.

    MediaIntent
  • alt required

    What the image shows (for a frame, its title). Its accessible name, and the source of the default initials.

    string
  • src

    The image URL. When it is missing, the fallback shows.

    string | null
  • fallback

    Text shown without an image. Defaults to the initials of alt.

    string
  • size

    For people: the size of the circle.

    'xs' | 'sm' | 'md' | 'lg' | 'xl'
  • loading

    When the image loads. Lazy by default.

    'lazy' | 'eager'
  • onError

    Called when the image fails, e.g. to clear src and show the fallback.

    () => void
  • vars

    Values that come from data, as CSS variables the intent reads: vars={{ '--accent': user.color }}.

    Record<`--${string}`, string | number>
  • unsafeClassName

    Bypasses the intent. Needs a // prongs-unsafe: <reason> comment on the line above, and prongs check counts it.

    string

Layout props

Where the element sits, never how it looks. Spacing between elements comes from the parent <Layout>.

  • align

    On text, the text alignment. On anything else, pushes it to that end of its row or column.

    'start' | 'center' | 'end'
  • width

    Full width, or a maximum width.

    'auto' | 'full' | 'prose' | 'sm' | 'md' | 'lg'
  • hideBelow

    Hidden on screens narrower than this breakpoint.

    'sm' | 'md' | 'lg'
  • showBelow

    Shown only on screens narrower than this breakpoint.

    'sm' | 'md' | 'lg'
  • truncate

    One line, cut off with an ellipsis.

    boolean
  • nowrap

    Keeps the text on one line.

    boolean

Rules

  • alt is required.

  • No className or style.