Zoeken...  ⌘K GitHub

ContentMedia content

Koptitel met tekst en media (afbeelding, video of embed) in configureerbare layout.

/content-media
src/components/content/ContentMedia.astro
---
interface MediaItem {
  type: "image" | "video" | "embed";
  src: string;
  alt?: string;
  caption?: string;
  poster?: string;
}

interface Props {
  heading?: string;
  text?: string;
  media?: MediaItem;
  layout?: "media-top" | "media-bottom" | "media-right" | "media-left";
}

const {
  heading = "Achter de schermen bij BLURR",
  text = "Elke campagne begint met een kick-off waarbij strategie, creatie en media samen aan tafel zitten. Zo werken we integraal en verliest niets zich in de overdracht tussen teams.",
  media = {
    type: "image",
    src: "https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=900&q=80",
    alt: "BLURR team meeting met strategy boards",
    caption: "Onze wekelijkse campagne-review sessie in het Amsterdam kantoor.",
  },
  layout = "media-top",
} = Astro.props;
---

<div class={`cme-wrap cme-wrap--${layout}`}>
  <div class="cme-media">
    {media.type === "image" && (
      <figure class="cme-figure">
        <img class="cme-img" src={media.src} alt={media.alt ?? ""} loading="lazy" />
        {media.caption && <figcaption class="cme-caption">{media.caption}</figcaption>}
      </figure>
    )}
    {media.type === "video" && (
      <figure class="cme-figure">
        <video class="cme-video" controls poster={media.poster} preload="metadata">
          <source src={media.src} />
          Je browser ondersteunt geen video.
        </video>
        {media.caption && <figcaption class="cme-caption">{media.caption}</figcaption>}
      </figure>
    )}
    {media.type === "embed" && (
      <div class="cme-embed-wrap">
        <iframe class="cme-embed" src={media.src} allowfullscreen loading="lazy" title={media.alt ?? "Embedded media"}></iframe>
        {media.caption && <p class="cme-caption">{media.caption}</p>}
      </div>
    )}
  </div>
  <div class="cme-text-block">
    {heading && <h2 class="cme-heading">{heading}</h2>}
    {text && <p class="cme-text">{text}</p>}
  </div>
</div>

<style>
  .cme-wrap { padding: 2.5rem 0; }
  .cme-wrap--media-top,
  .cme-wrap--media-bottom {
    display: flex;
    flex-direction: column;
    gap: 2rem;
  }
  .cme-wrap--media-bottom { flex-direction: column-reverse; }
  .cme-wrap--media-right,
  .cme-wrap--media-left {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3rem;
    align-items: center;
  }
  .cme-wrap--media-right { direction: rtl; }
  .cme-wrap--media-right > * { direction: ltr; }
  @media (max-width: 700px) {
    .cme-wrap--media-right,
    .cme-wrap--media-left {
      grid-template-columns: 1fr;
      direction: ltr;
    }
  }
  .cme-figure { margin: 0; }
  .cme-img,
  .cme-video {
    width: 100%;
    height: auto;
    display: block;
    border-radius: 10px;
    object-fit: cover;
  }
  .cme-embed-wrap {
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
    overflow: hidden;
    border-radius: 10px;
    background: #000;
  }
  .cme-embed {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    border: none;
  }
  .cme-caption {
    font-size: 0.85rem;
    color: #888;
    margin: 0.75rem 0 0;
    line-height: 1.4;
  }
  .cme-heading {
    font-size: 1.75rem;
    font-weight: 800;
    color: var(--color-primary, #0a0a0a);
    margin: 0 0 1rem;
  }
  .cme-text {
    font-size: 1rem;
    line-height: 1.8;
    color: #555;
    margin: 0;
  }
</style>

Props

Prop Type Default Beschrijving
heading string Sectietitel
text string Inleidende tekst
media { type: "image"|"video"|"embed"; src: string; alt?: string; caption?: string; poster?: string } Media object
layout 'media-top' | 'media-bottom' | 'media-right' | 'media-left' Positie van het mediaobject

* = verplicht