All checks were successful
Deploy to Pages / build (push) Successful in 2m51s
119 lines
3.4 KiB
Text
119 lines
3.4 KiB
Text
---
|
|
import { Picture } from 'astro:assets';
|
|
import type { CollectionEntry } from 'astro:content';
|
|
import { absoluteUrl } from '../lib/site';
|
|
|
|
interface Props {
|
|
post: CollectionEntry<'posts'>;
|
|
}
|
|
|
|
const { post } = Astro.props;
|
|
const demoLink = post.data.links.find(
|
|
(link) => !link.download && link.label.trim().toLowerCase() === 'demo'
|
|
);
|
|
const iframeUrl = post.data.iframeThumbnail ? demoLink?.url : undefined;
|
|
const iframeSrc = iframeUrl?.startsWith('/') ? absoluteUrl(iframeUrl) : iframeUrl;
|
|
const iframeTitle = demoLink
|
|
? `${demoLink.label}: ${post.data.title}`
|
|
: `Embedded demo: ${post.data.title}`;
|
|
const aspectRatio = `${post.data.thumbnail.src.width} / ${post.data.thumbnail.src.height}`;
|
|
const iframeThumbnailScript = `
|
|
for (const root of document.querySelectorAll('.post-thumbnail--iframe')) {
|
|
const trigger = root.querySelector('[data-thumbnail-iframe-trigger]');
|
|
const frame = root.querySelector('[data-thumbnail-iframe-frame]');
|
|
if (!(trigger instanceof HTMLButtonElement) || !(frame instanceof HTMLIFrameElement)) {
|
|
continue;
|
|
}
|
|
|
|
trigger.addEventListener(
|
|
'click',
|
|
() => {
|
|
const src = trigger.dataset.iframeSrc;
|
|
if (!src) return;
|
|
|
|
if (window.isSecureContext === false) {
|
|
const opened = window.open('', '_blank');
|
|
if (!opened) {
|
|
window.location.href = src;
|
|
} else {
|
|
opened.opener = null;
|
|
opened.location.href = src;
|
|
}
|
|
return;
|
|
}
|
|
|
|
frame.src = src;
|
|
frame.hidden = false;
|
|
root.classList.add('is-active');
|
|
trigger.setAttribute('aria-expanded', 'true');
|
|
frame.focus();
|
|
},
|
|
{ once: true }
|
|
);
|
|
}
|
|
`;
|
|
---
|
|
|
|
<div
|
|
class:list={['post-thumbnail', iframeSrc && 'post-thumbnail--iframe']}
|
|
style={iframeSrc ? `--post-thumbnail-aspect: ${aspectRatio}` : undefined}
|
|
data-uncropped-preview
|
|
data-preview-label={post.data.title}
|
|
>
|
|
<Picture
|
|
src={post.data.thumbnail.src}
|
|
alt={post.data.thumbnail.alt}
|
|
formats={['avif', 'webp']}
|
|
fallbackFormat="jpg"
|
|
widths={[640, 960, 1280, 1920]}
|
|
sizes="(max-width: 700px) calc(100vw - 3rem), (max-width: 1100px) calc(100vw - 4rem), 56rem"
|
|
quality="high"
|
|
loading="eager"
|
|
fetchpriority="high"
|
|
decoding="async"
|
|
/>
|
|
|
|
{
|
|
iframeSrc && (
|
|
<>
|
|
<button
|
|
class="post-thumbnail__play"
|
|
type="button"
|
|
data-thumbnail-iframe-trigger
|
|
data-iframe-src={iframeSrc}
|
|
aria-label={`Play ${demoLink?.label.toLowerCase() ?? 'demo'}`}
|
|
aria-expanded="false"
|
|
>
|
|
<span class="post-thumbnail__play-icon" aria-hidden="true">
|
|
<svg viewBox="0 0 24 24" focusable="false">
|
|
<path d="M8 5v14l11-7z" />
|
|
</svg>
|
|
</span>
|
|
<span class="sr-only">Play {demoLink?.label.toLowerCase() ?? 'demo'}</span>
|
|
</button>
|
|
<iframe
|
|
class="post-thumbnail__iframe"
|
|
data-thumbnail-iframe-frame
|
|
title={iframeTitle}
|
|
src="about:blank"
|
|
allow="fullscreen; webgpu"
|
|
allowfullscreen
|
|
referrerpolicy="strict-origin-when-cross-origin"
|
|
tabindex="0"
|
|
hidden
|
|
/>
|
|
<noscript>
|
|
<p class="post-thumbnail__noscript">
|
|
<a href={iframeSrc}>Open {demoLink?.label.toLowerCase() ?? 'demo'}</a>
|
|
</p>
|
|
</noscript>
|
|
</>
|
|
)
|
|
}
|
|
</div>
|
|
|
|
{
|
|
iframeSrc && (
|
|
<script is:inline data-thumbnail-iframe-script set:html={iframeThumbnailScript} />
|
|
)
|
|
}
|