schmelczer-dev/src/components/PostMediaFigure.astro
Andras Schmelczer ca6ba2eb51
All checks were successful
Deploy to Pages / build (push) Successful in 2m51s
Shorten descriptions
2026-05-28 16:58:04 +01:00

81 lines
2.3 KiB
Text

---
import type { CollectionEntry } from 'astro:content';
import { Picture } from 'astro:assets';
type MediaItem = CollectionEntry<'posts'>['data']['media'][number];
interface Props {
item: MediaItem;
}
const { item } = Astro.props;
const videoWidth = item.type === 'video' ? (item.poster?.width ?? 1280) : undefined;
const videoHeight = item.type === 'video' ? (item.poster?.height ?? 720) : undefined;
---
<figure class="post-media">
{
item.type === 'video' ? (
// Decorative videos stay inert and hidden from assistive tech. Meaningful
// videos expose controls, captions, and an accessible name.
item.decorative ? (
<video
muted
playsinline
preload="metadata"
poster={item.poster?.src}
width={videoWidth}
height={videoHeight}
aria-hidden="true"
tabindex="-1"
>
{item.webm && <source src={item.webm} type="video/webm" />}
{item.mp4 && <source src={item.mp4} type="video/mp4" />}
</video>
) : (
<video
controls
preload="none"
poster={item.poster?.src}
width={videoWidth}
height={videoHeight}
aria-label={item.alt}
>
{item.webm && <source src={item.webm} type="video/webm" />}
{item.mp4 && <source src={item.mp4} type="video/mp4" />}
{item.captions && (
<track
kind="captions"
src={item.captions}
srclang="en"
label={item.captionsLabel}
default
/>
)}
</video>
)
) : (
item.src && (
<Picture
src={item.src}
alt={item.decorative ? '' : (item.alt ?? '')}
formats={['avif', 'webp']}
widths={[480, 960, 1280, 1920]}
sizes="(max-width: 700px) calc(100vw - 2 * clamp(20px, 4vw, 32px)), (max-width: 1100px) min(calc(100vw - 4rem), 56rem), 56rem"
quality="high"
loading="lazy"
decoding="async"
/>
)
)
}
{item.caption && !item.decorative && <figcaption>{item.caption}</figcaption>}
{
item.transcript && (
<p class="media-transcript">
<strong>Transcript:</strong> {item.transcript}
</p>
)
}
</figure>